【问题标题】:Tensorflow custom loss function: ValueError using tf.VaraibleTensorflow 自定义损失函数:ValueError using tf.Variable
【发布时间】:2022-06-13 02:36:08
【问题描述】:

所以我正在为 keras 和 tensorflow 中的 LSTM 模型编写自定义损失函数。问题是我的损失函数目前包含一个 tf.Variable 以创建一个可重复更新的张量。但是,我收到一个我无法解决的错误。谁能帮我? 代码如下:

def custom_loss(y_true, y_pred):

    y_true_next = y_true[1:]
    y_pred_next = y_pred[1:]
    
    y_true_tdy = y_true[:-1]
    y_pred_tdy = y_pred[:-1]
    
    print('Shape of y_pred_back -', y_pred_tdy.get_shape())

    y_true_diff = tf.subtract(y_true_next, y_true_tdy)
    y_pred_diff = tf.subtract(y_pred_next, y_pred_tdy)
        
    standard = tf.zeros_like(y_pred_diff)
    
    y_true_move = tf.greater_equal(y_true_diff, standard)
    y_pred_move = tf.greater_equal(y_pred_diff, standard)
    y_true_move = tf.reshape(y_true_move, [-1])
    y_pred_move = tf.reshape(y_pred_move, [-1])
    
    condition = tf.not_equal(y_true_move, y_pred_move)
    indices = tf.where(condition)

    ones = tf.ones_like(indices)
    indices = tf.add(indices, ones)
    indices = K.cast(indices, dtype='int32')
    
    direction_loss = tf.Variable(tf.ones_like(y_pred), dtype='float32')
    updates = K.cast(tf.ones_like(indices), dtype='float32')
    alpha = 1000
    direction_loss = tf.compat.v1.scatter_nd_update(direction_loss, indices, alpha*updates)
    
    custom_loss = K.mean(tf.multiply(K.square(y_true - y_pred), direction_loss), axis=-1)
    
    return custom_loss

并且错误状态:

ValueError: tf.function only supports singleton tf.Variables created on the first call. Make sure the tf.Variable is only created once or created outside tf.function. See https://www.tensorflow.org/guide/function#creating_tfvariables for more information.

我将包括模型定义和训练调用的其余部分

def create_lstm_model():
      
    lstm_model = Sequential()
    lstm_model.add(LSTM(100, batch_input_shape=(BATCH_SIZE, TIME_STEPS, x_t.shape[2]),
                        dropout=0.0, recurrent_dropout=0.0,
                        stateful=True, return_sequences=True,
                        kernel_initializer='random_uniform'))

    lstm_model.add(LSTM(60, dropout=0.0))
    
    lstm_model.add(Dense(20,activation='relu'))
    lstm_model.add(Dense(1, activation='sigmoid'))
        
    #compile the model
    optimizer = tf.keras.optimizers.Adam(lr=params["LR"])
    lstm_model.compile(loss=custom_loss, optimizer=optimizer)
    print('model check')
  
    return lstm_model
    lstm_model = create_lstm_model()
    print(lstm_model.summary())
    
history_lstm = lstm_model.fit(x_t, y_t, epochs=params["EPOCHS"], verbose=1, batch_size=BATCH_SIZE,
                      shuffle=False, validation_data=(trim_dataset(x_val, BATCH_SIZE),
                      trim_dataset(y_val, BATCH_SIZE)))

【问题讨论】:

    标签: python tensorflow machine-learning keras lstm


    【解决方案1】:

    我在这个问题上停留了一段时间。看来您不应该在损失函数中使用 tf 变量;因此,我找到了一个不使用需要 tf.variable 的 scatter_nd_update 函数的解决方案。您可以将 scatter 视为 direction_loss 变量。

        scatter = tf.scatter_nd(tf.cast(indices, tf.int32), updates, tf.shape(y_pred)) * alpha
        scatter = tf.where(tf.equal(scatter, 0), tf.ones_like(scatter), scatter)
        scatter = K.cast(scatter, dtype='float32')
    

    【讨论】:

      猜你喜欢
      • 2018-10-28
      • 2017-12-29
      • 1970-01-01
      • 2020-12-24
      • 2018-12-28
      • 2020-10-14
      • 2020-10-21
      • 2019-12-16
      • 2020-07-29
      相关资源
      最近更新 更多