tf.losses 模块

写在前面

本文是介绍tf.losses 模块(实际就是对tf.nn.下面的loss函数的高级封装)。之前本人常用slim.losses.XXX(),但强迫症发作受不每次都提示:

"2016-12-30. Use tf.losses.sigmoid_cross_entropy instead."
"2016-12-30. "Use tf.losses.softmax_cross_entropy instead." 
......

于是乎换了tf.losses. 下的loss实现函数,刚用还是遇到坑,故写此文,总结下经验,如有错误,欢迎指正。

正文

首先放出tensorflow的官方的api:官网API

此模块下主要的Functions有:

absolute_difference(): 为训练过程添加一个“绝对差异”loss,其实就是做差后取绝对值作为loss。

add_loss(): 为loss集合添加额外定义的loss。

compute_weighted_loss(): 计算加权loss。

cosine_distance(): Adds a cosine-distance loss to the training procedure. (deprecated arguments)

get_losses(): 从loss集合中获取loss列表。

get_regularization_loss(): 获取整体的正则化loss。

get_regularization_losses(): 获得正则化loss列表。

get_total_loss(): 返回其值表示总损失的张量。

hinge_loss(): 为训练过程添加一个hinge loss。

huber_loss(): 为训练过程添加一个Huber Loss。

log_loss(): 为训练过程添加一个Log Loss。

mean_pairwise_squared_error(): 为训练过程添加一个pairwise-errors-squared loss。

mean_squared_error(): 为训练过程添加一个Sum-of-Squares loss,就是常说的均方误差loss。

sigmoid_cross_entropy(): sigmoid cross-entropy loss(用tf.nn.sigmoid_cross_entropy_with_logits 实现)

softmax_cross_entropy(): softmax cross-entropy loss (用tf.nn.softmax_cross_entropy_with_logits 实现)

sparse_softmax_cross_entropy(): 稀疏softmax Cross-entropy loss (用 tf.nn.sparse_softmax_cross_entropy_with_logits 实现)


详解

下面以常用的softmax_cross_entropy() 函数为例,做一个详细介绍。
softmax_cross_entropy() # 交叉熵loss

tf.losses.softmax_cross_entropy(
    onehot_labels,  # 注意此处参数名就叫 onehot_labels
    logits,
    weights=1.0,
    label_smoothing=0,
    scope=None,
    loss_collection=tf.GraphKeys.LOSSES,
    reduction=Reduction.SUM_BY_NONZERO_WEIGHTS
)

Args:

  • onehot_labels: [batch_size, num_classes] one_hot类型的label.
  • logits: [batch_size, num_classes] 神经网络的logits输出. 这两个参数都没什么好解释的,最基本的知识。
  • weights: 为可选参数,首先它是tensor 然后它可以是一个标量(此时作为loss的系数),也可以是一个[batch_size]的向量(看源码我个人理解就是对一个batch的样本进行加权,不知道有什么意义,因为一般来说训练样本的输入顺序是随机的,即每一个batch的样本全部都是随机的,这中情况下这个加权没有任何意义了)
  • label_smoothing: 这个参数如果设置大于0,则对label进行平滑,平滑的公式为:
    new_onehot_labels = onehot_labels*(1-label_smoothing) + label_smoothing/num_classes
  • scope: 命名空间
  • loss_collection: 指定loss集合。
  • reduction: 指定应用到这个loss的reduction类型.
    • NONE: Un-reduced weighted losses with the same shape as input.
    • SUM: Scalar sum of weighted losses.
    • MEAN: Scalar ‘SUM’ divided by sum of weights.
    • SUM_OVER_BATCH_SIZE: Scalar ‘SUM’ divided by number of elements in losses.
    • SUM_OVER_NONZERO_WEIGHTS: Scalar ‘SUM’ divided by number of non-zero weights.
    • SUM_BY_NONZERO_WEIGHTS: Same as ‘SUM_OVER_NONZERO_WEIGHTS’
      reduction一般都是使用MEAN而不是默认的SUM_BY_NONZERO_WEIGHTS,不过需要注意的是设置这个参数的时候是:reduction=tf.losses.Reduction.MEAN

实例:

# 本实例并不完整,只是为了尽量体现loss函数的参数设置以及“上下文”情况
import tensorflow as tf
Reduction = tf.losses.Reduction  # 免得下面写太长


......
input = tf.placeholder(tf.float32, shape=[None, None, None, 3], name='input')
output = tf.placeholder(tf.float32, shape=[None, None, None, classnum], name='output')

logits = network.build_model(input, classnum, is_training)

def myloss(logits, labels):
    soft_loss = tf.loses.softmax_cross_entropy(
        onehot_labels=output, logits=logits, reduction=Reduction.MEAN
        )
    regular_loss = tf.losses.get_regularization_loss()
    return soft_loss + regular_loss

......

# Train
loss = myloss(logist=logits, labels=output)
train_opt = tf.train.AdamOptimizer(learning_rate).minimize(loss, var_list=[var for var in tf.trainable_variables()])
......

本人也还是菜鸟,对于一些loss类型与各种奇怪的操作(比如加权loss、平滑label)都未曾接触过。不过如果只是使用基础的交叉熵损失,上面的解释足够你正确地使用了。

By the way

推荐一篇在知乎看到的文章:《如何通俗的解释交叉熵与相对熵? - CyberRep的回答》

你可能感兴趣的:(Tensorflow)