基于pytorch建立的模型踩坑记录

踩坑目录

1. forward函数内不要定义网络层

2.  每个batch中 时间序列长度不同的问题

3. GPU利用率低的问题

4. Pytorch: RuntimeError: expected Double tensor (got Float tensor)

5. Python: 使用pairwise_distance函数计算l1范数距离出现错误

 

开始使用pytorch建立神经网络模型,对一些遇到的坑进行记录。

1. forward函数内不要定义网络层。如卷积层、全连接层等

定义model类的时候,有init函数用于初始化一些网络层,forward里进行前向计算。

网络层,如Conv层、Linear层,要将其放在init里,不要放在forward里。

但需要注意的是,池化层定义在forward里应该是没有问题的。

测试案例:

1. 函数层放在init函数里:

基于pytorch建立的模型踩坑记录_第1张图片基于pytorch建立的模型踩坑记录_第2张图片

函数层放在forward函数里:

基于pytorch建立的模型踩坑记录_第3张图片基于pytorch建立的模型踩坑记录_第4张图片

猜测可能是因为在forward里定义函数层的话,其在测试时候没有eval,测试结果中,预测的data效果巨差。此外,虽然loss也是下降的,但是与第一个结果也存在明显差异。

2.  每个batch中 时间序列长度不同的问题

在时间序列处理中,采用在每个batch中选择最长长度序列长度 + 补零。

因此,在每个batch中,时间序列长度是不一样的,例如,在第一个时间序列batch为 (128, 36, 8),128位批大小,36为时间步长, 8位每个时间戳的特征量大小。第二个时间序列batch为(128, 46, 8)。

这就带来了问题,在lstm模型中,时间序列长度不一,对于一些应用可能带来影响。

解决方式:

torch.cat和torch.zeros,整理来说就是进行补零,相关代码如下:

a = torch.zeros((500, 32, 8))
b = torch.zeros((500, 12, 8))

c = torch.cat((a,b),1)

这样,c就被步长到了50个时间戳长度。对于46时间戳的方式,也可以用这个方法。

这在解决的问题之一,是batch内time steps长度一样的同时,补零到长度多少是一个问题,其实可以根据时间戳最长度进行组合,也可以人为设置一个大的数字,例如500、600等。

3.  手写模型GPU占用率低问题

自己写了一个attention的框架方法,在GPU训练时,一个256尺寸的数据的训练时间高达13min,简直是灾难。

大佬听到了我的这个答案之后,无奈的指导让我查看一下cpu和gpu的占用。

查看CPU占用指令:

top

看CPU的占用率。

查看GPU占用率:

nvidia-smi

基于pytorch建立的模型踩坑记录_第5张图片

smi的数据解读:

基于pytorch建立的模型踩坑记录_第6张图片

发现问题,GPU使用率竟然一直是1% 0%,说明很多关于数据的运算没有在GPU中进行。

解决方案: 将手写的Attention函数加入cuda,放入GPU中进行运算。

经过修改,现在经过一个batch_size的运行时间约为1min,较原来的14min明显改善,查看GPU的占用率也为33%多,GPU真香。

4. Pytorch: RuntimeError: expected Double tensor (got Float tensor)

错误提示为此时的量是一个double类型的tensor,而应该是一个float类型的。

解决方案:

tensor.from_numpy(img).float()

5. Python: 使用pairwise_distance函数计算l1范数距离出现错误

错误提示:return torch.pairwise_distance(x1, x2, p, eps, keepdim)
IndexError: Dimension out of range (expected to be in range of [-1, 0], but got 1)

解决方案: 直接写就行了

pwise_dist = torch.abs(distance_embeddings1[edge_ixs0[0]]- distance_embeddings1[edge_ixs0[1]])

你可能感兴趣的:(基于pytorch建立的模型踩坑记录)