tf.nn.softmax_cross_entropy_with_logits,...logits_v2,sparse_softmax_cross_entropy_with_logits的异同

tf.nn.softmax_cross_entropy_with_logits
tf.nn.softmax_cross_entropy_with_logits_v2
tf.nn.sparse_softmax_cross_entropy_with_logits

三者的异同

1、共同点

三者功能都是先计算输入 logits 的 softmax 分类,再计算与输入 labels 之间的交叉熵,最终返回的交叉熵结果相同

2、不同点

(1)softmax_cross_entropy_with_logits

已经弃用,相同功能被 softmax_cross_entropy_with_logits_v2 取代

(2)softmax_cross_entropy_with_logits_v2

labels 参数既可以接受整数形式的一维 labels,如:[0 1 2]

labels 参数也可以接受独热编码形式的 labels,如:
[[1 0 0]
 [0 1 0]
 [0 0 1]]

(3)sparse_softmax_cross_entropy_with_logits

labels 参数接受整数形式的一维 labels,如:[0 1 2];如果训练数据是 one-hots 编码,需要使用 tf.argmax() 将 one-hots 编码形式的类别标签转换为一维整数形式的类别标签

当分类问题只有一个正确答案时,可以使用这个函数加速交叉熵的计算”

二、官方 API

1、softmax_cross_entropy_with_logits

https://tensorflow.google.cn/api_docs/python/tf/nn/softmax_cross_entropy_with_logits

计算 logits 与 labels 之间的 softmax 交叉熵(已废弃)

该函数已经废弃,将在新版本中被移除

更新说明:新版本的 TensorFlow 默认允许通过后向传播将提出流向到输入的 labels,具体参见:tf.nn.softmax_cross_entropy_with_logits_v2

测量类互斥(每一项恰好在一类中)的离散分类任务的概率误差,例如,每一幅 CIFAR-10 图像仅属于一类,可以为狗、卡车,但不能同属于这两者

注意:尽管所有的类别是互斥的,它们的概率可能不是互斥的。因此,就要求 labels 中的每一行都是一个有效的概率分布,如果不是,将会导致计算的梯度不正确

如果使用互斥 labels (即每次有且仅有一个类别),参见:sparse_softmax_cross_entropy_with_logits

警告:该操作的输入参数 logits 接收的是没有经过非线性激活函数放缩的数据,直接在内部对未放缩的数据执行 softmax 计算可以提高效率。一定不能用该操作处理经过 softmax 处理后的数据,否则会导致错误结果。

labels 和 logits 最常见的形状为 [batch_size, num_classed],通过参数 dim 指定类别维度时支持更高维度。

反向传播同时会发生在 logits 中。如果想要交叉熵损失能够同时反向传播给 logits 和 labels,请参加tf.nn.softmax_cross_entropy_with_logits_v2

注意:为了避免混淆,需要将命名参数传递给该函数

tf.nn.softmax_cross_entropy_with_logits(
    _sentinel=None,
    labels=None,
    logits=None,
    dim=-1,
    name=None
)

参数:

  • _sentinel:用于保护位置参数。内部,不使用

  • labels:沿类别维度的每一个向量需要具有有效概率分布,例如:当 labels 的形状为 [batch_size, num_classes],labels[i] 的每一行都必须是一个有效的概率分布

  • logits:为经过非线性激活函数放缩的对数概率

  • dim:类别维度,默认是 -1,即最后一个维度

  • name:可选参数,操作的名称

返回:

值为 softmax 交叉熵的张量,除了没有类别标签最后一个维度外,其类型和 logits 相同,其形状和 labels 相同,除了没有类别标签最后一个维度外

2、softmax_cross_entropy_with_logits_v2

https://tensorflow.google.cn/api_docs/python/tf/nn/softmax_cross_entropy_with_logits_v2

计算 logits 与 labels 之间的 softmax 交叉熵

测量类互斥(每一项恰好在一类中)的离散分类任务的概率误差,例如,每一幅 CIFAR-10 图像仅属于一类,可以为狗、卡车,但不能同属于这两者

注意:尽管所有的类别是互斥的,它们的概率可能不是互斥的。因此,就要求 labels 中的每一行都是一个有效的概率分布,如果不是,将会导致计算的梯度不正确

如果使用互斥 labels (即每次有且仅有一个类别),参见: sparse_softmax_cross_entropy_with_logits

警告:该操作的输入参数 logits 接收的是没有经过非线性激活函数放缩的数据,直接在内部对未放缩的数据执行 softmax 计算可以提高效率。一定不能用该操作处理经过 softmax 处理后的数据,否则会导致错误结果。

labels 和 logits 最常见的形状为 [batch_size, num_classed],通过参数 dim 指定类别维度时支持更高维度。

logits 和 labels 的数据类型必须相同,可以是 float16,float32,float64

反向传播同时会发生在 logits 和 labels中。如果想禁用 labels 的反向传播,需要在将 labels 输入给该函数之前先通过 tf.stop_gradient 处理一下

注意:为了避免混淆,需要将命名参数传递给该函数

tf.nn.softmax_cross_entropy_with_logits_v2(
    _sentinel=None,
    labels=None,
    logits=None,
    dim=-1,
    name=None
)

参数:

  • _sentinel:用于保护位置参数。内部,不使用

  • labels:沿类别维度的每一个向量需要具有有效概率分布,例如:当 labels 的形状为 [batch_size, num_classes],labels[i] 的每一行都必须是一个有效的概率分布

  • logits:为经过非线性激活函数放缩的对数概率

  • dim:类别维度,默认是 -1,即最后一个维度

  • name:可选参数,操作的名称

返回:

值为 softmax 交叉熵的张量,除了没有类别标签最后一个维度外,其类型和 logits 相同,其形状和 labels 相同,除了没有类别标签最后一个维度外

3、sparse_softmax_cross_entropy_with_logits

https://tensorflow.google.cn/api_docs/python/tf/nn/sparse_softmax_cross_entropy_with_logits

计算 logits 与 labels 之间的稀疏 softmax 交叉熵

测量类互斥(每一项恰好在一类中)的离散分类任务的概率误差,例如,每一幅 CIFAR-10 图像仅属于一类,可以为狗、卡车,但不能同属于这两者

注意:对于该操作来说,给定类别标签的概率是惟一的,即不允许使用软类(soft classes),并且类别向量必须 logits 中每行的真实类别提供一个特征的索引值(每个 minibatch 中的数据条目)。对每个数据条目的概率分布的软 softmax 分类,请参加 softmax_cross_entropy_with_logits_v2。

警告:该操作的输入参数 logits 接收的是没有经过非线性激活函数放缩的数据,直接在内部对未放缩的数据执行 softmax 计算可以提高效率。一定不能用该操作处理经过 softmax 处理后的数据,否则会导致错误结果。

labels 和 logits 最常见的形状为 [batch_size, num_classed],也支持更高维度的情况,即 dim-th 个维度为 num_classes。

logits 的数据类型只能是 float16,float32,float64

labels 的数据类型智能是 int32 或 int 64

注意:为了避免混淆,需要将命名参数传递给该函数

tf.nn.sparse_softmax_cross_entropy_with_logits(
    _sentinel=None,
    labels=None,
    logits=None,
    name=None
)

参数:

  • _sentinel:用于保护位置参数。内部,不使用

  • labels:形状为 [d_0, d_1, …, d_{r-1}] 、类型为 int32 或 int64 的张量,其中, r 为 labels 和结果的阶。labels 中的每一个值的取值范围都必须在 [0, num_classes) 范围内。超过了该范围,在 CPU 上运行时会抛出异常,在 GPU 上运行时会返回 NaN

  • logits:未经过激活函数缩放的、形状为 [d_0, d_1, …, d_{r-1}, num_classes]、数据类型为 (loat16, float32, or float64) 的对数概率(log probabilities)

  • name:可选参数,操作的名称

返回:

形状与 lables 具相同、类型与 logits 经过 softmax 计算后取的交叉熵损失结果相同的张量

三、示例

1、softmax_cross_entropy_with_logits

已经弃用,目前还可以正常使用,只不过会提示警告信息:

WARNING:tensorflow:From <stdin>:1: softmax_cross_entropy_with_logits (from tensorflow.python.ops.nn_ops) is deprecated and will be removed in a future version.
Instructions for updating:

Future major versions of TensorFlow will allow gradients to flow
into the labels input on backprop by default.

See `tf.nn.softmax_cross_entropy_with_logits_v2`.

即推荐使用 tf.nn.softmax_cross_entropy_with_logits_v2


>>> import tensorflow as tf
>>> labels = tf.constant([[1,0,0],[0,1,0],[0,0,1]])
>>> labels
<tf.Tensor 'Const_1:0' shape=(3, 3) dtype=int32>
>>> logits = tf.random.normal(shape=[3,3],mean=0.0, stddev=1.0, dtype=tf.float32, seed=1, name="logits")
>>> logits
<tf.Tensor 'logits_1:0' shape=(3, 3) dtype=float32>
>>> loss = tf.nn.softmax_cross_entropy_with_logits(labels=labels, logits=logits)
WARNING:tensorflow:From <stdin>:1: softmax_cross_entropy_with_logits (from tensorflow.python.ops.nn_ops) is deprecated and will be removed in a future version.
Instructions for updating:
 
Future major versions of TensorFlow will allow gradients to flow
into the labels input on backprop by default.
 
See `tf.nn.softmax_cross_entropy_with_logits_v2`.
 
>>> loss_mean = tf.reduce_mean(loss)
>>> with tf.Session() as sess:
...     result_loss, result_loss_mean = sess.run([loss, loss_mean])
...     print(result_loss)
...     print(result_loss_mean)
...
[2.590495   0.99851835 1.6042291 ]
1.7310809

2、softmax_cross_entropy_with_logits_v2

(1)正确使用方式(one-hot编码)

>>> import tensorflow as tf
>>> labels = tf.constant([[1,0,0],[0,1,0],[0,0,1]])
>>> labels
<tf.Tensor 'Const_3:0' shape=(3, 3) dtype=int32>
>>> logits = tf.random.normal(shape=[3,3],mean=0.0, stddev=1.0, dtype=tf.float32, seed=1, name="logits")
>>> logits
<tf.Tensor 'logits_2:0' shape=(3, 3) dtype=float32>
>>> loss = tf.nn.softmax_cross_entropy_with_logits_v2(labels=labels, logits=logits)
>>> loss_mean = tf.reduce_mean(loss)
>>> with tf.Session() as sess:
...     result_loss, result_loss_mean = sess.run([loss, loss_mean])
...     print(result_loss)
...     print(result_loss_mean)
...
[2.590495   0.99851835 1.6042291 ]
1.7310809

(2)正确使用方式(整型 labels 形式转换 one-hot 编码形式)


>>> import tensorflow as tf
>>> labels = tf.constant([0,1,2])
>>> labels
<tf.Tensor 'Const_2:0' shape=(3,) dtype=int32>
>>> one_hot_labels = tf.one_hot(indices=labels,depth=3, on_value=1, off_value=0, axis=-1, dtype=tf.int32, name="one-hot")
>>> one_hot_labels
<tf.Tensor 'one-hot:0' shape=(3, 3) dtype=int32>
>>> logits = tf.random.normal(shape=[3,3],mean=0.0, stddev=1.0, dtype=tf.float32, seed=1, name="logits")
>>> logits
<tf.Tensor 'logits_1:0' shape=(3, 3) dtype=float32>
>>> loss = tf.nn.softmax_cross_entropy_with_logits_v2(labels=one_hot_labels,logits=logits)
>>> loss_mean = tf.reduce_mean(loss)
>>> with tf.Session() as sess:
...     result_labels, result_loss, result_loss_mean = sess.run([one_hot_labels, loss, loss_mean])
...     print(result_labels)
...     print(result_loss)
...     print(result_loss_mean)
...
[[1 0 0]
 [0 1 0]
 [0 0 1]]
[2.590495   0.99851835 1.6042291 ]
1.7310809

(3)正确使用方式(直接输入整型 labels 形式)


>>> import tensorflow as tf
>>> labels = tf.constant([0,1,2])
>>> labels
<tf.Tensor 'Const:0' shape=(3,) dtype=int32>
>>> logits = tf.random.normal(shape=[3,3],mean=0.0, stddev=1.0, dtype=tf.float32, seed=1, name="logits")
>>> logits
<tf.Tensor 'logits:0' shape=(3, 3) dtype=float32>
>>> loss = tf.nn.softmax_cross_entropy_with_logits_v2(labels=labels,logits=logits)
>>> loss_mean = tf.reduce_mean(loss)
>>> with tf.Session() as sess:
...     result_loss, result_loss_mean = sess.run([loss, loss_mean])
...     print(result_loss)
...     print(result_loss_mean)
...
[3.7222729 2.0116034 6.21272  ]
3.9821987

3、sparse_softmax_cross_entropy_with_logits

(1) 正确的使用方式(one-hot 编码形式的 labels 转换一维整型 labels)

因为 labels 采用 one-hot 编码形式,需要通过 tf.argmax 将其转换为一维整型形式

>>> import tensorflow as tf
>>> labels = tf.constant([[1,0,0],[0,1,0],[0,0,1]])
>>> argmax_labels = tf.argmax(input=labels, axis=0)
>>> argmax_labels
<tf.Tensor 'ArgMax:0' shape=(3,) dtype=int64>
>>> logits = tf.random.normal(shape=[3,3],mean=0.0, stddev=1.0, dtype=tf.float32, seed=1, name="logits")
>>> logits
<tf.Tensor 'logits:0' shape=(3, 3) dtype=float32>
>>> loss = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=tf.argmax(labels,1), logits=logits)
>>> loss_mean = tf.reduce_mean(loss)
>>> with tf.Session() as sess:
...     result_labels, result_loss, result_loss_mean = sess.run([argmax_labels, loss, loss_mean])
...     print(result_labels)
...     print(result_loss)
...     print(result_loss_mean)
...
[0 1 2]
[2.590495   0.99851835 1.6042291 ]
1.7310809

(2)正确使用方式(直接输入一维整型 labels)

>>> import tensorflow as tf
>>> labels = tf.constant([0,1,2])
>>> labels
<tf.Tensor 'Const_1:0' shape=(3,) dtype=int32>
>>> logits = tf.random.normal(shape=[3,3],mean=0.0, stddev=1.0, dtype=tf.float32, seed=1, name="logits")
>>> logits
<tf.Tensor 'logits_1:0' shape=(3, 3) dtype=float32>
>>> loss = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=labels,logits=logits)
>>> loss_mean = tf.reduce_mean(loss)
>>> with tf.Session() as sess:
...     result_loss, result_loss_mean = sess.run([loss, loss_mean])
...     print(result_loss)
...     print(result_loss_mean)
...
[2.590495   0.99851835 1.6042291 ]
1.7310809

(3)错误使用方式举例-1

错误原因:labels 参数接受一维整型类别标签,这里的类别标签是二维整型形式 (3, 1)


>>> import tensorflow as tf
>>> labels = tf.constant([[1],[2],[3]])
>>> labels
<tf.Tensor 'Const_4:0' shape=(3, 1) dtype=int32>
>>> logits = tf.random.normal(shape=[3,3],mean=0.0, stddev=1.0, dtype=tf.float32, seed=1, name="logits")
>>> logits
<tf.Tensor 'logits_1:0' shape=(3, 3) dtype=float32>
>>> loss = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=labels,logits=logits)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\WJW\AppData\Roaming\Python\Python36\site-packages\tensorflow\python\ops\nn_ops.py", line 2039, in sparse_softmax_cross_entropy_with_logits
    (labels_static_shape.ndims, logits.get_shape().ndims))
ValueError: Rank mismatch: Rank of labels (received 2) should equal rank of logits minus 1 (received 2).

(4)错误使用方式举例-2

错误原因:labels 参数接受一维整型类别标签,同时整数只能在为 [0 ~ n) 的范围内取值(n为类别数),这里类别标签的最大值是 n=3,取到了 n ,则在 CPU 上运行是会抛出异常,这里在 GPU 上运行给出的结果为 nan

>>> import tensorflow as tf
>>> labels = tf.constant([1,2,3])
>>> labels
<tf.Tensor 'Const_6:0' shape=(3,) dtype=int32>
>>> logits = tf.random.normal(shape=[3,3],mean=0.0, stddev=1.0, dtype=tf.float32, seed=1, name="logits")
>>> logits
<tf.Tensor 'logits_2:0' shape=(3, 3) dtype=float32>
>>> loss = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=labels,logits=logits)
>>> loss_mean = tf.reduce_mean(loss)
>>> with tf.Session() as sess:
...     result_loss, result_loss_mean = sess.run([loss, loss_mean])
...     print(result_loss)
...     print(result_loss_mean)
...
[0.29457802 0.50654244        nan]
nan

tensorflow运行出现的问题:
https://blog.csdn.net/qq_36271653/article/details/82316803

来源:https://blog.csdn.net/sdnuwjw/article/details/86086377

猜你喜欢

转载自blog.csdn.net/xc_zhou/article/details/88538815
今日推荐