此篇没有标题

实验CAM的代码时候为了测试大量图片而写了点愚蠢的代码然后断断续续花了好几天Debug的故事。

不得不说有时候不写写代码还真的发现不了自己的思维死角。由于要测试大量图片,没仔细思考就直接在整个代码外套了个循环。。。。。。然后程序不断奔溃。-_-||

精简后的原代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
clear
addpath('/home/wcx/caffe/matlab');

for imgID=1:1125
net_weights = ['models/imagenet_googleletCAM_train_iter_120000.caffemodel'];
net_model = ['models/deploy_googlenetCAM.prototxt'];
net = caffe.Net(net_model, net_weights, 'test');
caffe.set_mode_gpu();
caffe.set_device(0);
weights_LR = net.params('CAM_fc',1).get_data();

img = imread(['keyframe/' num2str(imgID) '.png']);
[height_original,weight_original,temp]=size(img);
img = imresize(img, [256 256]);
scores = net.forward({prepare_image(img)});
activation_lastconv = net.blobs('CAM_conv').get_data();
scores = scores{1};
caffe.reset_all();
end

老老实实设条件断点定位到每次崩溃停在net = caffe.Net(net_model, net_weights, 'test')

然后瞬间怀疑是缓存冗余过多,试着加了clear但没有任何效果。于是看了一段时间matlab如何回收内存,学了许多骚操作,能用的一个都没。同时发现我clear位置还写错了,调整了下在每次循环前clear一下来清除工作空间,然而并没什么卵用。原本预想这样做会非常有用,因为每次循环结束都清除了工作空间和caffe网络,按道理效果和重新运行程序差不多了。后来在网上发现有人解释说matlab清除工作空间后虽然释放了内存,但释放后的空间是碎片化的,即使空间都释放了也没法装入比碎片大的内存块,我豁然开朗,觉得计组和操作系统还是很有用的。

然后在日常debug的时候瞥了下shell发现了点神奇的玩意:
Check failed: error == cudaSuccess (2 vs. 0) out of memory
这个out of memory很有意思,有了关键字后在stackoverflow上找到了个回答。试着在shell下执行nvidia-smi,发现崩溃的时候Memory-Usage已经跑满了。

至此bug原因get,bug原因大概是循环中途多次重新加载网络,使得剩余内存越来越碎片化导致matlab不得不不断开辟新的内存空间直到GPU memory耗尽。然后改了循环后整个人都神清气爽了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
clear
addpath('/home/wcx/caffe/matlab');

net_weights = ['models/imagenet_googleletCAM_train_iter_120000.caffemodel'];
net_model = ['models/deploy_googlenetCAM.prototxt'];
net = caffe.Net(net_model, net_weights, 'test');
caffe.set_mode_gpu();
caffe.set_device(0);
weights_LR = net.params('CAM_fc',1).get_data();

for imgID=1:1125
img = imread(['keyframe/' num2str(imgID) '.png']);
[height_original,weight_original,temp]=size(img);
img = imresize(img, [256 256]);
scores = net.forward({prepare_image(img)});
activation_lastconv = net.blobs('CAM_conv').get_data();
scores = scores{1};
end
caffe.reset_all();

所以平时还是得多写写代码积累经验吧,唉。

转载请注明原博客地址

坚持原创技术分享,您的支持将鼓励我继续创作!