近期小编在做图像分类的实验,无奈状况连连。现将遇到的几个大坑简单记录一下,以备日后之需。如果你也出现了问题(1)中GPU内存问题,请看完整篇文章。

1、内存报错

如果你是GPU环境,那你要注意了,你的电脑上现在应该有两个内存限制。

(1)GPU内存

GPU内存大家可以使用下面命令查看

nvidia-smi



如果你想动态观测,那你可以使用下面命令:

nvidia-smi -l



如果程序在运行过程中提示如下错误,那就说明是你的GPU内存不够了。

Check failed: error == cudaSuccess (2 vs. 0) out of memory



解决方法:


(1)batch_size太大了,一次性读入的图片太多了,所以就超出了显存。因此需要将train.prototxt中的文件train和test的batch_size调小一点。


(2)如果图片的尺寸可以更改,可以通过设置crop_size来更改图片的大小尺寸,从而解决错误。


上述两种方法选一种即可,但过分的减少batch_size 亦可引发问题2 的出现,这事就要两种方法相结合进行解决。


(2)计算机内存

当计算机内存不足时,这个错误比较好判断,目前小编手里没有现有的错误,以后有了这个错误提示,再来补充。(一般大家看了都会知道是内存不足了)


问题2、caffe训练时accuracy,loss值迭代到一定程度后无论学习率怎么变化,两者值都不变。accura = 0.18833, loss=87.3365


小编被这个问题折磨的尤为惨烈,暂且不论accuracy值的大小,毕竟网络都是需要调的,不可能直接上来accuracy的值就很高。单说loss值,这也太高了。训练好的网络loss值一般要在0.01以下,这可倒好,没有下降反而上升到了天际。


小编各种方法都试验过了:

(1)学习率base_lr降低。从0.1到0.0000001我都试过了,顶多是迭代的次数不同而已,最终都会回归到一个问题上,那就是迭代到一定程度后两者值都不变:accura = 0.18833, loss=87.3365。

(2)查看标签是否正确,从0开始标记。小编一共就设计了两类,0和1,就这还看了好几遍。

(3)生成的lmdb数据包是否正确。生成数据包lmdb的程序看了一遍又一遍,生怕是自己生成的lmdb出现问题。


无奈小编都开始感觉是自己的图像库中的脏数据太多,都打算重新弄数据库。还好老天佑我,在我绝望之际给了我启示:我看到了这篇博文()


博文内容:

可以在solver里面设置:
debug_info: true
看看各个层的data和diff是什么值,一般这个时候那些值不是NAN(无效数字)就是INF(无穷大),
一般的解决办法是:
1、检查数据的标签是否从0开始且连续
2、把学习率base_lr调低
3、数据问题
4、中间层没有归一化,导致经过几层后,输出的值已经很小了,这个时候再计算梯度就比较尴尬了,
这也是我遇到的问题,所以我再各个卷积层加入了BN层和SCALE层,不过FC层没有必要加吧?
5、把base_lr调低,然后batchsize也调高
6、把data层的输入图片进行归一化,就是从0-255归一化到0-1,使用的参数是:

transform_param {  
    scale: 0.00390625//像素归一化,1/255
  }



7、网络参数太多,网络太深,删掉几层看看,可能因为数据少,需要减少中间层的num_output

8、记得要shuffle数据,否则数据不够随机,几个batch之间的数据差异很小,一旦连续几个batch把loss调很小,然后就。。。 现在不造解释,



上述博文内容中,第5和第8条引起我的注意:

5、把base_lr调低,然后batchsize也调高
8、记得要shuffle数据,否则数据不够随机,几个batch之间的数据差异很小,一旦连续几个batch把loss调很小,然后就。。。 现在不造解释,

虽然不太知道为什么,但是这改变了我的一个想法,数据层中的batch_size其实与训练过程是有关的。它的改变会引起accuracy或者loss的改变。


小编的batch_size 因为问题1的出现被小编严重调低,将batch_size设为了1 。为了调高batch_size,只能缩小图像,所以小编使用crop_size对图像进行裁剪,这时奇迹发生了,小编的loss值再没上来过。


所以,如果你的loss值一直loss=87.3365恒不变,你又找不到其他的原因,那你请试试提高你的batch_size.小编最后train部分的batch_size值增加到了20.