构建单层单向RNN网络对MNIST数据集分类

一、导入数据集

 1 import tensorflow as tf
 2 import numpy as np
 3     #清除默认图形堆栈并重置全局默认图形,tf.reset_default_graph函数只适用于当前线程.
 4     #当一个tf.Session或者tf.InteractiveSession激活时调用这个函数会导致未定义的行为.
 5     #调用此函数后使用任何以前创建的tf.Operation或tf.Tensor对象将导致未定义的行为.
 6     tf.reset_default_graph()
 7     from tensorflow.examples.tutorials.mnist import input_data
 8     
 9     #mnist是一个轻量级的类,它以numpy数组的形式存储着训练,校验,测试数据集  one_hot表示输出二值化后的10维
10     mnist = input_data.read_data_sets('MNIST-data',one_hot=True)
11     print('Training data shape:',mnist.train.images.shape)           #Training data shape: (55000, 784)
12     print('Test data shape:',mnist.test.images.shape)                #Test data shape: (10000, 784)
13     print('Validation data shape:',mnist.validation.images.shape)    #Validation data shape: (5000, 784)
14     print('Training label shape:',mnist.train.labels.shape)          #Training label shape: (55000, 10)

二、定义参数

1     n_input = 28             #LSTM单元输入节点的个数
2     n_steps = 28             #序列长度
3     n_hidden = 128           #LSTM单元输出节点个数(即隐藏层个数)
4     n_classes = 10           #类别
5  #定义占位符
6     #batch_size:表示一次的批次样本数量batch_size  n_steps:表示时间序列总数  n_input:表示一个时序具体的数据长度  即一共28个时序,一个时序送入28个数据进入LSTM网络
7     input_x = tf.placeholder(dtype=tf.float32,shape=[None,n_steps,n_input])
8     input_y = tf.placeholder(dtype=tf.float32,shape=[None,n_classes])

三、①、构建单层静态LSTM网络

 1 def single_layer_static_lstm(input_x,n_steps,n_hidden):
 2     '''
 3     返回静态单层LSTM单元的输出,以及cell状态
 4     args:
 5         input_x:输入张量 形状为[batch_size,n_steps,n_input]
 6         n_steps:时序总数
 7         n_hidden:LSTM单元输出的节点个数 即隐藏层节点数
 8     '''
 9     '''
10     #把输入input_x按列拆分,并返回一个有n_steps个张量组成的list 如batch_sizex28x28的输入拆成[(batch_size,28),((batch_size,28))....] 
11     #如果是调用的是静态rnn函数,需要这一步处理   即相当于把序列作为第一维度 
12     '''
13     input_x1 = tf.unstack(input_x,num=n_steps,axis=1)#①
14     '''可以看做隐藏层'''
15     lstm_cell = tf.contrib.rnn.BasicLSTMCell(num_units=n_hidden,forget_bias=1.0)#②
16     '''静态rnn函数传入的是一个张量list  每一个元素都是一个(batch_size,n_input)大小的张量 '''
17     hiddens,states = tf.contrib.rnn.static_rnn(cell=lstm_cell, inputs=input_x1, dtype=tf.float32)#③
18 
19     return hiddens,states

  ②、构建单层静态GRU网络

 1 def single_layer_static_gru(input_x,n_steps,n_hidden):
 2     '''
 3     返回静态单层GRU单元的输出,以及cell状态
 4     
 5     args:
 6         input_x:输入张量 形状为[batch_size,n_steps,n_input]
 7         n_steps:时序总数
 8         n_hidden:gru单元输出的节点个数 即隐藏层节点数
 9     '''
10     '''
11     #把输入input_x按列拆分,并返回一个有n_steps个张量组成的list 如batch_sizex28x28的输入拆成[(batch_size,28),((batch_size,28))....] 
12     #如果是调用的是静态rnn函数,需要这一步处理   即相当于把序列作为第一维度 
13     '''
14     input_x1 = tf.unstack(input_x,num=n_steps,axis=1)
15 
16     '''可以看做隐藏层'''
17     gru_cell = tf.contrib.rnn.GRUCell(num_units=n_hidden)
18     '''静态rnn函数传入的是一个张量list  每一个元素都是一个(batch_size,n_input)大小的张量 '''
19     hiddens,states = tf.contrib.rnn.static_rnn(cell=gru_cell,inputs=input_x1,dtype=tf.float32)
20         
21     return hiddens,states

 ③、构建单层动态LSTM网络

 1 def single_layer_dynamic_lstm(input_x,n_steps,n_hidden):
 2     '''
 3     返回动态单层LSTM单元的输出,以及cell状态
 4     
 5     args:
 6         input_x:输入张量  形状为[batch_size,n_steps,n_input]
 7         n_steps:时序总数
 8         n_hidden:LSTM单元输出的节点个数 即隐藏层节点数
 9     '''
10     #可以看做隐藏层
11     lstm_cell = tf.contrib.rnn.BasicLSTMCell(num_units=n_hidden,forget_bias=1.0)
12     #动态rnn函数传入的是一个三维张量,[batch_size,n_steps,n_input]  输出也是这种形状
13     hiddens,states = tf.nn.dynamic_rnn(cell=lstm_cell,inputs=input_x,dtype=tf.float32)
14 
15     #注意这里输出需要转置  转换为时序优先的
16     hiddens = tf.transpose(hiddens,[1,0,2])
17     return hiddens,states

  ④、构建单层动态GRU网络

 1 def single_layer_dynamic_gru(input_x,n_steps,n_hidden):
 2     '''
 3     返回动态单层GRU单元的输出,以及cell状态
 4     
 5     args:
 6         input_x:输入张量 形状为[batch_size,n_steps,n_input]
 7         n_steps:时序总数
 8         n_hidden:gru单元输出的节点个数 即隐藏层节点数
 9     '''
10     
11     #可以看做隐藏层
12     gru_cell = tf.contrib.rnn.GRUCell(num_units=n_hidden)
13     #动态rnn函数传入的是一个三维张量,[batch_size,n_steps,n_input]  输出也是这种形状
14     hiddens,states = tf.nn.dynamic_rnn(cell=gru_cell,inputs=input_x,dtype=tf.float32)
15         
16     
17     #注意这里输出需要转置  转换为时序优先的
18     hiddens = tf.transpose(hiddens,[1,0,2])    
19     return hiddens,states

四、初始化

 1     #调用单层静态LSTM网络
 2     hiddens,states = single_layer_static_lstm(input_x,n_steps,n_hidden)
 3     #取LSTM最后一个时序的输出,然后经过全连接网络得到输出值
 4     output = tf.contrib.layers.fully_connected(inputs=hiddens[-1],num_outputs=n_classes,activation_fn = tf.nn.softmax)
 5     #设置对数似然损失函数
 6     #代价函数 J =-(Σy.logaL)/n 表示逐元素乘
 7     cost = tf.reduce_mean(-tf.reduce_sum(input_y*tf.log(output),axis=1))
 8     #求解
 9     learning_rate = 1e-4     #学习率 
10     train = tf.train.AdamOptimizer(learning_rate).minimize(cost)
11     #预测结果评估
12     #tf.argmax(output,1)  按行统计最大值得索引
13     correct = tf.equal(tf.argmax(output,1),tf.argmax(input_y,1))       #返回一个数组 表示统计预测正确或者错误 
14     accuracy = tf.reduce_mean(tf.cast(correct,tf.float32))             #求准确率

五、训练以及测试

 1     with tf.Session() as sess:
 2         #使用会话执行图
 3         sess.run(tf.global_variables_initializer())   #初始化变量   
 4         batch_size = 128         #小批量大小
 5         training_step = 5000     #迭代次数
 6         display_step  = 200      #显示步数
 7         #开始迭代 使用Adam优化的随机梯度下降法
 8         for i in range(training_step): 
 9             x_batch,y_batch = mnist.train.next_batch(batch_size = batch_size)   
10             #Reshape data to get 28 seq of 28 elements
11             x_batch = x_batch.reshape([-1,n_steps,n_input])
12             
13             #开始训练
14             train.run(feed_dict={input_x:x_batch,input_y:y_batch})   
15             if (i+1) % display_step == 0:
16                  #输出训练集准确率        
17                 training_accuracy,training_cost = sess.run([accuracy,cost],feed_dict={input_x:x_batch,input_y:y_batch})   
18                 print('Step {0}:Training set accuracy {1},cost {2}.'.format(i+1,training_accuracy,training_cost))
19         
20         
21         #全部训练完成做测试  分成200次,一次测试50个样本
22         #输出测试机准确率   如果一次性全部做测试,内容不够用会出现OOM错误。所以测试时选取比较小的mini_batch来测试
23         for i in range(200):        
24             x_batch,y_batch = mnist.test.next_batch(batch_size = 50)      
25             #Reshape data to get 28 seq of 28 elements
26             x_batch = x_batch.reshape([-1,n_steps,n_input])
27             test_accuracy,test_cost = sess.run([accuracy,cost],feed_dict={input_x:x_batch,input_y:y_batch})
28             test_accuracy_list.append(test_accuracy)
29             test_cost_list.append(test_cost) 
30             if (i+1)% 20 == 0:
31                  print('Step {0}:Test set accuracy {1},cost {2}.'.format(i+1,test_accuracy,test_cost)) 
32         print('Test accuracy:',np.mean(test_accuracy_list))

六、训练模型保存

1  saver = tf.train.Saver()
2  saver.save(sess, './model/rnn_model.ckpt')

七、调用模型

1 saver = tf.train.Saver()
2 save_path = tf.train.latest_checkpoint('./model/')
3 with tf.Session() as sess:
4      saver.restore(sess=sess, save_path=save_path)    
5     feeds = {x:images,y:labels}
6      preds = sess.run(accr, feed_dict=feeds)

猜你喜欢

转载自www.cnblogs.com/chenfeifen/p/11360659.html
今日推荐