<>1. RNN实现股票预测
* 数据源:使用tushare模块下载的SH600519贵州茅台的日k线数据,只用该数据的C列数据,用连续60天的开盘价预测第61天的开盘价。
* 源码:p37_tushare.py import tushare as ts import matplotlib.pyplot as plt df1 =
ts.get_k_data('600519', ktype='D', start='2010-04-26', end='2020-04-26')
datapath1= "./SH600519.csv" df1.to_csv(datapath1)
<>2. LSTM
传统RNN可以通过记忆体实现短期记忆,进行连续数据的预测。但是当连续数据的序列变长时,会随展开时间步变长,在反向传播更新参数时,梯度要按照时间步连续相乘,对导致梯度消失。针对这个问题,Hochreitere等人在1997年提出了LSTM:
Hochreiter S , Schmidhuber J . Long Short-Term Memory[J]. Neural computation,
1997, 9(8):1735-1780.
<>1)三个门限
三个门限都是当前时刻的输入特征 x t x_t xt和上一时刻的短期记忆 h t − 1 h_{t-1} ht−1的函数。这三个公式中 W i , W
f 和 W o W_i, W_f和W_oWi,Wf和Wo是待训练参数矩阵, b i , b f 和 b o b_i, b_f和b_o bi,bf和bo
是待训练偏置项。他们都经过sigmoid激活函数,使门限的范围在0-1之间。
* 输入门(门限): i t = σ ( W t ⋅ [ h t − 1 , x t ] + b i ) i_t=\sigma(W_t·[h_{t-1},
x_t]+b_i)it=σ(Wt⋅[ht−1,xt]+bi)
* 遗忘门(门限): f t = σ ( W f ⋅ [ h t − 1 , x t ] + b f ) f_t=\sigma(W_f·[h_{t-1},
x_t]+b_f)ft=σ(Wf⋅[ht−1,xt]+bf)
* 输出门(门限): o t = σ ( W o ⋅ [ h t − 1 , x t ] + b o ) o_t=\sigma(W_o·[h_{t-1},
x_t]+b_o)ot=σ(Wo⋅[ht−1,xt]+bo)
<>2)细胞态(长期记忆)
* 你脑中记忆的是今天ppt第一页到第45页的长期记忆 C t C_t Ct
,它由两部分组成第一部分是ppt第一页到第44页的内容,也就是上一时刻的长期记忆 C t − 1 C_{t-1} Ct−1
,但你不可能一字不差的记住全部内容,会不自觉的忘掉一些,所以上个时刻的长期记忆 C t − 1 C_{t-1} Ct−1
要乘以遗忘门,该乘积项表示留存在你脑海中的对过去的记忆。
* 我现在讲的内容是新知识,是即将存入你脑中的现在的记忆。现在的记忆由两部分组成,一部分是我正在讲的第45页ppt,是当前时刻的输入 x t x_t xt
,还有一部分是第44页ppt的短期记忆留存,是上一时刻的短期记忆 h t − 1 h_{t-1} ht−1。你的脑袋把当前时刻的输入 x t x_t xt
和上一时刻的短期记忆 h t − 1 h_{t-1} ht−1归纳形成即将存入你脑中的现在的记忆 C t C_t Ct波浪号。
* 现在的记忆 C t C_t Ct波浪号乘以输入门与过去记忆一同存储为长期记忆。
* 细胞态(长期记忆): C t = f f + C t − 1 + i t ∗ C ~ t C_t=f_f+C_{t-1}+i_t*\widetilde
C_tCt=ff+Ct−1+it∗C t
* 记忆体(短期记忆): h t = o t ∗ t a n h ( C t ) h_t=o_t*tanh(C_t) ht=ot∗tanh(Ct)
* 候选态(归纳出的新知识): C ~ t = t a n h ( W c ⋅ [ h t − 1 , x t ] + b c ) \widetilde
C_t=tanh(W_c·[h_{t-1}, x_t]+b_c)C t=tanh(Wc⋅[ht−1,xt]+bc)
<>3)记忆体(短期记忆)
* 当你把这一讲复述给你朋友时,你不可能一直不差的讲出来,你讲的是存在你脑中的长期记忆,经过输出们筛选后的内容,这就是记忆体的输出 h t h_t ht。
* 当有多层循环网络时,第二层循环网络的输入 x t x_t xt就是第一层循环网络的输出 h t h_t ht
。输入第二层网络的是第一层网络提取的精华。
*
举例来说:我现在扮演的就是第一层循环网络,每一页ppt我都是从一篇一篇论文中提取出的精华输出给你。作为第二层循环网络的你接收到的数据是我的长期记忆过的tanh激活函数,再乘以输出门提取出的短期记忆
h t h_tht。
* 记忆体(短期记忆): h t = o t ∗ t a n h ( C t ) h_t=o_t*tanh(C_t) ht=ot∗tanh(Ct)
<>4)tensorflow描述LSTM层
tf.keras.layers.LSTM(记忆体个数, return_sequences=是否返回输出) return_sequences = True #
各时间步输出ht return_sequences = False # 仅在最后时间步输出ht(默认) model = tf.keras.Sequential(
[ LSTM(80, return_sequences=True), Dropout(0.2), LSTM(100), Dropout(0.2), Dense(
1) ])
<>3. GRU
* 在2014年cho等人简化了LSTM结构,GRU使记忆体 h t h_t ht融合了长期记忆和短期记忆。
Cho K , Van Merrienboer B , Gulcehre C , et al. Learning Phrase
Representations using RNN Encoder-Decoder for Statistical Machine
Translation[J]. Computer Science, 2014.
h t h_t ht包含了过去信息 h t − 1 h_{t-1} ht−1和现在信息 h t h_t ht波浪号。现在信息是过去信息 h t −
1 h_{t-1}ht−1过重置门与当前输入共同决定,两个门限的取值范围也是0到1之间。前向传播时直接使用这个记忆体更新公式,就可以算出每个时刻的 h t
h_tht值了。
* tensorflow描述GRU层 tf.keras.layers.GRU(记忆体个数, return_sequences=是否返回输出)
return_sequences= True # 各时间步输出ht return_sequences = False # 仅在最后时间步输出ht(默认)
model= tf.keras.Sequential([ GRU(80, return_sequences=True), Dropout(0.2), GRU(
100), Dropout(0.2), Dense(1) ])