import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
import pandas as pd
#导入mnist数据
mnist = pd.read_data_sets("data/", one_hot=True)#one_hot=True 表示 数据的标签是one_hot编码的,即数据标签为1*10的数组
#读取训练数据,训练标签,测试数据,测试标签
trainimgs, trainlabels, testimgs, testlabels
= mnist.train.images, mnist.train.labels, mnist.test.images, mnist.test.labels
#获取训练数据个数,测试集数据个数,图像维度和类别数
ntrain, ntest, dim, nclasses
= trainimgs.shape[0], testimgs.shape[0], trainimgs.shape[1], trainlabels.shape[1]
#输入数据维度,没一个RNN输入一个1*28的tensor
diminput = 28
#隐藏层大小
dimhidden = 128
#输出结果的维度
dimoutput = nclasses
#一共28个RNN结构
nsteps = 28
#权重
weights = {
'hidden':tf.Variable(tf.random_normal([diminput,dimhidden])), #28*128全连接的网络参数
'out':tf.Variable(tf.random_normal([dimhidden,dimoutput])) #128*10全连接输出网格
}
#偏置
biases = {
'hidden':tf.Variable(tf.random_normal([dimhidden])),
'out':tf.Variable(tf.random_normal([dimoutput]))
}
def _RNN(_X,_W,_b,_nsteps,_name):
# 1. Permute input from [batchsize, nsteps, diminput]
# => [nsteps, batchsize, diminput]
# 因为输入的数据维度为batch_size*28*28,而每一个LSTM运算的输入为batch_size*28,因此对数据进行转换为28*16*28,即第一个块是16个图像的第一行,第二个块是16个图像的第二行,以此类推
_X = tf.transpose(_X,[1,0,2])
# 2. Reshape input to [nsteps*batchsize, diminput]
# 将数据reshape,得到(28*16)*28
_X = tf.reshape(_X,[-1,diminput])
_H = tf.matmul(_X,_W['hidden']+_b['hidden'])
# 将计算的结果进行划分,也可先划分,然后分别计算,把(28*16)*28的数据划分为
_Hsplit = tf.split(0,_nsteps,_H)
with tf.variable_scope(_name) as scope:
# 变量共享,多次创建的变量是同一个东西
scope.reuse_variables()
#创建LSTM
lstm_cell = tf.nn.rnn_cell.BasicLSTMCell(dimhidden,forget_bias=1.0)
#计算以此得到的每一次输出
_LSTM_O,_LSTM_S = tf.nn.rnn(lstm_cell,_Hsplit,dtype = tf.float32)
_O = tf.matmul(_LSTM_O[-1],_W['out'])+_b['out']
return {
'X':_X,'H':_H,'Hsplit':_Hsplit,
'LSTM_O':_LSTM_O,'LSTM_S':_LSTM_S,'O':_O
}
#设置优化算法和损失函数
#学习率
learning_rate = 0.001
#训练集输入数据与标记
x = tf.placeholder('float',[None,nsteps,diminput])
y = tf.placeholder('float',[None,dimoutput])
#定义RNN
myrnn = _RNN(x,weights,biases,nsteps,'basic')
#预测结果是myrnn['O']中最后一个
pred = myrnn['O']
#损失函数交叉熵
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(pred,y))
#梯度下降优化
optm = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)
#计算机准确率
accr = tf.reduce_mean(tf.cast(tf.equal(tf.argmax(pred,1),tf.argmax(y,1),tf.float32)))
init = tf.global_variables_initializer()
#开始训练
#循环次数
training_epochs = 5
#一次训练输入图像的个数,即输入为28*28*16
batch_size = 16
#每循环一次输出一次结果
display_step = 1
sess = tf.Session()
#初始化
sess.run(init)
print('Start optimization')
for epoch in range(training_epochs):
avg_cost = 0
total_batch = 100
for i in range(total_batch):
batch_xs,batch_ys = mnist.train.next_batch(batch_size)
batch_xs = batch_xs.reshape((batch_size,nsteps,diminput))
feeds = {x:batch_xs,y:batch_ys}
sess.run(optm,feed_dict=feeds)
avg_cost += sess.run(cost,feed_dict=feeds)/total_batch
if epoch%display_step==0:
print("Epoch: %03d/%03d cost: %.9f" % (epoch, training_epochs, avg_cost))
feeds = {x:batch_xs,y:batch_ys}
train_acc = sess.run(accr,feed_dict=feeds)
print(" Training accuracy: %.3f" % (train_acc))
testimgs = testimgs.reshape((ntest,nsteps,diminput))
feeds = {x: testimgs, y: testlabels, istate: np.zeros((ntest, 2 * dimhidden))}
test_acc = sess.run(accr, feed_dict=feeds)
print(" Test accuracy: %.3f" % (test_acc))
print("Optimization Finished.")