眼底图像数据集迭代时Jupyter Notebook崩溃的优化方案与最佳实践咨询
眼底图像数据集迭代时Jupyter Notebook崩溃的优化方案与最佳实践咨询
看起来你的Jupyter Notebook崩溃主要原因是一次性把太多图像加载到内存里了——3662张眼底图哪怕每张是1024x1024的RGB图,每张就占3MB左右,全部存起来就是10GB+,内存肯定扛不住!下面给你几个优化思路和修改后的代码示例:
核心问题分析
你的原代码有两个关键问题:
- 不必要的分块逻辑:把3662条数据分成1000块,相当于每次只处理3-4张图,反而增加了循环的额外开销
- 内存爆炸的存储方式:把所有图像的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




