我希望體驗嘈雜的 GRU 狀態,而不是為每個批次將它們重置為零。我嘗試下面的實作。我的初始代碼將初始狀態重置為零(states = None),我更改了train_stepwith
noisy_states = tf.convert_to_tensor(np.random.random([BATCH_SIZE, RNN_UNITS]).astype(np.float32))
predictions, states = self(inputs, states=noisy_states, return_state=True, training=True)
從 Tensorflow Model 繼承的模型類現在看起來像
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,
stateful=True,
return_sequences=True,
return_state=True,
activation='tanh',
recurrent_activation='sigmoid',
recurrent_dropout=0.2,
dropout=0.2,
reset_after=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
@tf.function
def train_step(self, inputs):
inputs, labels = inputs
with tf.GradientTape() as tape:
noisy_states = tf.convert_to_tensor(np.random.random([BATCH_SIZE, RNN_UNITS]).astype(np.float32))
predictions, states = self(inputs, states=noisy_states, return_state=True, training=True)
loss=self.compiled_loss(labels, predictions, regularization_losses=self.losses)
grads=tape.gradient(loss, model.trainable_variables)
self.optimizer.apply_gradients(zip(grads, model.trainable_variables))
self.compiled_metrics.update_state(labels, predictions)
return {m.name: m.result() for m in self.metrics}
訓練運行沒有錯誤,但推理失敗
ValueError: in user code:
train.py:239 generate_one_step *
predicted_logits, states = self.model(inputs=input_ids, states=states,
train-v4.py:133 call *
x, states = self.gru(x, initial_state=states, training=training)
/usr/local/lib/python3.6/dist-packages/keras/layers/recurrent.py:716 __call__ **
return super(RNN, self).__call__(inputs, **kwargs)
[...]
ValueError: Input 0 is incompatible with layer gru: expected shape=(64, None, 256), found shape=(1, None, 256)
生成器看起來像這樣
class OneStep(tf.keras.Model):
def __init__(self, model, chars_from_ids, ids_from_chars, temperature=1.0):
super().__init__()
self.temperature = temperature
self.model = model
[initialize stuff]
[...]
@tf.function
def generate_one_step(self, inputs, states=None):
input_chars = tf.strings.unicode_split(inputs, 'UTF-8')
input_ids = self.ids_from_chars(input_chars).to_tensor()
predicted_logits, states = self.model(inputs=input_ids, states=states,
return_state=True)
predicted_logits = predicted_logits[:, -1, :]
predicted_logits = predicted_logits/self.temperature
predicted_logits = predicted_logits self.prediction_mask
predicted_ids = tf.random.categorical(predicted_logits, num_samples=1)
predicted_ids = tf.squeeze(predicted_ids, axis=-1)
predicted_chars = self.chars_from_ids(predicted_ids)
return predicted_chars, states
并且引發錯誤的代碼是
for n in range(10000):
next_char, states = one_step_model.generate_one_step(next_char, states=states)
result.append(next_char)
據我了解,我們用一些噪聲而不是零來初始化狀態,以避免過度擬合。模型像以前一樣得到更好的訓練,并且保留了權重以進行推理。推理模型是否也應該改變,狀態行為是否也應該在生成器中更新?
uj5u.com熱心網友回復:
IIUC,我認為您可能會遇到這個問題,其中Keras要求您GRU在訓練期間使用的相同批量大小也在推理期間使用。stateful當您將引數設定為 時,會彈出此要求True。查看我鏈接的帖子以獲取更多詳細資訊和可能的解決方法。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/429747.html
