美文网首页python与Tensorflow
Tensorflow——关于loss

Tensorflow——关于loss

作者: SpareNoEfforts | 来源:发表于2018-10-30 21:04 被阅读19次

    tf.nn.sigmoid_cross_entropy_with_logits()

    • tf.nn.sigmoid_cross_entropy_with_logits(_sentinel=None,,labels=None,logits=None,name=None)
      对于给定的logits计算sigmoid的交叉熵。
      对于给定的logits计算sigmoid的交叉熵。
      衡量的是分类任务中的概率误差.
      logits和labels必须有相同的类型和大小。

    • 第一个参数:_sentinel内部的并不使用。

    • 第二个参数:labels和logits的shape和type一样。

    • 第三个参数:logits类型为float32或者float64

    • 第四个参数:操作的名称,可省。

    • 返回的是:一个张量,和logits的大小一致。是逻辑损失

    
    import numpy as np
    import tensorflow as tf
     
    def sigmoid(x):
        return 1.0/(1+np.exp(-x))
     
    labels=np.array([[1.,0.,0.],[0.,1.,0.],[0.,0.,1.]])
    logits=np.array([[11.,8.,7.],[10.,14.,3.],[1.,2.,4.]])
    y_pred=sigmoid(logits)
    prob_error1=-labels*np.log(y_pred)-(1-labels)*np.log(1-y_pred)
    print(prob_error1)
     
    print(".............")
    labels1=np.array([[0.,1.,0.],[1.,1.,0.],[0.,0.,1.]])#不一定只属于一个类别
    logits1=np.array([[1.,8.,7.],[10.,14.,3.],[1.,2.,4.]])
    y_pred1=sigmoid(logits1)
    prob_error11=-labels1*np.log(y_pred1)-(1-labels1)*np.log(1-y_pred1)
    print(prob_error11)
     
    print(".............")
    with tf.Session() as sess:
        print(sess.run(tf.nn.sigmoid_cross_entropy_with_logits(labels=labels,logits=logits)))
        print(".............")
        print(sess.run(tf.nn.sigmoid_cross_entropy_with_logits(labels=labels1,logits=logits1)))
    

    结果:你会发现第一个输出与第三个一致,第二个输出和第四个一致

    总结公式

    \begin{array}{l} y = labels\\ {p_{ij}} = sigmoid(\log it{s_{ij}}) = \frac{1}{{1 + {e^{ - \log it{s_{ij}}}}}}\\ los{s_{ij}} = - [{y_{ij}}*\ln {p_{ij}} + (1 - {y_{ij}})\ln (1 - {p_{ij}})] \end{array}

    tf.reduce_sum()

    • 定义:
    reduce_sum(
        input_tensor,
        axis=None,
        keep_dims=False,
        name=None,
        reduction_indices=None
    )
    

    reduce_sumtensor 内部求和的工具。其参数中:

    1. input_tensor 是要求和的 tensor
    2. axis 是要求和的 rank,如果为 none,则表示所有 rank 都要求和
    3. keep_dims 求和后是否要降维
    4. 这个操作的名称,可能在 graph 中 用
    5. 已被淘汰的,被参数 axis 替代

    其实在reduce_sum()中,是从维度上去考虑的(感觉这个Matlab中数据的概念比较像)


    调用reduce_sum(arg1, arg2)时,参数arg1即为要求和的数据,arg2有两个取值分别为01,通常用reduction_indices=[0]reduction_indices=[1]来传递参数。从上图可以看出,当arg2 = 0时,是纵向对矩阵求和,原来矩阵有几列就得到几个值;相似地,当arg2 = 1时,是横向对矩阵求和;当省略arg2参数时,默认对矩阵所有元素进行求和。

    reduce_sum()中就是按照求和的方式对矩阵降维。

    • 例子
    x = tf.constant([[1, 1, 1], [1, 1, 1]])
    tf.reduce_sum(x, 0)  # 对 tensor 的 0 级进行求和,[1,1,1] + [1,1,1] =  [2, 2, 2]
    tf.reduce_sum(x, 1)  # 对 tensor 的 1 级进行求和,[1+1+1, 1+1+1] = [3, 3]
    tf.reduce_sum(x, 1, keep_dims=True)  # 对第 1 级进行求和,但不降维, [[3], [3]]
    tf.reduce_sum(x, [0, 1])  # 0 级和 1级都要求和,6
    tf.reduce_sum(x)  # 因为 x 只有 2 级,所以结果同上一个,6
    
    

    tf.reduce_mean()

    • 定义
    reduce_mean(
        input_tensor,
        axis=None,
        keep_dims=False,
        name=None,
        reduction_indices=None
    )
    

    计算张量的各个维度上的元素的平均值。

    • 参数
    1. input_tensor:要减少的张量。应该有数字类型。输入待求平均值的张量。
    2. axis:要减小的尺寸。None(默认):对全局求平均值;0:求每一列平均值;1:求每一行平均值。
    3. keep_dims:如果为true,则保留长度为1的缩小尺寸。保留原来的维度(例如不会从二维矩阵降为一维向量)
    4. name:操作的名称(可选)。
    5. reduction_indices:和 axis 等价,被弃用。
    • 例子
    x = tf.constant([[1., 1.], [2., 2.]])
    tf.reduce_mean(x)  # 1.5
    tf.reduce_mean(x, 0)  # [1.5, 1.5]
    tf.reduce_mean(x, 1)  # [1.,  2.]
    

    tf.nn.l2_loss()

    • 定义:
    tf.nn.l2_loss(
        t,
        name=None
    )
    
    • 参数
      • t: 一个Tensor. 其types为: half, bfloat16, float32, float64.
      • name: A name for the operation (optional).
      • 作用:不使用sqrt计算张量的L2范数的一半:
      • 计算公式:output=sum(t^2)/2..简单的可以理解成张量中的每一个元素进行平方,然后求和,最后乘一个1/2

    l2_loss一般用于优化目标函数中的正则项,防止参数太多复杂容易过拟合(所谓的过拟合问题是指当一个模型很复杂时,它可以很好的“记忆”每一个训练数据中的随机噪声的部分而忘记了要去“学习”训练数据中通用的趋势)

    • 例子:
    import tensorflow as tf
    x = tf.constant([1,2,3],dtype=tf.float32)
    with tf.Session() as sess:
        print(sess.run(tf.nn.l2_loss(x)))
    

    结果输出:
    7.0
    计算的过程:
    1/2(1^2+2^2+3^2) = 1/2(1+4+9) = 7.0

    题外话
    正则化的基本思想是向损失函数添加一个惩罚项用于惩罚大的权重,隐式地减少自由参数的数量,所以可以达到弹性地适用不同数据量训练的要求而不产生过拟合的问题。

    正则化方法是将惩罚因子加入到各层的参数或激活函数中。其实现位置通常是在模型的optimization里,在计算损失函数时将该惩罚因子加进去。

    tf.trainable_variables方法

    (http://www.cnblogs.com/guqiangjs/p/7805098.html)
    tf.trainable_variables 返回所有 当前计算图中 在获取变量时未标记 trainable=False 的变量集合.

    import tensorflow as tf
     
    v1 = tf.get_variable('v1', shape=[1])
    v2 = tf.get_variable('v2', shape=[1], trainable=False)
     
    with tf.variable_scope('scope1'):
        s1 = tf.get_variable('s1', shape=[1], initializer=tf.random_normal_initializer())
    g1=tf.Graph()
    g2=tf.Graph()
     
    with g1.as_default():
        g1v1 = tf.get_variable('g1v1', shape=[1])
        g1v2 = tf.get_variable('g1v2', shape=[1], trainable=False)
        g1vs = tf.trainable_variables()
        # [<tf.Variable 'g1v1:0' shape=(1,) dtype=float32_ref>]
        print(g1vs)
     
    with g2.as_default():
        g2v1 = tf.get_variable('g2v1', shape=[1])
        g2v2 = tf.get_variable('g2v2', shape=[1], trainable=False)
        g2vs = tf.trainable_variables()
        # [<tf.Variable 'g2v1:0' shape=(1,) dtype=float32_ref>]
        print(g2vs)
     
    with tf.Session() as sess:
        vs = tf.trainable_variables()
        # [<tf.Variable 'v1:0' shape=(1,) dtype=float32_ref>, <tf.Variable 'scope1/s1:0' shape=(1,) dtype=float32_ref>]
        print(vs)
    

    输出

    [<tf.Variable 'g1v1:0' shape=(1,) dtype=float32_ref>]
    
    [<tf.Variable 'g2v1:0' shape=(1,) dtype=float32_ref>]
    
    [<tf.Variable 'v1:0' shape=(1,) dtype=float32_ref>, <tf.Variable 'scope1/s1:0' shape=(1,) dtype=float32_ref>]
    

    相关文章

      网友评论

        本文标题:Tensorflow——关于loss

        本文链接:https://www.haomeiwen.com/subject/ntdntqtx.html