You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

眼底图像数据集迭代时Jupyter Notebook崩溃的优化方案与最佳实践咨询

眼底图像数据集迭代时Jupyter Notebook崩溃的优化方案与最佳实践咨询

看起来你的Jupyter Notebook崩溃主要原因是一次性把太多图像加载到内存里了——3662张眼底图哪怕每张是1024x1024的RGB图,每张就占3MB左右,全部存起来就是10GB+,内存肯定扛不住!下面给你几个优化思路和修改后的代码示例:

核心问题分析

你的原代码有两个关键问题:

  1. 不必要的分块逻辑:把3662条数据分成1000块,相当于每次只处理3-4张图,反而增加了循环的额外开销
  2. 内存爆炸的存储方式:把所有图像的numpy数组都存在training_images列表里,这是内存占用的重灾区,完全没必要(尤其是你现在只是做可视化探索)

优化方案与修改后的代码

1. 内存友好的迭代思路

只存储轻量的元数据(图像路径、标签ID),不把整个图像数组长期保存在内存中;可视化时按需加载图像,用完就释放资源。

import os
import cv2
import pandas as pd
import numpy as np
import tqdm
import matplotlib.pyplot as plt
import gc

# 初始化统计项
count = {"No DR": 0, "Mild DR": 0, "Moderate DR": 0, "Severe DR": 0, "Proliferative DR": 0}
missing_labels = []  # 只存图像ID,不存图像数组
invalid_image_paths = []  # 记录无法读取的图像路径
# 如果你后续需要保留数据关联,只存路径和标签即可(内存占用极低)
dataset_meta = []

# 直接迭代整个DataFrame,用tqdm显示全局进度
for idx, row in tqdm.tqdm(df.iterrows(), total=len(df)):
    img_id = row['id_code']
    img_path = os.path.join(path, f"{img_id}.png")
    label = row["diagnosis"]
    
    # 处理缺失标签的情况
    if pd.isna(label):
        missing_labels.append(img_id)
        continue
    
    # 统计标签分布:把数字诊断映射到类别名称
    diag_to_class = {
        0: "No DR",
        1: "Mild DR",
        2: "Moderate DR",
        3: "Severe DR",
        4: "Proliferative DR"
    }
    class_name = diag_to_class[label]
    count[class_name] += 1
    
    # 保存轻量元数据(可选,用于后续处理)
    dataset_meta.append( (img_path, label) )
    
    # 可视化探索:每50张图显示1张(避免一次性显示太多)
    if idx % 50 == 0:
        try:
            # 按需加载图像
            img = cv2.imread(img_path, cv2.IMREAD_COLOR)
            if img is None:
                invalid_image_paths.append(img_path)
                continue
            
            # cv2默认读BGR,转RGB适配matplotlib显示
            img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
            
            # 显示图像
            plt.figure(figsize=(6,6))
            plt.imshow(img_rgb)
            plt.title(f"Diagnosis: {class_name}\nImage ID: {img_id}")
            plt.axis('off')
            plt.show()
            
            # 释放当前图像的内存
            plt.close()  # 关闭画布
            del img, img_rgb  # 删除变量
            gc.collect()  # 手动触发垃圾回收
        except Exception as e:
            print(f"Error processing {img_path}: {str(e)}")
            invalid_image_paths.append(img_path)

# 输出统计结果
print("\n===== 数据集统计结果 =====")
for cls, cnt in count.items():
    print(f"{cls}: {cnt}")
print(f"\n缺失标签的图像数量: {len(missing_labels)}")
print(f"无法读取的图像路径数量: {len(invalid_image_paths)}")
if invalid_image_paths:
    print("部分无效路径示例:", invalid_image_paths[:5])

2. 额外的Jupyter内存管理技巧

  • 定期重启Kernel:如果Jupyter内存占用越来越高,重启Kernel可以清空之前的变量占用
  • %memit魔法命令检测代码块的内存消耗(需要先安装memory_profiler
  • 避免在循环中创建大量临时变量,用完就用del删除

备注:内容来源于stack exchange,提问作者Abas jama

火山引擎 最新活动