keras中的自定义损失函数将可变长度的输入向量映射到可变长度的输出向量
Custom loss function in keras to map input vectors of variable length to output vectors of variable lengths
我有一个关于使用 keras 将输入映射到输出的监督学习的一般性问题。可以通过插入一些不会在映射中考虑(或将被映射到其他虚拟变量)的虚拟变量来改变输入和输出向量的长度。所以基本上映射应该是这样的 (v: value, d: dummy)
输入向量 1 [v,v,v,v,v] --> 输出向量 1 [v,v,v,v,v]
输入向量 2 [v,v,v,v,v]--> 输出向量 2 [v,v,v,v,v]
输入向量 3 [v,v,v,d,d] --> 输出向量 3 [v,v,v,d,d]
输入向量 4 [v,v,d,d,d] --> 输出向量 4 [v,v,d,d,d]
输入向量 5 [v,d,d,d,d] --> 输出向量 5 [v,d,d,d,d]
输入和输出向量的长度为 5,有 5 个值。然而,有时只有一个大小的向量,例如3(基本上是一个长度为 5 的向量,带有 2 个虚拟变量)应该映射到长度为 3 的输出向量。因此,在训练 ANN 之后应该知道,如果它获得一个长度为 3 的输入向量,它应该产生一个输出长度为 3 的向量。
keras 这可能吗?这种映射的自定义损失函数会是什么样子。也许是这样的(假设 y_true 是一个二维向量 [Batchsize, 5]:
def my_loss_fn(y_true, y_pred):
for i in range (0, len(y_true)):
for j in range (0, len(y_true[i]):
if y_true[i][j] ==d:
squared_difference = 0
else:
squared_difference = tf.square(y_true[i][j] - y_pred[i][j])
return tf.reduce_mean(squared_difference, axis=-1)
def my_loss_fn(y_true, y_pred):
mask = y_true != d
loss = tf.reduce_mean((y_true - y_pred) ** 2 * tf.cast(mask, dtype=y_true.dtype), axis=-1)
return loss
P.S.
将长度传递给损失可能会更好
y_true = {"value": value, "length": length}
并使用
tf.sequence_mask
。例如:
import tensorflow as tf
max_length = 5
def my_loss_fn(y_true, y_pred):
y_true_value = y_true["value"]
y_true_length = y_true["length"]
mask = tf.sequence_mask(lengths=y_true_length, maxlen=max_length)
loss = tf.reduce_mean((y_true_value - y_pred) ** 2 * tf.cast(mask, dtype=y_pred.dtype), axis=-1)
return loss
batch_size = 2
y_true={
"value": tf.random.normal(shape=[batch_size, max_length]),
"length": tf.random.uniform(shape=[batch_size], maxval=max_length, dtype=tf.int32) + 1
}
y_pred=tf.random.normal(shape=[batch_size, max_length])
my_loss_fn(y_true=y_true, y_pred=y_pred)
我有一个关于使用 keras 将输入映射到输出的监督学习的一般性问题。可以通过插入一些不会在映射中考虑(或将被映射到其他虚拟变量)的虚拟变量来改变输入和输出向量的长度。所以基本上映射应该是这样的 (v: value, d: dummy)
输入向量 1 [v,v,v,v,v] --> 输出向量 1 [v,v,v,v,v]
输入向量 2 [v,v,v,v,v]--> 输出向量 2 [v,v,v,v,v]
输入向量 3 [v,v,v,d,d] --> 输出向量 3 [v,v,v,d,d]
输入向量 4 [v,v,d,d,d] --> 输出向量 4 [v,v,d,d,d]
输入向量 5 [v,d,d,d,d] --> 输出向量 5 [v,d,d,d,d]
输入和输出向量的长度为 5,有 5 个值。然而,有时只有一个大小的向量,例如3(基本上是一个长度为 5 的向量,带有 2 个虚拟变量)应该映射到长度为 3 的输出向量。因此,在训练 ANN 之后应该知道,如果它获得一个长度为 3 的输入向量,它应该产生一个输出长度为 3 的向量。
keras 这可能吗?这种映射的自定义损失函数会是什么样子。也许是这样的(假设 y_true 是一个二维向量 [Batchsize, 5]:
def my_loss_fn(y_true, y_pred):
for i in range (0, len(y_true)):
for j in range (0, len(y_true[i]):
if y_true[i][j] ==d:
squared_difference = 0
else:
squared_difference = tf.square(y_true[i][j] - y_pred[i][j])
return tf.reduce_mean(squared_difference, axis=-1)
def my_loss_fn(y_true, y_pred):
mask = y_true != d
loss = tf.reduce_mean((y_true - y_pred) ** 2 * tf.cast(mask, dtype=y_true.dtype), axis=-1)
return loss
P.S. 将长度传递给损失可能会更好
y_true = {"value": value, "length": length}
并使用
tf.sequence_mask
。例如:
import tensorflow as tf
max_length = 5
def my_loss_fn(y_true, y_pred):
y_true_value = y_true["value"]
y_true_length = y_true["length"]
mask = tf.sequence_mask(lengths=y_true_length, maxlen=max_length)
loss = tf.reduce_mean((y_true_value - y_pred) ** 2 * tf.cast(mask, dtype=y_pred.dtype), axis=-1)
return loss
batch_size = 2
y_true={
"value": tf.random.normal(shape=[batch_size, max_length]),
"length": tf.random.uniform(shape=[batch_size], maxval=max_length, dtype=tf.int32) + 1
}
y_pred=tf.random.normal(shape=[batch_size, max_length])
my_loss_fn(y_true=y_true, y_pred=y_pred)