首页 > 解决方案 > Tensorflow,训练选定的输出单元

问题描述

我正在尝试训练两个单元网的单个单元,这是代码,我将它与单个单元网进行比较:

import numpy as np
import tensorflow as tf

model1 = tf.keras.Sequential(tf.keras.layers.Dense(1))
model2 = tf.keras.Sequential(tf.keras.layers.Dense(2))

model1.compile(loss=tf.keras.losses.MSE, optimizer=tf.keras.optimizers.Adam(), metrics=['mse'])

def loss(y_true, y_pred):
    return tf.keras.losses.MSE(y_true, y_pred[:,0])

model2.compile(loss=loss, optimizer=tf.keras.optimizers.Adam(), metrics=['mse'])

X = np.linspace(0,2, 50)
model1.fit(X, 2*X, batch_size=32, epochs=1000, verbose=0);
model2.fit(X, 2*X, batch_size=32, epochs=1000, verbose=0);

x = np.linspace(-1,1, 50)
y1 = model1.predict(x)
y2 = model2.predict(x)[:,0]
f, ax = plt.subplots()
ax.scatter(x, 2*x)
ax.plot(x, y1, label='model 1')
ax.plot(x, y2, label='model 2')
f.legend()

我希望从两个网络中得到类似的结果,但这是输出: 在此处输入图像描述

自动微分应该适用于切片,所以我不明白是什么阻止了第二个模型在它的第一个输出中得到正确训练。

编辑:因为似乎人们误解了问题的重点。我知道上面的整件事毫无意义。我的最终目标是能够训练一个具有自定义损失的网络,它以不同的方式使用不同输出单元的输出,所以在这里我只尝试了最简单的版本,使用一个单元的两个单元网络而另一个忽略。

标签: pythontensorflow

解决方案


将您的loss功能更改为以下内容:

def loss(y_true, y_pred):
    return tf.keras.losses.MSE(y_true, y_pred[:, :1])

y_truey_predin的形状loss(None, 1)(None, 2)。如果你这样做y_pred[:, 0],你会得到一个带有 shape 的张量(None,),然后两者都y_truey_pred被广播到(None, None),但是计算出的 MSE 将是所有y_true值对所有y_pred[:, 0]值,这是错误的。使用y_pred[:, :1](或等价地tf.expand_dims(y_pred[:, 0], axis=1)),您会得到一个具有形状的张量,(None, 1)并且 MSE 计算是正确的。


推荐阅读