我开发了一款基于LSTM层的基于Keras的NN模型。为了提高Paperspace(GPU云处理基础架构)的速度,我使用新的 CuDNNLSTM 层切换了 LSTM 层。但是,这仅适用于支持GPU cuDNN的计算机。 PS:CuDNNLSTM仅适用于Keras master
,而不是最新版本。
所以我已经生成了权重并将其保存为云上的hdf5
格式,我想在我的MacBook上本地使用它们。由于CuDNNLSTM层不可用,仅用于本地安装,我已切换回LSTM。
阅读此tweet about CuDNN from @fchollet我认为它可以正常工作,只需将权重读回LSTM模型即可。
但是,当我尝试导入它们时,Keras会抛出此错误:
Traceback (most recent call last):
{...}
tensorflow.python.framework.errors_impl.InvalidArgumentError: Dimension 0 in both shapes must be equal, but are 2048 and 4096 for 'Assign_2' (op: 'Assign') with input shapes: [2048], [4096].
{...}
ValueError: Dimension 0 in both shapes must be equal, but are 2048 and 4096 for 'Assign_2' (op: 'Assign') with input shapes: [2048], [4096]
使用h5cat分析hdf5
个文件我可以看到两个结构不同。
TL; DR
我无法将 CuDNNLSTM 生成的权重加载到 LSTM 模型中。 我是以错误的方式做事吗?如何让它们无缝地工作?
这是我的模特:
SelectedLSTM = CuDNNLSTM if is_gpu_enabled() else LSTM
# ...
model = Sequential()
model.add(SelectedLSTM(HIDDEN_DIM, return_sequences=True, input_shape=(SEQ_LENGTH, vocab_size)))
model.add(Dropout(0.2))
model.add(SelectedLSTM(HIDDEN_DIM, return_sequences=False))
model.add(Dense(vocab_size))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
答案 0 :(得分:4)
原因是CuDNNLSTM
图层的bias
是LSTM
的两倍。这是因为cuDNN API的底层实现。您可以将以下等式(从cuDNN用户指南中复制)与通常的LSTM等式进行比较:
CuDNN使用两个偏置项,因此偏置权重的数量加倍。要将其转换回LSTM
使用的值,需要对两个偏差项求和。
我已提交PR进行转换并将其合并。你可以从GitHub安装最新的Keras,解决重量加载的问题。
答案 1 :(得分:2)
只需添加到上述@ Yu-Yang的答案中,最新的Keras会自动将CuDMMLSTM
的权重转换为LSTM
,但不会更改您的.json您的模型架构。
要在LSTM上运行推理,您需要打开JSON文件,并将CuDNNLSTM
的所有实例手动更改为LSTM
。然后运行model_from_json
加载模型,运行load_weights
加载权重。
我尝试先运行load_weights
而不先手动更改CuDNNLSTM
模型,但是出现了很多错误。