使用image_dataset_from_directory时损失函数选择困惑与输出行为咨询
损失函数选择困惑解析:sparse_categorical_crossentropy vs categorical_crossentropy
核心逻辑说明
你当前的代码逻辑是自洽的,原因很明确:
image_dataset_from_directory生成的数据集,标签默认是整数索引格式(二分类场景下标签为0或1),并非独热编码。sparse_categorical_crossentropy损失函数就是专门适配「整数标签 + softmax输出」这种组合的,它会自动在计算过程中把整数标签转换为独热编码形式,和模型的输出做交叉熵计算——所以你看到模型输出是独热格式,但用sparse损失完全能正常工作。
切换到categorical_crossentropy的具体步骤
如果你确实想改用categorical_crossentropy,需要让数据集标签格式和损失函数要求匹配(该损失要求标签为独热编码),有两种实现方式:
方式一:手动转换标签格式
给训练和验证数据集添加独热编码转换:
import tensorflow as tf # 定义标签转换函数 def one_hot_encode(image, label): label = tf.one_hot(label, depth=2) # depth对应你的类别总数,这里是2 return image, label # 应用到数据集 train_ds = train_ds.map(one_hot_encode) val_ds = val_ds.map(one_hot_encode) # 修改模型编译的损失函数 rn50v2_model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
方式二:直接生成独热标签
利用image_dataset_from_directory的label_mode参数,直接生成独热编码格式的标签:
# 训练集生成时指定label_mode train_ds = tf.keras.utils.image_dataset_from_directory( '/content/dataset/train', validation_split=0.05, subset="training", seed=123, image_size=(IMAGE_SIZE, IMAGE_SIZE), batch_size=BATCH_SIZE, label_mode='categorical' # 直接输出独热标签 ) # 验证集同理 val_ds = tf.keras.preprocessing.image_dataset_from_directory( '/content/dataset/val', image_size=(IMAGE_SIZE, IMAGE_SIZE), batch_size=BATCH_SIZE, label_mode='categorical' ) # 直接使用categorical_crossentropy rn50v2_model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
额外建议
二分类场景下,你也可以简化模型和损失的搭配:把模型最后一层改为Dense(1, activation='sigmoid'),搭配binary_crossentropy损失,这样标签依然可以用整数格式,模型输出是单个概率值,计算效率会更高。
内容的提问来源于stack exchange,提问作者EdgeDev
相关产品推荐
相关产品推荐

