解决异常退出
代码问题
一、进程已结束,退出代码-1073740791 (0xC0000409)
描述:医学图像的处理任务,图片的读取方式不对,未加载到图片,退出
异常代码:
roi_mask = Image.open(self.roi_masks[idx]).convert('L')
可运行的读取方式:
- png、tif一般格式读取
img = cv2.imread(self.images[idx])
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
- gif动图读取
gif_roi = imageio.get_reader(self.roi_masks[idx])
first_frame = gif_roi.get_data(0)
roi_mask = np.uint8(np.array(first_frame))
二、电脑一直运行代码
win+R、control到控制面板
三、远程服务器搭建
- 新建解释器
选择系统环境下创建,一般路径如下:
2. 配置
配置选UTF-8:
选项:
- 同步文件夹——FileZilea
设置站点,输入接口、用户、密码
打开共享的文件夹和代码在本地的文件夹。上传时,让光标在对应的位置,是上传或者下载到对应的文件夹下
四、小问题
1.进程已结束,退出代码137
内存不够,选择远程服务器
2.损失函数
-
BCELoss
需要输出经过sigmoid函数 -
DiceLoss
输出与标签需要相同Size,但是为图像分割任务,设置分割内容和背景为两类,仅有标签输出,格式无法统一,不知怎么使用DiceLoss -
交叉熵损失
比较简单,虽然效果不好
3.RuntimeError: DataLoader worker (pid(s) 41716) exited unexpectedly
解决:把num_work变成0,但会降低训练效率
4.【PaddleDetection报错】IndexError: Target xxx is out of bounds. 或者 loss.backward()报错RuntimeError: CUDA error: device-side assert triggered
试过num_class加1、交叉熵函数的输入权值W,都不是这的问题
排查后,是代码的问题:标签有异常值
manual[manual == 255] = 1 # 前景像素点为 1
roi_mask = 255 - np.array(roi_mask)
target = np.clip(manual + roi_mask , a_min=0, a_max=255) # ground truth中前景为1,背景为0不感兴趣为255
正确结果要求输入网络的样本是这几种值,才能正确训练
5.一个小问题:
由于数据加载的方式不对,样本和标签未对齐
img_names = [i for i in os.listdir(os.path.join(data_root, "images")) if i.endswith(".png")] # 保存images的 tif 结尾的文件名 改为png
self.images = [os.path.join(data_root, "images", i) for i in img_names]
self.labels = [os.path.join(data_root, "1st_manual", "task-" + str(int(re.search(r'\d+', i).group())) + ".png" ) for i in img_names]
self.transforms = transforms
# mask 文件的路径
self.roi_masks = [os.path.join(data_root, "mask", "mask" + str(int(re.search(r'\d+', i).group())) + ".tif" ) for i in img_names]
注:unet传统网络的输入分辨率是480*480
6.确定normalization的参数 mean、std
统计数据集中的mean和std
7.image.permute(1, 2, 0),图像显示
为了适应特定的图像显示或处理库的格式。在很多图像处理库(比如 Matplotlib)中,期望的维度顺序是 (height, width, channels),而 PyTorch 默认的维度顺序是 (batch_size, channels, height, width)。
总结
对于问题的解决,大致有两种,一是共性问题,属于电脑环境或者某个属性设置,在网上找攻略解决;二是个人代码问题,要进入debug,一部一部找到异常代码定位
通常,就个人而言,大致为第二种,要先从自身代码去找问题!