1. sample_weights
Да, вы понимаете это неправильно. В этом случае у вас есть 2
выборки, 10
временных шагов с 5
функциями каждый. Вы можете передать 2D
тензор таким образом, чтобы каждый временной шаг для каждого образца по-разному вносил вклад в общую потерю, все функции были одинаково взвешены (как это обычно бывает).
Это не то, что вам нужно на все . Вы хотите замаскировать определенные значения потерь после их расчета, чтобы они не вносили вклад.
2. Пользовательские потери
Одним из возможных решений является реализация собственной функции потерь, которая умножает тензор потерь на маску перед тем, как взять mean
или sum
.
По сути, вы передаете mask
и * 1021. * как-то соединяются вместе и разделяют его внутри функции для использования. Этого достаточно:
def my_loss_function(y_true_mask, y_pred):
# Recover y and mask
y_true, mask = tf.split(y_true_mask, 2)
# You could user reduce_sum or other combinations
return tf.math.reduce_mean(tf.math.abs(y_true - y_pred) * mask)
Теперь ваш код (без взвешивания, так как он не нужен):
simple_lstm_model = tf.keras.models.Sequential(
[tf.keras.layers.LSTM(8, return_sequences=True), tf.keras.layers.Dense(2)]
)
simple_lstm_model.compile(optimizer="adam", loss=my_loss_function)
n_sample = 2
seq_len = 10
n_feat = 5
n_out = 2
x = np.random.randn(n_sample, seq_len, n_feat)
y_true = np.random.randn(n_sample, seq_len, n_out)
mask = np.ones([n_sample, seq_len, n_out])
mask[0, 3:8, 1] = 0
# Stack y and mask together
y_true_mask = np.stack([y_true, mask])
simple_lstm_model.fit(x, y_true_mask)
И так все работает. Вы также можете сложить значения другим способом, но я надеюсь, что вы почувствуете, как это можно сделать.
3. Маскировка выходов
Обратите внимание, что выше возникает несколько проблем. Если у вас много нулей и вы взяли mean
, вы можете получить очень маленькое значение потери и помешать обучению. С другой стороны, если вы go с sum
, он может взорваться.