caffe loss nan降低到什么程度

基于Caffe的Large Margin Softmax Loss的实现(中) - 推酷
基于Caffe的Large Margin Softmax Loss的实现(中)
小喵的唠叨话:前一篇博客,我们做完了L-Softmax的准备工作。而这一章,我们开始进行前馈的研究。
还记得上一篇博客,小喵给出的三个公式吗?不记得也没关系。
这次,我们要一点一点的通过代码来实现这些公式。小喵主要是GPU上实现前后馈的代码,因为这个层只是用来训练,GPU速度应该会快一点。
我们首先要进行一般的FC层的前馈,因为LM_FC的前馈只是修改了一般的FC中的若干个值,而大部分的值都是没有修改过的。
const Dtype* bottom_data = bottom[0]-&gpu_data();
const Dtype* label_data = bottom[1]-&gpu_data();
Dtype* top_data = top[0]-&mutable_gpu_data();
const Dtype* weight = this-&blobs_[0]-&gpu_data();
// 普通fc层的计算
if (M_ == 1) {
&&caffe_gpu_gemv&Dtype&(CblasNoTrans, N_, K_, (Dtype)1.,
&&&&&&&&&&&&&&&&&&&&&&weight, bottom_data, (Dtype)0., top_data);
&&caffe_gpu_gemm&Dtype&(CblasNoTrans,
&&&&&&&&&&&&&&&&&&&&&&&&transpose_ ? CblasNoTrans : CblasTrans,
&&&&&&&&&&&&&&&&&&&&&&&&M_, N_, K_, (Dtype)1.,
&&&&&&&&&&&&&&&&&&&&&&&&bottom_data, weight, (Dtype)0., top_data);
这样就计算完了一个普通的FC的前馈。
之后是一些具体的实现。
这是要求出label为的weight的权值和feature之间的余弦值。公式大家在高中应该就学过了。这样需要出三部分:
和。这里表示feature的序号,因为一个mini batch中有很多张图片。表示正确的label值。
的计算非常简单,因为FC层的前馈计算出来的就是这个值。因此我们可以直接从FC的前馈结果中直接复制对应位置的结果。
和是比较简单的模值的计算,使用caffe_cpu_dot很容易就可以求得(为什么不使用caffe_gpu_dot呢?因为小喵在使用caffe_gpu_dot的时候,caffe会报一个奇怪的错误,不知道是不是因为GPU的显存不能随意访问的)。
最后的余弦值带入到上面的式子,就一下子搞定~
这里用到了几个变量:
M_: batch size
N_: class num
K_: feature length
// 直接从前馈的结果中复制
Dtype *wx_data = this-&wx_.mutable_gpu_data();
copy_label_score&Dtype&&&&CAFFE_GET_BLOCKS(M_), CAFFE_CUDA_NUM_THREADS&&&(M_, N_, label_data, top_data, wx_data);
Dtype *abs_w_data = this-&abs_w_.mutable_cpu_data();
for (int m = 0; m & M_; ++ m) {
&&abs_w_data[m] = caffe_cpu_dot&Dtype&(
&&&&this-&blobs_[0]-&cpu_data() + static_cast&int&(label_cpu_data[m]) * K_,
&&&&this-&blobs_[0]-&cpu_data() + static_cast&int&(label_cpu_data[m]) * K_
Dtype *abs_x_data = this-&abs_x_.mutable_cpu_data();
for (int m = 0; m & M_; ++ m) {
&&abs_x_data[m] = caffe_cpu_dot&Dtype&(
&&&&bottom[0]-&cpu_data() + m * K_,
&&&&bottom[0]-&cpu_data() + m * K_
// abs_w, abs_x
caffe_gpu_powx&Dtype&(M_, this-&abs_w_.mutable_gpu_data(), 0.5, this-&abs_w_.mutable_gpu_data());
caffe_gpu_powx&Dtype&(M_, this-&abs_x_.mutable_gpu_data(), 0.5, this-&abs_x_.mutable_gpu_data());
// cos_t = wx / (|x| * |w|)
Dtype *cos_t_data = this-&cos_t_.mutable_gpu_data();
caffe_gpu_div&Dtype&(M_, wx_data, this-&abs_x_.gpu_data(), cos_t_data);
caffe_gpu_div&Dtype&(M_, cos_t_data, this-&abs_w_.gpu_data(), cos_t_data);
其中copy_label_score是我们自己编写的用来复制结果的核函数(如何编写Cuda程序就是另一门学科了):
template &typename Dtype&
__global__void copy_label_score(const int M, const int N, const Dtype *label_data, const Dtype *top_data, Dtype *wx_data) {
&&CUDA_KERNEL_LOOP(index, M) {
&&&&wx_data[index] = top_data[index * N + static_cast&int&(label_data[index])];
相信机智如你的喵粉,看到这几行代码,一定可以轻松理解。
这里,小喵想多介绍一点东西。
我们知道Caffe里面的数据都是通过Blob结构来存储的,比如这里的bottom_data,其实就是一个blob,默认形状是(n, c, h, w),n表示的就是batch size,c是channel数,h,w分贝表示高和宽。而且blob中的内存的存储顺序,也和一般的C语言中的数组一样。因此我们这里计算feature的模的时候,是直接每K_个数值计算一次点乘。
同理,weight是存储在this-&blobs[0]中的,那么weight的形状又是什么样子的呢?这里非常碰巧的是,如果我们在prototxt中设置的transpose为false的话,weight的形状是N_*K_,也就是说,我们可以将weight看成一个矩阵,它的每一行都与feature直接点乘,得到输出,也就是说weight的每一行都是我们需要计算模值的,所以我们计算weight的模的时候,用的计算方法和计算feature模时很相似。我们这里强制设置transpose为false,因为这样计算会比较简单。如果你设成了true,那就必须自己写个求模的函数了。
我们在(1)中求出了,对于给定的margin,只需要代入公式就可以求出的值了。
template &typename Dtype&
__global__void cal_cos_mt(const int count, const unsigned int margin, const int *C_M_N, const Dtype *cos_t_data, Dtype *cos_mt_data) {
&&CUDA_KERNEL_LOOP(index, count) {
&&&&Dtypecos_t = cos_t_data[index];
&&&&Dtypesin_t_2 = 1 - cos_t * cos_t;
&&&&Dtypecos_mt = 0.;
&&&&int flag = -1;
&&&&for (int n = 0; n &= (margin / 2); ++ n) {
&&&&&&flag *= -1;
&&&&&&cos_mt += flag * C_M_N[2 * n] * powf(cos_t, (margin - 2 * n)) * powf(sin_t_2, n);
&&&&cos_mt_data[index] = cos_
上面是用来计算的cuda函数,调用也十分的简单:
// cos(mt)
cal_cos_mt&Dtype&&&&CAFFE_GET_BLOCKS(M_), CAFFE_CUDA_NUM_THREADS&&&(
&&M_, this-&margin, this-&C_M_N_.gpu_data(), this-&cos_t_.mutable_gpu_data(), this-&cos_mt_-&mutable_gpu_data());
严格上来说,我们需要求的并不是这个式子,而是:
可以看出,当为0的时候,这两个式子就退化成前面的一个式子了。
k的求法十分简单,只需要将与各个区间进行比较就可以得到。
int *k_cpu_data = this-&k_.mutable_cpu_data();
const Dtype *cos_t_cpu_data = this-&cos_t_.cpu_data();
for (int m = 0; m & M_; ++ m) {
&&for (int _k = 0; _k & this-&cos_theta_bound_.count(); ++ _k) {
&&&&if (this-&cos_theta_bound_.cpu_data()[_k] & cos_t_cpu_data[m]) {
&&&&&&k_cpu_data[m] = _k - 1;
最后一步就是计算出真正的前馈值了!按照公式容易编写程序:
template &typename Dtype&
__global__void LMForward(
&&const int M, const int N, const float lambda,
&&const Dtype *label_data, const Dtype *cos_mt_data, const int *k_data,
&&const Dtype *abs_w_data, const Dtype *abs_x_data, Dtype *top_data) {
&&CUDA_KERNEL_LOOP(index, M) {
&&&&Dtypecos_mt = cos_mt_data[index];
&&&&int k = k_data[index];
&&&&int label = static_cast&int&(label_data[index]);
&&&&Dtypeabs_w = abs_w_data[index];
&&&&Dtypeabs_x = abs_x_data[index];
&&&&top_data[N * index + label] =&&(lambda * top_data[N * index + label] + abs_w * abs_x * ( powf(-1, k) * cos_mt - 2 * k )) / (1 + lambda);
调用也十分简单:
LMForward&Dtype&&&&CAFFE_GET_BLOCKS(M_), CAFFE_CUDA_NUM_THREADS&&&(
&&M_, N_, this-&lambda,
&&label_data, this-&cos_mt_-&gpu_data(), this-&k_.gpu_data(),
&&this-&abs_w_.gpu_data(), this-&abs_x_.gpu_data(), top[0]-&mutable_gpu_data());
最后附上,完整的前馈代码(省略头文件和caffe的名字空间):
template &typenameDtype&
__global__void copy_label_score(const int M, const int N, const Dtype *label_data, const Dtype *top_data, Dtype *wx_data) {
&&CUDA_KERNEL_LOOP(index, M) {
&&&&wx_data[index] = top_data[index * N + static_cast&int&(label_data[index])];
template &typenameDtype&
__global__void cal_cos_mt(const int count, const unsigned int margin, const int *C_M_N, const Dtype *cos_t_data, Dtype *cos_mt_data) {
&&CUDA_KERNEL_LOOP(index, count) {
&&&&Dtypecos_t = cos_t_data[index];
&&&&Dtypesin_t_2 = 1 - cos_t * cos_t;
&&&&Dtypecos_mt = 0.;
&&&&int flag = -1;
&&&&for (int n = 0; n &= (margin / 2); ++ n) {
&&&&&&flag *= -1;
&&&&&&cos_mt += flag * C_M_N[2 * n] * powf(cos_t, (margin - 2 * n)) * powf(sin_t_2, n);
&&&&cos_mt_data[index] = cos_
template &typenameDtype&
__global__void LMForward(
&&const int M, const int N, const float lambda,
&&const Dtype *label_data, const Dtype *cos_mt_data, const int *k_data,
&&const Dtype *abs_w_data, const Dtype *abs_x_data, Dtype *top_data) {
&&CUDA_KERNEL_LOOP(index, M) {
&&&&Dtypecos_mt = cos_mt_data[index];
&&&&int k = k_data[index];
&&&&int label = static_cast&int&(label_data[index]);
&&&&Dtypeabs_w = abs_w_data[index];
&&&&Dtypeabs_x = abs_x_data[index];
&&&&top_data[N * index + label] =&&(lambda * top_data[N * index + label] + abs_w * abs_x * ( powf(-1, k) * cos_mt - 2 * k )) / (1 + lambda);
template &typenameDtype&
void LargeMarginInnerProductLayer&Dtype&::Forward_gpu(const vector&Blob&Dtype&*&& bottom,
&&&&const vector&Blob&Dtype&*&& top) {
&&const Dtype* bottom_data = bottom[0]-&gpu_data();
&&const Dtype* label_data = bottom[1]-&gpu_data();
&&Dtype* top_data = top[0]-&mutable_gpu_data();
&&const Dtype* weight = this-&blobs_[0]-&gpu_data();
&&// 普通fc层的计算
&&if (M_ == 1) {
&&&&caffe_gpu_gemv&Dtype&(CblasNoTrans, N_, K_, (Dtype)1.,
&&&&&&&&&&&&&&&&&&&&&&&&weight, bottom_data, (Dtype)0., top_data);
&&} else {
&&&&caffe_gpu_gemm&Dtype&(CblasNoTrans,
&&&&&&&&&&&&&&&&&&&&&&&&&&transpose_ ? CblasNoTrans : CblasTrans,
&&&&&&&&&&&&&&&&&&&&&&&&&&M_, N_, K_, (Dtype)1.,
&&&&&&&&&&&&&&&&&&&&&&&&&&bottom_data, weight, (Dtype)0., top_data);
&&const Dtype* label_cpu_data = bottom[1]-&cpu_data();
&&// w * x
&&// 直接从前馈的结果中复制
&&Dtype *wx_data = this-&wx_.mutable_gpu_data();
&&copy_label_score&Dtype&&&&CAFFE_GET_BLOCKS(M_), CAFFE_CUDA_NUM_THREADS&&&(M_, N_, label_data, top_data, wx_data);
&&// w * w
&&Dtype *abs_w_data = this-&abs_w_.mutable_cpu_data();
&&for (int m = 0; m & M_; ++ m) {
&&&&abs_w_data[m] = caffe_cpu_dot&Dtype&(
&&&&&&this-&blobs_[0]-&cpu_data() + static_cast&int&(label_cpu_data[m]) * K_,
&&&&&&this-&blobs_[0]-&cpu_data() + static_cast&int&(label_cpu_data[m]) * K_
&&// x * x
&&Dtype *abs_x_data = this-&abs_x_.mutable_cpu_data();
&&for (int m = 0; m & M_; ++ m) {
&&&&abs_x_data[m] = caffe_cpu_dot&Dtype&(
&&&&&&bottom[0]-&cpu_data() + m * K_,
&&&&&&bottom[0]-&cpu_data() + m * K_
&&// abs_w, abs_x
&&caffe_gpu_powx&Dtype&(M_, this-&abs_w_.mutable_gpu_data(), 0.5, this-&abs_w_.mutable_gpu_data());
&&caffe_gpu_powx&Dtype&(M_, this-&abs_x_.mutable_gpu_data(), 0.5, this-&abs_x_.mutable_gpu_data());
&&// cos_t = wx / (|x| * |w|)
&&Dtype *cos_t_data = this-&cos_t_.mutable_gpu_data();
&&caffe_gpu_div&Dtype&(M_, wx_data, this-&abs_x_.gpu_data(), cos_t_data);
&&caffe_gpu_div&Dtype&(M_, cos_t_data, this-&abs_w_.gpu_data(), cos_t_data);
&&// cos(mt)
&&cal_cos_mt&Dtype&&&&CAFFE_GET_BLOCKS(M_), CAFFE_CUDA_NUM_THREADS&&&(
&&&&M_, this-&margin,
&&&&this-&C_M_N_.gpu_data(),
&&&&this-&cos_t_.gpu_data(),
&&&&this-&cos_mt_.mutable_gpu_data()
&&int *k_cpu_data = this-&k_.mutable_cpu_data();
&&const Dtype *cos_t_cpu_data = this-&cos_t_.cpu_data();
&&for (int m = 0; m & M_; ++ m) {
&&&&for (int _k = 0; _k & this-&cos_theta_bound_.count(); ++ _k) {
&&&&&&if (this-&cos_theta_bound_.cpu_data()[_k] & cos_t_cpu_data[m]) {
&&&&&&&&k_cpu_data[m] = _k - 1;
&&LMForward&Dtype&&&&CAFFE_GET_BLOCKS(M_), CAFFE_CUDA_NUM_THREADS&&&(
&&&&M_, N_, this-&lambda,
&&&&label_data, this-&cos_mt_.gpu_data(), this-&k_.gpu_data(),
&&&&this-&abs_w_.gpu_data(), this-&abs_x_.gpu_data(), top[0]-&mutable_gpu_data());
那么,这样关于large margin softmax loss的前馈我们就轻松的实现了。下一篇,我们要讲最复杂的后馈的实现了。
如果您觉得本文对您有帮助,那请小喵喝杯茶吧~~O(∩_∩)O~~ 再次感慨大法好。
转载请注明出处~
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致caffe loss
caffe loss
损失函数,一般由两项组成,一项是loss term,另外一项是regularization term。
先说损失项loss,再说regularization项。
1. 分对得分1,分错得分0.gold standard
2. hinge loss(for softmargin svm),J=1/2||w||^2 +&sum(max(0,1-yf(w,x)))
3. log los, cross entropy loss function in logistic regression model.J=lamda||w||^2+sum(log(1+e(-yf(wx))))
4. squared loss, in linear regression. loss=(y-f(w,x))^2
5. exponential loss in boosting. J=lambda*R+exp(-yf(w,x))
再说regularization项,
一般用的多的是R2=1/2||w||^2,R1=sum(|w|)。R1和R2是凸的,同时R1会使得损失函数更加具有sparse,而R2则会更加光滑些。具体可以参见下图:
caffe的损失函数,目前已经囊括了所有可以用的了吧,损失函数由最后一层分类器决定,同时有时会加入regularization,在BP过程中,使得误差传递得以良好运行。&
contrastive_loss,对应contrastive_loss_layer,我看了看代码,这个应该是输入是一对用来做验证的数据,比如两张人脸图,可能是同一个人的(正样本),也可能是不同个人(负样本)。在caffe的examples中,这个例子中,用的损失函数是该类型的。该损失函数具体数学表达形式可以参考lecun的文章&
euclidean_loss,对应euclidean_loss_layer,该损失函数就是l=(y-f(wx))^2,是线性回归常用的损失函数。
hinge_loss,对应hinge_loss_layer,该损失函数就是。主要用在SVM分类器中。
infogain_loss,对应infogain_loss_layer,损失函数表达式没找到,只知道这是在文本处理中用到的损失函数。
multinomial_logistic_loss,对应multinomial_logistic_loss_layer,
sigmoid_cross_entropy,对应sigmoid_cross_entropy_loss_layer,也就是logistic regression使用的损失函数。
softmax_loss,对应softmax_loss_layer,损失函数等可以见UFLDL中关于softmax章节。在caffe中多类分类问题,损失函数就是softmax_loss,比如imagenet, mnist等。softmax_loss是sigmoid的多类问题。但是,我就没明白,multinomial_logistic_loss和这个有什么区别,看代码,输入有点差别,softmax的输入是probability,而multinomial好像不要求是probability,但是还是没明白,如果只是这样,岂不是一样啊?
详细说明了两者之间的差异,并且有详细的测试结果,非常赞。简单理解,multinomial
是将loss分成两个层进行,而softmax则是合在一起了。或者说,multinomial loss是按部就班的计算反向梯度,而softmax则是把两个步骤直接合并为一个步骤进行了,减少了中间的精度损失等 ,从计算稳定性讲,softmax更好,multinomial是标准做法,softmax则是一种优化吧。
LayerType:&SOFTMAX_LOSS
The softmax loss layer computes the multinomial logistic loss of the softmax of its inputs. It’s conceptually identical to a softmax layer followed by a multinomial logistic loss layer, but provides a more numerically
stable gradient.
references:
http://caffe.berkeleyvision.org/tutorial/layers.html
Bishop, pattern recognition and machine learning
http://deeplearning.stanford.edu/wiki/index.php/Softmax%E5%9B%9E%E5%BD%92
http://freemind.pluskid.org/machine-learning/softmax-vs-softmax-loss-numerical-stability/
Caffe中的损失函数解析
在有监督的机器学习中,需要有标签数据,与此同时,也需要有对应的损失函数(Loss Function)。
在Caffe中,目前已经实现了一些损失函数,包括最常见的L2损失函数,对比损失函数,信息增益损失函数等等。在这里做一个笔记,归纳总结Caffe中用到的不同的损失函数,以及分析它们各自适合的使用场景。
欧式距离损失函数(Euclidean Loss)
预测的值:&y^∈[-∞,+∞],
其中,它们的形状为:N×C×H×W
标签的值:&y∈[-∞,+∞],
其中,它们的形状为:N×C×H×W
损失的值:Loss=12N∑Nn=1∥y^n-yn∥22
适合场景:
回归,特别是其回归的值是实数值得时候。
对比损失函数(Contrastive loss)
形状:(N×C×1×1)&特征&a∈[-∞,+∞]
形状:(N×C×1×1)&特征&b∈[-∞,+∞]
形状:(N×1×1×1)&相似性&y∈[0,1]
形状:(1×1×1×1)
对比损失函数为:&E=12N∑n=1N(y)d+(1-y)max(margin-d,0)
其中&d=||an-bn||22.
适合场景:
可以用来训练Siamese网络
铰链损失函数(Hinge Loss)
形状:(N×C×H×W)&预测值&t∈[-∞,+∞]&代表着预测&K=CHW&个类中的得分(注:CHW表示着在网络设计中,不一定要把预测值进行向量化,只有其拉直后元素的个数相同即可。)
. 在SVM中,&t&是
D 维特征X∈RD×N,
和学习到的超平面参数W∈RD×K&内积的结果&XTW&
所以,一个网络如果仅仅只有全连接层 + 铰链损失函数,而没有其它的可学习的参数,那么它就等价于SVM
标签值:
(N×1×1×1)&标签&l,
是一个整数类型的数&ln∈[0,1,2,...,K-1]&其代表在&K&个类中的正确的标签。
形状:(1×1×1×1)&
损失函数计算:&E=1N∑n=1N∑k=1K[max(0,1-δ{ln=k}tnk)]p,&Lp&范数
(默认是&p=1,
是 L1 范数; L2 范数,正如在 L2-SVM中一样,也有实现),
其中&δ{条件}={1-1成立不成立
应用场景:
在一对多的分类中应用,类似于SVM.
形状:(N×C×H×W)&预测值&p^∈[0,1]&内,
表示这预测每一类的概率,共&K=CHW&个类,
每一个预测 概率p^n&的和为1:&?n∑k=1Kp^nk=1.
形状:(N×1×1×1)&标签值:&l,
是一个整数值,其范围是&ln∈[0,1,2,...,K-1]&表示着在&K&个类中的索引。
形状:(1×1×K×K)&(可选)
信息增益矩阵&H.作为第三个输入参数,.
则它等价于多项式逻辑损失函数
形状:(1×1×1×1)
计算公式:&E=-1N∑n=1NHlnlog(p^n)=-1N∑n=1N∑k=1KHln,klog(p^n,k),
其中&Hln&表示
行&ln&of&H.
多项式逻辑损失函数(Multinomial Logistic Loss)
形状:(N×C×H×W)&预测值&p^∈[0,1]范围中,
表示这预测的每一类的概率,共&K=CHW&个类.
每一个预测概率p^n&的和为1:&?n∑k=1Kp^nk=1.
形状:(N×1×1×1)&标签&l,
是一个整数值,其范围是&ln∈[0,1,2,...,K-1]&表示着在&K&个类中的索引。
形状:(1×1×1×1)&计算公式:&E=-1N∑n=1Nlog(p^n,ln)
应用场景:
在一对多的分类任务中使用,直接把预测的概率分布作为输入.
Sigmoid 交叉熵损失函数(Sigmoid Cross Entropy Loss)
形状:&(N×C×H×W)&得分&x∈[-∞,+∞],
这个层使用 sigmoid 函数&σ(.)&映射到概率分布&p^n=σ(xn)∈[0,1]
形状:(N×C×H×W)&标签&y∈[0,1]
形状:(1×1×1×1)&计算公式:&E=-1n∑n=1N[pnlogp^n+(1-pn)log(1-p^n)]
应用场景:&
预测目标概率分布
Softmax+损失函数(Softmax With Loss)
形状:(N×C×H×W)&预测值&x∈[-∞,+∞]&代表预测每个类的得分。
共&K=CHW&类.
这一层把得分通过softmax映射到概率分布p^nk=exp(xnk)/[∑k′exp(xnk′)]
形状:(N×1×1×1)&标签值
是一个整数值,其范围是&ln∈[0,1,2,...,K-1]&表示着在&K&个类中的索引。
形状:(1×1×1×1)&计算公式:&E=-1N∑n=1Nlog(p^n,ln),
其中&p^&为softmax输出的类概率。
应用场景:
在一对多分类中应用。
我的热门文章
即使是一小步也想与你分享将caffe训练时loss的变化曲线用matlab绘制出来
时间: 21:10:42
&&&& 阅读:375
&&&& 评论:
&&&& 收藏:0
标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&1. 首先是提取 训练日志文件;
2. 然后是matlab代码:
log_file = ‘/home/wangxiao/Downloads/43_attribute_baseline.log‘;
fid = fopen(log_file, ‘r‘);
fid_accuracy = fopen(‘/home/wangxiao/Downloads/output_accuracy.txt‘, ‘w‘);
fid_loss = fopen(‘/home/wangxiao/Downloads/output_loss.txt‘, ‘w‘);
iteration ={};
loss = {};
accuracy = {};
path = ‘/home/wangxiao/Downloads/‘;
fid_ = fopen([path, ‘loss_file_.txt‘], ‘a‘);
while(~feof(fid))
tline = fgetl(fid);
if strfind(tline, ‘sgd_solver.cpp:‘)
iter_index = strfind(tline, ‘Iteration ‘);
rest = tline((iter_index+9):end);
iter_current = strtok(rest, ‘,‘);
iteration = [iteration
iter_current];
lr_index = strfind(tline, ‘lr = ‘);
lr_current = tline((lr_index+4):end);
if strfind(tline, ‘solver.cpp:228]‘)
iter_index = strfind(tline, ‘loss = ‘);
loss_current = tline((iter_index+7):end);
fprintf(fid_, ‘%s \n‘, loss_current );
loss = [loss
loss_current] ;
if strfind(tline, ‘aver_accuracy: ‘)
aver_accuracy_index = strfind(tline, ‘aver_accuracy: ‘);
aver_accuracy_current = tline((aver_accuracy_index+15):end);
accuracy = [accuracy
aver_accuracy_current];
loss_file_Path = importdata(‘/home/wangxiao/Downloads/loss_file_.txt‘);
plot(loss_file_Path)
3. 结果展示:
标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&原文:/wangxiaocvpr/p/5425427.html
&&国之画&&&& &&&&&&
&& &&&&&&&&&&&&&&
鲁ICP备号-4
打开技术之扣,分享程序人生!Caffe学习(六)损失层及其参数设置
Caffe学习(六)损失层及其参数设置
机器学习的目的就是通过对训练样本输出与真实值不一致的进行惩罚,得到损失Loss,然后采用一定的优化算法对loss进行最小优化,进而得到合理的网络权值。本文介绍Caffe中含有的常见的LossLayer及其参数设置方法
Caffe的LossLayer主要由6个:
(1)ContrastiveLossLayer
对比损失函数主要用来训练siamese网络,改网络为专门处理同时输入两张图像的网络,如用于FaceVerification的DeepID网络。在改网络的最后需要对比两张图像是否为一张人脸,因此需要一个对比损失函数。目标检测暂时不会用到
(2)EuclideanLossLayer
适合回归任务,尤其输出值为实数时。
输入blob向量:长度为2,两个(N,C,H,W)维的prediction与groundTruth blob,N张图像,在这里的CHW应该都是1.
输出blob:预测值与真实值的均方误差E,实数
(3)HingeLossLayer
按损失函数,适用于多分类任务。
输入blob向量:长度为2,包括
&&&&&&&&&&&&&&&&&&&&& 预测的score值:(N,C,H,W)维,代表N个样本每一个样本在C类中的每一类上的得分。其中HW应该都为1
&&&&&&&&&&&&&&&&&&&&& 真实值:(N,1,1,1),样本的真实Label
输出blob:损失值E
其中表示第n个样本在第k类上的得分,p表示L范数的阶,默认为1范数。可取2范数。
由SVM的原理可知一层全连接网络+HingeLossLayer等价于一个线性SVM,2范数Hinge损失的SVM也叫做L2-SVM
(4)InfogainLossLayer
信息增益损失。MultinomialLogisticLoss的泛化版本,不仅仅接受预测的每个样本在每类上的概率信息,还接受信息增益矩阵信息。当信息增益矩阵为单位阵的时候两者是等价的。
输入blob:
&&&&&&&&&&&& 预测概率值:(N,C,H,W)维,其中HW应该为1
&&&&&&&&&&&& 真实标签:(N,1,1,1)维
&&&&&&&&&&&& 信息增益矩阵H(可选,默认为单位阵):(1,1,K,K)维,其中K为类别的个数
输出blob:误差损失E
(5)MultinomialLogisticLossLayer
多项逻辑损失,主要处理多分类问题。当输出是每一类的概率时用这个损失函数。
输入blob:
&&&&&&&&&&& 预测概率值:每一个样本在每一类的概率,(N,C,H,W)维,N为样本个数,C为类别个数,HW应该均为1
&&&&&&&&&&& 真实标签:(N,1,1,1)维
输出blob:误差损失E,其中表示估计的样本n为其真实标签label的概率
(5)SoftmaxLossLayer
等价于softmaxLayer+MultinomialLogisticLossLayer。在训练时用该层,测试时用softmax层。为什么要多添加一个SoftmaxLossLayer,而不是用Softmax+MltinomialLogisticLayer来做?主要原因是直接采用这种SoftmaxLoss计算梯度时在数值计算上更稳定!!!具体原因参考
输入blob:每个样本在每个类别的得分
输出blob:误差损失E,形式同多项逻辑损失,只不过估计概率P的来源不一样
(6)SigmoidCrossEntroyLossLayer
Sigmoid交叉熵损失,主要用于二分类问题。
等价于SigmoidLayer+CrossEntropyLayer,第一层先将score转为概率输入(为什么不是softmaxLayer转换为概率呢???对于二分类问题用Sigmoid函数计算出一个概率即可,多分类问题用softmax函数),第二层计算交叉熵损失.采用一个新层而不是由两个已有的层来实现,主要原因也是由于数值稳定性
输入blob:每个样本在每一类上的得分。(N,C,H,W)维,其中HW应该为1。
输出blob:误差损失E,其中Pn表示估计的该类为类1的概率,labeln为样本n的类别(0或者1)。
由E的定义可知,该E其实等价于MultinomialLogisticLoss中的二分类情况
最后来个提醒,Caffe中,默认每一层都可以作为LossLayer,不过层的名字中不带Loss的层其&Loss_weight&属性默认为0,即对最后的总的Loss贡献为0。名字中带Loss的层可以在网络的任意位置使用(不一定非在网络的输出最后部分),且可以有不止一个LossLayer,最后的训练所使用的Loss为所有LossLayer损失的加权和,即按下式计算:
for layer in layers:
for top, loss_weight in layer.tops, layer.loss_weights:
loss += loss_weight * sum(top)
我的热门文章
即使是一小步也想与你分享

我要回帖

更多关于 caffe 绘制loss曲线 的文章

 

随机推荐