8个计算机视觉深度学习中常见的Bug
a, b, c, d = i, min(h, i + self.size), j, min(w, j + self.size) patch = x[a:b, c:d, :] mask[a:b, c:d, :] += np.expand_dims(self.predictor(patch), -1) weights[a:b, c:d, :] += 1 return mask / weights 如果你仍然不知道问题出在哪里,请注意 weights[a:b,c:d,:]+=1这一行。 8. Imagenet归一化 当一个人需要进行转移学习时,用训练Imagenet时的方法将图像归一化通常是一个好主意。 让我们使用我们已经熟悉的albumentations库。 from albumentations import Normalize norm = Normalize() img = cv2.imread('img_small.jpg') mask = cv2.imread('mask_small.png', cv2.IMREAD_GRAYSCALE) mask = np.expand_dims(mask, -1) # shape (64, 64) -> shape (64, 64, 1) normed = norm(image=img, mask=mask) img, mask = [normed[x] for x in ['image', 'mask']] def img_to_batch(x): x = np.transpose(x, (2, 0, 1)).astype('float32') return torch.from_numpy(np.expand_dims(x, 0)) img, mask = map(img_to_batch, (img, mask)) criterion = F.binary_cross_entropy 现在是时候训练一个网络并对单个图像进行过度拟合了——正如我所提到的,这是一种很好的调试技术: model_a = UNet(3, 1) optimizer = torch.optim.Adam(model_a.parameters(), lr=1e-3) losses = [] for t in tqdm(range(20)): loss = criterion(model_a(img), mask) losses.append(loss.item()) optimizer.zero_grad() loss.backward() optimizer.step()
_ = plt.plot(losses) 曲率看起来很好,但是交叉熵的损失值-300是不可预料的。是什么问题? 归一化处理图像效果很好,但是mask没有:需要手动缩放到 [0,1]。 model_b = UNet(3, 1) optimizer = torch.optim.Adam(model_b.parameters(), lr=1e-3) losses = [] for t in tqdm(range(20)): loss = criterion(model_b(img), mask / 255.) losses.append(loss.item()) optimizer.zero_grad() loss.backward() optimizer.step()
_ = plt.plot(losses) 训练循环的简单运行时断言(例如 assertmask.max()<=1会很快检测到问题。同样,也可以是单元测试。 总结 测试很有必要 运行时断言可以用于训练的pipeline; 可视化是一种幸福 复制粘贴是一种诅咒 没有什么是灵丹妙药,一个机器学习工程师必须总是小心(或只是受苦)。 (编辑:应用网_丽江站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |