zoukankan      html  css  js  c++  java
  • tensorflow 基础学习三:损失函数讲解

    交叉熵损失:

    给定两个概率分布p和q,通过q来表示p的交叉熵为:

    从上述公式可以看出交叉熵函数是不对称的,即H(p,q)不等于H(q,p)。

    交叉熵刻画的是两个概率分布之间的距离,它表示通过概率分布q来表示概率分布p的困难程度。所以使用交叉熵作为

    神经网络的损失函数时,p代表的是正确答案,q代表的是预测值。当两个概率分布越接近时,它们的交叉熵也就越小。

    由于神经网络的输出并不是一个概率分布,所以需要先使用softmax将网络输出变成一个概率分布,再计算交叉熵。

    比如,原始的神经网络输出为y1,y2,……,yn,那么经过softmax处理后的输出为:

    小例子:

    以一个三分类为例,比如某个样本正确答案为(1,0,0)。某模型经过softmax回归后的预测答案为(0.5,0.4,0.1),则这个预测值和正确答案之间的交叉熵为:

     H((1,0,0),(0.5,0.4,0.1))=-(1*log0.5+0*log0.4+0*log0.1))=0.3

    假设另外一个模型的预测值是(0.8,0.1,0.1),则该预测值和真实值之间的交叉熵为:

    H((1,0,0),(0.8,0.1,0.1))=-(1*log0.8+0*log0.1+0*log0.1)=0.1

    从上述结果可以看出第二个预测答案要由于第一个。

    tensorflow中实现交叉熵,如下所示:

    cross_entropy=-tf.reduce_mean(y_*tf.log(tf.clip_by_value(y,1e-10,1.0)))

    其中y_代表正确结果,y代表预测结果。tf.clip_by_value函数可以将一个张量中的数值限制在一个范围内,这样可以避免

    一些运算错误(比如log0是无效的)。下面讲解使用tf.clip_by_value函数的简单样例。

    v=tf.constant([[1.0,2.0,3.0],[4.0,5.0,6.0]])
    with tf.Session() as sess:
        print(tf.clip_by_value(v,2.5,4.5).eval())
    '''
    输出为
    [[ 2.5  2.5  3. ]
     [ 4.   4.5  4.5]]
    '''
    # tensorflow中提供的直接计算交叉熵损失的函数,y代表神经网络的输出结果,y_表示真实类别
    cross_entropy=tf.nn.softmax_cross_entropy_with_logits(logits=y,y_)

    均方误差(MSE,mean squared error):

    常用于回归问题中。它的具体定义如下:

    $MES(y,y^{'})=frac{sum _{i=1}^{n}(y_{i}-y_{i}^{'})^{2}}{n}$

       其中,yi表示一个batch中第i个样本的真实类别,yi'为神经网络输出的预测值。tensorflow代码实现如下:

    mse=tf.reduce_mean(tf.square(y_-y))

    自定义损失函数:

    tensorlfow支持自定义损失函数,以下演示一个简单的示例:

    首先定义一个分段损失函数,然后提供它的代码实现:

    $Loss(y,y^{'})=sum_{i=1}^{n}f(y_{i},y_{i}^{'}), f(x,y)=left{egin{matrix}a(x-y)
     & x>y \
     b(y-x) & xleqslant y
    end{matrix} ight. $

    loss=tf.recue_sum(tf.where(tf.greater(v1,v2),(v1-v2)*a,(v2-v1)*b))

    tf.where和tf.greater函数用法如下:

    # tf.where和tf.greater函数的用法
    v1=tf.constant([1.0,2.0,3.0,4.0])
    v2=tf.constant([4.0,3.0,2.0,1.0])
    
    with tf.Session() as sess:
        print(tf.greater(v1,v2).eval())
        # 输出 [False False  True  True]
        print(.where(tf.greater(v1,v2),v1,v2).eval())
        # 输出 [ 4.  3.  3.  4.]

     使用自定义损失函数实现一个简单的神经网络

    该网络只有两个输入节点和一个输出节点,相当于实现了一个回归。

    import tensorflow as tf
    from numpy.random import RandomState
    
    batch_size=8
    
    # 定义两个输入节点
    x=tf.placeholder(tf.float32,shape=(None,2),name='x-input')
    # 回归问题一般只有一个输出节点
    y_=tf.placeholder(tf.float32,shape=(None,1),name='y-input')
    
    # 定义一个单层的神经网络
    w1=tf.Variable(tf.random_normal([2,1],stddev=1,seed=1))
    y=tf.matmul(x,w1)
    
    # 使用上述自己定义的损失函数
    a=1;b=10
    loss=tf.reduce_sum(tf.where(tf.greater(y,y_),(y-y_)*a,(y_-y)*b))
    
    train_step=tf.train.AdamOptimizer(0.001).minimize(loss)
    
    # 随机生成一个模拟数据集
    rdm=RandomState(1)
    dataset_size=128
    X=rdm.rand(dataset_size,2)
    # 设置随机噪声,范围在-0.05~0.05
    Y = [[x1+x2+rdm.rand()/10.0-0.05] for (x1,x2) in X]
    
    # 训练神经网路
    with tf.Session() as sess:
        init_op = tf.global_variables_initializer()
        sess.run(init_op)
        STEPS=5000
        for i in range(STEPS):
            start=(i*batch_size) % dataset_size
            end = min(start+batch_size,dataset_size)
            sess.run(train_step,feed_dict={x:X[start:end],y_:Y[start:end]})
        print(sess.run(w1))
  • 相关阅读:
    httpModules与httpHandlers之httpModules(转载)
    一个人的命运决定于晚上8点到10点之间【认真看完本篇文章,你的人生将会有所改变】
    关于错误Access Violation和too many consecutive exceptions 解决方法
    Delphi PChar与String互转
    Delphi+MySQL:TADOQuery使用插入中文乱码解决方法
    Delphi中的操作二进制文件的两个重要函数
    JavaWeb错误处理集锦
    Codeforces Round #286 (Div. 1) B. Mr. Kitayuta's Technology (强连通分量)
    从头认识java-16.4 nio的读与写(ByteBuffer的使用)
    php在数字前面补0得到固定长度数字的两种方法
  • 原文地址:https://www.cnblogs.com/hypnus-ly/p/8047214.html
Copyright © 2011-2022 走看看