#-*- codeing = utf-8 -*-
#@Time :2021/5/20 19:40
#@Author :Onion
#@File :LSTMMNISTDemo.py
#@Software :PyCharm
import tensorflow as tf
import os
from tensorflow.examples.tutorials.mnist import input_data
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
# 获取MNIST数据
# tf.disable_v2_behavior()
mnist = input_data.read_data_sets("./MNIST_data", one_hot=True)
tf.compat.v1.disable_eager_execution()
tf.compat.v1.reset_default_graph()
# MNIST数据的大小为28*28,把输入的x当成28个时间段,每段内容为28个值
# 这28个时序一次送入RNN中
n_input = 28 # 序列的长度(时间段)
n_steps = 28 # 序列的个数
n_hidden = 128 # 隐藏层的个数(128个cell)
n_classes = 10 # MNIST的输出为10个数,(0~9)表示分类
# 参数设置
learning_rate = 0.001
training_iters = 100000
batch_size = 128
display_step = 10
# 定义占位符
X = tf.compat.v1.placeholder("float",[None,n_steps,n_input])
Y = tf.compat.v1.placeholder("float",[None,n_classes])
# 使用unstack将原始的输入28*28调整成具有28个元素的list,每个元素为1*28的数组
X1 = tf.unstack(X, n_steps, 1)
# 构建LSTM网络
# num_units 表示LSTM单元中的单位数,即Cell的个数
# RNN以前是非常难以训练的, 因为随时间传递的状态C如果有一个小的误差delta, 这个误差会在传递的过程中指数级别增加或者减少, 造成输出爆炸(Explosion)或者消失(Vanish)LSTM的forget GATE就是解决这个问题用的. 刚开始初始化成1, LSTM不会传递任何状态C, 因为forget GATE把C归零了. 这避免了刚开始训练就有输出爆炸或者消失的问题.
lstm_cell = tf.compat.v1.nn.rnn_cell.BasicLSTMCell(num_units=n_hidden,forget_bias=1.0)
# 输出
outputs,states = tf.compat.v1.nn.static_rnn(lstm_cell,X1,dtype=tf.float32)
# 全连接函数dense,将LSTM的Cell层的输出做一次全连接,并将激活函数设置为None表示线性激活
# 全连接层之前的作用是提取特征、分类
# 全连接层的每一个结点都与上一层的所有结点相连,用来把前边提取到的特征综合起来。
pred = tf.compat.v1.layers.dense(outputs[-1],n_classes,activation=None)
# 损失函数,(输出值与Y标签之间的损失值)
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=pred,labels=Y))
# 优化器
optimizer = tf.compat.v1.train.AdamOptimizer(learning_rate=learning_rate).minimize(loss)
# 计算平均错误率
correct_prediction = tf.equal(tf.argmax(pred,1), tf.argmax(Y,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
init = tf.compat.v1.global_variables_initializer()
with tf.compat.v1.Session() as sess:
sess.run(init)
step = 1
# Keep training until reach max iterations
while step * batch_size < training_iters:
batch_x, batch_y = mnist.train.next_batch(batch_size)
# Reshape data to get 28 seq of 28 elements
batch_x = batch_x.reshape((batch_size, n_steps, n_input))
# Run optimization op (backprop)
sess.run(optimizer, feed_dict={X: batch_x, Y: batch_y})
if step % display_step == 0:
# 计算批次数据的准确率
acc = sess.run(accuracy, feed_dict={X: batch_x, Y: batch_y})
# Calculate batch loss
# 这里返回值不可以用loss来命名变量,因为计算loss的时候必须是一个Tensor,如果把loss改了,返回的就是一个float,会报错
newloss = sess.run(loss, feed_dict={X: batch_x, Y: batch_y})
print ("Iter " + str(step*batch_size) + ", Minibatch Loss= " + \
"{:.5f}".format(newloss) + ", Training Accuracy= " + \
"{:.5f}".format(acc))
step += 1
print (" Finished!")
# 计算准确率 for 128 mnist test images
test_len = 128
test_data = mnist.test.images[:test_len].reshape((-1, n_steps, n_input))
test_label = mnist.test.labels[:test_len]
print ("Testing Accuracy:", \
sess.run(accuracy, feed_dict={X: test_data, Y: test_label}))
多层的也很简单,在单层的基础上用tf.compat.v1.nn.rnn_cell.MultiRNNCell([lstm_cell]*hidden_layer_nums)
就可以完成多层LSTM网络的构建了
#-*- codeing = utf-8 -*-
#@Time :2021/5/21 0:31
#@Author :Onion
#@File :MultiLSTMMNISTDemo.py
#@Software :PyCharm
import tensorflow as tf
import os
from tensorflow.examples.tutorials.mnist import input_data
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
# 获取MNIST数据
# tf.disable_v2_behavior()
mnist = input_data.read_data_sets("./MNIST_data", one_hot=True)
tf.compat.v1.disable_eager_execution()
tf.compat.v1.reset_default_graph()
# MNIST数据的大小为28*28,把输入的x当成28个时间段,每段内容为28个值
# 这28个时序一次送入RNN中
n_input = 28 # 序列的长度(时间段)
n_steps = 28 # 序列的个数
n_hidden = 128 # 单个隐藏层的cell的个数(128个cell)
n_classes = 10 # MNIST的输出为10个数,(0~9)表示分类
hidden_layer_nums = 3# 三层LSTM网络
# 参数设置
learning_rate = 0.001
training_iters = 100000
batch_size = 128 # 每一批128张图片
display_step = 10 # 每训练10次打印一次结果
# 定义占位符
X = tf.compat.v1.placeholder("float",[None,n_steps,n_input])
Y = tf.compat.v1.placeholder("float",[None,n_classes])
# 使用unstack将原始的输入28*28调整成具有28个元素的list,每个元素为1*28的数组
X1 = tf.unstack(X, n_steps, 1)
# 构建LSTM网络
# num_units 表示LSTM单元中的单位数,即Cell的个数
# RNN以前是非常难以训练的, 因为随时间传递的状态C如果有一个小的误差delta, 这个误差会在传递的过程中指数级别增加或者减少, 造成输出爆炸(Explosion)或者消失(Vanish)LSTM的forget GATE就是解决这个问题用的. 刚开始初始化成1, LSTM不会传递任何状态C, 因为forget GATE把C归零了. 这避免了刚开始训练就有输出爆炸或者消失的问题.
lstm_cell = tf.compat.v1.nn.rnn_cell.BasicLSTMCell(num_units=n_hidden,forget_bias=1.0)
# 构建3层LSTM网络
lstm_cells = tf.compat.v1.nn.rnn_cell.MultiRNNCell([lstm_cell]*hidden_layer_nums)
# 输出
outputs,states = tf.compat.v1.nn.static_rnn(lstm_cells,X1,dtype=tf.float32)
# 全连接函数dense,将LSTM的Cell层的输出做一次全连接,并将激活函数设置为None表示线性激活
# 全连接层之前的作用是提取特征、分类
# 全连接层的每一个结点都与上一层的所有结点相连,用来把前边提取到的特征综合起来。
pred = tf.compat.v1.layers.dense(outputs[-1],n_classes,activation=None)
# 损失函数,(输出值与Y标签之间的损失值)
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=pred,labels=Y))
# 优化器
optimizer = tf.compat.v1.train.AdamOptimizer(learning_rate=learning_rate).minimize(loss)
# 计算平均错误率
# 【Tensorflow】 tf.equal(tf.argmax(y, 1),tf.argmax(y_, 1))用法
# 作用:输出正确的预测结果
# 利用tf.argmax()按行求出真实值y_、预测值y最大值的下标,用tf.equal()求出真实值和预测值相等的数量,也就是预测结果正确的数量,tf.argmax()和tf.equal()一般是结合着用
correct_prediction = tf.equal(tf.argmax(pred,1), tf.argmax(Y,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
init = tf.compat.v1.global_variables_initializer()
with tf.compat.v1.Session() as sess:
sess.run(init)
step = 1
# Keep training until reach max iterations
while step * batch_size < training_iters:
batch_x, batch_y = mnist.train.next_batch(batch_size)
# Reshape data to get 28 seq of 28 elements
batch_x = batch_x.reshape((batch_size, n_steps, n_input))
# Run optimization op (backprop)
# 在run执行的时候,内部做了128次运算,每一次取batch_x(128)个中的一个,传入X,并unpack成X1,,做这样的运算在内部进行了128次
sess.run(optimizer, feed_dict={X: batch_x, Y: batch_y})
if step % display_step == 0:
# 计算批次数据的准确率
acc = sess.run(accuracy, feed_dict={X: batch_x, Y: batch_y})
# Calculate batch loss
# 这里返回值不可以用loss来命名变量,因为计算loss的时候必须是一个Tensor,如果把loss改了,返回的就是一个float,会报错
newloss = sess.run(loss, feed_dict={X: batch_x, Y: batch_y})
print ("Iter " + str(step*batch_size) + ", Minibatch Loss= " + \
"{:.5f}".format(newloss) + ", Training Accuracy= " + \
"{:.5f}".format(acc))
step += 1
print (" Finished!")
# 计算准确率 for 128 mnist test images
test_len = 128
test_data = mnist.test.images[:test_len].reshape((-1, n_steps, n_input))
test_label = mnist.test.labels[:test_len]
print ("Testing Accuracy:", \
sess.run(accuracy, feed_dict={X: test_data, Y: test_label}))
当然,还可以将单层的GRU网络和多层的LSTM网络连接起来构成一个多层的RNN网络
#-*- codeing = utf-8 -*-
#@Time :2021/5/21 0:56
#@Author :Onion
#@File :MixRNNDemo.py
#@Software :PyCharm
#-*- codeing = utf-8 -*-
#@Time :2021/5/20 19:40
#@Author :Onion
#@File :LSTMMNISTDemo.py
#@Software :PyCharm
# 构建GRU和LSTM混合的网络
import tensorflow as tf
import os
from tensorflow.examples.tutorials.mnist import input_data
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
# 获取MNIST数据
# tf.disable_v2_behavior()
mnist = input_data.read_data_sets("./MNIST_data", one_hot=True)
tf.compat.v1.disable_eager_execution()
tf.compat.v1.reset_default_graph()
# MNIST数据的大小为28*28,把输入的x当成28个时间段,每段内容为28个值
# 这28个时序一次送入RNN中
n_input = 28 # 序列的长度(时间段)
n_steps = 28 # 序列的个数
n_hidden = 128 # 隐藏层的cell的个数(128个cell)
n_classes = 10 # MNIST的输出为10个数,(0~9)表示分类
# 参数设置
learning_rate = 0.001
training_iters = 100000
batch_size = 128 # 每一批128张图片
display_step = 10 # 每训练10次打印一次结果
hidden_layer_nums =3
# 定义占位符
X = tf.compat.v1.placeholder("float",[None,n_steps,n_input])
Y = tf.compat.v1.placeholder("float",[None,n_classes])
# 使用unstack将原始的输入28*28调整成具有28个元素的list,每个元素为1*28的数组
X1 = tf.unstack(X, n_steps, 1)
# 构建单层GRU网络
gru_cell = tf.compat.v1.nn.rnn_cell.GRUCell(num_units=n_hidden*2)
# 构建3层LSTM网络
# num_units 表示LSTM单元中的单位数,即Cell的个数
# RNN以前是非常难以训练的, 因为随时间传递的状态C如果有一个小的误差delta, 这个误差会在传递的过程中指数级别增加或者减少, 造成输出爆炸(Explosion)或者消失(Vanish)LSTM的forget GATE就是解决这个问题用的. 刚开始初始化成1, LSTM不会传递任何状态C, 因为forget GATE把C归零了. 这避免了刚开始训练就有输出爆炸或者消失的问题.
lstm_cell = tf.compat.v1.nn.rnn_cell.BasicLSTMCell(num_units=n_hidden,forget_bias=1.0)
lstm_cells = tf.compat.v1.nn.rnn_cell.MultiRNNCell([lstm_cell]*hidden_layer_nums)
# 将3层LSTM网络和单层的GRU网络连接成一个4层的RNN网络
RNN_cells = tf.compat.v1.nn.rnn_cell.MultiRNNCell([lstm_cells.gru])
# 输出
outputs,states = tf.compat.v1.nn.static_rnn(lstm_cell,X1,dtype=tf.float32)
# 全连接函数dense,将LSTM的Cell层的输出做一次全连接,并将激活函数设置为None表示线性激活
# 全连接层之前的作用是提取特征、分类
# 全连接层的每一个结点都与上一层的所有结点相连,用来把前边提取到的特征综合起来。
pred = tf.compat.v1.layers.dense(outputs[-1],n_classes,activation=None)
# 损失函数,(输出值与Y标签之间的损失值)
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=pred,labels=Y))
# 优化器
optimizer = tf.compat.v1.train.AdamOptimizer(learning_rate=learning_rate).minimize(loss)
# 计算平均错误率
# 【Tensorflow】 tf.equal(tf.argmax(y, 1),tf.argmax(y_, 1))用法
# 作用:输出正确的预测结果
# 利用tf.argmax()按行求出真实值y_、预测值y最大值的下标,用tf.equal()求出真实值和预测值相等的数量,也就是预测结果正确的数量,tf.argmax()和tf.equal()一般是结合着用
correct_prediction = tf.equal(tf.argmax(pred,1), tf.argmax(Y,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
init = tf.compat.v1.global_variables_initializer()
with tf.compat.v1.Session() as sess:
sess.run(init)
step = 1
# Keep training until reach max iterations
while step * batch_size < training_iters:
batch_x, batch_y = mnist.train.next_batch(batch_size)
# Reshape data to get 28 seq of 28 elements
batch_x = batch_x.reshape((batch_size, n_steps, n_input))
# Run optimization op (backprop)
# 在run执行的时候,内部做了128次运算,每一次取batch_x(128)个中的一个,传入X,并unpack成X1,,做这样的运算在内部进行了128次
sess.run(optimizer, feed_dict={X: batch_x, Y: batch_y})
if step % display_step == 0:
# 计算批次数据的准确率
acc = sess.run(accuracy, feed_dict={X: batch_x, Y: batch_y})
# Calculate batch loss
# 这里返回值不可以用loss来命名变量,因为计算loss的时候必须是一个Tensor,如果把loss改了,返回的就是一个float,会报错
newloss = sess.run(loss, feed_dict={X: batch_x, Y: batch_y})
print ("Iter " + str(step*batch_size) + ", Minibatch Loss= " + \
"{:.5f}".format(newloss) + ", Training Accuracy= " + \
"{:.5f}".format(acc))
step += 1
print (" Finished!")
# 计算准确率 for 128 mnist test images
test_len = 128
test_data = mnist.test.images[:test_len].reshape((-1, n_steps, n_input))
test_label = mnist.test.labels[:test_len]
print ("Testing Accuracy:", \
sess.run(accuracy, feed_dict={X: test_data, Y: test_label}))