写在前面
本文是介绍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的tf.losses模块,包括常用的损失函数如absolute_difference、hinge_loss、softmax_cross_entropy等,并以softmax_cross_entropy为例,解释了参数含义和使用方法,特别提到了label_smoothing和reduction参数的作用。
84

被折叠的 条评论
为什么被折叠?



