如何正确堆叠 RNN 层?
How to properly stack RNN layers?
我一直在尝试基于this tutorial在tensorflow中实现字符级语言模型。
我想通过允许堆叠多个 RNN 层来扩展模型。到目前为止,我已经想出了这个:
class MyModel(tf.keras.Model):
def __init__(self, vocab_size, embedding_dim, rnn_type, rnn_units, num_layers, dropout):
super().__init__(self)
self.rnn_type = rnn_type.lower()
self.num_layers = num_layers
self.embedding = tf.keras.layers.Embedding(vocab_size, embedding_dim)
if self.rnn_type == 'gru':
rnn_layer = tf.keras.layers.GRU
elif self.rnn_type == 'lstm':
rnn_layer = tf.keras.layers.LSTM
elif self.rnn_type == 'rnn':
rnn_layer = tf.keras.layers.SimpleRNN
else:
raise ValueError(f'Unsupported RNN layer: {rnn_type}')
setattr(self, self.rnn_type, rnn_layer(rnn_units, return_sequences=True, return_state=True, dropout=dropout))
for i in range(1, num_layers):
setattr(self, f'{self.rnn_type}_{i}', rnn_layer(rnn_units, return_sequences=True, return_state=True, dropout=dropout))
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)
rnn = self.get_layer(self.rnn_type)
if states is None:
states = rnn.get_initial_state(x)
x, states = rnn(x, initial_state=states, training=training)
for i in range(1, self.num_layers):
layer = self.get_layer(f'{self.rnn_type}_{i}')
x, states = layer(x, initial_state=states, training=training)
x = self.dense(x, training=training)
if return_state:
return x, states
else:
return x
model = MyModel(
vocab_size=vocab_size,
embedding_dim=embedding_dim,
rnn_type='gru',
rnn_units=512,
num_layers=3,
dropout=dropout)
在教程中的数据集上训练 30 个时期后,此模型会生成一些随机的乱码。现在我不知道是我做错了堆叠还是数据集太小了。
导致模型预测错误的因素有多种:
- 数据集很小
- 您使用的模型本身非常简单
- 训练时间很短
即使训练正确,预测莎士比亚的十四行诗也会产生随机的乱码
尝试训练更长的时间。这最终会带来更好的结果,尽管基于文本预测正确的语音可能是一般机器学习中最困难的任务之一。例如GPT3,其中一个几乎完美解决了这个问题的模型,由数十亿个参数组成(参见here)。
编辑:尽管你有更多堆叠的 RNN 层,但你的模型表现比教程中的模型差的原因可能是更多的层需要更多的训练时间。简单地增加层数不一定会提高预测质量。正如我所说,尝试增加训练时间或使用超参数(学习率、规范化层等)。
我一直在尝试基于this tutorial在tensorflow中实现字符级语言模型。
我想通过允许堆叠多个 RNN 层来扩展模型。到目前为止,我已经想出了这个:
class MyModel(tf.keras.Model):
def __init__(self, vocab_size, embedding_dim, rnn_type, rnn_units, num_layers, dropout):
super().__init__(self)
self.rnn_type = rnn_type.lower()
self.num_layers = num_layers
self.embedding = tf.keras.layers.Embedding(vocab_size, embedding_dim)
if self.rnn_type == 'gru':
rnn_layer = tf.keras.layers.GRU
elif self.rnn_type == 'lstm':
rnn_layer = tf.keras.layers.LSTM
elif self.rnn_type == 'rnn':
rnn_layer = tf.keras.layers.SimpleRNN
else:
raise ValueError(f'Unsupported RNN layer: {rnn_type}')
setattr(self, self.rnn_type, rnn_layer(rnn_units, return_sequences=True, return_state=True, dropout=dropout))
for i in range(1, num_layers):
setattr(self, f'{self.rnn_type}_{i}', rnn_layer(rnn_units, return_sequences=True, return_state=True, dropout=dropout))
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)
rnn = self.get_layer(self.rnn_type)
if states is None:
states = rnn.get_initial_state(x)
x, states = rnn(x, initial_state=states, training=training)
for i in range(1, self.num_layers):
layer = self.get_layer(f'{self.rnn_type}_{i}')
x, states = layer(x, initial_state=states, training=training)
x = self.dense(x, training=training)
if return_state:
return x, states
else:
return x
model = MyModel(
vocab_size=vocab_size,
embedding_dim=embedding_dim,
rnn_type='gru',
rnn_units=512,
num_layers=3,
dropout=dropout)
在教程中的数据集上训练 30 个时期后,此模型会生成一些随机的乱码。现在我不知道是我做错了堆叠还是数据集太小了。
导致模型预测错误的因素有多种:
- 数据集很小
- 您使用的模型本身非常简单
- 训练时间很短
即使训练正确,预测莎士比亚的十四行诗也会产生随机的乱码
尝试训练更长的时间。这最终会带来更好的结果,尽管基于文本预测正确的语音可能是一般机器学习中最困难的任务之一。例如GPT3,其中一个几乎完美解决了这个问题的模型,由数十亿个参数组成(参见here)。
编辑:尽管你有更多堆叠的 RNN 层,但你的模型表现比教程中的模型差的原因可能是更多的层需要更多的训练时间。简单地增加层数不一定会提高预测质量。正如我所说,尝试增加训练时间或使用超参数(学习率、规范化层等)。