PyTorch与Keras正则化:Keras中自定义关联L1惩罚的等效实现
在Keras中实现自定义关联L1惩罚逻辑
步骤1:计算皮尔逊相关系数与目标特征索引
先基于训练集计算每个特征与标签y的皮尔逊相关系数,筛选出相关系数绝对值小于0.3的特征索引,逻辑和PyTorch端完全一致:
from scipy.stats import pearsonr import numpy as np # 假设train是(X_train, y_train)的元组 X_train, y_train = train pearson_corr = [] for col_idx in range(X_train.shape[1]): corr, _ = pearsonr(X_train[:, col_idx], y_train) pearson_corr.append(corr) pearson_corr = np.array(pearson_corr) # 筛选目标特征索引 pearson_index = np.where(np.abs(pearson_corr) < 0.3)[0]
步骤2:构建Keras模型并添加自定义惩罚项
Keras中通过add_loss方法可以直接将自定义惩罚项整合到模型总损失中,需要注意Keras与PyTorch的Dense层权重形状差异:
- PyTorch的
nn.Linear权重形状为(输出维度, 输入维度),按dim=0求和得到每个输入特征的权重L1和 - Keras的
Dense层权重(kernel)形状为(输入维度, 输出维度),需按axis=1求和得到每个输入特征的权重L1和
代码实现:
import tensorflow as tf from tensorflow import keras alpha = 5.0 # 构建模型 inputs = keras.Input(shape=(X_train.shape[1],)) # 定义对应PyTorch中fc1的Dense层,指定name方便获取权重 fc1 = keras.layers.Dense(64, activation='relu', name='fc1')(inputs) # 后续层根据你的模型结构补充 outputs = keras.layers.Dense(1)(fc1) model = keras.Model(inputs=inputs, outputs=outputs) # 定义自定义关联L1惩罚函数 def corr_l1_penalty(fc1_kernel): # 计算每个输入特征对应的权重L1和 weight_l1_per_feature = tf.reduce_sum(tf.abs(fc1_kernel), axis=1) # 筛选目标特征的L1和并求和,乘以alpha得到最终惩罚项 return alpha * tf.reduce_sum(tf.gather(weight_l1_per_feature, pearson_index)) # 将惩罚项添加到模型总损失中 model.add_loss(corr_l1_penalty(model.get_layer('fc1').kernel)) # 编译模型,使用MSE作为基础损失 model.compile(optimizer='adam', loss='mse')
可选:自定义损失函数实现
如果偏好通过自定义损失函数整合惩罚项,也可以参考以下代码(注意模型层的依赖问题):
def custom_loss(y_true, y_pred): mse_loss = tf.keras.losses.MSE(y_true, y_pred) fc1_kernel = model.get_layer('fc1').kernel weight_l1_per_feature = tf.reduce_sum(tf.abs(fc1_kernel), axis=1) penalty = alpha * tf.reduce_sum(tf.gather(weight_l1_per_feature, pearson_index)) return mse_loss + penalty # 编译时指定自定义损失 model.compile(optimizer='adam', loss=custom_loss)
内容的提问来源于stack exchange,提问作者Caterina
相关产品推荐
相关产品推荐

