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 编码形式的类别标签转换为一维整数形式的类别标签
当分类问题只有一个正确答案时,可以使用这个函数加速交叉熵的计算”
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 相同,除了没有类别标签最后一个维度外
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 相同,除了没有类别标签最后一个维度外
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 :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
>>> logits = tf.random.normal(shape=[3,3],mean=0.0, stddev=1.0, dtype=tf.float32, seed=1, name="logits")
>>> logits
>>> loss = tf.nn.softmax_cross_entropy_with_logits(labels=labels, logits=logits)
WARNING:tensorflow:From :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
>>> logits = tf.random.normal(shape=[3,3],mean=0.0, stddev=1.0, dtype=tf.float32, seed=1, name="logits")
>>> logits
>>> 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
>>> 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
>>> logits = tf.random.normal(shape=[3,3],mean=0.0, stddev=1.0, dtype=tf.float32, seed=1, name="logits")
>>> logits
>>> 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
>>> logits = tf.random.normal(shape=[3,3],mean=0.0, stddev=1.0, dtype=tf.float32, seed=1, name="logits")
>>> logits
>>> 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
>>> logits = tf.random.normal(shape=[3,3],mean=0.0, stddev=1.0, dtype=tf.float32, seed=1, name="logits")
>>> logits
>>> 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
>>> logits = tf.random.normal(shape=[3,3],mean=0.0, stddev=1.0, dtype=tf.float32, seed=1, name="logits")
>>> logits
>>> 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
>>> logits = tf.random.normal(shape=[3,3],mean=0.0, stddev=1.0, dtype=tf.float32, seed=1, name="logits")
>>> logits
>>> loss = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=labels,logits=logits)
Traceback (most recent call last):
File "", line 1, in
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
>>> logits = tf.random.normal(shape=[3,3],mean=0.0, stddev=1.0, dtype=tf.float32, seed=1, name="logits")
>>> logits
>>> 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