Python Tensorflow,训练选定的输出单元

Python Tensorflow,训练选定的输出单元,python,tensorflow,Python,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.ke

我试着训练两个单元网络中的一个单元,这是代码,我将它与一个单元网络进行比较:

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()
我希望从两个网络中得到类似的结果,但这是结果:

自动微分应该可以很好地与切片一起工作,所以我不明白是什么阻止了第二个模型在第一个输出中得到正确的训练

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

将您的
损耗
函数更改为以下内容:

def丢失(y_真,y_pred):
返回tf.keras.loss.MSE(y_true,y_pred[:,:1])

loss
中的
y\u true
y\u pred
的形状是
(无,1)
(无,2)
。如果你做了
y_pred[:,0]
你会得到一个形状为
(None,)
的张量,然后
y_true
y_pred
都会被广播到
(None,None)
,但是计算出来的MSE将是所有
y_true
值与所有
y_pred[:,0]
值的比较,这是错误的。使用
y\u pred[:,:1]
(或者,相当于
tf.expand\u dims(y\u pred[:,0],axis=1)
)可以得到一个形状为
(None,1)
的张量,并且MSE计算是正确的。

我不理解你们的任何一条评论,请详细说明你的意思好吗?两个单元模型应输出形状为[n,2]的矩阵,切片[:,0]应选择第一列,这是第一个单元的输出。为什么我要添加另一层?我知道我所做的毫无意义,我只是试着训练两个单位输出网络中的一个单位,看看它是否有效,只是为了测试我将要用于实际目的的技术。我真的认为是你在这里不理解发生了什么。。。。我为两个单位的净损失定义了一个新的损失。这种损失只取决于第一次输出,因此损失的梯度只取决于第一次输出的权重,该梯度应与第一次网络发现的梯度完全相同,权重更新也应相同。这个过程的逻辑是正确的,关于Tensorflow肯定有一些我不知道的技术问题。我在代码中所做的显然没有实际目的,也没有任何意义,我知道,这只是一个测试。我有一个两个单位的感知器,其中一个单位在损耗中被忽略了,所以它的重量没有更新,它也被忽略了一个测试时间,最终的结果应该相当于一个单位的感知器,但它不是,你还没有提供任何令人满意的解释。为了让人满意,你应该指出一个技术缺陷,或者写出解释错误原因的数学公式。但是我真的认为你根本不理解这个问题和代码。让我们来看看。关于这个东西以及默认的tensorflow层是如何形成的,有什么参考吗?@ClaudioP你是说
tf.layers
模块?我还没有真正使用过它,我认为它与Keras共享代码,但我不知道这种细节。不管怎样,它在2.x中被删除了。不,我是说keras层,我是否必须直接查看源代码才能知道在形状和数据上到底发生了什么,然后再将它们的形状提供给构建方法,然后批量创建等等?为什么会有这种“无”形状,我可以在一维输出的情况下理解它们,但在返回二维输出的情况下也可以理解它们。@ClaudioP我认为这些东西没有详细的规范,字面上建议您查看源代码。一般来说,在这样一个简单的情况下,
y_-true
y_-pred
都是二维的,第一维是批量大小,第二维是“特征”的数量(对于
y_-true
的标签向量的大小和对于
y_-pred
的网络中的输出单元的数量)。大多数时候你不需要关心它,但是因为你在做一些不寻常的事情(不同的标签和输出大小),你需要考虑这些事情。