【发布时间】:2021-09-05 10:26:40
【问题描述】:
我想要做的是从这个paper 实现损失函数。
损失函数利用串联和并联链接的多个独立模型。第一个模型是低保真模型,第二个模型是一组两个并行模型,最后一个模型是物理信息神经网络 (PINN)。我的具体实现不会使用 PINN。
规定的损失函数需要低保真输出的MSE和低保真输出的梯度(至少我是这样理解公式的)以及高保真输出的MSE,即PINN 输出,最后是正则化项。
所以,
-
如何获得中间模型输出的 MSE?
-
如何计算 y* 和 y 的梯度项?
-
鉴于可能有几种不同的方法可以实现这一点, 就清晰度而言,哪种方法最好? (我意识到这有点主观)
我自己的搜索得出的结论是,我需要通过将 Model.add_loss() 函数添加到子类层或通过 tf.keras.Model API 添加它来使用它。这一切都说得通。我遇到问题的部分是将y_true 带到我实现损失函数的位置。到目前为止我发现的最好的事情是在模型声明输入和输出中使用字典:
model = tf.keras.Model( inputs = some_dict{'input_name':input_name},
outputs = another_dict{'output_name0': output_name0,
'output_name1': output_name1, name = 'my_name' }
我找到了大致思路here。在阅读本文之前,我什至不知道 tf.keras.Model 输入甚至可以使用字典。我的问题是作者最终使用一些“输出”作为评估的输入。我现在的框架看起来有点像这样
def load_model0():
init_model = [ *Load model of choice* ]
input0 = tf.keras.Input((size,),name = 'input_zero')
x = input0
model0_out = init_model(x)
model = tf.keras.Model( inputs=input0, outputs = {'model0_out': model0_out},
name = "model0")
return model
def load_model1():
init_model = [ *Load model of choice* ]
input1 = tf.keras.Input((size,),name = 'input_one')
x = input0
model1_out = init_model(x)
model = tf.keras.Model( inputs=input1, outputs = {'model1_out': model1_out},
name = "model1")
return model
def link_models(model0,model1):
input0 = tf.keras.Input((size0,), name = "first_input")
input1 = tf.keras.Input((size1,), name = "second_input")
first_model_out = model0(input0)
x = tf.keras.layers.Concatenate([first_model_out,input1])
linked_out = model1(x)
linked_model = tf.keras.Model( intputs = {'input0': input0, 'input1': input1},
outputs = {"linked_out": linked_out, [ *insert confusion* ]}
loss_function0 = tf.keras.losses.MSE([*insert model0 true values here*],first_model_out)
linked_model.add_loss(loss_function0)
loss_function1 = tf.keras.losses.MSE([*insert model1 true values here*], linked_out )
linked_model.add_loss(loss_function1)
截至目前,我不知道model.add_loss() 损失函数是否可以与Model.compile() 中的常规损失函数/类一起使用。我如何获得真正的价值?如何运行 Model.fit() 来完成这项工作?
编辑:回应拉普拉斯瑞奇。 我有一组端到端连接的三个网络。第一个网络在这里无关紧要。第二个网络输出维度 15。第三个网络输出维度 40。最终模型的设置如下所示:
# top/first model takes input dimension of (40,)
inputs = tf.keras.Input((40,))
# middle_out dimension is (size,15)
middle_out = middle_model(top_model(inputs))
linked_model = tf.keras.Model( inputs = inputs,
outputs = [bottom_model(middle_out),middle_out],
name = 'linked_model' )
我这样设置损失和优化器:
opt = tf.keras.optimizers.Adam()
loss = [ tf.keras.losses.MSE, tf.keras.losses.MSE ]
linked_model.compile(optimizer = opt, loss = losses)
适合
y_list = [data0,data1]
linked_model.fit(x,y_list, epoch = 10, batch_size = 32 )
其中 data0 是维度 (size,40),并且 data1 是维度 (size,15)。
这会产生错误:
ValueError: Dimensions must be equal, but are 15 and 40 for '{{node Mul_6}} = Mul[T=DT_FLOAT](IteratorGetNext:3, Cast_4)' with input shapes: [160,15], [40].
我也尝试过 dict 替代方法(对model.fit() 中的预期输出进行必要的更改):
loss = {'middle_model': tf.keras.losses.MSE,
'bottom_model': tf.keras.losses.MSE}
# Tensorflow gave me a very explicit error saying I need
# the name of the bottom model as opposed to the name of the
# linked model
【问题讨论】:
-
请在这里找到我的 colab:colab.research.google.com/drive/…
-
在您提供的信息中很难判断形状错误来自何处。错误不在于您提供的内容。 colab 有一个顶部模型、一个中间模型(输出形状 15)和一个底部模型(输出形状 40)以及您指定的初始输入形状 40,现在它正在工作。希望它可以帮助您调试。
-
@LaplaceRicky 问题已解决。我遇到了维度受限度量的问题,并且我没有区分具有单独度量的两个输出。谢谢!!
标签: python tensorflow keras loss-function