如何将Keras模型的categorical_crossentropy损失替换为加权自定义损失?
Keras自定义加权损失函数适配方案
因为训练集、测试集对应的returns权重向量不同,不能用固定权重的闭包损失方案,因此我们改用Keras Functional API构建多输入模型,将returns作为额外输入传入,自动匹配训练/验证阶段的不同权重。
完整修改后代码
import tensorflow as tf from tensorflow.keras.layers import Input, Dense, Dropout from tensorflow.keras.models import Model # 1. 定义输入层 input_features = Input(shape=(X_train.shape[1],), name='feature_input') input_returns = Input(shape=(1,), name='returns_input') # 若returns是多维权重可对应调整shape # 2. 原有网络结构保留不变 x = Dense(2, activation='relu')(input_features) x = Dropout(0.1)(x) x = Dense(2, activation='relu')(x) output_pred = Dense(3, activation='softmax', name='pred_output')(x) # 3. 定义自定义加权损失 def get_weighted_abs_loss(returns): def loss(y_true, y_pred): abs_diff = tf.abs(y_true - y_pred) weighted_diff = abs_diff * returns return tf.reduce_sum(weighted_diff) return loss # 4. 构建并编译模型 model = Model(inputs=[input_features, input_returns], outputs=output_pred) callback = tf.keras.callbacks.EarlyStopping(monitor='loss', patience=50) model.compile( loss=get_weighted_abs_loss(input_returns), optimizer='RMSprop', metrics=['AUC'] ) # 5. 训练模型,传入对应训练/测试集的returns向量 epochs=1000 history = model.fit( [X_train, returns_train], # returns_train为训练集对应权重向量 y_train, epochs=epochs, batch_size=32, validation_data=([X_test, returns_test], y_test), # returns_test为测试集对应权重向量 callbacks=[callback] ) # 可选:定义仅需特征输入的推理模型,预测时无需传入returns infer_model = Model(inputs=input_features, outputs=output_pred) # 预测调用示例:y_pred = infer_model.predict(X_test)
注意事项
- 提前准备好
returns_train和returns_test,若每个样本对应1个权重,需调整shape为(样本数, 1)适配广播规则,可通过returns_train = returns_train.reshape(-1, 1)实现 - 若需要同时保留原始交叉熵损失和新的加权损失,可在compile时传入损失列表,按需求设置权重即可
- 训练完成后直接用
infer_model做预测,无需额外传入returns参数,使用逻辑和原Sequential模型一致
内容的提问来源于stack exchange,提问作者Lorenzo Viola
相关产品推荐
相关产品推荐

