【发布时间】:2021-10-04 10:56:15
【问题描述】:
我正在开发我的第一个 Python 机器学习项目 - 使用 TensorFlow 尝试使用 Moby Hyphenator II 数据集对单词进行音节化。
我将此视为多标签分类问题,其中单词及其音节按以下格式编码:
T e n - s o r - f l o w
0 0 1 0 0 1 0 0 0 0
在阅读 this guide 作为起点时,我看到作者使用了一个自定义函数——他们在 PyTorch 中用均方根误差对加权二元交叉熵进行平均:
def bce_rmse(pred, target, pos_weight = 1.3, epsilon = 1e-12):
# Weighted binary cross entropy
loss_pos = target * torch.log(pred + epsilon)
loss_neg = (1 - target) * torch.log(1 - pred + epsilon)
bce = torch.mean(torch.neg(pos_weight * loss_pos + loss_neg))
# Root mean squared error
mse = (torch.sum(pred, dim = 0) - torch.sum(target, dim = 0)) ** 2
rmse = torch.mean(torch.sqrt(mse + epsilon))
return (bce + rmse) / 2
我已经尝试通过以下方式在 TensorFlow 中实现这一点:
def weighted_bce_mse(y_true, y_prediction):
# Binary crossentropy with weighting
epsilon = 1e-12
positive_weight = 4.108897148948174
loss_positive = y_true * tf.math.log(y_prediction + epsilon)
loss_negative = (1 - y_true) * tf.math.log(1 - y_prediction + epsilon)
bce_loss = np.mean(tf.math.negative(positive_weight * loss_positive + loss_negative))
# Mean squared error
mse = tf.keras.losses.MeanSquaredError()
mse_loss = mse(y_true, y_prediction)
averaged_bce_mse = (bce_loss + mse_loss) / 2
return averaged_bce_mse
这样做时,我收到错误 ValueError: 'outputs' must be defined before the loop.,我不确定为什么在构建和编译模型之前定义此函数。
我正在使用 Keras 功能 API,我的编译和适配阶段是:
model.compile(optimizer="adam", loss=weighted_bce_mse, metrics=["accuracy"], steps_per_execution=64)
history = model.fit(padded_inputs, padded_outputs, validation_data=(validation_inputs, validation_outputs), epochs=10, verbose=2)
【问题讨论】:
-
outputs定义在哪里? -
@kkgarg 我正在使用 Keras 功能 API,如前所述,输出定义为:
model = tf.keras.models.Model(inputs=inputs, outputs=x)我确定问题不在模型构建中,因为它可以与任何其他功能完美配合我以前使用过的损失函数(二元交叉熵或均方误差)——该错误仅出现在此自定义损失函数中。有趣的是,当我取二元交叉熵的平均值和不加权的均方误差时,该模型也有效,所以我相信加权是导致问题的具体原因。 -
新的损失函数似乎没有问题。你能粘贴错误堆栈和完整代码吗?
-
@kkgarg 是的!这是error stack 和relevant code。
-
谢谢!我对在 Stack Overflow 上提问很陌生,所以我不知道这是最佳做法,但以后会继续这样做。
标签: python tensorflow keras nlp loss-function