为了账号安全,请及时绑定邮箱和手机立即绑定

如何在Keras中定义具有不同值的自定义损失?

如何在Keras中定义具有不同值的自定义损失?

holdtom 2022-09-13 10:02:31
我想定义我的损失函数,以便它考虑自动编码器的输入和输出之间的MSE,以及代码和我调用S的真实值之间的MSE。我的自动曝光定义如下:input_fts = Input(shape=(self.input_length,), name='ae_input')encoded = Dense(1826, activation='relu', name='e_dense1')(input_fts)encoded = Dense(932, activation='relu', name='e_dense2')(encoded)encoded = Dense(428, activation='relu', name='e_dense3')(encoded)encoded = Dropout(0.1)(encoded)code = Dense(self.encoding_length, activation='relu', name='code')(encoded)decoded = Dense(428, activation='relu', name='d_dense4')(code)decoded = Dense(932, activation='relu', name='d_dense5')(decoded)decoded = Dense(1826, activation='relu', name='d_dense6')(decoded)output_fts = Dense(self.output_length, activation='relu', name='ae_output')(decoded)ae = Model(inputs=input_fts, outputs=output_fts)ae.compile(optimizer='adam', loss=ModelFactory.custom_loss(code, self.S, self.lambda_), metrics=['mae', 'acc'])我的自定义损失为:@staticmethoddef custom_loss(layer, S, lambda_):    def loss(y_true, y_pred):        return K.mean(K.square(y_pred - y_true), axis=-1) + lambda_ * K.mean(K.square(layer - S[0, :]), axis=-1)    return loss这有效,但它不是我想要的。我希望根据当时正在评估的示例来选择 S 中的示例,因此 S[0, :] 将是 S[i, :],其中“i”是示例的索引。变量“层”是形状的张量 [None, 312]。变量 S 是一个 NumPy 数组 o 形状 [1194, 312],其中 1194 是我在训练集中的示例数。我的猜测是,我也必须将S转换为某种类型的张量。所以我尝试了:self.S = K.variable(S)并将custom_loss更改为:... lambda_ * K.mean(K.square(layer - S), axis=-1)现在的问题是我的批处理和S之间的形状不匹配:tensorflow.python.framework.errors_impl.InvalidArgumentError:  Incompatible shapes: [128] vs. [1194]AE 训练配置为:self.model.fit(x_train, x_train, epochs=nepochs, batch_size=128, shuffle=True, verbose=1,                                      validation_split=0.2, callbacks=[classification])如何使 S 也随批大小而变化?
查看完整描述

1 回答

?
慕容708150

TA贡献1831条经验 获得超4个赞

如果我理解正确,S本质上只是模型的另一个输入。在这种情况下,您可以为 S 添加第二个输入层,并在训练期间将 S 传递到模型。这将使以下内容变为:


input_fts = Input(shape=(self.input_length,), name='ae_input')

S_in = Input(shape=(312,), name='s_input')


encoded = Dense(1826, activation='relu', name='e_dense1')(input_fts)

encoded = Dense(932, activation='relu', name='e_dense2')(encoded)

encoded = Dense(428, activation='relu', name='e_dense3')(encoded)


encoded = Dropout(0.1)(encoded)

code = Dense(self.encoding_length, activation='relu', name='code')(encoded)


decoded = Dense(428, activation='relu', name='d_dense4')(code)

decoded = Dense(932, activation='relu', name='d_dense5')(decoded)

decoded = Dense(1826, activation='relu', name='d_dense6')(decoded)

output_fts = Dense(self.output_length, activation='relu', name='ae_output')(decoded)


ae = Model(inputs=[input_fts, S_in], outputs=output_fts)


ae.add_loss(self.lambda_ * K.mean(K.square(S_in-code)))

ae.add_loss(K.mean(K.square(input_fts - output_fts)))


ae.compile(optimizer='adam')

然后,传递正常输入和 S 以使用列表进行预测(请参阅 https://keras.io/getting-started/functional-api-guide/)。


查看完整回答
反对 回复 2022-09-13
  • 1 回答
  • 0 关注
  • 65 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信