Python 在使用中间输出的多输出模型中,将加法损耗与keras损耗相结合
之前在另一篇文章()中,我讨论了我遇到的问题。最后,通过以下方式解决了此问题:Python 在使用中间输出的多输出模型中,将加法损耗与keras损耗相结合,python,tensorflow,machine-learning,keras,deep-learning,Python,Tensorflow,Machine Learning,Keras,Deep Learning,之前在另一篇文章()中,我讨论了我遇到的问题。最后,通过以下方式解决了此问题: def MyLoss(true1, true2, out1, out2, out3): loss1 = tf.keras.losses.someloss1(out1, true1) loss2 = tf.keras.losses.someloss2(out2, true2) loss3 = tf.keras.losses.someloss3(out2, out3) loss = los
def MyLoss(true1, true2, out1, out2, out3):
loss1 = tf.keras.losses.someloss1(out1, true1)
loss2 = tf.keras.losses.someloss2(out2, true2)
loss3 = tf.keras.losses.someloss3(out2, out3)
loss = loss1 + loss2 + loss3
return loss
input1 = Input(shape=input1_shape)
input2 = Input(shape=input2_shape)
# do not take into account the notation, only the idea
output1 = Submodel1()([input1,input2])
output2 = Submodel2()(output1)
output3 = Sumbodel3()(output1)
true1 = Input(shape=true1shape)
true2 = Input(shape=true2shape)
model = Model([input1,input2,true1,true2], [output1,output2,output3])
model.add_loss(MyLoss(true1, true2, output1, output2, output3))
model.compile(optimizer='adam', loss=None)
model.fit(x=[input1 ,input2 ,true1,true2], y=None, epochs=n_epochs)
在这个问题中,我使用的所有损失都是keras损失(即tf.keras.loss.someloss
),但现在我想再添加几个损失,并将自定义损失与keras损失结合起来。也就是说,现在我有了这个方案:
为了增加这两个损失,即SSIM损失,我尝试了以下方法:
def SSIMLoss(y_true, y_pred):
return 1-tf.reduce_mean(tf.image.ssim(y_true, y_pred, 1.0))
def MyLoss(true1, true2, out1, out2, out3):
loss1 = tf.keras.losses.someloss1(out1, true1)
customloss1 = SSIMLoss(out1,true1)
loss2 = tf.keras.losses.someloss2(out2, true2)
loss3 = tf.keras.losses.someloss3(out2, out3)
customloss2 = SSIMLoss(out2,out3)
loss = loss1 + loss2 + loss3 + customloss1 + customloss2
return loss
但我得到了这个错误:
OperatorNotAllowedInGraphError:在图形执行中不允许将'tf.Tensor'用作Python'bool'。使用渴望执行或用@tf.function修饰此函数。
我已尝试使用@tf.function
装饰函数,但出现以下错误:
\u SymbolicException:到急切执行函数的输入不能作为符号张量,但可以找到[,]
我发现了将keras损失与
添加损失相结合的方法(),也许这就是问题所在,但我不知道如何解决它。我能够在TF 2.3
中重现您的上述错误。但是在TF2.4
和夜间TF2.6
中,没有这样的问题,但是当我试图绘制模型时,我遇到了另一个错误,尽管没有问题。summary()
以及使用.fit
进行培训。但是,如果禁用了急切模式,则TF 2.3/2.4将不会出现问题
细节 在TF 2.3中,我可以复制您的问题,如下所示。要解决这一问题,只需禁用上面显示的急切模式即可 在
tf2.4
/tfnightly 2.6
中,我不需要禁用急切模式。模型编译良好,并按预期进行了训练。但唯一的问题发生在我试图绘制模型时,它给出了以下错误
tf.keras.utils.plot_model(model)
....
AttributeError: 'tensorflow.python.framework.ops.EagerTensor' object has no
attribute '_keras_history'
此问题导致了SSIMLoss
方法中的1-..
表达式;某物
但是,同样地,通过禁用渴望模式,它无论如何都会解决问题。但是,一般来说,最好升级到tf2.4
代码示例 在这里,我将向您展示一个可能与您的培训管道类似的虚拟示例。在本例中,我们有一个输入(
28,28,3
)和三个输出(28,28,3
)
自定义损失函数。
def SSIMLoss(y_true, y_pred):
return 1 - tf.reduce_mean(tf.image.ssim(y_true, y_pred, 1.0))
def MyLoss(true1, true2, out1, out2, out3):
loss1 = tf.keras.losses.cosine_similarity(out1, true1)
loss2 = tf.keras.losses.cosine_similarity(out2, true2)
loss3 = tf.keras.losses.cosine_similarity(out2, out3)
customloss1 = SSIMLoss(true1, out1)
customloss2 = SSIMLoss(out2, out3)
loss = loss1 + loss2 + loss3 + customloss1 + customloss2
return loss
数据
imgA = tf.random.uniform([10, 28, 28, 3], minval=0, maxval=256)
tarA = np.random.randn(10, 28, 28, 3)
tarB = np.random.randn(10, 28, 28, 3)
型号
具有一个输入和三个输出的模型
input = Input(shape=(28, 28, 3))
middle = Conv2D(16, kernel_size=(3,3), padding='same')(input)
outputA = Dense(3, activation='relu')(middle)
outputB = Dense(3, activation='selu')(middle)
outputC = Dense(3, activation='elu')(middle)
target_inputA = Input(shape=(28, 28, 3))
target_inputB = Input(shape=(28, 28, 3))
model = Model([input, target_inputA, target_inputB],
[outputA, outputB, outputC])
model.add_loss(MyLoss(target_inputA, target_inputB,
outputA, outputB, outputC))
# tf.keras.utils.plot_model(model) # disable eager mode
model.summary()
编译并运行
model.compile(optimizer='adam', loss=None)
model.fit([imgA, tarA, tarB], steps_per_epoch=5)
5/5 [==============================] - 2s 20ms/step - loss: 1.4338
<tensorflow.python.keras.callbacks.History at 0x7efde188d450>
model.compile(优化器='adam',loss=None)
模型拟合([imgA、tarA、tarB],每历元步长=5)
5/5[===================================================]秒/步-损耗:1.4338
请您对给出的答案给出一些反馈意见好吗?您好@M.Innat,是的,对不起。这几天我有点忙,无法检查您的解决方案。我现在已经开始了,它似乎正在工作,尽管我得到了与此无关的其他错误。非常感谢你!你好@M.Innat。我一直在使用您在TF2.3和TF2.4上的解决方案,但没有禁用它。这两种方法似乎都有效,但在TF2.4中,执行一个历元需要5小时,而在TF2.3中则需要5分钟(这对于我来说太多了)。然而,在TF2.4中,GPU的volatile实用程序是0%,所以我想我没有使用GPU。这是一个已知的问题,即与图形模式相比,渴望模式是缓慢的。请检查此问题。另外,如果可能的话,试着用最新的tf2.5
和夜间软件包运行你的代码,看看效果如何。好的,谢谢!
model.compile(optimizer='adam', loss=None)
model.fit([imgA, tarA, tarB], steps_per_epoch=5)
5/5 [==============================] - 2s 20ms/step - loss: 1.4338
<tensorflow.python.keras.callbacks.History at 0x7efde188d450>