报错原因,图片分类时的label形式与模型的损失函数不匹配。
解析图片时,label_mode的设定要与后面模型complile时设定的损失函数一致
train_ds = tf.keras.preprocessing.image_dataset_from_directory(
data_dir,
#默认int,需要配合sparse_categorical_crossentropy损失函数
# 设置为categorical以后,需要配合categorical_crossentropy损失函数,具体看这两个损失函数的接收数据就可以理解
# binary可以用binary_crossentropy
# label_mode="categorical",
validation_split=0.2,
subset="training",
seed=123,
image_size=(img_width, img_height),
batch_size=batch_size)
下面介绍相匹配的两个交叉熵损失函数
交叉熵表示两个概率分布之间的距离。
交叉熵越大,两个概率分布距离越远,两个概率分布越相异;交叉熵越小,两个概率分布距离越近,两个概率分布越相似。
SparseCategoricalCrossentropy:多分类,经常搭配Softmax使用,和CategoricalCrossentropy不同之处在于,CategoricalCrossentropy是one-hot编码,而SparseCategoricalCrossentropy使用一个位置整数表示类别。SparseCategoricalCrossentropy的y_true = [1, 2, 3],等价于CategoricalCrossentropy的 y_true = [[0, 1, 0, 0], [0, 0, 1, 0],[0, 0, 0, 1]]
对应的 y_pred = [[0.05, 0.95, 0, 0.66], [0.1, 0.8, 0.1, 0.35], [0.1, 0.8, 0.1, 0.35]]
from_logits:默认False。为True,表示接收到了原始的logits,为False表示输出层经过了概率处理(softmax)
以下为SparseCategoricalCrossentropy的测试
# 官方示例,实际为3类2样本
# y_true = [1, 2]
# y_pred = [[0.05, 0.95, 0], [0.1, 0.8, 0.1]]
# 3类3样本
# y_true = [0, 1, 2]
# y_true = [2, 3]# 报错
# y_true = [0, 2] # 正常
# y_true = [0, 1] # 正常 说明最大值为2即表示有三类
# y_pred = [[0.05, 0.95, 0], [0.1, 0.8, 0.1]] #报错
# y_pred = [[0.05, 0.95, 0], [0.1, 0.8, 0.1],[0.1, 0.8, 0.1]] #正常
#3类2样本
# y_true = [1, 2]
# y_pred = [[0.05, 0.95, 0], [0.1, 0.8, 0.1], [0.1, 0.8, 0.1]]#报错
# y_pred = [[0.05, 0.95, 0], [0.1, 0.8, 0.1]] #正常
# y_pred = [[0.05, 0.95, 0, 0.5], [0.1, 0.8, 0.1, 0.6]] #正常,这种情况被解读为4类2样本,y_true里有隐藏的3
# y_pred = [[0.95, 0, 0.5], [0.8, 0.1, 0.6]] #正常
# 4类3样本预测时
# y_true = [0, 1, 3]
# # y_pred = [[0.05, 0.95, 0], [0.1, 0.8, 0.1], [0.1, 0.8, 0.1], [0.1, 0.8, 0.1]]#报错
# # y_pred = [[0.05, 0.95, 0], [0.1, 0.8, 0.1], [0.1, 0.8, 0.1]] #报错
# y_pred = [[0.05, 0.95, 0, 0.22], [0.1, 0.8, 0.1, 0.55], [0.1, 0.8, 0.1, 0.3]] # 正常
# 4类2样本预测时
# y_true = [2, 3]
# # y_pred = [[0.05, 0.95, 0, 0.22], [0.1, 0.8, 0.1, 0.55], [0.1, 0.8, 0.1, 0.3]] #报错
# y_pred = [[0.05, 0.95, 0, 0.22], [0.1, 0.8, 0.1, 0.3]] # 正常
# 通过上面的测试可以得出,y_true的数量表示样本数量,与y_pred的预测数组数量对应
# y_true的最大数值,表示分类数量,与y_pred预测里的数组元素的数量对应
# y_true的shape是[batch_size],y_pred的shape是[batch_size, num_classes]
#from_logits为True表示把y_pred解读为一个logits张量,否则解读为一个概率分布,默认为false
scce = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False)
scce(y_true, y_pred).numpy()
网友评论