使用CuDNNLSTM层的Keras模型不适用于生产服务器

时间:2018-01-03 22:20:39

标签: python tensorflow keras tensorflow-gpu

我使用AWS p3实例使用GPU加速来训练以下模型:

x = CuDNNLSTM(128, return_sequences=True)(inputs)
x = Dropout(0.2)(x)
x = CuDNNLSTM(128, return_sequences=False)(x)
x = Dropout(0.2)(x)
predictions = Dense(1, activation='tanh')(x)
model = Model(inputs=inputs, outputs=predictions)

训练结束后,我用Keras' save_model功能并将其移至没有GPU的单独生产服务器。

当我尝试预测在生产服务器上使用该模型时,它会失败,并显示以下错误:

  

没有注册OpKernel来支持Op' CudnnRNN'与这些attrs。已注册的设备:[CPU],已注册的内核:     

我猜测这是因为生产服务器没有GPU支持,但我希望这不会成为问题。有没有什么办法可以在没有GPU的生产服务器上使用这个模型?

5 个答案:

答案 0 :(得分:3)

不,你不能,CuDNN需要使用CUDA GPU。您必须使用标准LSTM层替换CuDNNLSTM层。

答案 1 :(得分:2)

简短答案: 是的你可以。

只需使用LSTM层而不是CuDNNLSTM重新创建您的体系结构。

您的代码应为以下代码:

x = LSTM(128, return_sequences=True, recurrent_activation='sigmoid')(inputs)
x = Dropout(0.2)(x)
x = LSTM(128, return_sequences=False, recurrent_activation='sigmoid')(x)
x = Dropout(0.2)(x)
predictions = Dense(1, activation='tanh')(x)
model = Model(inputs=inputs, outputs=predictions)

然后

model.load_weights(path_to_your_weights_file)

请注意recurrent_activation='sigmoid'。这很重要。

详细解释:

LSTM和CuDNNLSTM是彼此兼容的,因此您可以毫无问题地将重量从一个加载到另一个。但是,其激活功能的默认值略有不同。据here报道,有时它会导致彼此之间的微小差异,但可能会导致很大的差异。

CuDNNLSTM的[激活值]在CuDNN中进行了硬编码,无法从Keras进行更改。它们对应于激活=“ tanh”和recurrent_activation =“ Sigmoid”(与[LSTM] Keras中的默认hard_sigmoid稍有不同)。 ref

答案 2 :(得分:1)

解决此问题的最简单方法是 将CuDNN图层替换为常规的keras图层, 即。将CudNNLSTM转换为LSTM等

如果使用Google Colab,请转到“运行时”>“更改运行时设置”,并将加速器设置为 GPU

答案 3 :(得分:0)

尝试

pip install tensorflow-gpu

答案 4 :(得分:0)

您肯定可以在CuDNNLSTM上进行训练,然后在LSTM上进行推理。

诀窍是在加载h5文件之前,将.json文件中的图层体系结构从CuDNNLSTM更改为LSTM。当您加载h5文件时,CuDNNLSTM权重的2倍偏差会自动转换,但是Keras 不会会自动为您更改.json文件。

换句话说,只需打开保存的.json模型,将CuDNNLSTM的所有实例更改为LSTM,保存.json文件,然后加载.h5文件。然后,您应该能够对模型进行推断。