0%

第一个python+ml实验的踩坑记录

记下bug笔记,随时更新。


1.jpg的图片读入三通道,.bmp读入单通道。不知道是不是所有的,反正我看到的这个dataset是的。

三通道转一通道方法可能很多吧,到了我这各种不好用/嫌麻烦。目前的处理方法,维度是对的imread读进来直接(0,255)的整数。但是保存图像的时候需要转换成-1~1的格式 (至于怎么弄成<0的我也不知道)。

*更新:读取/保存图像的时候都是既可能出现(0,1)的,又可能出现(0,255)的,python碰到这两种都会自动读写,但是自己使用需要注意带适应性的转换。

*图像格式转化应该是我改了时间最长的bug。

*注意:0是黑。1、255是白。= =。

*做dl的时候要用0-1的。不然训练可能不好。

  • //是整除, /如果想做float运算,除数尽量不要放整数。

刚刚修改,之前用的as_gray=True,跑了下不错

然后因为warning用回旧版本,发现旧版本的imread不支持

希望这回不出问题

img = imread(self._path + name + ‘.jpg’, as_grey=True)
img = img.astype(np.uint8)

  • 更新:as_grey和as_gray都可能报错/报警告,取决于当前环境版本(- -),反正我换服务器的时候遇到了麻烦。

2.linux环境下用os.listdir()读文件夹下的所有文件的顺序不固定。排序即可。windows有顺序。

if not os.path.exists(new_path):
os.makedirs(new_path)
files = os.listdir(new_path)
files.sort()
pictures = os.listdir(old_path)
pictures.sort()
3.Dataloader+lambda在windows+cpu下好像不是很好用,建议使用linux。查了一下windows好像需要手写一大段东西。

运行时出现Ran out of input以及Can’t pickle local object ‘train..
4.遍历、用Dataset等,文件夹地址不要少写后面的/。

更新:基本上训练的时候发现loss和acc怎么弄都不变,训练得还很快,八成是这个问题。

test_data = KidneyData(‘/data2/wzy/train_subset/0_100/‘, transforms=Null, mode=’train’)
loader = DataLoader(test_data, batch_size=1, num_workers=1)
5.cv2.imshow在我用ssh连linux服务器跑程序的时候不能用。很吃惊了。X server是linux显示图像的应用程序。

更新:但是plt.show是可以用的。另外,root选对,pycharm可以查看远程服务器的代码。

cannot connect to X server
6.pytorch,unsample废弃的改写方法:

更新:需要小心谨慎,换回原版本的服务器,用新写法反而可以报错。

nn.functional.interpolate(…, mode=’bilinear’, align_corners=True)
7.pytorch.Dataset一定不要同时保存img和label的name用来遍历。因为在shuffle=True的情况下,遍历可能会出现img和label不对应的情况。

self._img_names = load_img_names(path)
# self._lbl_names = load_label_names(path)
8.传参可以少一点,适当定义全局变量,大量传参和定义新数据会让网络训练变慢。函数内部调用全局变量用global。

1
2
3
4
5
6
7
8
9
10
11
12
13
import UNet
net = UNet(in_shape, 1)
net.load_state_dict(torch.load(model_file))
initial_loss, initial_acc = val(net, main_device, validate_loader)
pre_loss, pre_acc = initial_loss, initial_acc
# wzy, 2019/3/6
def get_reward(data, target):
(batch_data, batch_labels) = extend_one_image_to_batch(data, target, args.batch_size)
global pre_loss
global pre_acc
global net
...
return

9.resize从正方形到小矩形可能出错?待验证。

10.cv2.resize比skimage快很多,尽量用这个。

*更新:不同的函数速度也可以差很多。有点担心可以用time打一下。

1
2
3
4
start_time = time.time()
self._take_action(action)
end_time = time.time()
print('s_take_action%%%%%%%%%%%%%%%%%%Time:{}'.format(end_time - start_time))

11.常数级优化很重要,尤其是和图像和神经网络相关的操作就本身很慢,例如能少用一次val就少用一次

12.linux文件可以空格开头,导致读写文件找不到。(debug半天发现的,第一感觉是活久见- -)

13.如果import文件A.py,所有A.py全局的东西都会在import的时候自动创建对象。

比如网络加载和全局计算,调用类也一样。import的时候要谨慎,尽量装在类里调用类。反正注意结构。

14.某些强调的东西(如image类型、size)打上注释,简洁明了不易遗忘,方便debug。

15.有时候没必要保证代码迁移性,除非是自己之后工作还用得到。

16.函数拆成小块,尽量不要大段的写在主函数里,命名尽量不要main(),便于在其他函数中调用多跑几次。

17.服务器vnc的代码,一个文件可以同时多次运行。但是来一个stop就不一定是哪个停了。

18.注意模型中所有的seed,该固定还是随机。怕重复和复现就不断修改,避免出现:随机分dataset每次结果不同 / 跑几次实验结果一模一样 的尴尬局面。

19.可能会修改的东西留个记录。比如 centroid_distance 应该用欧式距离还是曼哈顿距离,可以把x,y结果分别存起来。

20.注意内存消耗:以后绝对用不到的东西(如中间模型)就删了吧,或者用完自动删。不小心占满服务器是个很可怕的东西。

21.注意修改范围:如setting有3个GPU。到了文件,不要直接从setting调用,可以先在文件全局放一个now。方便修改。

22.(用于分割)提取mask边缘,用于多方法对比。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from skimage.color import gray2rgb
from skimage.feature import canny
from skimage.morphology import dilation, square # 滤波器,dilation扩张白色部分压缩黑色部分。square正方形

# img(0-255),想提取边缘特征的图

rgb_img = gray2rgb(img)
gt_edges = canny(gt_img, sigma=3) # 提取边缘特征。sigma是画笔粗细
gt_edges = dilation(gt_edges, square(2)) # 或许是填充吧。。

# 反正输出是边缘白其他地方黑的图gt_edges。
# 以下给边缘染色,得到rgb_img.

if mode == 'r':
rgb_img[gt_edges == 1, 0] = 255
rgb_img[gt_edges == 1, 1] = 0
rgb_img[gt_edges == 1, 2] = 0

# 考虑 /= 255.0

return rgb_img

23.数组(图像)裁剪(注意范围),注意如果只有一个:的时候位置不要错。

img_cropped = img[max(0, coordinate[0] - 75):min(256,coordinate[0] + 75), max(0, coordinate[1] - 75):min(256,coordinate[1] + 75)]
24.尽量少对result文件用reset。如果删了有用的结果,比有一些闲杂的数据问题大一些。

25.保存结果,对比实验的命名尽量不同,文件夹尽量相同。

  • 尽量用tsv(脑补)。

  • 如果要处理结果,比如排序和筛选,变色,一定要另存为excel。

  1. format()和,os.path.join(),虽然写起来麻烦,写错的概率比+和%低一些?

27.不需要规规矩矩一个一个验证、而且可能要跑多次取均值的model,可以通过预先判断筛选掉一些。(反正服务器早晚是你的,没必要不浪费,不如节省时间多跑跑好的模型)

-------------这么快就看完啦^ω^谢谢阅读哟-------------