您的位置:首页 > 其它

softmaxwithloss入门及88.3365解决之道

2017-08-03 15:06 316 查看
softmax with loss:

softmax从名字上看就是软最大,其做法其实很简单:
前提:最后输出向量长度为N,与要区分的类别个数一致

1 第一步,取向量的最大值,将每个值减去最大值,这样就会将所有的数都变成非正数

2 求softmax:



3 经过第二步就会将向量变成全部小于1,大于0,累加为1的向量,这样就比较符合我们输出每个类别的概率的判断:在那个类别下的值最大,就判别为哪一类

4 有了类别输出概率,在训练的时候还需要求loss,根据loss去更新梯度,优化参数,类别向量长度也为N,求loss的公式:

loss=−∑kyklog(pk)

5 在实际计算的时候,比第四步要简单的多,直接取对应类别下的概率输出,取负对数,就得到了loss,即只管对应类别下的概率,将其进行优化,因为概率和为1,对应类别下的概率值变大,其他值自然变小:
loss -= log(std::max(prob_data[i * dim + label_value * inner_num_ + j],
Dtype(FLT_MIN)));


这样取prob_data的值是因为在loss的公式中,只需要关注k=y^(i)的那一类即可

dim:批大小个数

label_value:标签

inner_num_:标签个数

FLT_MIN的值:1.17549435E-38F

这个值的自然对数是:-87.3365,取负号变成87.3365

这个值是在训练的时候经常会出现的一个值,出现这个值是因为,求得的值比系统能够表示的float最小值还小,一般就是0了,即求得的概率值为0,
而前面已经说过了。经过softmax后,值都在0-1之间,观察以e为底的指数函数的曲线的话,你会发现,当取值趋向于无穷小时,其值才趋近于0:



由此可以判断是前面的计算出现了float溢出导致出现inf,nan等值

因此问题就出现在前面的features值溢出,即超过float能够表示的范围成为inf,inf在和其他数的运算中会将其他数也变成inf,最后在取inf和FLT_MIN较大值后做log运算后就变成了传说中的87.3365
softmax输入的feature由两部分计算得到:一部分是上一层的输入数据,另部分是各层权重参数,针对性的可以尝试下面的方法进行解决:

1 学习率太大,尝试降低学习率

2  增大批处理试试
3 有时未加归一化时,也会导致loss为这个值,尝试着在最后面的fc层添加批处理层试试
4 数据标签未从0开始,将数据标签改成从0开始,并将SoftmaxWithLoss层的前一层的fc层的输出个数改成类别个数,如果类别个数不对,也有可能出现这个问题
5 偏置初始化值太大,最好初始化为0,或者是权重初始化值太大,尝试降低权重初始化方差

6 在solver 中加clip_gradients设置,也许能够解决这个问题

7 还有一个可能的原因就是:当你的批大小不大,而图像中混有一些灰度图,注意,虽然有些图是3通道,但是各个通过值相等,也是灰度图,在这种情况下,有些网络结构就会出现这个值,这个值的出现与批大小,网络结构,灰度图,这个三都有关系,如果是这种情况,将灰度图进行排除
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: