keras中lstm参数_LSTM之Keras中Stateful参数

一、Sateful参数介绍

在Keras调用LSTM的参数中,有一个stateful参数,默认是False,也就是无状态模式stateless,为True的话就是有状态模式stateful,所以这里我们就归为两种模式:

有状态模型(stateful LSTM)

无状态模型(stateless LSTM)

那两者到底是什么区别呢,怎么使用呢?

二、区别

stateful LSTM

除了正常的单个sample内部时间步之间的状态互相传递外(这个是LSTM的基本功能),sample之间的状态还能互相传递。但是需要确定batch_size大小,传递的时候是前一个batch的第i个sample最终输出状态,传递给后一个batch的第i个sample,作为其状态的初始化值。以“解放军第72集团军某旅500名抗洪子弟兵撤离安徽铜陵枞阳县,赶赴合肥庐江县继续抗洪。当地百姓冒着大雨追着驶出的车辆,递上自家的莲蓬、葡萄、熟鸡蛋等食物,送别子弟兵。”为例子,第一句话为一个sample,第二句话为第二个sample,每个sample内部的word为一个时间步,很明显前后两个sample是相互关联的。如果设置batch_size=1,则第一句话最终输出状态(即最后一个word的状态输出),就可以传递给第二句话作为其初始状态值。

优点:后面的语句有了更合理的初始化状态值,显然会加快网络的收敛,所以需要更小的网络、更少的训练时间。

缺点:每一个epoch后,要重置一下状态,因为训练一遍了,状态不能循环使用,要从头开始。

使用注意事项:调用fit() 时指定 shuffle = False,要保证sample之间的前后顺序;可以使用 model.reset_states()来重置模型中所有层的状态,也可使用layer.reset_states()来重置指定有状态 RNN 层的状态。

stateless LSTM

stateless就是与stateful相反了,就是sample之间没有前后状态传递的关系,输入samples后,默认就会shuffle,可以说是每个sample独立,适合输入一些没有关系的样本。

三、问答

1、在Keras中stateless LSTM中的stateless指的是?

注意,此文所说的stateful是指的在Keras中特有的,是batch之间的记忆cell状态传递。而非说的是LSTM论文模型中表示那些记忆门,遗忘门,c,h等等在同一sequence中不同timesteps时间步之间的状态传递。假定我们的输入X是一个三维矩阵,shape = (nb_samples, timesteps, input_dim),每一个row代表一个sample,每个sample都是一个sequence小序列。X[i]表示输入矩阵中第i个sample。步长啥的我们先不用管。当我们在默认状态stateless下,Keras会在训练每个sequence小序列(=sample)开始时,将LSTM网络中的记忆状态参数reset初始化(指的是c,h而并非权重w),即调用model.reset_states()。

2、为啥stateless LSTM每次训练都要初始化记忆参数?

因为Keras在训练时会默认地shuffle samples,所以导致sequence之间的依赖性消失,sample和sample之间就没有时序关系,顺序被打乱,这时记忆参数在batch、小序列之间进行传递就没意义了,所以Keras要把记忆参数初始化。

四、代码举例

通过对cos函数的预测来分别对比stateless和stateful的差别

1、 单层无状态LSTM模型(序列长度为20)

importnumpy as npfrom keras.models importSequentialfrom keras.layers importDense, LSTM, Dropoutimportmatplotlib.pyplot as plt#创建数据集,每隔50个就是一个整Π,围绕Π的系数不断变化

dataset = np.cos(np.arange(1000)*(20*np.pi/1000))#dataset的值域再-1~1之间。

#转换数据为LSTM输入格式: dataset matrix

def create_dataset(dataset, look_back=1):

dataX, dataY=[], []for i in range(len(dataset)-look_back):

dataX.append(dataset[i:(i+look_back)])

dataY.append(dataset[i+look_back])returnnp.array(dataX), np.array(dataY)#20长度的滑动窗口进行预测

look_back = 20

#归一化,y值域为(0,1)

dataset = (dataset+1) / 2.#split into train and test sets

train_size = int(len(dataset) * 0.8)

test_size= len(dataset) -train_size

train, test=dataset[:train_size], dataset[train_size:]

trainX, trainY=create_dataset(train, look_back)

testX, testY=create_dataset(test, look_back)print(trainX.shape)print(trainY.shape)

trainX= np.reshape(trainX, (trainX.shape[0], trainX.shape[1], 1))

testX= np.reshape(testX, (testX.shape[0], testX.shape[1], 1))'''trainX.shape = (780, 20, 1)

testX.shape = (180, 20, 1)

trainY.shape = (780,)

testY.shape = (180,)'''

#构建无状态LSTM模型

batch_size = 1model=Sequential()

model.add(LSTM(32, input_shape=(20, 1)))

model.add(Dropout(0.2))

model.add(Dense(1))

model.compile(loss= 'mse', optimizer = 'adam')

model.fit(trainX,trainY,batch_size= batch_size,epochs=30, verbose=2)#从训练集的最后一个sample样本截取后面的19个+y值得1个,构成一个新的sample(20,1),来预测一个值,其实这个值就是测试集的第一个值,

x = np.vstack((trainX[-1][1:],(trainY[-1])))#vstack就是竖着拼起来

preds=[]

pred_num= 500

for i innp.arange(pred_num):#重新转换成适合lstm的格式,并进行预测

pred = model.predict(x.reshape((1,-1,1)),batch_size =batch_size)

preds.append(pred.squeeze())

x= np.vstack((x[1:],pred))#横坐标就是1~500

plt.figure(figsize=(12,5))

plt.plot(np.arange(pred_num),np.array(preds),'r',label='predctions')

cos_y= (np.cos(np.arange(pred_num)*(20*np.pi/1000))+1)/ 2.

plt.plot(np.arange(pred_num),cos_y,label='origin')

plt.legend()

plt.show()

2、单层有状态LSTM模型(序列长度为40)

#单层有状态 LSTM network#创建数据集,每隔50个就是一个整Π,围绕Π的系数不断变化

dataset = np.cos(np.arange(1000)*(20*np.pi/1000))#dataset的值域再-1~1之间。

#转换数据为LSTM输入格式: dataset matrix

def create_dataset(dataset, look_back=1):

dataX, dataY=[], []for i in range(len(dataset)-look_back):

dataX.append(dataset[i:(i+look_back)])

dataY.append(dataset[i+look_back])returnnp.array(dataX), np.array(dataY)#建立模型:双层stacked Stateful LSTM

look_back =40dataset= np.cos(np.arange(1000)*(20*np.pi/1000))#归一化,y值域为(0,1)

dataset = (dataset+1) / 2.#split into train and test sets

train_size = int(len(dataset) * 0.8)

test_size= len(dataset) -train_size

train, test=dataset[:train_size], dataset[train_size:]

trainX, trainY=create_dataset(train, look_back)

testX, testY=create_dataset(test, look_back)

trainX= np.reshape(trainX, (trainX.shape[0], trainX.shape[1], 1))

testX= np.reshape(testX, (testX.shape[0], testX.shape[1], 1))

batch_size= 1model2=Sequential()

model2.add(LSTM(32, batch_input_shape=(batch_size, look_back, 1), stateful=True))

model2.add(Dropout(0.2))

model2.add(Dense(1))

model2.compile(loss='mse', optimizer='adam')for i in range(30):

model2.fit(trainX, trainY, epochs=1, batch_size=batch_size, shuffle=False)

model2.reset_states()

x= np.vstack((trainX[-1][1:],(trainY[-1])))

preds=[]

pred_num= 500

for i innp.arange(pred_num):

pred= model2.predict(x.reshape((1,-1,1)),batch_size =batch_size)

preds.append(pred.squeeze())

x= np.vstack((x[1:],pred))

plt.figure(figsize=(12,5))

plt.plot(np.arange(pred_num),np.array(preds),'r',label='predctions')

cos_y= (np.cos(np.arange(pred_num)*(20*np.pi/1000))+1)/ 2.

plt.plot(np.arange(pred_num),cos_y,label='origin')

plt.legend()

plt.show()

3、双层有状态LSTM模型(序列长度为40)

#创建数据集,每隔50个就是一个整Π,围绕Π的系数不断变化

dataset = np.cos(np.arange(1000)*(20*np.pi/1000))#dataset的值域再-1~1之间。

#转换数据为LSTM输入格式: dataset matrix

def create_dataset(dataset, look_back=1):

dataX, dataY=[], []for i in range(len(dataset)-look_back):

dataX.append(dataset[i:(i+look_back)])

dataY.append(dataset[i+look_back])returnnp.array(dataX), np.array(dataY)#建立模型:双层stacked Stateful LSTM

look_back =40dataset= np.cos(np.arange(1000)*(20*np.pi/1000))#归一化,y值域为(0,1)

dataset = (dataset+1) / 2.#split into train and test sets

train_size = int(len(dataset) * 0.8)

test_size= len(dataset) -train_size

train, test=dataset[:train_size], dataset[train_size:]

trainX, trainY=create_dataset(train, look_back)

testX, testY=create_dataset(test, look_back)

trainX= np.reshape(trainX, (trainX.shape[0], trainX.shape[1], 1))

testX= np.reshape(testX, (testX.shape[0], testX.shape[1], 1))#建立模型:有状态

batch_size = 1model3=Sequential()

model3.add(LSTM(32, batch_input_shape=(batch_size, look_back, 1), stateful=True, return_sequences=True))

model3.add(Dropout(0.3))

model3.add(LSTM(32, batch_input_shape=(batch_size, look_back, 1), stateful=True))

model3.add(Dropout(0.3))

model3.add(Dense(1))

model3.compile(loss='mean_squared_error', optimizer='adam')for i in range(100):print(i)

model3.fit(trainX, trainY, epochs=1, batch_size=batch_size, verbose=0, shuffle=False)

model3.reset_states()#预测

x = np.vstack((trainX[-1][1:],(trainY[-1])))

preds=[]

pred_num= 500

for i innp.arange(pred_num):

pred= model3.predict(x.reshape((1,-1,1)),batch_size =batch_size)

preds.append(pred.squeeze())

x= np.vstack((x[1:],pred))#print(preds[:20])#print(np.array(preds).shape)

plt.figure(figsize=(12,5))

plt.plot(np.arange(pred_num),np.array(preds),'r',label='predctions')

cos_y= (np.cos(np.arange(pred_num)*(20*np.pi/1000))+1)/ 2.

plt.plot(np.arange(pred_num),cos_y,label='origin')

plt.legend()

plt.show()

参考连接:

你可能感兴趣的:(keras中lstm参数)