tensorflow2.x学习笔记八:tensorflow(keras)损失函数之交叉熵

下面都是我自己的一些简单的总结,如果有错误的地方,还请大家指出来。

一、BinaryCrossentropy类和binary_crossentropy函数

BinaryCrossentropy类的使用:

tf.keras.losses.BinaryCrossentropy(
from_logits=False, label_smoothing=0,
reduction=losses_utils.ReductionV2.AUTO,
name='binary_crossentropy'
)
1
2
3
4
5
参数解释:

from_logits:为True时,表示预测结果非概率分布,而是确切的类别值;为False时表示输出是概率分布
reduction:当对多组数据(比如多个batch)进行计算时,用来表示对计算的loss做怎样的处理,取值是 tf.keras.losses.Reduction所包含的几个属性值,主要有:
value 作用
AUTO 根据上下文来判断处理方式
NONE 不做任何处理,保持默认
SUM 对各组所得loss求和
SUM_OVER_BATCH_SIZE 对各组所得loss求平均值
先来看一下只有一组数据时,它的计算公式是怎样的:

y_true=[1., 0., 1., 0.]
y_pred=[1., 1., 1., 0.]
bce = tf.keras.losses.BinaryCrossentropy()
loss=bce(y_true, y_pred)
print('Loss: ', loss.numpy())

#输出:Loss: 3.833
'''
# EPSILON = 1e-7, y = y_true, y` = y_pred, Y_MAX = 0.9999999
# y` = clip_ops.clip_by_value(output, EPSILON, 1. - EPSILON)
# y` = [Y_MAX, Y_MAX, Y_MAX, EPSILON]

# Metric = -(y log(y` + EPSILON) + (1 - y) log(1 - y` + EPSILON))
# = [-log(Y_MAX + EPSILON), -log(1 - Y_MAX + EPSILON),
# -log(Y_MAX + EPSILON), -log(1)]
# = [(0 + 15.33) / 2, (0 + 0) / 2]
# Reduced metric = 7.665 / 2 = 3.833
'''
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
为了演示reduction参数的具体作用,我们提供两组数据进行计算,每一组的计算方式都是和上面一个例子是一样的:

y_true=([1., 0., 1., 0.], [1., 1., 1., 0.])
y_pred=([1., 1., 1., 0.], [1., 0., 1., 0.])

bce = tf.keras.losses.BinaryCrossentropy()
loss = bce(y_true,y_pred)
print('Loss: ', loss.numpy())
#默认输出:Loss: 3.8447733
1
2
3
4
5
6
7
可以看出默认情况下是求的平均值,这时候改变reduction来看一下效果,如下面的例子所示:

bce = tf.keras.losses.BinaryCrossentropy(
reduction=tf.keras.losses.Reduction.NONE)
loss1=bce(y_true, y_pred)
print('Loss: ', loss1.numpy())

#输出:Loss: [3.8333097 3.8562372]
1
2
3
4
5
6
bce = tf.keras.losses.BinaryCrossentropy(
reduction=tf.keras.losses.Reduction.SUM)

loss2=bce(y_true, y_pred)
print('Loss: ', loss2.numpy())

#求和输出:Loss: 7.6895466
1
2
3
4
5
6
7
bce = tf.keras.losses.BinaryCrossentropy(
reduction=tf.keras.losses.Reduction.SUM_OVER_BATCH_SIZE)

loss3=bce(y_true, y_pred)
print('Loss: ', loss3.numpy())

#求平均输出:Loss: 3.8447733
1
2
3
4
5
6
7
binary_crossentropy函数的使用:

tf.keras.losses.binary_crossentropy(
y_true, y_pred, from_logits=False, label_smoothing=0
)
1
2
3
y_true=[1., 0., 1., 0.]
y_pred=[1., 1., 1., 0.]
loss=tf.keras.losses.binary_crossentropy(
y_true, y_pred)
print('Loss: ', loss.numpy())
#输出:3.833
1
2
3
4
5
6
二、CategoricalCrossentropy类和categorical_crossentropy函数。

CategoricalCrossentropy类

tf.keras.losses.CategoricalCrossentropy(
from_logits=False, label_smoothing=0,
reduction=losses_utils.ReductionV2.AUTO,
name='categorical_crossentropy'
)
1
2
3
4
5
y_true=([0, 1, 0], [0, 0, 1])
y_pred=([0.05, 0.95, 0], [0.1, 0.8, 0.1])
cce = tf.keras.losses.CategoricalCrossentropy()
loss=cce(y_true, y_pred)
print('Loss: ', loss.numpy())

#输出:Loss: 1.176
'''
# EPSILON = 1e-7, y = y_true, y` = y_pred
# y` = clip_ops.clip_by_value(output, EPSILON, 1. - EPSILON)
# y` = [[0.05, 0.95, EPSILON], [0.1, 0.8, 0.1]]

# xent = -sum(y * log(y'), axis = -1)
# = -((log 0.95), (log 0.1))
# = [0.051, 2.302]
# Reduced xent = (0.051 + 2.302) / 2 = 1.176
'''
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
可以看出默认也是计算的平均值,可以通过设置reduction的值来改变其对多组数据的计算结果的处理方式,用法和BinaryCrossentropy中介绍的一模一样,这里就不多说了,可以自己试一试。
categorical_crossentropy函数

tf.keras.losses.categorical_crossentropy(
y_true, y_pred, from_logits=False, label_smoothing=0
)
1
2
3
y_true=([0, 1, 0], [0, 0, 1])
y_pred=([0.05, 0.95, 0], [0.1, 0.8, 0.1])
loss=tf.keras.losses.categorical_crossentropy(
y_true, y_pred)
print('Loss: ', loss.numpy())

#输出:Loss: 1.176
1
2
3
4
5
6
7
除了上述的用法之外,它们还可以作为model.compile()里的loss参数,使用方法如下:
import tensorflow as tf

inputs = tf.keras.Input(shape=(3,))
x = tf.keras.layers.Dense(4, activation=tf.nn.relu)(inputs)
outputs = tf.keras.layers.Dense(5, activation=tf.nn.softmax)(x)
model = tf.keras.Model(inputs=inputs, outputs=outputs)
1
2
3
4
5
6
model.compile('sgd',
loss=tf.keras.losses.BinaryCrossentropy())
model.compile('sgd',
loss=tf.keras.losses.binary_crossentropy)
 郑州看男科医院那家好:http://www.xasgnanke.com/郑州治男科哪家医院好:http://www.xasgnanke.com/郑州男科医院排名:http://www.xasgnanke.com/
model.compile('sgd',
loss=tf.keras.losses.CategoricalCrossentropy())
model.compile('sgd',
loss=tf.keras.losses.categorical_crossentropy)

1
2
3
4
5
6
7
8
9
10
有一点需要注意的是,如果使用的是类,那么别忘了后面呢还有一个括号,用来得到实例化的对象;如果是函数就只写函数名就可以了

三、最后还要说的一点就是,不管是BinaryCrossentropy还是CategoricalCrossentropy,其实两者都可以用于二分类或者多分类,没有那么明显的界线,后者是在前者的基础上进行扩展得来的。但是一般情况下都是按照上述例子中的默认用法进行使用的。
————————————————
版权声明:本文为CSDN博主「万能的小黑Alex」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_39507748/article/details/105005427

猜你喜欢

转载自www.cnblogs.com/sushine1/p/12642821.html