日萌社
人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度学习实战(不定时更新)
# 损失基本计算方法为稀疏类别交叉熵损失
# from_logits=True代表是否将预测结果预期为非 0/1 的值进行保留
# 理论来讲二分类最终的结果应该只有0/1,函数将自动将其变为0/1,from_logits=True后,值不会被改变
# reduction='none',接下来我们将自定义损失函数,reduction必须设置为None,
# 我们可以将它看作是自定义损失函数的识别属性
loss_object = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True, reduction='none')
"""
tf.keras.losses.SparseCategoricalCrossentropy(
from_logits=False, reduction=losses_utils.ReductionV2.AUTO,
name='sparse_categorical_crossentropy'
)
from_logits:
y_pred是否预期为对数张量。 默认情况下,我们假设y_pred编码概率分布。
注意:使用from_logits = True可能在数值上更稳定。
import tensorflow as tf
help(tf.losses.categorical_crossentropy)
查看categorical_crossentropy函数的默认参数列表和使用方法介绍
其中形参默认为from_logits=False,网络预测值y_pred 表示必须为经过了 Softmax函数的输出值。
当 from_logits 设置为 True 时,网络预测值y_pred 表示必须为还没经过 Softmax 函数的变量 z。
from_logits=True 标志位将softmax激活函数实现在损失函数中,便不需要手动添加softmax损失函数,提升数值计算稳定性。
from_logits 指的就是是否有经过Logistic函数,常见的Logistic函数包括Sigmoid、Softmax函数。
reduction:
(可选的)
tf.keras.losses.reduction的类型,适用于损失。 默认值为自动。 AUTO表示减少选项将由使用情况决定。
在几乎所有情况下,该默认值均为SUM_OVER_BATCH_SIZE。
与tf.distribute.Strategy一起使用时,在诸如tf.keras之类的内置训练循环之外,使用AUTO或SUM_OVER_BATCH_SIZE会引发错误。
1.reduction='none':
默认值为losses_utils.ReductionV2.AUTO,即默认使用SUM_OVER_BATCH_SIZE的方式计算批量样本个数的loss的sum总和返回一个总和值。
设置'none'代表将自定义损失函数,即自定义损失函数的识别属性,代表每个样本的loss均保留返回。
2.reduction='none'
打印loss为 Tensor("sparse_categorical_crossentropy_4/weighted_loss/Mul:0", shape=(64,), dtype=float32)
shape=(64,) 代表每个样本的loss均保留返回。
3.reduction=默认值losses_utils.ReductionV2.AUTO
打印loss为 Tensor("sparse_categorical_crossentropy_7/weighted_loss/value:0", shape=(), dtype=float32)
shape=() 代表默认使用SUM_OVER_BATCH_SIZE的方式计算批量样本个数的loss的sum总和,那么返回的loss只有一个总和值。
"""
SparseCategoricalCrossentropy
1.loss_object = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True, reduction='none')
SparseCategoricalCrossentropy稀疏类别交叉熵损失,自动将其中一方不是one-hot表示的数据转换为one-hot表示。
from_logits=True:softmax激活函数实现在损失函数中,便不需要手动添加softmax损失函数
reduction='none':
默认值为losses_utils.ReductionV2.AUTO,即默认使用SUM_OVER_BATCH_SIZE的方式计算批量样本个数的loss的sum总和返回一个总和值。
设置'none'代表将自定义损失函数,即自定义损失函数的识别属性,代表每个样本的loss均保留返回。
2.reduction='none'
打印loss为 Tensor("sparse_categorical_crossentropy_4/weighted_loss/Mul:0", shape=(64,), dtype=float32)
shape=(64,) 代表每个样本的loss均保留返回。
3.reduction=默认值losses_utils.ReductionV2.AUTO
打印loss为 Tensor("sparse_categorical_crossentropy_7/weighted_loss/value:0", shape=(), dtype=float32)
shape=() 代表默认使用SUM_OVER_BATCH_SIZE的方式计算批量样本个数的loss的sum总和,那么返回的loss只有一个总和值。
# 因为每次生成的结果都是局部结果,要和真实结果进行比较需要对真实结果进行遮掩
# 等效于对损失计算结果进行掩码
def loss_function(real, pred):
"""自定义损失函数,参数为预测结果pred和真实结果real"""
# 使用tf.math.equal方法对real和0进行对比
# 对结果再进行逻辑非操作生成掩码张量mask
bool_result = tf.math.equal(real, 0) #tf.math.logical_not([False,True]) 结果 tf.Tensor([ True False], shape=(2,), dtype=bool)
mask = tf.math.logical_not(bool_result)
# print("mask", mask) #Tensor("LogicalNot_4:0", shape=(64,), dtype=bool)
# print("mask.shape",mask.shape) #(64,)
# 使用基本计算方法计算损失
loss_ = loss_object(real, pred)
# print("loss_",loss_) #Tensor("sparse_categorical_crossentropy_4/weighted_loss/Mul:0", shape=(64,), dtype=float32)
# 将mask进行类型转换,使其能够进行后续操作
mask = tf.cast(mask, dtype=loss_.dtype)
# 将loss_与mask相乘即对loss_进行掩码
loss_ *= mask
# 计算loss_张量所有元素的均值
return tf.reduce_mean(loss_)