用vgg和alexnet在mnist数据集上遇到的错误(Negative dimension size caused by subtracting 3 from 1 for...)

前言

在用mnist训练vgg和alexnet数据集时,出现标题所示的错误。而再用Le-Net训练的时候则不会出现错误。另外这里我使用的输入图片维度为28x28x1(mnist的数据维度为784x1x1),修改为784x1x1依然出错;采用的填充方式是,卷积层采用补零填充,池化层不采用补零填充。

解决

先说解决办法。

  1. 修改输出图片的大小。往大的修改。
  2. 修改卷积层和池化层的填充方式。往填充零方向修改。
  3. 其他博客介绍的方法。

原因

首先先来看卷积层和池化层过滤后的矩阵输出维度公式,分为补零和不补零两种情况。

  • 补充零公式:

    o u t l o n g = ⌈ i n l e n g t h s t r i d e l e n g t h ⌉ out_{long} = \lceil{\frac{in_{length}}{stride_{length}}}\rceil outlong=stridelengthinlength

    o u t w i d t h = ⌈ i n w i d t h s t r i d e w i d t h ⌉ out_{width} = \lceil{\frac{in_{width}}{stride_{width}}}\rceil outwidth=stridewidthinwidth

  • 不补零公式:

    o u t l o n g = ⌈ i n l e n g t h − f i l t e r l e n g t h + 1 s t r i d e l e n g t h ⌉ out_{long} = \lceil{\frac{in_{length}-filter_{length}+1}{stride_{length}}}\rceil outlong=stridelengthinlengthfilterlength+1

    o u t w i d t h = ⌈ i n w i d t h − f i l t e r w i d t h + 1 s t r i d e w i d t h ⌉ out_{width} = \lceil{\frac{in_{width}-filter_{width}+1}{stride_{width}}}\rceil outwidth=stridewidthinwidthfilterwidth+1

    注:out表示输出矩阵维度,in表示输入矩阵维度,filter表示滤波器(卷积核),stride表示步长,long表示矩阵的长,width表示矩阵的宽。

AlexNet

先来看alexnet的情况。下面是AlexNet的神经网络每一层的输出维度。

卷积层补0 , 池化层不补0

输入维度[输出维度、移动步长s、卷积核尺寸f]输出维度
第一层卷积28x28x1[48,4,11]7x7x48
第二层池化7x7x48[48,2,3]3x3x48
第三层卷积3x3x48[128,1,5]3x3x128
第四层池化3x3x128[128,2,3]1x1x128
第五层卷积1x1x128[192,1,3]1x1x192
第六层卷积1x1x192[192,1,3]1x1x192
第七层卷积1x1x192[128,1,3]1x1x128
第八层池化1x1x128[128,2,3]出错
输入维度[输出维度、移动步长s、卷积核尺寸f]输出维度
第一层卷积784x1x1[48,4,11]196x1x48
第二层池化196x1x48[48,2,3]出错

可以看出,不管采用哪个维度都会出错,出错的原因也很简单,根据上面两个公式进行计算,最后得出的矩阵输出维度为负数,所以肯定会报错的。

VGG

同样的道理,采用vgg进行训练也会报错,vgg网络输出维度如下。

卷积层补0 , 池化层不补0

输入维度[输出维度、移动步长s、卷积核尺寸f]输出维度
第一层卷积28x28x1[64,1,3]28x28x64
第二层卷积28x28x64[64,1,3]28x28x64
第三层池化28x28x64[64,2,3]13x13x64
第四层卷积13x13x64[128,1,3]13x13x128
第五层卷积13x13x128[128,1,3]13x13x128
第六层池化13x13x128[128,2,3]6x6x128
第七层卷积6x6x128[256,1,3]6x6x256
第八层卷积6x6x256[256,1,3]6x6x256
第十三层卷积2x2x512[512,1,1]2x2x512
第十四层卷积2x2x512[512,2,3]出错
输入维度[输出维度、移动步长s、卷积核尺寸f]输出维度
第一层卷积784x1x1[64,1,3]784x1x64
第二层卷积784x1x64[64,1,3]784x1x64
第三层池化784x1x64[64,2,3]出错

发现了把,每次报错都是在池化层报错,因为池化层没有采用全零填充,所有导致输出的矩阵维度可能就变成负数,从而导致报错。这一点从公式也可以看的出来,采用全零填充的公式,不管输出矩阵的维度大小,因为向上取整的缘故,输出的矩阵维度至少为1。而不采用零填充,就有可能出现负数维度。

至于Le-Net为什么没有报错,因为Le-Net的网络层数没有那么多,到最后输出的矩阵维度还是为正,当然不会报错。

总结

报错原因:采用了非零填充的方式,导致矩阵的维度不断减小,出现负维度。

解决:1)增大输入图片的大小,使得最后神经网络的输出矩阵维度依然为正。不过增大图片的大小对训练速度有直接影响,而且影响还很大,训练速度会变慢。2)改变填充方法,变为零填充。因为改用零填充,池化层的输入输出维度不变,减小参数的作用就变小,一定程度上也会影响训练速度。(也就是把 padding=‘VALID’ 改为 padding=‘SAME’)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值