如何在TensorFlow CNN中自定义最小化误分类矩阵成本的损失函数?
构建基于误分类成本矩阵的自定义损失函数TensorFlow CNN模型
需求说明
需构建TensorFlow CNN模型,自定义损失函数以最小化误分类矩阵的总成本为目标。例如,当误分类矩阵中错误分类对应的成本分别为4、6、2、3、5、1时,损失为这些值的总和(实际训练中采用平均损失更利于优化)。
修正后的CNN模型代码
先修正原代码中的语法错误(缺失闭合括号、Dense层参数顺序错误),基础模型结构如下:
import tensorflow as tf from tensorflow import keras import numpy as np # 需提前定义图片尺寸 IMG_HEIGHT = 224 IMG_WIDTH = 224 model = keras.models.Sequential() model.add(keras.layers.experimental.preprocessing.Rescaling(1./255, input_shape=(IMG_HEIGHT, IMG_WIDTH, 3))) model.add(keras.layers.Conv2D(filters=32, kernel_size=(3,3), padding='same', activation='relu')) model.add(keras.layers.MaxPooling2D(pool_size=(2,2))) model.add(keras.layers.Conv2D(filters=64, kernel_size=(3,3), padding='same', activation='relu')) model.add(keras.layers.MaxPooling2D(pool_size=(2,2))) model.add(keras.layers.Conv2D(filters=128, kernel_size=(3,3), padding='same', activation='relu')) model.add(keras.layers.MaxPooling2D(pool_size=(2,2))) model.add(keras.layers.Flatten()) model.add(keras.layers.Dense(128, activation="relu")) model.add(keras.layers.Dense(64, activation="relu")) model.add(keras.layers.Dense(5, activation="softmax"))
自定义损失函数实现
步骤1:定义误分类成本矩阵
定义5类对应的成本矩阵,cost_matrix[i][j]表示真实类别为i,被预测为j时的成本,正确分类(对角线)成本设为0:
# 示例成本矩阵,需根据实际业务需求填充完整 cost_matrix = np.array([ [0, 4, 6, 2, 3], [5, 0, 1, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0] ], dtype=np.float32)
步骤2:实现可导的自定义损失函数
为保证损失函数支持梯度下降优化,基于softmax输出的概率计算期望误分类成本,避免使用不可导的硬分类结果:
def custom_loss(y_true, y_pred): # 将one-hot编码的真实标签转换为类别索引 y_true_idx = tf.argmax(y_true, axis=1) # 取出每个样本真实类别对应的成本行 cost_rows = tf.gather(cost_matrix, y_true_idx) # 计算每个样本的期望成本:预测概率与对应成本行的点积 sample_costs = tf.reduce_sum(y_pred * cost_rows, axis=1) # 返回所有样本的平均成本作为损失 return tf.reduce_mean(sample_costs)
步骤3:编译模型
将自定义损失函数传入模型编译环节:
model.compile( loss=custom_loss, optimizer="Adam", metrics=["accuracy"] ) model.summary()
关键说明
- 可导性:使用softmax概率计算期望成本,确保损失函数可导,模型能正常进行梯度下降优化。
- 成本矩阵调整:需根据实际业务场景填充完整的5x5成本矩阵,准确赋值不同误分类场景的成本。
- 损失计算方式:示例采用平均样本成本作为损失,也可根据需求改为总样本成本(将
tf.reduce_mean替换为tf.reduce_sum)。
内容的提问来源于stack exchange,提问作者Need
相关产品推荐
相关产品推荐

