我一直在尝试基于本教程在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,其中一个模型,几乎完美地解决了这个问题,由数十亿个参数组成(见这里)。
编辑:虽然你有更多的堆叠RNN层,但你的模型比教程中的模型表现更差的原因可能是,更多的层需要更多的训练时间。仅仅增加层数并不一定会提高你的预测质量。正如我所说,尝试增加训练时间或使用超参数(学习率,规范化层等)。