0
点赞
收藏
分享

微信扫一扫

TensorFlow 中的 Loss 函数介绍

TensorFlow 中的 Loss 函数介绍

前言

TensorFlow 提供了很多计算 Loss 的 API, 很多时候容易忘记这些 API 的输入和输出的 Shape. 这里对经常用到的 API 做个记录, 并配上 API 的使用实例, 加深体会.

广而告之

可以在微信中搜索 “珍妮的算法之路” 或者 “world4458” 关注我的微信公众号;另外可以看看知乎专栏 ​​PoorMemory-机器学习​​, 以后文章也会发在知乎专栏中;

softmax_cross_entropy_with_logits

​tf.nn.softmax_cross_entropy_with_logits​​​ 用于分类问题计算交叉熵, 输入分别是 ​​labels​​​ 和 ​​logits​​​ (​​logits​​​ 是神经网络的输出结果, 但还未输入到 ​​tf.nn.softmax​​​ 方法中; ​​labels​​​ 一般是 OneHot 的形式, 可以使用 ​​tf.one_hot​​). 下面看个例子:

import os
import tensorflow as tf

os.environ['TF_CPP_MIN_LOG_LEVEL']='3'
os.environ['CUDA_VISIBLE_DEVICES'] = '-1'

logits = tf.constant([[1.0,2.0,3.0],
[1.0,2.0,3.0],
[1.0,2.0,3.0]])
y_ = tf.constant([[0.0,0.0,1.0],
[0.0,0.0,1.0],
[0.0,0.0,1.0]])

loss = tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=y_)

logits = tf.nn.softmax(logits)
manual_loss = tf.reduce_sum(-y_ * tf.log(tf.clip_by_value(logits, 1e-10, 1.)), axis=1)

with tf.Session() as sess:
loss_, logits_, manual_loss_ = sess.run([loss, logits, manual_loss])
print('loss: {}'.format(loss_))
print('logits_: {}'.format(logits_))
print('manual_loss_: {}'.format(manual_loss_))

### -----------------输出结果 --------------------------
loss_: [0.40760595 0.40760595 0.40760595]
logits_: [[0.09003057 0.24472848 0.66524094]
[0.09003057 0.24472848 0.66524094]
[0.09003057 0.24472848 0.66524094]]
manual_loss_: [0.407606 0.407606 0.40760598]

可以看到

  • ​loss_​​​ 和​​manual_loss_​​ 的结果是一致的 (请忽略些许的误差).
  • 如果输入的​​logits​​​ 的 Shape 为​​(B, T)​​​, 那么​​labels​​​ 变换成 OneHot 的形式, 大小也为​​(B, T)​​.
  • 将​​logits​​​ 和​​labels​​​ 输入到​​tf.nn.softmax_cross_entropy_with_logits​​​ 后, 得到的结果是​​(B,)​​; 因此, 在实践中, 为了得到一个 Batch 的平均 loss, 需要使用:

loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=y_))

  • ​manual_loss_​​​ 的计算方式:TensorFlow 中的 Loss 函数介绍_tensorflow, 其中TensorFlow 中的 Loss 函数介绍_深度学习_02.

sparse_softmax_cross_entropy_with_logits

和 ​​softmax_cross_entropy_with_logits​​​ 不同的是, ​​labels​​​ 无需变换成 OneHot 的形式. 还是拿上面的作为例子, 代码只需要对 ​​labels​​ 做一定修改即可.

import os
import tensorflow as tf

os.environ['TF_CPP_MIN_LOG_LEVEL']='3'
os.environ['CUDA_VISIBLE_DEVICES'] = '-1'

logits = tf.constant([[1.0,2.0,3.0],
[1.0,2.0,3.0],
[1.0,2.0,3.0]])
y = tf.constant([2, 2, 2], dtype=tf.int32) # 和上一节的代码相比, 注意此处的改动

loss = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits, labels=y)

logits = tf.nn.softmax(logits)
y_ = tf.one_hot(y, depth=3) ## 注意此处的改动
manual_loss = tf.reduce_sum(-y_ * tf.log(tf.clip_by_value(logits, 1e-10, 1.)), axis=1)

with tf.Session() as sess:
loss_, logits_, manual_loss_ = sess.run([loss, logits, manual_loss])
print('loss_: {}'.format(loss_))
print('logits_: {}'.format(logits_))
print('manual_loss_: {}'.format(manual_loss_))

### -----------------输出结果 --------------------------
loss_: [0.40760595 0.40760595 0.40760595]
logits_: [[0.09003057 0.24472848 0.66524094]
[0.09003057 0.24472848 0.66524094]
[0.09003057 0.24472848 0.66524094]]
manual_loss_: [0.407606 0.407606 0.40760598]

举报

相关推荐

0 条评论