# 教你从零开始在 TensorFlow 上搭建 RNN（完整代码）！

RNN 处理系列数据的过程图解

## 设置

1. from __future__ import print_function, division
2. import numpy as np
3. import tensorflow as tf
4. import matplotlib.pyplot as plt
5. num_epochs = 100
6. total_series_length = 50000
7. truncated_backprop_length = 15
8. state_size = 4
9. num_classes = 2
10. echo_step = 3
11. batch_size = 5
12. num_batches = total_series_length//batch_size//truncated_backprop_length

## 生成数据

1. def generateData():
2. x = np.array(np.random.choice(2, total_series_length, p=[0.5, 0.5]))
3. y = np.roll(x, echo_step)
4. y[0:echo_step] = 0
5. x = x.reshape((batch_size, -1)) # The first index changing slowest, subseries as rows
6. y = y.reshape((batch_size, -1))
7. return (x, y)

## 创建计算图

TensorFlow 的工作方式会首先创建一个计算图，来确认哪些操作需要完成。计算图的输入和输出一般是多维阵列，即张量（tensor）。计算图或其中一部分，将被迭代执行。这既可以在 CPU、GPU，也可在远程服务器上执行。

## 变量和 placeholder

1. batchX_placeholder = tf.placeholder(tf.float32, [batch_size, truncated_backprop_length])
2. batchY_placeholder = tf.placeholder(tf.int32, [batch_size, truncated_backprop_length])
3. init_state = tf.placeholder(tf.float32, [batch_size, state_size])

1. W = tf.Variable(np.random.rand(state_size+1, state_size), dtype=tf.float32)
2. b = tf.Variable(np.zeros((1,state_size)), dtype=tf.float32)
3. W2 = tf.Variable(np.random.rand(state_size, num_classes),dtype=tf.float32)
4. b2 = tf.Variable(np.zeros((1,num_classes)), dtype=tf.float32)

## Unpacking

1. # Unpack columns
2. inputs_series = tf.unpack(batchX_placeholder, axis=1)
3. labels_series = tf.unpack(batchY_placeholder, axis=1)

## Forward pass

1. # Forward pass
2. current_state = init_state
3. states_series = []
4. for current_input in inputs_series:
5. current_input = tf.reshape(current_input, [batch_size, 1])
6. input_and_state_concatenated = tf.concat(1, [current_input, current_state]) # Increasing number of columns
7. next_state = tf.tanh(tf.matmul(input_and_state_concatenated, W) + b) # Broadcasted addition
8. states_series.append(next_state)
9. current_state = next_state

## 计算损失

1. logits_series = [tf.matmul(state, W2) + b2 for state in states_series] #Broadcasted addition
2. predictions_series = [tf.nn.softmax(logits) for logits in logits_series]
3. losses = [tf.nn.sparse_softmax_cross_entropy_with_logits(logits, labels) for logits, labels in zip(logits_series,labels_series)]
4. total_loss = tf.reduce_mean(losses)

## 训练可视化

1. def plot(loss_list, predictions_series, batchX, batchY):
2. plt.subplot(2, 3, 1)
3. plt.cla()
4. plt.plot(loss_list)
5. for batch_series_idx in range(5):
6. one_hot_output_series = np.array(predictions_series)[:, batch_series_idx, :]
7. single_output_series = np.array([(1 if out[0] < 0.5 else 0) for out in one_hot_output_series])
8. plt.subplot(2, 3, batch_series_idx + 2)
9. plt.cla()
10. plt.axis([0, truncated_backprop_length, 0, 2])
11. left_offset = range(truncated_backprop_length)
12. plt.bar(left_offset, batchX[batch_series_idx, :], width=1, color="blue")
13. plt.bar(left_offset, batchY[batch_series_idx, :] * 0.5, width=1, color="red")
14. plt.bar(left_offset, single_output_series * 0.3, width=1, color="green")
15. plt.draw()
16. plt.pause(0.0001)

## 运行训练环节

1. with tf.Session() as sess:
2. sess.run(tf.initialize_all_variables())
3. plt.ion()
4. plt.figure()
5. plt.show()
6. loss_list = []
7. for epoch_idx in range(num_epochs):
8. x,y = generateData()
9. _current_state = np.zeros((batch_size, state_size))
10. print("New data, epoch", epoch_idx)
11. for batch_idx in range(num_batches):
12. start_idx = batch_idx * truncated_backprop_length
13. end_idx = start_idx + truncated_backprop_length
14. batchX = x[:,start_idx:end_idx]
15. batchY = y[:,start_idx:end_idx]
16. _total_loss, _train_step, _current_state, _predictions_series = sess.run(
17. [total_loss, train_step, current_state, predictions_series],
18. feed_dict={
19. batchX_placeholder:batchX,
20. batchY_placeholder:batchY,
21. init_state:_current_state
22. })
23. loss_list.append(_total_loss)
24. if batch_idx%100 == 0:
25. print("Step",batch_idx, "Loss", _total_loss)
26. plot(loss_list, _predictions_series, batchX, batchY)
27. plt.ioff()
28. plt.show()

AI 研习社提醒，这只是一个解释 RNN 工作原理的简单例子，该功能可以很容易地用几行代码编写出来。该神经网络将能够准确地学习 echo 行为，所以没有必要用测试数据。

## 整个系统

1. from __future__ import print_function, division
2. import numpy as np
3. import tensorflow as tf
4. import matplotlib.pyplot as plt
5. num_epochs = 100
6. total_series_length = 50000
7. truncated_backprop_length = 15
8. state_size = 4
9. num_classes = 2
10. echo_step = 3
11. batch_size = 5
12. num_batches = total_series_length//batch_size//truncated_backprop_length
13. def generateData():
14. x = np.array(np.random.choice(2, total_series_length, p=[0.5, 0.5]))
15. y = np.roll(x, echo_step)
16. y[0:echo_step] = 0
17. x = x.reshape((batch_size, -1)) # The first index changing slowest, subseries as rows
18. y = y.reshape((batch_size, -1))
19. return (x, y)
20. batchX_placeholder = tf.placeholder(tf.float32, [batch_size, truncated_backprop_length])
21. batchY_placeholder = tf.placeholder(tf.int32, [batch_size, truncated_backprop_length])
22. init_state = tf.placeholder(tf.float32, [batch_size, state_size])
23. W = tf.Variable(np.random.rand(state_size+1, state_size), dtype=tf.float32)
24. b = tf.Variable(np.zeros((1,state_size)), dtype=tf.float32)
25. W2 = tf.Variable(np.random.rand(state_size, num_classes),dtype=tf.float32)
26. b2 = tf.Variable(np.zeros((1,num_classes)), dtype=tf.float32)
27. # Unpack columns
28. inputs_series = tf.unpack(batchX_placeholder, axis=1)
29. labels_series = tf.unpack(batchY_placeholder, axis=1)
30. # Forward pass
31. current_state = init_state
32. states_series = []
33. for current_input in inputs_series:
34. current_input = tf.reshape(current_input, [batch_size, 1])
35. input_and_state_concatenated = tf.concat(1, [current_input, current_state]) # Increasing number of columns
36. next_state = tf.tanh(tf.matmul(input_and_state_concatenated, W) + b) # Broadcasted addition
37. states_series.append(next_state)
38. current_state = next_state
39. logits_series = [tf.matmul(state, W2) + b2 for state in states_series] #Broadcasted addition
40. predictions_series = [tf.nn.softmax(logits) for logits in logits_series]
41. losses = [tf.nn.sparse_softmax_cross_entropy_with_logits(logits, labels) for logits, labels in zip(logits_series,labels_series)]
42. total_loss = tf.reduce_mean(losses)
44. def plot(loss_list, predictions_series, batchX, batchY):
45. plt.subplot(2, 3, 1)
46. plt.cla()
47. plt.plot(loss_list)
48. for batch_series_idx in range(5):
49. one_hot_output_series = np.array(predictions_series)[:, batch_series_idx, :]
50. single_output_series = np.array([(1 if out[0] < 0.5 else 0) for out in one_hot_output_series])
51. plt.subplot(2, 3, batch_series_idx + 2)
52. plt.cla()
53. plt.axis([0, truncated_backprop_length, 0, 2])
54. left_offset = range(truncated_backprop_length)
55. plt.bar(left_offset, batchX[batch_series_idx, :], width=1, color="blue")
56. plt.bar(left_offset, batchY[batch_series_idx, :] * 0.5, width=1, color="red")
57. plt.bar(left_offset, single_output_series * 0.3, width=1, color="green")
58. plt.draw()
59. plt.pause(0.0001)
60. with tf.Session() as sess:
61. sess.run(tf.initialize_all_variables())
62. plt.ion()
63. plt.figure()
64. plt.show()
65. loss_list = []
66. for epoch_idx in range(num_epochs):
67. x,y = generateData()
68. _current_state = np.zeros((batch_size, state_size))
69. print("New data, epoch", epoch_idx)
70. for batch_idx in range(num_batches):
71. start_idx = batch_idx * truncated_backprop_length
72. end_idx = start_idx + truncated_backprop_length
73. batchX = x[:,start_idx:end_idx]
74. batchY = y[:,start_idx:end_idx]
75. _total_loss, _train_step, _current_state, _predictions_series = sess.run(
76. [total_loss, train_step, current_state, predictions_series],
77. feed_dict={
78. batchX_placeholder:batchX,
79. batchY_placeholder:batchY,
80. init_state:_current_state
81. })
82. loss_list.append(_total_loss)
83. if batch_idx%100 == 0:
84. print("Step",batch_idx, "Loss", _total_loss)
85. plot(loss_list, _predictions_series, batchX, batchY)
86. plt.ioff()
87. plt.show()

via medium，原作者 Erik Hallström，雷锋网编译

1607 篇文章140 人订阅

0 条评论

## 相关文章

12420

47150

343110

21610

16330

### 如何在Python中用LSTM网络进行时间序列预测

Matt MacGillivray 拍摄，保留部分权利 翻译 | AI科技大本营（rgznai100） 长短记忆型递归神经网络拥有学习长观察值序列的潜力。它似...

1.2K40

15000

### Python：SMOTE算法

17.11.28更新一下：最近把这个算法集成到了数据预处理的python工程代码中了，不想看原理想直接用的，有简易版的python开发：特征工程代码模版 ，进...

35040

49140

40580