• Tensorflow踩坑系列---softmax_cross_entropy_with_logits


    一:常见激活函数Sigmoid、Relu、Tanh、Softmax 

    (一)sigmoid:https://www.jianshu.com/p/506595ec4b58---以作为激活函数

    1)  值域在0和1之间
    2)  函数具有非常好的对称性
    3)  函数对输入超过一定范围就会不敏感

    (二)tanh:http://www.ai-start.com/dl2017/html/lesson1-week3.html---以作为激活函数

    tanh函数或者双曲正切函数是总体上都优于sigmoid函数的激活函数,值域是位于+1和-1之间,其均值是更接近零均值的。在训练一个算法模型时,如果使用tanh函数代替sigmoid函数中心化数据,使得数据的平均值更接近0而不是0.5.

    但是在二分类中(0,1)还是用sigmoid更好,因为范围在(0,1)之间。

    sigmoid与tanh缺点: sigmoid函数和tanh函数两者共同的缺点是,在特别大或者特别小的情况下,导数的梯度或者函数的斜率会变得特别小,最后斜率就会接近于0,导致降低梯度下降的速度 

    (三)relu:http://www.ai-start.com/dl2017/html/lesson1-week3.html---可以作为激活函数

    修正线性单元的函数(ReLu  所以,只要是正值的情况下,导数恒等于1,当是负值的时候,导数恒等于0。

    补充:从实际上来说,当使用的导数时,=0的导数是没有定义的。但是当编程实现的时候,的取值刚好等于0.00000001,这个值相当小,所以,在实践中,不需要担心这个值,是等于0的时候,假设一个导数是1或者0效果都可以。

    注意:这里也有另一个版本的Relu被称为Leaky Relu

    当是负值时,这个函数的值不是等于0,而是轻微的倾斜,这个函数通常比Relu激活函数效果要好,尽管在实际中Leaky ReLu使用的并不多。

    Relu优点:

    第一,在的区间变动很大的情况下,激活函数的导数或者激活函数的斜率都会远大于0,在程序实现就是一个if-else语句,而sigmoid函数需要进行浮点四则运算,在实践中,使用ReLu激活函数神经网络通常会比使用sigmoid或者tanh激活函数学习的更快。

    第二,sigmoidtanh函数的导数在正负饱和区的梯度都会接近于0,这会造成梯度弥散,而ReluLeaky ReLu函数大于0部分都为常数,不会产生梯度弥散现象。(同时应该注意到的是,Relu进入负半区的时候,梯度为0,神经元此时不会训练,产生所谓的稀疏性,而Leaky ReLu不会有这问题)

    ReLu的梯度一半都是0,但是,有足够的隐藏层使得z值大于0,所以对大多数的训练数据来说学习过程仍然可以很快。 

    (四):回归函数softmax

    1)softmax第一步就是将模型的预测结果转化到指数函数上,这样保证了概率的非负性。
    2)各种预测结果概率之和等于1

    softmax不同于其他激活函数,一般只用于输出层上!!之前,我们的激活函数都是接受单行数值输入,例如SigmoidReLu激活函数,输入一个实数,输出一个实数。Softmax激活函数的特殊之处在于,因为需要将所有可能的输出归一化,就需要输入一个向量,最后输出一个向量。

    补充:hardmax

    二:交叉熵函数

    (一)错误记忆-XXX

    由于先去学习的二分类,所以把交叉熵求解记成了如下格式:https://www.jianshu.com/p/b07f4cd32ba6

    这只是二分类当中的交叉熵函数!!!,对于多分类是错误的!!!!

    (二)正确版本-√√√

    其中,k是类别。交叉熵刻画的是通过概率分布y^来表达概率分布y的困难程度。因为正确答案是希望得到的结果,所以当交叉熵作为神经网络的损失函数时,y代表的是正确答案,y^代表的是预测值。

    交叉熵刻画的是两个概率分布的距离,也就是说交叉熵值越小, 两个概率分布越接近。  

    补充:交叉熵代价函数见:https://www.zhihu.com/question/341500352/answer/795497527 

    (三)在tensorflow中的交叉熵求解

    labels = [[0.2,0.3,0.5]] #真实值
    logits = [[2,0.5,1]] #预测值
    
    #直接计算交叉熵
    result1 = tf.nn.softmax_cross_entropy_with_logits(labels=labels,logits=logits) #输入的不是经过softmax缩放过的值
    
    #需要先对预测值进行缩放
    logits_scaled = tf.nn.softmax(logits)
    result2 = -tf.reduce_sum(labels*tf.log(logits_scaled),1)
    
    with tf.Session() as sess:
        print(sess.run(result1))
        print(sess.run(result2))    

    三:softmax_cross_entropy_with_logits解惑

    其实上面案例(三)已经给出了解答:就是Tensorflow交叉熵计算函数输入中的logits都不是softmax或sigmoid的输出,而是softmax或sigmoid函数的输入,因为它在函数内部进行sigmoid或softmax操作。softmax_cross_entropy_with_logits内部会实现缩放,即softmax操作。

    (一)案例一如二中(三)

    (二)案例二

    labels = [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0]
    logits = [5.414214045506107, 1.0364190761952838, 1.0931452034494957, 3.894246202026429, 2.3824730004342136, 5.965072403073978, 2.076533529367469, 1.4828656147245602, 2.3414934241076537, 3.5602012920818584, 0.11375485316768152, 3.450451299129589, 2.8094892586761437, 1.788879710725854, 2.80663522176181, 4.924723247878252, 2.4961140164238786, 5.9613323377434995, 0.7989157311136863, 4.2635188203807335, 3.4873045567789664, 5.11255294433231, 3.2693959007989832, 4.490670418324648, 1.6669091076779448, 5.747519715144237, 1.4899624466441748, 4.077105711625433, 0.1835752962824988, 5.337763177515887, 5.809078207371751, 3.070040261173903, 2.4653770382715177, 0.03311200569409323, 3.3492673710270733, 3.477621449855114, 3.63523160480906, 2.312116025458221, 0.45082654327315574, 0.4283251243179722]
    #logits是随机初始化的值
    labels = np.array([labels])
    logits = np.array([logits])
    logits_scaled = tf.nn.softmax(logits)
    #两种交叉熵正确解法
    result1 = tf.nn.softmax_cross_entropy_with_logits(labels=labels,logits=logits)
    result2 = -tf.reduce_sum(labels*tf.log(logits_scaled),1)
    #使用缩放后的值作为输入,是错误的
    result3 = tf.nn.softmax_cross_entropy_with_logits(labels=labels,logits=logits_scaled)
    with tf.Session() as sess:
        print(sess.run(result1))
        print(sess.run(result2))
        print(sess.run(result3)) #使用缩放的值作为输入,结果会出错

    (三)使用缩放后的值作为softmax_cross_entropy_with_logits输入,导致的错误

    CNN实现验证码识别中:

    正确使用softmax_cross_entropy_with_logits时:

    在4000次迭代后,误差降为0.03,准确率在98%。

    错误使用softmax_cross_entropy_with_logits时:

     

    发现5000+迭代,误差没有变化,准确率也没有增加.....!!! 

  • 相关阅读:
    测试数据生成利器
    9.22“月饼杯”递归算法欢乐赛测试报告总结
    lemon评测软件配置使用方法
    1200:分解因数
    大犇博客
    C++ |递归原理与构造技巧
    2018.9.8信息奥赛集训评测报告总结
    1195 判断整除
    计算机图形学初步
    AcWing
  • 原文地址:https://www.cnblogs.com/ssyfj/p/13966848.html
Copyright © 2020-2023  润新知