如何在linux下的caffe中添加centerloss层

如何在linux下的caffe中添加centerloss层,第1张

1、属于哪个类型的layer,就打开哪个hpp文件,这里就打开vision_layers.hpp,然后自己添加该layer的定义,或者直接复制Convolution_Layer的相关代码来修改类名和构造函数名都改为Aaa_Layer,如果不用GPU,将*_gpu的声明都去掉。

2、实现自己的layer,编写Aaa_Layer.cpp,加入到src/caffe/layers,主要实现Setup、Forward_cpu、Backward_cpu。

3、如果需要GPU实现,那么在Aaa_Layer.cu中实现Forward_gpu和Backward_gpu。

4、修改src/caffe/proto/caffe.proto,好到LayerType,添加Aaa,并更新ID,如果Layer有参数,添加AaaParameter类。

5、在src/caffe/layer_factory.cpp中添加响应代码。

6、在src/caffe/test中写一个test_Aaa_layer.cpp,用include/caffe/test/test_gradient_check_util.hpp来检查前向后向传播是否正确。

定义CAFFE为caffe跟目录,caffe的核心代码都在$CAFFE/src/caffe 下,主要有以下部分:net, blob, layer, solver.

net.cpp:

net定义网络, 整个网络中含有很多layers, net.cpp负责计算整个网络在训练中的forward, backward过程, 即计算forward/backward 时各layer的gradient。

layers:

在$CAFFE/src/caffe/layers中的层,在protobuffer (.proto文件中定义message类型,.prototxt或.binaryproto文件中定义message的值) 中调用时包含属性name, type(data/conv/pool…), connection structure (input blobs and output blobs),layer-specific parameters(如conv层的kernel大小)。定义一个layer需要定义其setup, forward 和backward过程。

blob.cpp:

net中的数据和求导结果通过4维的blob传递。一个layer有很多blobs, e.g,

对data,weight blob大小为Number * Channels * Height * Width, 如256*3*224*224;

对conv层,weight blob大小为 Output 节点数 * Input 节点数 * Height * Width,如AlexNet第一个conv层的blob大小为96 x 3 x 11 x 11;

对inner product 层, weight blob大小为 1 * 1 * Output节点数 * Input节点数; bias blob大小为1 * 1 * 1 * Output节点数( conv层和inner product层一样,也有weight和bias,所以在网络结构定义中我们会看到两个blobs_lr,第一个是weights的,第二个是bias的。类似地,weight_decay也有两个,一个是weight的,一个是bias的);

blob中,mutable_cpu/gpu_data() 和cpu/gpu_data()用来管理memory,cpu/gpu_diff()和 mutable_cpu/gpu_diff()用来计算求导结果。

slover.cpp:

结合loss,用gradient更新weights。主要函数:

Init(),

Solve(),

ComputeUpdateValue(),

Snapshot(), Restore(),//快照(拷贝)与恢复 网络state

Test();

在solver.cpp中有3中solver,即3个类:AdaGradSolver, SGDSolver和NesterovSolver可供选择。

关于loss,可以同时有多个loss,可以加regularization(L1/L2);

Protocol buffer:

上面已经将过, protocol buffer在 .proto文件中定义message类型,.prototxt或.binaryproto文件中定义message的值;

Caffe

Caffe的所有message定义在$CAFFE/src/caffe/proto/caffe.proto中。

Experiment

在实验中,主要用到两个protocol buffer: solver的和model的,分别定义solver参数(学习率啥的)和model结构(网络结构)。

好吧,copy了一大段,不晓得有没有帮助,说点accuracy = 0.5的问题。简单说,就是分错了,好吧我知道这是废话。既然是分错了,那么就要检查下了,首先检查你的训练模型。

根据训练过程来看,训练应该是已经收敛了,(反正loss一直在减小)。

这句可能是我理解问题,如果模型收敛的话,loss应该趋于平稳,如这样。

哦这是对数图。如果没有完全收敛的话,考虑下调整参数吧。说到调参,又是个坑啊。。。这个我也是懵懵懂懂。不过可以参考某些大牛的做法,比如用浅层CNN参数初始化深层CNN,或者学hinton老爷子用DBN来搞个预训练。不过即使是随机初始参数,按道理不应该出现这种accuracy=0.5的情况。个人感觉要么就是训练没有完成,要么就是在做最后二分的那一层有什么问题。。。

其实应该先检查训练数据,训练数据搞混了,其他都是白搭。

如果检查模型,你可以先看下你参数更新的梯度是否已经趋于零了,然后再看看你二分那一层有木有问题。

当然,说了这么多,可能也没啥帮助,如果你哪天改用matlab或者theano了,可以交流下,caffe确实不甚了解。。。

在尝试用caffe分类一个自己的二分类图像数据库。根据训练过程来看,训练应该是已经收敛了,(反正loss一直在减小)。然而测试集上的accuracy一直都是=0.5.

所以现在想着把生成的模型文件调出来用数据测试下,观察下是什么问题,请问应当如何去实现呢。

或者各位如果能指点下,可能是什么原因导致的accuracy = 0.5 不变。那就更好啦。

谢谢!

绘制caffe训练过程中的loss和accurary的曲线方法如下:

1. 你可以从系统 /tmp 文件夹获取,名字是什么 caffe.ubuntu.username.log.INFO.....之类。

2. 在train的时候最后加 tee $folder_prefix/caffe.log,就可以重定向到文件夹了。

然后写个parser就能把图画出来了。

也不是parser。。。因为output规律很强,就是最最naive的字符串处理一下。

贴一下matlab给题主好了

% Well, this is a function that write the

% iteration vs accurancy

% iteration vs loss

% To a file

clc

clear

% log file of caffe model

logName = 'caffe.log.INFO.20150704-163137.27688'

fid = fopen(logName, 'r')

fid_accuracy = fopen('output_accuracy.txt', 'w')

fid_loss = fopen('output_loss.txt', 'w')

tline = fgetl(fid)

while ischar(tline)

% First find the accuracy line

k = strfind(tline, 'Test net output')

if (k)

k = strfind(tline, 'accuracy')

if (k)

% If the string contain test and accuracy at the same time

% The bias from 'accuracy' to the float number

indexStart = k + 11

indexEnd = size(tline)

str = tline(indexStart : indexEnd(2))

end

% Get the number of index

k = strfind(tline, '#')

if (k)

indexStart = k + 1

indexEnd = strfind(tline, ':')

str2 = tline(indexStart : indexEnd - 1)

end

% Concatenation of two string

res_str = strcat(str2, '/', str)

fprintf(fid_accuracy, '%s\r\n', res_str)

end

% Then find the loss line

k1 = strfind(tline, 'Iteration')

if (k1)

k2 = strfind(tline, 'loss')

if (k2)

indexStart = k2 + 7

indexEnd = size(tline)

str1 = tline(indexStart:indexEnd(2))

indexStart = k1 + 10

indexEnd = strfind(tline, ',') - 1

str2 = tline(indexStart:indexEnd)

res_str1 = strcat(str2, '/', str1)

fprintf(fid_loss, '%s\r\n', res_str1)

end

end

tline = fgetl(fid)

end

fclose(fid)

fclose(fid_accuracy)


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/bake/11623580.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-17
下一篇2023-05-17

发表评论

登录后才能评论

评论列表(0条)

    保存