Rnn最大的不同是,它有 状态(State
)
相对于普通的神经网络和算法
如何体现State
的不同呢?
我们现在有这样一个需求:
我一次又一次的输入一些值,
我希望在我每次输入的时候,
我的程序会输出我之前 倒数第3次时的输入的值
比如,
我输入 1 2 3 4 5 6 7 8 (一次 输入 一个)
它输出 - - - 1 2 3 4 5
然后我又输入 5 4 3 2 1 0
然后它的输出 6 7 8 5 4 3
引入需要的库
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
一 生成数据
函数generateData随机生成了5w个由0和1组成的序列,
然后把x分成5份,变成一个5行,10000列的二维数组,
y也是一样,不过y中的项全部向右位移了3位
total_series_length = 50000 #总共有5万个数让Rnn训练
truncated_backprop_length = 15 #某种限制的长度为15,之后会用到
batch_size = 5 #把数据分成5份
echo_step = 3 #位移的大小
def generateData():
# 1.返回一个 total_series_length 长度的数组
# 2.返回数组中的每一项,都是从 0 1 中随机选出的(第一个参数的含义)
# 3.选0和选1的概率分别为0.5和0.5
x = np.random.choice(2, total_series_length, p=[0.5, 0.5])
# 整体向右移动echo_step个数,超出的补在前面
y = np.roll(x, echo_step)
# 从后面补到前面的项都设置为0
y[0:echo_step] = 0
# 把x(长度为50000)变成一个5行,10000列的数组
x = x.reshape((batch_size, -1)) # -1 表示自动计算出column的数量
y = y.reshape((batch_size, -1))
return (x, y)
二 构造输入序列
truncated_backprop_length = 15 #某种限制的长度为15,之后会用到
batch_size = 5 #把数据分成5份
# 定义两个placeholder, 数据的结构为(5,15)的二维数组
# 注意,虽然placeholder没有输入实际的值,但是我们已经把定了了数据结构
batchX_placeholder = tf.placeholder(tf.float32, [batch_size, truncated_backprop_length])
batchY_placeholder = tf.placeholder(tf.int32, [batch_size, truncated_backprop_length])
# 之后会把第一部分生成的5行10000列的数据,撕成一片一片的,
# 每片长度15列(行数不变,5x15), 喂给placeholder
# 按列解包,你可以理解成转置,(变成15x5了)
# 但是要注意的是:
# 现在inputs_series是一个长度为15的list,list中的每一项是一个长度为5的array
inputs_series = tf.unstack(batchX_placeholder, axis=1)
labels_series = tf.unstack(batchY_placeholder, axis=1)
# 为什么把数据倒来倒去,看得人都是晕的
# unstack的目的是,
# 你可以理解那5行10000列的数据(现在是5行15列),当成5根并列的葱,
# 然后一刀切下去,
三 构造状态序列, 吸收新的input
input 和 原来的state 通过W和b融合之后形成了新的state
# 这是state每次吸收新的input的时候 用到的权重
W = tf.Variable(np.random.rand(state_size+1, state_size), dtype=tf.float32)
b = tf.Variable(np.zeros((1