使用Keras,如何将CuDNNLSTM生成的权重加载到LSTM模型中?

时间:2017-10-29 17:56:24

标签: python tensorflow neural-network keras cudnn

我开发了一款基于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')

2 个答案:

答案 0 :(得分:4)

原因是CuDNNLSTM图层的biasLSTM的两倍。这是因为cuDNN API的底层实现。您可以将以下等式(从cuDNN用户指南中复制)与通常的LSTM等式进行比较:

cuDNN LSTM equations

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模型,但是出现了很多错误。