PyTorch自定义AdjMSELoss转TensorFlow及全零预测排查
问题描述
复现论文代码过程中,将一段PyTorch编写的自定义损失函数自行转换为TensorFlow版本后,模型训练阶段的指标日志数值看似正常(loss与val_loss变化趋势相近),但训练完成后模型预测结果全部为0,现咨询两个问题:
- 编写的TensorFlow版本损失函数是否为原PyTorch版本的正确等价实现?
- 使用该自定义损失函数时,模型仅输出0值预测结果的原因是什么?
相关代码
原PyTorch自定义损失函数
#Pytorch class AdjMSELoss1(nn.Module): def __init__(self): super(AdjMSELoss1, self).__init__() def forward(self, outputs, labels): outputs = torch.squeeze(outputs) alpha = 2 loss = (outputs - labels)**2 adj = torch.mul(outputs, labels) adj[adj>0] = 1 / alpha adj[adj<0] = alpha loss = loss * adj return torch.mean(loss)
自行实现的TensorFlow版本损失函数
#Tensorflow def custom_loss_function(outputs,labels): outputs = tf.squeeze(outputs) alpha = 2.0 loss = (outputs - labels) ** 2.0 adj = tf.math.multiply(outputs,labels) adj = tf.where(tf.greater(adj, 0.0), tf.constant(1/alpha), adj) adj = tf.where(tf.less(adj, 0.0), tf.constant(alpha), adj) loss = loss * adj return tf.reduce_mean(loss)
模型编译代码
model.compile( loss= custom_loss_function, optimizer=optimization, metrics = [custom_loss_function] )
简化后模型结构
#Simplified for readability model = Sequential() model.add(LSTM(32,input_shape=(SEQ_LEN,feature_number),return_sequences=True,)) model.add(Dropout(0.3)) model.add(LSTM(96, return_sequences = False)) model.add(Dropout(0.3)) model.add(Dense(1)) return model
补充信息
- 数据逻辑:输入特征为前
SEQ_LEN天的价格涨跌幅pct_change,即通过SEQ_LEN天的历史数据预测下一交易日的目标值;输出/目标值为下一交易日价格涨跌幅*100(例如数值5代表5%的涨跌幅),单条样本对应1个目标值。 - 对照表现:当损失函数设置为RMSE时模型可正常预测,仅使用上述自定义损失函数时会出现预测结果全为0的异常。
内容的提问来源于stack exchange,提问作者Yassin Sameh
相关产品推荐
相关产品推荐

