gpt4 book ai didi

python - 如何在损失函数中使用模型输入?

转载 作者:行者123 更新时间:2023-12-05 08:11:10 24 4
gpt4 key购买 nike

我正在尝试使用自定义损失函数,它取决于模型没有的一些参数。

该模型有两个输入(mel_specspred_inp)并需要一个 labels 张量进行训练:

def to_keras_example(example):
# Preparing inputs
return (mel_specs, pred_inp), labels

# Is a tf.train.Dataset for model.fit(train_data, ...)
train_data = load_dataset(fp, 'train).map(to_keras_example).repeat()

在我的损失函数中,我需要计算 mel_specspred_inp 的长度。这意味着我的损失看起来像这样:

def rnnt_loss_wrapper(y_true, y_pred, mel_specs_inputs_):
input_lengths = get_padded_length(mel_specs_inputs_[:, :, 0])
label_lengths = get_padded_length(y_true)
return rnnt_loss(
acts=y_pred,
labels=tf.cast(y_true, dtype=tf.int32),
input_lengths=input_lengths,
label_lengths=label_lengths
)

但是,无论我选择哪种方法,我都面临着一些问题。


选项 1) 在 model.compile() 中设置损失函数

如果我真的包装损失函数 s.t.它返回一个接受 y_truey_pred 的函数,如下所示:

def rnnt_loss_wrapper(mel_specs_inputs_):
def inner_(y_true, y_pred):
input_lengths = get_padded_length(mel_specs_inputs_[:, :, 0])
label_lengths = get_padded_length(y_true)
return rnnt_loss(
acts=y_pred,
labels=tf.cast(y_true, dtype=tf.int32),
input_lengths=input_lengths,
label_lengths=label_lengths
)
return inner_

model = create_model(hparams)
model.compile(
optimizer=optimizer,
loss=rnnt_loss_wrapper(model.inputs[0]
)

这里我在调用 model.fit() 后得到一个 _SymbolicException:

tensorflow.python.eager.core._SymbolicException: Inputs to eager execution function cannot be Keras symbolic tensors, but found [...]

选项 2) 使用 model.add_loss()

add_loss() 的文档状态:

[Adds a..] loss tensor(s), potentially dependent on layer inputs.
..
Arguments:
losses: Loss tensor, or list/tuple of tensors. Rather than tensors, losses
may also be zero-argument callables which create a loss tensor.
inputs: Ignored when executing eagerly. If anything ...

所以我尝试执行以下操作:

def rnnt_loss_wrapper(y_true, y_pred, mel_specs_inputs_):
input_lengths = get_padded_length(mel_specs_inputs_[:, :, 0])
label_lengths = get_padded_length(y_true)
return rnnt_loss(
acts=y_pred,
labels=tf.cast(y_true, dtype=tf.int32),
input_lengths=input_lengths,
label_lengths=label_lengths
)

model = create_model(hparams)
model.add_loss(
rnnt_loss_wrapper(
y_true=model.inputs[2],
y_pred=model.outputs[0],
mel_specs_inputs_=model.inputs[0],
),
inputs=True
)
model.compile(
optimizer=optimizer
)

但是,调用 model.fit() 会抛出一个 ValueError:

ValueError: No gradients provided for any variable: [...]

以上任何选项都应该有效吗?

最佳答案

我使用了如下的 add_loss 方法:

def custom_loss(y_true, y_pred, input_):
# custom loss function
y_estim = input_[...,0]*y_pred
shape = tf.cast(tf.shape(y_true)[1], dtype='float32')
return tf.reduce_mean(1/shape*tf.reduce_sum(tf.pow(y_true-y_estim, 2), axis=1))


mix_input = layers.Input(shape=(301, 257, 4)) # input 1
ref_input = layers.Input(shape=(301, 257, 1)) # input 2
target = layers.Input(shape=(301, 257)) # output target

smss_model = Model(inputs=[mix_input, ref_input], outputs=smss) # my model that accept two inputs

model = Model(inputs=[mix_input, ref_input, target], outputs=smss) # this one used just to train the model, with the additional paramters
model.add_loss(custom_loss(target, smss, mix_input)) # the add_loss where to pass the custom loss function
model.summary()

model.compile(loss=None, optimizer='sgd')
model.fit([mix, ref, y], epochs=1, batch_size=1, verbose=1)

即使我已经使用了这种方法并且有效,我仍在寻找另一种不涉及创建训练模型的方法

关于python - 如何在损失函数中使用模型输入?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62691100/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com