[英]How to use model input in loss function?
I am trying to use a custom loss-function which depends on some arguments that the model does not have.我正在尝试使用自定义损失函数,它取决于 model 没有的一些 arguments。
The model has two inputs ( mel_specs
and pred_inp
) and expects a labels
tensor for training: model 有两个输入(
mel_specs
和pred_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()
In my loss function I need to calculate the lengths of mel_specs
and pred_inp
.在我的损失 function 中,我需要计算
mel_specs
和pred_inp
的长度。 This means my loss looks like this:这意味着我的损失看起来像这样:
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
)
However, no matter which approach I choose, I am facing some issue.但是,无论我选择哪种方法,我都面临一些问题。
If I actually wrap the loss function st it returns a function which takes y_true
and y_pred
like this:如果我实际上包装了损失 function st 它返回一个 function ,它采用
y_true
和y_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]
)
Here I get a _SymbolicException
after calling model.fit()
:在这里我在调用
model.fit()
后得到一个_SymbolicException
:
tensorflow.python.eager.core._SymbolicException: Inputs to eager execution function cannot be Keras symbolic tensors, but found [...]
The documentation of add_loss()
states: 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...
So I tried to do the following:所以我尝试执行以下操作:
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
)
However, calling model.fit()
throws a ValueError
:但是,调用
model.fit()
会引发ValueError
:
ValueError: No gradients provided for any variable: [...]
Is any of the above options supposed to work?上述任何选项都应该起作用吗?
I have used the add_loss method as follow:我使用了 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)
even do I have used this method and works, I still looking for another method, that not involve creating a training model即使我使用过这种方法并且有效,我仍在寻找另一种方法,不涉及创建培训 model
Did using lambda function work?使用 lambda function 工作了吗? ( https://www.w3schools.com/python/python_lambda.asp )
( https://www.w3schools.com/python/python_lambda.asp )
loss = lambda x1, x2: rnnt_loss(x1, x2, acts, labels, input_lengths,
label_lengths, blank_label=0)
In this way your loss function should be a function accepting parameters x1
and x2
, but rnnt_loss can also be aware of acts
, labels
, input_lengths
, label_lengths
and blank_label
这样你的损失 function 应该是一个 function 接受参数
x1
和x2
,但input_lengths
也可以知道acts
, labels
,输入长度,标签label_lengths
和blank_label
标签
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.