加载的 keras 模型无法继续训练,尺寸不匹配

Posted

技术标签:

【中文标题】加载的 keras 模型无法继续训练,尺寸不匹配【英文标题】:Loaded keras model fails to continue training, dimensions mismatch 【发布时间】:2021-03-17 09:59:25 【问题描述】:

我正在使用带有 keras 的 tensorflow 来使用 google colabs 训练到 char-RNN。我训练我的模型 10 个 epoch 并保存它,使用“model.save()”,如 documentation for saving models 所示。紧接着,我再次加载它只是为了检查,我尝试在加载的模型上调用 model.fit() 并使用完全相同的训练集得到“尺寸必须相等”错误。训练数据位于分批组织的 tensorflow 数据集中,如documentation for 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: 维度必须相等,但对于 'node 来说是 20 和 150 相等 = 相等[T=DT_INT64, incompatible_shape_error=true](ArgMax, ArgMax_1)',输入形状为:[20]、[20,150]。

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

有什么建议吗? 谢谢!

【问题讨论】:

【参考方案1】:

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

【讨论】:

使用检查点保存模型会导致与使用 model.save() 相同的行为,当我尝试训练加载的模型时,我仍然遇到相同的错误。 什么是 emb_dim = 20 ?因为这对保存的模型来说似乎是新的。另外,在数据进入模型之前,使用 data.shape() 检查形状并查看数据是否具有相同的形状。由于上述原因,我假设您的新配置正在检测差异形状。 'emb_dim' 是模型中第一层 Embedding 层的嵌入维度。 “数据集”对象的描述是:。但是,错误消息中的“20”来自 batch_size。从一开始就设置 batch_size = 30,错误消息是:“Dimensions must be equal, but are 30 and 150 for 'node Equal = Equal[T=DT_INT64, incompatible_shape_error=true](ArgMax, ArgMax_1)' with输入形状:[30]、[30,150]"。因此,这必须与使用 BatchDataset 对象有关 data.reshape() 如果您可以相应地重塑输入需求,则可以为您提供帮助。 注意问题不在于数据的形状。在新构建的模型上进行训练效果很好。它只是训练显示错误的加载模型。我还验证了该问题与使用 BatchDataset 对象无关,因为如果我对数据集使用 numpy 数组并在拟合行中传递批处理大小,我也会得到相同的错误。【参考方案2】:

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

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

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

【讨论】:

以上是关于加载的 keras 模型无法继续训练,尺寸不匹配的主要内容,如果未能解决你的问题,请参考以下文章

我在 google colab 上训练了一个 keras 模型。现在无法在我的系统上本地加载它。

无法使用 keras.models.load_model() 加载 TF 变压器模型

恢复培训 tf.keras Tensorboard

无法从 keras 中的检查点模型恢复训练

Keras:如何保存模型并继续训练?

keras 如何保存训练集与验证集正确率的差最小那次epoch的网络及权重