如何在 Keras 中使用 reset_states(states) 函数?
How to use reset_states(states) function in Keras?
我正在尝试在训练每批之前设置 LSTM 内部状态。
我正在分享我的测试代码和发现,希望找到答案并帮助其他正在解决类似问题的人。
特别是,对于每个数据,我都有一个特征 X(不随时间变化)和一个序列 P = p1、p2、p3、... p30。
目标是:给定 X 和 p1、p2、p3 预测 p4、p5、.. p30.
为了这个目标,我想用 X 初始化 LSTM 的隐藏状态,就像在几个作品(例如,neuraltalk)中所做的那样,然后 LSTM 必须与 p1、p2、p3 相匹配才能预测 p4, ..,第 30 页。
在每批 (batch_size=1) 之前需要进行此初始化,因此我需要控制 LSTM 状态初始化。
考虑这个问题 我测试了以下代码:
首先,我在 recurrent.py 中定义的 reset_states() 函数中添加了一些打印,以便了解到底发生了什么。
def reset_states(self, states=None):
if not self.stateful:
raise AttributeError('Layer must be stateful.')
batch_size = self.input_spec[0].shape[0]
if not batch_size:
raise ValueError('If a RNN is stateful, it needs to know '
'its batch size. Specify the batch size '
'of your input tensors: \n'
'- If using a Sequential model, '
'specify the batch size by passing '
'a `batch_input_shape` '
'argument to your first layer.\n'
'- If using the functional API, specify '
'the time dimension by passing a '
'`batch_shape` argument to your Input layer.')
# initialize state if None
if self.states[0] is None:
self.states = [K.zeros((batch_size, self.units))
for _ in self.states]
print "reset states A (all zeros)"
elif states is None:
for state in self.states:
K.set_value(state, np.zeros((batch_size, self.units)))
print "reset states B (all zeros)"
else:
if not isinstance(states, (list, tuple)):
states = [states]
print "reset states C (list or tuple copying)"
if len(states) != len(self.states):
raise ValueError('Layer ' + self.name + ' expects ' +
str(len(self.states)) + ' states, '
'but it received ' + str(len(states)) +
' state values. Input received: ' +
str(states))
for index, (value, state) in enumerate(zip(states, self.states)):
if value.shape != (batch_size, self.units):
raise ValueError('State ' + str(index) +
' is incompatible with layer ' +
self.name + ': expected shape=' +
str((batch_size, self.units)) +
', found shape=' + str(value.shape))
K.set_value(state, value)
print "reset states D (set values)"
print value
print "\n"
这里是测试代码:
import tensorflow as tf
from keras.layers import LSTM
from keras.layers import Input
from keras.models import Model
import numpy as np
import keras.backend as K
input = Input(batch_shape=(1,3,1))
lstm_layer = LSTM(10,stateful=True)(input)
>>> reset states A (all zeros)
可以看到,第一次打印是在创建lstm层的时候执行的
model = Model(input,lstm_layer)
model.compile(optimizer="adam", loss="mse")
with tf.Session() as sess:
tf.global_variables_initializer().run()
h = sess.run(model.layers[1].states[0])
c = sess.run(model.layers[1].states[1])
print h
>>> [[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]]
print c
>>> [[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]]
内部状态已设置为全零。
作为替代方案,可以使用函数 reset_states()
model.layers[1].reset_states()
>>> reset states B (all zeros)
本例中已打印第二条消息。一切似乎都正常工作。
现在我想用任意值设置状态。
new_h = K.variable(value=np.ones((1, 10)))
new_c = K.variable(value=np.ones((1, 10))+1)
model.layers[1].states[0] = new_h
model.layers[1].states[1] = new_c
with tf.Session() as sess:
tf.global_variables_initializer().run()
h = sess.run(model.layers[1].states[0])
c = sess.run(model.layers[1].states[1])
print h
>>> [[ 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]]
print c
>>> [[ 2., 2., 2., 2., 2., 2., 2., 2., 2., 2.]]
好的,我已经用全一和全二的向量成功地设置了两个隐藏状态。
但是,值得利用 class 函数 reset_states() 将状态作为输入。
这个函数利用函数 K.set_values(x,values) 期望 'values' 是一个 numpy 数组。
new_h_5 = np.zeros((1,10))+5
new_c_24 = np.zeros((1,10))+24
model.layers[1].reset_states([new_h_5,new_c_24])
似乎有效,确实输出是:
>>> reset states D (set values)
>>> [[ 5. 5. 5. 5. 5. 5. 5. 5. 5. 5.]]
>>>
>>>
>>>
>>>
>>> reset states D (set values)
>>> [[ 24. 24. 24. 24. 24. 24. 24. 24. 24. 24.]]
但是,如果我想检查状态是否已经初始化,我会找到以前的初始化值(全部一个,全部两个)。
with tf.Session() as sess:
tf.global_variables_initializer().run()
hh = sess.run(model.layers[1].states[0])
cc = sess.run(model.layers[1].states[1])
print hh
>>> [[ 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]]
print cc
>>> [[ 2., 2., 2., 2., 2., 2., 2., 2., 2., 2.]]
这里究竟发生了什么?为什么函数看起来根据打印件工作但不更改内部状态的值?
您可能会读到 here,value 参数设置了一个变量应该初始化的值。因此,当您调用 tf.global_variables_initializer().run()
时,您的状态将使用此处定义的值进行初始化:
new_h = K.variable(value=np.ones((1, 10)))
new_c = K.variable(value=np.ones((1, 10))+1)
编辑:
这对我来说似乎很明显,但我会再次解释为什么 reset_states
不起作用。
变量定义:当你将你的内部状态定义为由某个值初始化的变量时,每次调用variable_initializer
.
时都会设置这个特定的vaklue
重置状态:它将更新此变量的当前值,但不会更改初始值设定项的默认值。为此,您需要通过另一个将给定状态设置为默认值的变量重新分配此状态。
我正在尝试在训练每批之前设置 LSTM 内部状态。 我正在分享我的测试代码和发现,希望找到答案并帮助其他正在解决类似问题的人。
特别是,对于每个数据,我都有一个特征 X(不随时间变化)和一个序列 P = p1、p2、p3、... p30。 目标是:给定 X 和 p1、p2、p3 预测 p4、p5、.. p30.
为了这个目标,我想用 X 初始化 LSTM 的隐藏状态,就像在几个作品(例如,neuraltalk)中所做的那样,然后 LSTM 必须与 p1、p2、p3 相匹配才能预测 p4, ..,第 30 页。
在每批 (batch_size=1) 之前需要进行此初始化,因此我需要控制 LSTM 状态初始化。
考虑这个问题
首先,我在 recurrent.py 中定义的 reset_states() 函数中添加了一些打印,以便了解到底发生了什么。
def reset_states(self, states=None):
if not self.stateful:
raise AttributeError('Layer must be stateful.')
batch_size = self.input_spec[0].shape[0]
if not batch_size:
raise ValueError('If a RNN is stateful, it needs to know '
'its batch size. Specify the batch size '
'of your input tensors: \n'
'- If using a Sequential model, '
'specify the batch size by passing '
'a `batch_input_shape` '
'argument to your first layer.\n'
'- If using the functional API, specify '
'the time dimension by passing a '
'`batch_shape` argument to your Input layer.')
# initialize state if None
if self.states[0] is None:
self.states = [K.zeros((batch_size, self.units))
for _ in self.states]
print "reset states A (all zeros)"
elif states is None:
for state in self.states:
K.set_value(state, np.zeros((batch_size, self.units)))
print "reset states B (all zeros)"
else:
if not isinstance(states, (list, tuple)):
states = [states]
print "reset states C (list or tuple copying)"
if len(states) != len(self.states):
raise ValueError('Layer ' + self.name + ' expects ' +
str(len(self.states)) + ' states, '
'but it received ' + str(len(states)) +
' state values. Input received: ' +
str(states))
for index, (value, state) in enumerate(zip(states, self.states)):
if value.shape != (batch_size, self.units):
raise ValueError('State ' + str(index) +
' is incompatible with layer ' +
self.name + ': expected shape=' +
str((batch_size, self.units)) +
', found shape=' + str(value.shape))
K.set_value(state, value)
print "reset states D (set values)"
print value
print "\n"
这里是测试代码:
import tensorflow as tf
from keras.layers import LSTM
from keras.layers import Input
from keras.models import Model
import numpy as np
import keras.backend as K
input = Input(batch_shape=(1,3,1))
lstm_layer = LSTM(10,stateful=True)(input)
>>> reset states A (all zeros)
可以看到,第一次打印是在创建lstm层的时候执行的
model = Model(input,lstm_layer)
model.compile(optimizer="adam", loss="mse")
with tf.Session() as sess:
tf.global_variables_initializer().run()
h = sess.run(model.layers[1].states[0])
c = sess.run(model.layers[1].states[1])
print h
>>> [[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]]
print c
>>> [[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]]
内部状态已设置为全零。 作为替代方案,可以使用函数 reset_states()
model.layers[1].reset_states()
>>> reset states B (all zeros)
本例中已打印第二条消息。一切似乎都正常工作。 现在我想用任意值设置状态。
new_h = K.variable(value=np.ones((1, 10)))
new_c = K.variable(value=np.ones((1, 10))+1)
model.layers[1].states[0] = new_h
model.layers[1].states[1] = new_c
with tf.Session() as sess:
tf.global_variables_initializer().run()
h = sess.run(model.layers[1].states[0])
c = sess.run(model.layers[1].states[1])
print h
>>> [[ 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]]
print c
>>> [[ 2., 2., 2., 2., 2., 2., 2., 2., 2., 2.]]
好的,我已经用全一和全二的向量成功地设置了两个隐藏状态。 但是,值得利用 class 函数 reset_states() 将状态作为输入。 这个函数利用函数 K.set_values(x,values) 期望 'values' 是一个 numpy 数组。
new_h_5 = np.zeros((1,10))+5
new_c_24 = np.zeros((1,10))+24
model.layers[1].reset_states([new_h_5,new_c_24])
似乎有效,确实输出是:
>>> reset states D (set values)
>>> [[ 5. 5. 5. 5. 5. 5. 5. 5. 5. 5.]]
>>>
>>>
>>>
>>>
>>> reset states D (set values)
>>> [[ 24. 24. 24. 24. 24. 24. 24. 24. 24. 24.]]
但是,如果我想检查状态是否已经初始化,我会找到以前的初始化值(全部一个,全部两个)。
with tf.Session() as sess:
tf.global_variables_initializer().run()
hh = sess.run(model.layers[1].states[0])
cc = sess.run(model.layers[1].states[1])
print hh
>>> [[ 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]]
print cc
>>> [[ 2., 2., 2., 2., 2., 2., 2., 2., 2., 2.]]
这里究竟发生了什么?为什么函数看起来根据打印件工作但不更改内部状态的值?
您可能会读到 here,value 参数设置了一个变量应该初始化的值。因此,当您调用 tf.global_variables_initializer().run()
时,您的状态将使用此处定义的值进行初始化:
new_h = K.variable(value=np.ones((1, 10)))
new_c = K.variable(value=np.ones((1, 10))+1)
编辑:
这对我来说似乎很明显,但我会再次解释为什么 reset_states
不起作用。
变量定义:当你将你的内部状态定义为由某个值初始化的变量时,每次调用
时都会设置这个特定的vakluevariable_initializer
.重置状态:它将更新此变量的当前值,但不会更改初始值设定项的默认值。为此,您需要通过另一个将给定状态设置为默认值的变量重新分配此状态。