在python中遇到的错误(二):用pytorch的CNN发生的报错

目录

一、conv2d() received an invalid combination of arguments

二、 expected scalar type double but found float

三、shape '[-1, 3136]' is invalid for input of size 35200000

四、expected scalar type Long but found Double

五、训练精度和测试精度都很低


最近在写机器学习的第二个大作业,因为要求是用神经网络去完成,上一学期模式识别用的是简单的BP,但是这学期是要求深度神经网络,所以想用CNN——卷积神经网络来做。但是。。。当然,遇到了特别多的问题。

一、conv2d() received an invalid combination of arguments

写CNN的时候,我借鉴的是这篇文章:

(60条消息) Python PyTorch6:卷积神经网络_Amzmks的博客-CSDN博客_卷积神经网络python

然后我把其中下载的数据集换成了我的数据集,就会发生以下报错

 刚开始我真的以为是cov2d这个函数的参数输入不对,然鹅,我发现怎么该参数都一样地报错,后来我思考了一下,我新建了一个文件,输入以下代码:

self.conv1 = nn.Sequential(nn.Conv2d(1, 64, 5, 1, 2), nn.ReLU(), nn.MaxPool2d(2, 2))

也就是报错的那句代码,运行,却没有报错。

然后我就觉得,一定是我输入的图片的格式的问题。

我的图片数据是np.array格式,二维数组,于是我就觉得我应该在原代码里调试一下,看一下别人训练前的数据格式是什么。

发现原来别人的格式是Tensor

参照文章:(60条消息) Pytorch中Tensor与各种图像格式的相互转化_明泽.的博客-CSDN博客_tensor转图片

可以知道在pytorch中,应该是用tensor ,但是我用cv2读取图片,得到的数据格式是array,所以在训练前应该先将格式转换。

同学们可以参照上面那篇文章进行格式转换。

二、 expected scalar type double but found float

这里卡了很久,出错原因是因为我的输入是的是float64类型的tensor,但是我改为double后并不能解决问题,后面运行示例代码调试,查看输入数据的类型,发现是float32,将64转化为32后,这个问题就能解决了。

即在训练前,加入以下语句:

imag = imag.type(torch.float32)

三、shape '[-1, 3136]' is invalid for input of size 35200000

啊,这就是困扰了我很久的问题,查找资料,如下面一篇:

(60条消息) mat1 and mat2 shapes cannot be multiplied ( )的解决_相扑小猫的博客-CSDN博客

在这篇文章当中,作者的错误是前后不一致,当然我并没有犯这个错,当然不排除有同学会犯这个错。

然后我又看到了一篇文章:(60条消息) bug解决:shape [-1, 400] is invalid for input of size 179776_hamimelon2020的博客-CSDN博客

可以看到,这个作者并没有犯和先前一个作者一样的错,但他依然得到了报错,这是为什么呢?

通过观察这篇文章,我们发现,这个作者解决问题是将原来的数字改大了:

#self.fc1 = nn.Linear(16 * 5 * 5, 120) # 接着三个全连接层 ,原代码,错误的代码
self.fc1 = nn.Linear(16 * 53 * 53, 120) # 接着三个全连接层 修改后的正确的代码
#.....后面的
#x = x.view(-1, 16 * 5 * 5) #原代码,错误的代码
x = x.view(-1, 16 * 53 * 53) #修改后的正确的代码

现在让我们仔细分析一下,到底是怎么一回事?

后来,经过我的发现,这里的“16”代表的是你训练时输入的这一批样本的数量,'53*53’代表的是你的每张输入的图片的大小/2^全连接层层数,也就是说,如果你的这个参数跟你输入样本的参数不一致的话,就会发生这样的报错。

解决方法:将nn.Linear的第一个参数改为 

你一次性输入网络的图片样本数量*(你输入的图片的高/(2^全连接层数))*(你输入图片的宽/(2^全连接层数))

,并且同时修改下面的view()中的参数

如果你的错误跟我一样,也许就能解决了

四、expected scalar type Long but found Double

这个错误是在用entropy_loss()时出现的。

值得注意的是用这个函数时,Label要转换成long类型

loss = entropy_loss(out, labels.long())

五、训练精度和测试精度都很低

刚开始我的网络精度无论是训练精度,还是测试精度只有10%左右,把我给吓倒了。

于是我开始四处寻找解决方案。

总结出了以下几个可能:

1. 自身的代码有问题

2.样本数量太少,不够网络训练,可以改成更小的网络

3.网络输出结果不变,可能是因为激活函数使用ReLu等,换成Tanh或者其他激活函数应该可能有所帮助,激活函数的修改可以参考:

(61条消息) Pytorch的22个激活函数_Wanderer001的博客-CSDN博客

4.LOSS变化不大(不是一成不变),可能是因为训练次数不够,加入更多的数据集,或者可以尝试将训练集打乱,再输入网络训练。

5.如果是分类问题,可以尝试换作编码来解决问题,比如第一类的label设为100,第二类的label设为010,第三类的Label设为001

6.没有进行归一化

后面通过这些解决方案也能达到90%的精确度了。

你可能感兴趣的:(在Python里遇到的各种错误,python,开发语言,cnn)