1

我正在使用带有 keras 的 tensorflow 来使用 google colabs 训练到 char-RNN。我将模型训练 10 个 epoch 并保存它,使用“model.save()”,如保存模型的文档中所示。紧接着,我再次加载它只是为了检查,我尝试在加载的模型上调用 model.fit() 并使用完全相同的训练集得到“尺寸必须相等”错误。训练数据位于分批组织的 tensorflow 数据集中,如tf datasets 的文档中所示。这是一个最小的工作示例:

import numpy as np
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Embedding, LSTM, Dense

X = np.random.randint(0,50,(10000))

seq_len = 150
batch_size = 20
dataset = tf.data.Dataset.from_tensor_slices(X)
dataset = dataset.batch(seq_len+1,drop_remainder=True)
dataset = dataset.map(lambda x: (x[:-1],x[1:]))
dataset = dataset.shuffle(20).batch(batch_size,drop_remainder=True)

def make_model(vocabulary_size,embedding_dimension,rnn_units,batch_size,stateful):
  model = Sequential()
  model.add(Embedding(vocabulary_size,embedding_dimension,
                      batch_input_shape=[batch_size,None]))
  model.add(LSTM(rnn_units,return_sequences=True,stateful=stateful))
  model.add(Dense(vocabulary_size))
  model.compile(loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
                optimizer='adam',metrics=['accuracy'])
  model.summary()
  return model

vocab_size = 51
emb_dim = 20
rnn_units = 10
model = make_model(vocab_size,emb_dim,rnn_units,batch_size,False)

model.fit(dataset,epochs=10)
model.save('/content/test_model')
model2 = tf.keras.models.load_model('/content/test_model')
model2.fit(dataset,epochs=10)

第一个训练行“model.fit()”运行良好,但最后一行返回错误:

ValueError:尺寸必须相等,但对于输入形状为 [20]、[20,150] 的“{{node Equal}} = Equal[T=DT_INT64, incompatible_shape_error=true](ArgMax, ArgMax_1)”,尺寸必须是 20 和 150。

我希望以后能够恢复训练,因为我的真实数据集要大得多。因此,仅保存权重并不是一个理想的选择。

有什么建议吗?谢谢!

4

2 回答 2

0

如果您已经保存了检查点,则可以从这些检查点恢复使用减少的数据集。您的神经网络/层和尺寸应该相同。

于 2020-12-05T16:13:34.863 回答
0

问题在于“准确性”指标。出于某种原因,正如我在这个线程中发现的那样,当模型加载了这个指标时,预测中的维度存在一些错误处理(见最后一条评论)。在具有相同指标的加载模型上运行 model.compile() 可以继续训练。但是,没有必要再次编译模型。此外,这意味着优化器状态丢失,如本答案中所述,因此,这对于恢复训练不是很有用。

另一方面,从一开始就使用“sparse_categorical_accuracy”就可以了。我能够加载模型并继续训练,而无需重新编译。事后看来,这个选择更合适,因为我最后一层的输出是字符分布的 logits。因此,这不是一个二元分类问题,而是一个多类分类问题。尽管如此,在我的具体示例中,我验证了 'accuracy' 和 'sparse_categorical_accuracy' 返回了相同的值。因此,我相信 keras 在内部将准确性转换为分类准确性,但是在刚刚加载的模型上执行此操作时会出现问题,这会导致需要重新编译。

我还验证了如果保存的模型是用“准确度”编译的,加载模型并用“sparse_categorical_accuracy”重新编译将允许恢复训练。然而,如前所述,这会丢弃优化器的状态,我怀疑这不会比仅仅制作一个新模型并只加载保存的模型中的权重更好。

于 2020-12-06T18:56:56.743 回答