Аргументы вызова уровня Tensorflow GRU () — ошибка типа: вызов() получил неожиданный аргумент ключевого слова «reset_after»

#python #tensorflow #machine-learning #keras #recurrent-neural-network

Вопрос:

Я реализую модель со слоем GRU, модель и ее обучение прекрасно работают только с

    class MyModel(tf.keras.Model):
      def __init__(self, vocab_size, embedding_dim, rnn_units):
        super().__init__(self)
        self.embedding = tf.keras.layers.Embedding(vocab_size, embedding_dim)
        self.gru = tf.keras.layers.GRU(rnn_units,
                                       return_sequences=True,
                                       return_state=True)
        self.dense = tf.keras.layers.Dense(vocab_size)
    
      def call(self, inputs, states=None, return_state=False, training=False):
        x = inputs
        x = self.embedding(x, training=training)
        if states is None:
          states = self.gru.get_initial_state(x)
        x, states = self.gru(x, initial_state=states, training=training)
        x = self.dense(x, training=training)
    
        if return_state:
          return x, states
        else:
          return x
 

Я просто изменяю определение слоя GRU, чтобы сделать его (1) совместимым с cuDNN (2) добавить отсев

В определении модели я сохранил

     self.gru = tf.keras.layers.GRU(rnn_units,
                                   return_sequences=True,
                                   return_state=True)
 

В функции вызова я установил

     if states is None:
      states = self.gru.get_initial_state(x)
    x, states = self.gru(x, initial_state=states, training=training,
                         reset_after=True, recurrent_activation='sigmoid', # to make it more GPU friendly
                         recurrent_dropout=0.2, dropout=0.2 # to add some dropout to it
                         )
 

Рекомендации Keras или Tensorflow, похоже, соблюдаются, в то время как я получаю эту ошибку

 Traceback (most recent call last):
  File "rnn_train_004.py", line 125, in <module>
    example_batch_predictions = model(input_example_batch)
  File "/usr/local/lib/python3.6/dist-packages/keras/engine/base_layer.py", line 1037, in __call__
    outputs = call_fn(inputs, *args, **kwargs)
  File "rnn_train_004.py", line 107, in call
    recurrent_dropout=0.2, dropout=0.2 # to add some dropout to it
  File "/usr/local/lib/python3.6/dist-packages/keras/layers/recurrent.py", line 716, in __call__
    return super(RNN, self).__call__(inputs, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/keras/engine/base_layer.py", line 1037, in __call__
    outputs = call_fn(inputs, *args, **kwargs)
TypeError: call() got an unexpected keyword argument 'reset_after'
 

Комментарии:

1. Большинство из этих аргументов (reset_after, recurrent_activation, recurrent_dropout, выпадение) должны быть переданы конструктору. Вы передаете их call кому-то .

Ответ №1:

Передача аргументов конструктору, а не методу call()

    class MyModel(tf.keras.Model):
      def __init__(self, vocab_size, embedding_dim, rnn_units):
        super().__init__(self)
        self.embedding = tf.keras.layers.Embedding(vocab_size, embedding_dim)
        self.gru = tf.keras.layers.GRU(rnn_units,
                                       return_sequences=True,
                                       return_state=True,
                                       reset_after=True,
                                       recurrent_activation='sigmoid', # to make it more GPU friendly
                                       recurrent_dropout=0.2,
                                       dropout=0.2 # to add some dropout to it
                                       )
        self.dense = tf.keras.layers.Dense(vocab_size)
    
      def call(self, inputs, states=None, return_state=False, training=False):
        x = inputs
        x = self.embedding(x, training=training)
        if states is None:
          states = self.gru.get_initial_state(x)
        x, states = self.gru(x, initial_state=states, training=training)
        x = self.dense(x, training=training)
    
        if return_state:
          return x, states
        else:
          return x