python - Keras 模型的自定义损失函数给出不正确的答案
问题描述
我正在尝试为 keras NN 模型编写自定义损失函数,但似乎损失函数输出了错误的值。我的损失函数是
def tangle_loss3(input_tensor):
def custom_loss(y_true, y_pred):
true_diff = y_true - input_tensor
pred_diff = y_pred - input_tensor
normalized_diff = K.abs(tf.math.divide(pred_diff, true_diff))
normalized_diff = tf.reduce_mean(normalized_diff)
return normalized_diff
return custom_loss
然后我在这个简单的前馈网络中使用它:
input_layer = Input(shape=(384,), name='input')
hl_1 = Dense(64, activation='elu', name='hl_1')(input_layer)
hl_2 = Dense(32, activation='elu', name='hl_2')(hl_1)
hl_3 = Dense(32, activation='elu', name='hl_3')(hl_2)
output_layer = Dense(384, activation=None, name='output')(hl_3)
optimizer = tf.keras.optimizers.Adam(learning_rate=0.001)
model = tf.keras.models.Model(input_layer, output_layer)
model.compile(loss=tangle_loss3(input_layer), optimizer=optimizer)
然后为了测试损失函数是否有效,我创建了一个随机输入和目标向量,并按照我的预期进行了 numpy 计算,但这似乎与 keras 的结果不匹配。
X = np.random.rand(1, 384)
y = np.random.rand(1, 384)
np.mean(np.abs((model.predict(X) - X)/(y - X)))
# returns some number
model.test_on_batch(X, y)
# always returns 0.0
为什么我的损失函数总是返回零?这些答案应该匹配吗?
解决方案
我误解了你的问题,我已经更新了我的方法。它现在应该可以工作了。我堆叠输入层和输出层以获得传递给输出的新层。
def tangle_loss3(y_true, y_pred):
true_diff = y_true - y_pred[0]
pred_diff = y_pred[1] - y_pred[0]
normalized_diff = tf.abs(tf.math.divide(pred_diff, true_diff))
normalized_diff = tf.reduce_mean(normalized_diff)
return normalized_diff
input_layer = Input(shape=(384,), name='input')
hl_1 = Dense(64, activation='elu', name='hl_1')(input_layer)
hl_2 = Dense(32, activation='elu', name='hl_2')(hl_1)
hl_3 = Dense(32, activation='elu', name='hl_3')(hl_2)
output_layer = Dense(384, activation=None, name='output')(hl_3)
out = tf.stack([input_layer, output_layer])
optimizer = tf.keras.optimizers.Adam(learning_rate=0.001)
model = tf.keras.models.Model(input_layer, out)
model.compile(loss=tangle_loss3, optimizer=optimizer)
现在当我计算损失时它起作用了
X = np.random.rand(1, 384)
y = np.random.rand(1, 384)
np.mean(np.abs((model.predict(X)[1] - X)/(y - X)))
# returns some number
model.test_on_batch(X, y)
请注意,我必须使用 model.predict(X)[1] 因为我们得到两个输出,即输入层和输出层的结果。这只是一个 hacky 解决方案,但它有效。
推荐阅读
- python - 将行附加到空数据帧返回空数据帧
- c++ - C++ 错误:表达式列表在 mem-initializer [-fpermissive] 中被视为复合表达式|
- python - 将列表添加到 tkinter 中的文件子菜单
- google-sheets - 在 Google 表格中将矩形范围转换为行或列表示
- javascript - React Formik:如何在不手动处理状态的情况下使用自定义 onChange?
- javascript - 如何将日期格式化为今天的日期,例如上午 8:00 或晚上 9:00?时刻JS
- c# - 具有特定文化的 C# DisplayAttribute.GetName
- node.js - 设置passenger_nodejs在Nginx服务器中不起作用
- bash - 从 bash 函数调用时,`kubectl` 失败
- python - Pandas Pivot 表并保留两列作为组合标识符