赞
踩
数据集和代码:链接:https://pan.baidu.com/s/1hwk7rRJr_pZgKbUBWI6TNQ
提取码:jwpl
数据集是精简排序过的,我们唯一需要用到的属性就是[‘Lane 1 Flow (Veh/5 Minutes)’]。
任务就是用前12个连续时刻的状态数据[St0,St1,…,St11]预测第13个时刻的状态pSt12。
我就min-max归一化了一下,没特别处理。其中lags=12就是时间步,也就是time_step,所有数据都被我做成了三维的矩阵,与LSTM的输入输出[batch_size,time_step,feature_num]对应:
#数据集处理: trainData=np.array(list(pd.read_csv('train.csv', lineterminator='\n')['Lane 1 Flow (Veh/5 Minutes)'])) testData=np.array(list(pd.read_csv('test.csv',lineterminator='\n')['Lane 1 Flow (Veh/5 Minutes)'])) trainLen=len(trainData) testLen=len(testData) combineData=np.append(trainData,testData) scl=MinMaxScaler() combineData=scl.fit_transform(combineData.reshape(-1, 1)) min=scl.data_min_ max=scl.data_max_ trainData=combineData[:trainLen] testData=combineData[trainLen:trainLen+testLen] lags=12 train=[] test=[] #虽然特征只有一维,但我们还是做成[batch_size,time_step,feature_num]的形式 for i in range(lags,trainLen): train.append(trainData[i-lags:i+1]) for i in range(lags,testLen): test.append(testData[i-lags:i+1]) train=np.array(train) test=np.array(test) x_train=train[:,:-1] y_train=train[:,-1,np.newaxis] x_test=test[:,:-1] y_test=test[:,-1,np.newaxis]
tensorflow搭建神经网络的流程是建立计算图,编译计算图,然后传入数据,也就是静态图(2.0有动态图了,不过没用过)。计算图其实就是张量tensor和数据流向flow组成的,张量其实就是矩阵,也就是说tensorflow实现神经网络的本质实际上就是自定义了一个大的矩阵运算函数,LSTM、GRU都可以理解为一种封装好的复杂矩阵运算。
Tensorflow中的LSTM接受一个形状为[batch_size,time_step,feature_num]的矩阵,输出一个形状为[batch_size,time_step,rnn_units]的矩阵,batch_size即batch的大小,time_step是时间步,也就是本题中的lags=12,feature_num是每项数据的属性列数量,本题中只有一个[‘Lane 1 Flow (Veh/5 Minutes)’],所以为1,rnn_units即RNN神经元的数量。
RNN的处理过程,可以理解为,对于接受的矩阵[batch_size,time_step,feature_num]进行batch_size次操作;在每个batch的操作中,又进行time_step次计算,每次计算的是t-1时刻的状态,输出的是模型预测的t时刻的状态。比如对于每个batch:
然后LSTM的输入输出就是batch_size个这样的矩阵的拼接。
即用t0-t11这样12个时刻的状态数据,预测t13的状态,不考虑batch_size,ti时刻状态用Sti表示,投入LSTM的输入是序列[St0,St1,…,St11],而LSTM的输出是序列[pSt1,pSt2,…,pSt12]。
其中pSti代表LSTM根据输入i-1时刻的输入状态,预测的i时刻的状态。
所以对于从LSTM输出的数据,就有两种处理方法;
1.把整个输出[pSt1,pSt2,…,pSt12]后面接一层全连接层,这样的理论依据是可以包含以往数据的信息。
2.只取出最后的输出pSt12作为结果,舍弃[pSt1,pSt2,…,pSt11]
同样的损失函数的计算也就分为对[pSt1,pSt2,…,pSt12]和[St1,St2,…,St11,St12(y)]算损失函数和只对pSt12和St12(y)算损失函数。
我的代码里是直接取了pSt12作为结果,只对pSt12和St12(y)算损失函数。
#定义神经网络: feature_num=1 batch_size=128 epochs=4 time_step=12 pre_num=1 x_in=tf.placeholder(tf.float32, [None, time_step,feature_num]) y_in=tf.placeholder(tf.float32, [None, pre_num,feature_num]) batch=tf.shape(x_in)[0] #定义常量 rnn_unit=32 #hidden layer units output_size=1 lr=5e-4 #学习率 #输入层、输出层权重、偏置(relu) weights={ 'out':tf.Variable(tf.random_normal([rnn_unit,1])) } biases={ 'out':tf.Variable(tf.constant(0.1,shape=[1,])) } cell=tf.nn.rnn_cell.BasicLSTMCell(rnn_unit) init_state=cell.zero_state(batch,dtype=tf.float32) output_rnn,final_states=tf.nn.dynamic_rnn(cell, x_in,initial_state=init_state, dtype=tf.float32) #output_rnn是记录lstm每个输出节点的结果,final_states是最后一个cell的结果 output=output_rnn[:,time_step-pre_num:time_step,:] output=tf.reshape(output,[-1,rnn_unit]) w_out = weights['out'] b_out = biases['out'] pred = tf.matmul(output, w_out) + b_out loss = tf.losses.mean_squared_error(tf.reshape(pred, [-1]), tf.reshape(y_in, [-1])) #tf.reduce_mean(tf.square(tf.reshape(pred, [-1]) - tf.reshape(y_in, [-1]))) train_op = tf.train.AdamOptimizer(lr).minimize(loss)
这里主要说一下学习率的问题,学习率设高了无法通过递归下降到极值点,学习率设低了也可能会因为学习率太小而下降到局部极值点,从而成为局部最优,两种都不能产生比较好的模型:
with tf.Session() as sess: sess.run(tf.global_variables_initializer()) print('模型训练:') for i in range(epochs): for j in range(len(x_train)//batch_size): _,pre_loss=sess.run([train_op,loss],feed_dict={x_in:x_train[j*batch_size:(j+1)*batch_size],y_in:y_train[j*batch_size:(j+1)*batch_size]}) if (len(x_train) % batch_size != 0): _,pre_loss=sess.run([train_op,loss],feed_dict={x_in: x_train[(len(x_train) // batch_size) * batch_size:len(x_train)],y_in:y_train[(len(x_train) // batch_size) * batch_size:len(x_train)]}) print(i,'th epaoch,last batch:',pre_loss) print('模型预测:') resPre=[] for i in range(len(x_test)//batch_size): predList=sess.run(pred,feed_dict={x_in:x_test[i*batch_size:(i+1)*batch_size]}) for j in predList: resPre.append(j[0]); if (len(x_test)%batch_size!=0): predList=sess.run(pred,feed_dict={x_in:x_test[(len(x_test)//batch_size)*batch_size:len(x_test)]}) for j in predList: resPre.append(j[0]); accRes=[] for i in y_test:accRes.append(i[0][0]) resPre=np.array(resPre) accRes=np.array(accRes) print(sess.run(tf.losses.mean_squared_error(resPre, accRes))) plt.plot(list(range(len(accRes))), accRes, color='b') plt.plot(list(range(len(resPre))), resPre, color='r') plt.show()
没太多的调参,均方差0.0027658767:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。