这是一个用来练习tensonflow的repo。数据集是一组空气数据,详见下面的数据介绍,目标是24小时之后的三种污染物的浓度,输入是三个城市每个城市12个数据项,共71小时的历史数据(71*(12*3))。目标是使用71小时,三个城市的历史数据,预测24小时后北京的三种空气污染物的情况。
需要写代码位于MLP_placeholder.py。
现在我们的数据集的形状:Target是(14208,3),Data是 (14208,71,36)
这代表着我们有14208组训练数据,训练的目标有三个,而每一个训练数据的样例的维度是71*36.
首先我们需要构建一个71*36的Placeholder用于送入输入数据,以及一个3维的Placeholder作为输出数据。
利用tf.Reshape把每一个训练数据进行Reshape,将71*36转变成2556维的一个Tensor。
同时构建一个多层感知器网络MLP,并定义优化器(optimizer),损失函数(cost),以及准确率的计算方式(accuracy,平均方差,或者平均绝对差,或者对数方差等)。MLP具体做法可以参考网络博客,而优化器可以使用SGD,cost需要使用tf.reduce_mean等函数,可以从官网上查到使用方法。
初始化所有变量后,可以使用:
with tf.Session() as sess:
sess.run(init)
for epoch in range(training_epochs):
for i in range(total_batch):
_, c = sess.run([optimizer,cost],feed_dict={_X: Something,Y:Something])
avg_cost += c / total_batch
开始训练。
外层循环叫做epoch,为训练的次数,内层循环遍历所有的训练样例(在此情况下14208个)
测试时可以使用测试集,计算自己指定的表示准确率的数值(accuracy)
acc = accuracy.eval({x: X_test, y: y_test})
P.S. 这种做法我没有测试过标准结果,由于数据集分割问题,训练一开始有可能会出现测试集准确率高于训练集的情况。
###LSTM记忆网络 大家已经看过了多层感知器网络,这种网络我们可以吧所有的历史信息(在这个样例里面71小时的信息)一股脑的送到神经网络中,期望他固定的给我们一个结果。然而在真实的情况下,
- 一方面我们希望我们训练出一个模型之后不仅能接收71小时的数据,同时还能接收100小时的数据,还能接受1000小时的数据
- 另一方面,之前的网络在感知之后,信息就消逝了,并没有能保留在网络之中,有时候历史上的信息对现在的训练也是会产生影响的。
为了解决上面这两个问题,人们简单的想:那我直接把输出的结果再送回输入
不就好啦,这就是最简单的RNN的雏形。
这就是一个RNN Cell按照时间展开的示意图
但是不幸的是,这样的方式网络的记忆力并不是这么好长期信息丢失的很厉害,所以就有了LSTM(LSTM有很多变体,GRU是最常见的一种).
我们在Tensorflow中并不需要自己实现LSTM,
from tensorflow.contrib import rnn
之后可以直接调用:
lstm_cell = rnn.LSTMCell(num_units=hidden_size,
forget_bias=1.0,
state_is_tuple=True, time_major=False)
LSTM由于我传给他的是一个序列,是一个Seq2Seq 即 序列对序列的训练过程。我把连续的(假如)100个小时的数据送入神经网络,每当我送入一小时的数据,我期望LSTM网络输出24小时后的数据。即送入0,输出24,送入1,输出25······送入100,输出124.所以输入的状态应该是(71,36),即我每一组的输入有71个小时,每小时有36个数据项。输出应该为(71,1)即每送入一小时的数据(36),网络就会输出一个数据。
在Saver_Class.py
文件中,h_state
变量是所有lstm Cell的最后一个时间下的输出(-1,36),我将最后一个时间片的一共hidden_size(256)个输出通过矩阵乘法,转变为output_parameters(3)。这样我只取了LSTM每一个Cell输出(71,1)的最后一个,一共256个,将他们通过矩阵变换,变换为我期望的3个监测污染物的输出。
- 任务:需要做的就是在文件102行的位置,通过
rnn.LSTMCell
构建自己的LSTM网络,并且通过mlstm_cell = rnn.MultiRNNCell
将多层LSTM连接起来。
参考资料:
###Saver类用于保存模型
我们不可能每一次训练都从新开始,并且我们也希望能保存下来我们训练的模型。这个时候Tensorflow提供了一个简单的方法。首先我们需要创建一个Saver
对象:
saver = tf.train.Saver()
这个对象如果在初始化时不指定内容,会自动存储所有的Variable变量。 接下来我们可以选择是每一次都保存一下还是比如训练十次保存一下。
saver.save(sess,
'你想要保存到的路径/model.ckpt',
global_step=i+1)
其中sess
是要保存的session,第二个参数是指定模型的路径以及名称,以Checkpoint(.ckpt
)为后缀,第三个参数是标志当前模型存档是第几个循环时保存得的数字。
恢复模型时,
ckpt = tf.train.get_checkpoint_state(checkpoint_dir)
if ckpt and ckpt.model_checkpoint_path:
saver.restore(sess, ckpt.model_checkpoint_path)
else:
pass
通过这样的方法就可以将ckpt文件里面的模型恢复到当前session中,注意,这里恢复的只是模型中的变量值Variable
,网络结构都不存在文件之中,所以还需要把之前构建Computation Graph的代码都运行一遍。构建出Computation Graph之后才能restore,如果尝试将一个128节点的model恢复到一个256节点的图中,Tensorflow会报错。
- 任务:在Saver Class 149行前后的位置,在训练过程中,将模型保存到models文件夹下面。
Comming soon.
Comming soon.
Comming soon.
Comming soon.
这是一个LSTM的实现,如果有疑问可以看看里面的做法,重要的代码都在这里面,数据处理以及最终的ComputationGraph的构建以及训练的代码。
其中数据位于dev_data中,这里面的每一个文件的文件名都是UNIX时间戳,每个文件中有三行数据,分别是北京天津和葫芦岛在这个时间点的空气质量数据以及天气数据。
数据列 | 内容 | 描述 |
---|---|---|
0 | RecordID | |
1 | LocatID | Location ID generated by unique latitude-longitude pairs for each monitor location |
2 | StationName | Station Name as defined by the monitor owner (might change, might not be unique) |
3 | ChName | Chinese language station name (UTF8 encoding) |
4 | Latitude | Latitude North in decimal degrees WGS84 |
5 | Longitude | Longitude East in decimal degrees WGS84 |
6 | PM2.5 | Particulate Matter 2.5 micron diameter |
7 | PM10 | Particulate Matter 10 micron diameter µg/m3 (micrograms per cubic metre) |
8 | O3 | Ozone pphm (parts per hundred million) |
9 | NO2 | NOX NitrogenDioxide pphm (parts per hundred million) |
10 | SO2 | SOX SodiumDioxide pphm (parts per hundred million) |
11 | CO | CarbonMonoxide ppm (parts per million) |
12 | Temperature | degrees Celsius |
13 | DewPoint | degrees Celsius |
14 | Pressure | millibars |
15 | Humidity | absolute humidity in grams/meter3 |
16 | Wind | km / hour |
17 | Date | |
18 | UMT_time | data collection time Greenwich Meat Time |
随便编的一个表示读取速度的进度条。似乎只有在控制台里面才能看到。
一个用来处理数据的小程序,没什么用
这才是工程本体
ㄟ( ▔, ▔ )ㄏ