我正在尝试用纯Numpy编写一个经过训练的有状态RNN Keras模型,使用tensorflow后端。
我的模型构建为:
model = Sequential()
num_layers_first_stage = 64
model.add(GRU(num_layers_first_stage, stateful=True, name=input_node_name, batch_input_shape=(1,1,4), return_sequences=True))
model.add(GRU(64, stateful=True, name='gru_layer_1', return_sequences=True))
model.add(GRU(64, stateful=True, name='gru_layer_2', return_sequences=True))
model.add(Dense(2, activation='softmax', name=output_node_name))
model.compile(loss='categorical_crossentropy',
optimizer='Adam',
metrics=['accuracy'])
return model
字符串
在训练之后,我保存模型,然后在不同的会话中再次加载它。我用来构建纯Numpy模型的代码看起来像这样:
def hard_sigmoid(x):
return np.clip(x * 0.2 + 0.5, 0.0, 1.0)
class MyKerasGRULayer(object):
def __init__(self, keras_layer):
self.num_units = keras_layer.units
self.W_z = keras_layer.cell.kernel_z.eval(session=K.get_session())
self.W_r = keras_layer.cell.kernel_r.eval(session=K.get_session())
self.W_h = keras_layer.cell.kernel_h.eval(session=K.get_session())
self.U_z = keras_layer.cell.recurrent_kernel_z.eval(session=K.get_session())
self.U_r = keras_layer.cell.recurrent_kernel_r.eval(session=K.get_session())
self.U_h = keras_layer.cell.recurrent_kernel_h.eval(session=K.get_session())
self.b_z = keras_layer.cell.input_bias_z.eval(session=K.get_session())
self.b_r = keras_layer.cell.input_bias_r.eval(session=K.get_session())
self.b_h = keras_layer.cell.input_bias_h.eval(session=K.get_session())
self.input_shape = keras_layer.input_shape
self.h = np.zeros((1, self.num_units), dtype=np.float32)
def forward_pass(self, x):
z = hard_sigmoid(np.dot(x, self.W_z) + np.dot(self.h, self.U_z) + self.b_z)
r = hard_sigmoid(np.dot(x, self.W_r) + np.dot(self.h, self.U_r) + self.b_r)
h_ = np.tanh(np.dot(x, self.W_h) + np.dot(np.multiply(r, self.h), self.U_h) + self.b_h)
self.h = np.multiply((1-z), self.h) + np.multiply(z, h_)
print(self.h)
型
我试着将它与我的Keras模型进行比较,如下所示:
model = load_model(model_file)
model.reset_states()
model.predict(np.ones((1,1,4)))
print(model.updates[0][0].eval(session=K.get_session()))
GRU0 = MyKerasGRULayer(model.layers[0])
GRU0.forward_pass(np.ones((4,)))
型
但结果不同。希望能得到指针,指出这里的错误
1条答案
按热度按时间oxalkeyp1#
Keras
GRU
使用以下代码计算h
:字符串
这与
forward_pass
方法不同。将最后一行改为:
型
你应该能得到同样的结果。