pytorch & tensorflow一些记录

Pytorch的DataParallel多GPU

可以多卡并行训练,但是当输入size过大或者模型过大(一般是因为输入),即使是batch_size=1,显存也会炸。实际上DataParallel的机制可以理解为:

一个batch的数据可以根据卡数分配到各个GPU上做前向和后向传播,举个例子,4卡训练的时候batch_size=4每张卡相当于读一个数据,batch=2的时候只会用上2张卡。

所以即使是多卡,也需要保证一次输入所耗费的显存(包括模型、输入、优化等的总和)小于单卡显存。

当用到模型具体子layer时如果多卡训练调用要改一下,out = model.fc(input)要改成out = model.module.fc(input)

refer:DATA parallelism

实时可视化

tensorboardX (推荐)
visdom

pytorch中的深浅拷贝和引用

a = np.arange(12)
b = a   #没有copy,b和a指向的是同一个对象
b = a.view()  #b是新对象,但是和a共享数据
b = a.copy()  #深拷贝
numpy.repeat在不同维度上复制

tensor和numpy转换,实际上也是引用,abc会同时修改:

b = torch.from_numpy(a); c = a.numpy()

clone相当于完全复制,也包括了梯度的复制,所以带梯度的变量的clone的requires_grad也是True。

修改clone后的变量不会改变原始变量,他们不共享内存,如果简单的a=b,是共享内存,同时改变。detach也是共享内存的,只是return的是requires_grad=False的tensor

refer:discuss

pytorch 记录

detach().clone()clone().detach()的区别,先分离再clone和先clone再分离,第一种更合理,detach and clone

leaf变量不能进行in-place操作

Pytorch逻辑控制,不能用((target>0) and (normal_mask>0)).detach()或者(target>0 & normal_mask>0).detach(),而是要用((target>0) & (normal_mask>0)).detach(), logical-operation-in-torch

train时出现nan可能是因为lr过大,loss reference

dataload偶尔报错

File "/mnt/lustre/chenshenzhou/anaconda3/envs/torch/lib/python3.6/site-packages/torch/utils/data/dataloader.py", line 289, in __init__
w.start()
File "/mnt/lustre/chenshenzhou/anaconda3/envs/torch/lib/python3.6/multiprocessing/popen_fork.py", line 66, in _launch
self.pid = os.fork()
OSError: [Errno 12] Cannot allocate memory

Google到原因是多任务训练的时候load数据的时候内存峰值爆了。解决:dataloader的num_worker=0,即不使用多线程。当然这样速度会变慢。

如果output是一个scalar,只用普通的out.backward(), 如果输出是一个向量就要加参数,如输出是一个三维向量y时,就要vector-Jacobian product:

v = torch.tensor([0.1, 1.0, 0.0001], dtype=torch.float) y.backward(v)

pytorch设置可学习系数

在model的init中:

self.a0 = torch.nn.Parameter(torch.FloatTensor(1), requires_grad=True)
self.a0.data.fill_(0.0)

然后在forward中:

conv0_sum = torch.add(xd, torch.mul(xi, self.b0))
conv0I_sum = torch.add(xi * self.a0, xi)
conv1_d = self.conv1_d(conv0_sum) 
conv1_i = self.conv1_i(conv0I_sum)

pytorch loss 可学习weight

注意不能:

self.weight_d = torch.nn.Parameter(torch.FloatTensor(1), requires_grad=True).cuda()

这样的话分配到cuda上后不参与梯度计算了。而是要:

self.weight_d = torch.nn.Parameter(torch.FloatTensor(1).cuda(), requires_grad=True)

reference:
tensor-grad-none-for-tensors-on-gpu

而且不能把weight单独写到loss func里面就完事。那样的话虽然会算梯度但是weight值不会变,正确的操作在loss func中的init定义nn.Parameter形式的weight,并在其forward中使用,然后把整个loss func加入到网络中,在train阶段调用model.module.lossfunc。此外,为了保证loss加权的时候0-1,要先对weight经过一次sigmoid之类的激活。
For example:

w_sigmoid = self.m(self.weight)
self.loss = (diff ** 2).mean() * w_sigmoid + (diff_intensity ** 2).mean() * (1 - w_sigmoid) * self.lamda

pytorch eval时显存炸的问题:

有时网络在train的时候不会炸,但是存在best模型用eval模式跑gpu显存会炸,Google到原因:
eval issues
是因为之前的代码,只在算loss和评估指标的时候用

with torch.no_grad():

包裹,实际上在dataloader取batch和inference之前就要包裹,否则动态图会越来越大

tensorflow记录

有的estimator要tf1.5及以上版本,查官网得知tf1.4以上需要cuda9,最新的1.13需要cuda10. 为了保证一致性选择和作者一样的1.11.0, cuda9版本。cuda8和9共存安装见it网站。同时,用pip install tensorflow-gpu==1.11.0安装后调用一直没法用gpu,只能检测到device cpu0. 解决方案:pip uninstall tensorflow* , conda create -n tf_gpu tensorflowgpu =1.11.0, 直接在conda环境下使用,可以在本地用gpu。然而在集群上不能跑,1.11版本会报错:

tensorflow.python.framework.errors_impl.InternalError: cudaGetDevice() failed. Status: CUDA driver version is insufficient for CUDA runtime version

解决方案:tf1.11依赖nvidia驱动版本396.54,集群是384.90, 需要降级,降级的时候还要注意cudnn的版本集群上是7.0.4, 而conda直接安装tf会下cudnn7.3的依赖。。要先手动装cudnn7.0再装tf。

tensorflow是静态图,定义一个图以后重复运行,只有input能改;pytorch是动态图,每次forward都是一个新的计算图。静态图高效,不用重复建图,适合多机分布、落地;动态图使用更灵活。

train的时候标准化等CNNTricks reference

CNNTricks

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值