当前课程知识点:深度学习基础 >  第八讲 生成式神经网络 >  附:8.4程序 >  附:5.4程序

返回《深度学习基础》慕课在线视频课程列表

附:5.4程序资料文件与下载

reader.py---点此下载文件

附:5.4程序

  1. #演示内容:利用tensorflow实现的循环神经网络RNN(本程序使用了LSTM)来做语言模型,并输出其困惑度。

  2. #语言模型主要是根据一段给定的文本来预测下一个词最有可能是什么。困惑度用于评价语言模型。困惑度越小,则模型的性能越好。

  3.  

  4. import tensorflow as tf

  5.  

  6. #reader模块用于读取数据集,以及做训练集、验证集和测试集的切分等。如果无法导入reader模块,也可以从网上下载reader.py,加入到同级目录即可,下载地址:http://github.com/tensorflow/models/blob/master/tutorials/rnn/ptb/reader.py

  7. import reader 

  8. import numpy as np

  9.  

  10. DATA_PATH='data' #data目录中应该预先存放本程序中要用到的语料,即PTB(Penn Treebank Dataset)数据集,也就是宾州树库数据集 。PTB数据集是语言模型研究常用的数据集。其下载地址在 Tomas Mikolov的主页: http://www.fit.vutbr.cz/~imikolov/rnnlm/simple-examples.tgz。解压后,将其中的整个data文件夹拷贝到当前目录即可。数据集共有9998个单词,加上稀有词语的特殊符号<unk>和语句的结束标记,共有10000个单词。

  11.  

  12. #超参数的设置

  13. HIDDEN_SIZE=200#size of RNN hidden state,指表示每个单词的词向量的维度

  14. NUM_LAYERS=2   #表示使用了两个LSTM层

  15. VOCAB_SIZE=10000 #词汇表中词的个数

  16.  

  17. LEARNING_RATE=1.0 # 设置学习速率超参数

  18. TRAIN_BATCH_SIZE=20  # 训练阶段每个数据批量设置为多少个样本。在本例中每个样本是指由若干个词构成的一个序列

  19. TRAIN_NUM_STEP=35    # 训练阶段时间步的个数,即在训练阶段中文本数据的截断长度,也可以称为序列长度seq_length

  20.  

  21. # 可以将测试数据看成一个很长的序列,所以下面这两个参数都设置为1

  22. EVAL_BATCH_SIZE=1    #在后面main函数中计算valid_batch_len时会用到

  23. EVAL_NUM_STEP=1      #在后面main函数中计算valid_epoch_size时会用到

  24. NUM_EPOCH=2    #训练的轮数

  25. KEEP_PROB=0.5  # 节点不被dropout的概率

  26. MAX_GRAD_NORM=5 #这个超参数后面会用到,用于避免梯度膨胀问题

  27.  

  28. # 类PTBModel的定义,是这个多层循环神经网络模型的描述

  29. class PTBModel(object):

  30.       #初始化函数,其参数包括当前是否在训练阶段,批量的大小,数据的截断长度即序列长度等

  31.     def __init__(self,is_training,batch_size,num_steps): 

  32.         # 根据给定的参数数值来设置使用的batch大小和时间步数(截断长度)

  33.         self.batch_size=batch_size

  34.         self.num_steps=num_steps

  35.          

  36.         # 定义输入层的数据维度为: batch_size * num_steps。 这里tf.placeholder可以理解为采用占位符进行占位,等以后实际运行时进行具体填充。等建立session,运行模型的时候才feed数据        

  37.         self.input_data=tf.placeholder(tf.int32,[batch_size,num_steps])

  38.          

  39.         # 定义输出层的数据维度为:batch_size*num_steps。num_steps相当于seq_length

  40.         self.targets=tf.placeholder(tf.int32,[batch_size,num_steps])

  41.          

  42.         # 定义使用LSTM结构作为循环体的基本结构。每个单词向量的维度为HIDDEN_SIZE

  43.         lstm_cell=tf.nn.rnn_cell.BasicLSTMCell(HIDDEN_SIZE)

  44.         #如果是在训练阶段,则使用dropout.此时每个单元以(1-keep_prob)的概率不工作,目的是防止过拟合。

  45.         if is_training:

  46.             lstm_cell=tf.nn.rnn_cell.DropoutWrapper(lstm_cell,output_keep_prob=KEEP_PROB)

  47.          

  48.         #将多层RNN单元封装到一个单元cell中。层的个数NUM_LAYERS前面已经设定为2了

  49.         cell=tf.nn.rnn_cell.MultiRNNCell([lstm_cell]*NUM_LAYERS) 

  50.                  

  51.         # 使用zero_state函数来初始化网络的状态

  52.         self.initial_state=cell.zero_state(batch_size,tf.float32)

  53.          

  54.         # 下面两条语句是将单词转换成向量

  55.         #VOCAL_SIZE即单词的总数;  HIDDEN_SIZE,即每个单词的向量维度。所以 embedding参数的维度为VOCAB_SIZE * HIDDEN_SIZE. #则inputs的维度为:batch_size * num_steps * HIDDEN_SIZE    

  56.         embedding=tf.get_variable('embedding',[VOCAB_SIZE,HIDDEN_SIZE])       

  57.         inputs=tf.nn.embedding_lookup(embedding,self.input_data)

  58.          

  59.         # 如果在训练阶段,则进行dropout

  60.         if is_training:

  61.             inputs=tf.nn.dropout(inputs,KEEP_PROB)

  62.              

  63.         #定义LSTM结构的输出列表

  64.         outputs=[]

  65.         # state存储LSTM的初始状态

  66.         state=self.initial_state

  67.         #TensorFlow提供了Variable Scope 机制,用于共享变量

  68.         with tf.variable_scope('RNN'): 

  69.             #对于每个时间步

  70.             for time_step in range(num_steps):

  71.                 if time_step>0:

  72.                     tf.get_variable_scope().reuse_variables() #重用变量

  73.                  

  74.                 # 从输入数据inputs中获取当前时刻的输入并传入LSTM的单元,并得到输出。

  75.                 #每次的输出都是一个张量,其shape=(20, 200),其中20是BATCH_SIZE,200是词向量维度

  76.                 cell_output,state=cell(inputs[:,time_step,:],state)

  77.                #将当前单元的输出加入到输出的列表中

  78.                 outputs.append(cell_output)

  79.          

  80.         # 将输出的列表利用tf.concat函数变成(batch,hidden_size*num_steps)的形状,然后再reshape成(batch*num_steps,hidden_size)的形状

  81.         #,即为 (20*35, 200)=(700, 200)

  82.         output = tf.reshape(tf.concat(outputs, 1), [-1, HIDDEN_SIZE])

  83.          

  84.         #下面三条语句利用刚才LSTM的输出向量output乘以权重weight再加上偏置bias,得到最后的预测结果logits

  85.         weight=tf.get_variable('weight',[HIDDEN_SIZE,VOCAB_SIZE])  #weight的形状为 [200, 10000] 

  86.         bias=tf.get_variable('bias',[VOCAB_SIZE])

  87.         logits=tf.matmul(output,weight)+bias

  88.  

  89.         #计算交叉熵损失

  90.         loss=tf.contrib.legacy_seq2seq.sequence_loss_by_example(

  91.             [logits], #logits是刚才预测的结果  shape=(700, 10000)

  92.             [tf.reshape(self.targets,[-1])], # self.targets是正确的结果.这里对其shape进行了调整,变为shape=(700,)

  93.             [tf.ones([batch_size*num_steps],dtype=tf.float32)]# 设置损失的权重。所有的权重都设为1,即不同batch和不同时刻的权重相同

  94.             )

  95.          

  96.         # 计算每个batch的平均损失,并更新网络的状态

  97.         self.cost=tf.reduce_sum(loss)/batch_size

  98.         self.final_state=state

  99.          

  100.         # 如果当前是在训练阶段,则继续进行下面的反向传播以更新梯度

  101.         if not is_training:

  102.             return 

  103.         #返回的是需要训练的变量列表

  104.         trainable_variables=tf.trainable_variables()

  105.          

  106.         # 通过clip_by_global_norm函数控制梯度的大小,避免梯度膨胀问题

  107.         grads,_=tf.clip_by_global_norm(

  108.             tf.gradients(self.cost,trainable_variables),MAX_GRAD_NORM)

  109.          

  110.         #定义模型的优化方法

  111.         optimizer=tf.train.GradientDescentOptimizer(LEARNING_RATE)

  112.         #应用梯度对trainable_variables进行更新

  113.         self.train_op=optimizer.apply_gradients(zip(grads,trainable_variables))

  114.          

  115.          

  116. # 定义的函数run_epoch。使用刚才定义的模型model在数据data上运行train_op并返回perplexity值

  117. def run_epoch(session,model,data,train_op,output_log,epoch_size):

  118.     # 这两个变量是用于计算perplexity的辅助中间变量

  119.     total_costs=0.0

  120.     iters=0

  121.     #对模型进行初始化操作

  122.     state=session.run(model.initial_state)

  123.     # 对每一轮,使用当前数据训练模型

  124.     for step in range(epoch_size):    

  125.           

  126.         #这个run语句会返回并得到预测值y        

  127.         x, y = session.run(data) 

  128.          

  129.         #下面的run语句计算得到cost,即交叉熵值

  130.         cost,state,_=session.run([model.cost, model.final_state, train_op],

  131.                                 {model.input_data:x, model.targets:y, model.initial_state:state})

  132.                

  133.         #【然后求和】

  134.         total_costs+=cost

  135.         iters+=model.num_steps

  136.  

  137.         # 如果output_log为真,且每隔100步,就会输出困惑度的数值。困惑度ppx=exp(loss/N)

  138.         if output_log and step % 100 ==0:

  139.             print('After {} steps,perplexity is {}'.format(step,np.exp(total_costs/iters)))   

  140.  

  141.     # 返回perplexity值

  142.     return np.exp(total_costs/iters)

  143.  

  144. #主函数的定义

  145. def main(_):

  146.     # 利用reader.ptb_raw_data 函数 从数据目录DATA_PATH中读取训练数据集,验证数据集和测试数据集

  147.     train_data,valid_data,test_data,_=reader.ptb_raw_data(DATA_PATH)

  148.      

  149.      #得到训练阶段中每个epoch所需要训练的次数,即 train_epoch_size。

  150.     train_data_len = len(train_data)  #得到训练数据的文本长度

  151.     train_batch_len = train_data_len // TRAIN_BATCH_SIZE  #得到训练数据共计需要多少个batch

  152.     train_epoch_size = (train_batch_len - 1// TRAIN_NUM_STEP  #再除以时间步的个数,从而得到每个epoch所需要训练的次数

  153.  

  154.     #下同

  155.     valid_data_len = len(valid_data)

  156.     valid_batch_len = valid_data_len // EVAL_BATCH_SIZE  

  157.     valid_epoch_size = (valid_batch_len - 1// EVAL_NUM_STEP

  158.  

  159.     test_data_len = len(test_data)

  160.     test_batch_len = test_data_len // EVAL_BATCH_SIZE

  161.     test_epoch_size = (test_batch_len - 1// EVAL_NUM_STEP

  162.      

  163.     #利用tf.random_uniform_initializer生成均匀分布的随机数

  164.     initializer=tf.random_uniform_initializer(-0.05,0.05)

  165.      

  166.     #定义训练阶段使用的模型,PTBModel是之前定义过的类,其定义了网络结构。

  167.     with tf.variable_scope('language_model',reuse=None,initializer=initializer):  

  168.         train_model=PTBModel(True,TRAIN_BATCH_SIZE,TRAIN_NUM_STEP)

  169.          

  170.     #定义测试阶段使用的模型

  171.     with tf.variable_scope('language_model',reuse=True,initializer=initializer):

  172.         eval_model=PTBModel(False,EVAL_BATCH_SIZE,EVAL_NUM_STEP)

  173.      

  174.     #使用with tf.Session()语句来创建上下文(Context)并执行

  175.     with tf.Session() as sess:

  176.         #初始化变量

  177.         tf.global_variables_initializer().run()

  178.          

  179.         #利用reader.ptb_producer函数切分生成训练集、验证集和测试集上各自的队列

  180.          

  181.         train_queue = reader.ptb_producer(train_data, train_model.batch_size, train_model.num_steps)

  182.         eval_queue = reader.ptb_producer(valid_data, eval_model.batch_size, eval_model.num_steps)

  183.         test_queue = reader.ptb_producer(test_data, eval_model.batch_size, eval_model.num_steps)

  184.  

  185.         #使用tf.train.Coordinator()来创建一个线程管理器对象。然后调用tf.train.start_queue_runners,把数据推入内存序列中供计算单元调用

  186.         coord = tf.train.Coordinator()

  187.         threads = tf.train.start_queue_runners(sess=sess, coord=coord)

  188.          

  189.         # 对于每个epoch进行训练。NUM_EPOCH表示总的训练的轮数

  190.         for in range(NUM_EPOCH):

  191.             print('In EPOCH: {}'.format(i+1)) #【对于每个epoch】

  192.             # 调用之前的run_epoch函数来训练模型,当然要提供训练的模型,训练数据等

  193.             run_epoch(sess,train_model,train_queue,train_model.train_op,True,train_epoch_size)

  194.              

  195.             #使用验证数据来计算模型的困惑度,并打印输出

  196.             valid_perplexity=run_epoch(sess,eval_model,eval_queue,tf.no_op(),False,valid_epoch_size)

  197.             print('Epoch: {} Validation Perplexity: {}'.format(i+1,valid_perplexity))

  198.              

  199.         # 计算并返回在测试数据集上的困惑度,然后打印输出

  200.         test_perplexity=run_epoch(sess,eval_model,test_queue,tf.no_op(),False,test_epoch_size)

  201.         print('Test Perplexity: {}'.format(test_perplexity))

  202.         

  203.         

  204.        #使用coord.request_stop()来发出终止所有线程的命令,使用coord.join(threads)把线程加入主线程,等待threads结束。

  205.         coord.request_stop()

  206.         coord.join(threads)

  207.  

  208. #主函数的入口

  209.  

  210. if __name__ == '__main__':

  211.     tf.app.run()


返回《深度学习基础》慕课在线视频列表

深度学习基础课程列表:

第一讲 深度学习概述

-1.1 深度学习的引出

-1.2 数据集及其拆分

-1.3 分类及其性能度量

-1.4 回归问题及其性能评价

-1.5 一致性的评价方法

-1.6 程序讲解:使用Sklearn进行精确率-召回率曲线的绘制

-第一讲讲义

-第一讲 作业

-附:1.6程序

第二讲 特征工程概述

- 2.1 特征工程

-2.2 向量空间模型及文本相似度计算

-2.3 特征处理(特征缩放、选择及降维)

-2.4 程序讲解:使用sklearn对文档进行向量化的实例

-2.5 程序讲解:使用sklearn进行量纲缩放的实例

- 第二讲 讲义

-第二讲 作业

-附:2.4程序

-附:2.5程序

第三讲 回归问题及正则化

-3.1 线性回归模型及其求解方法

-3.2 多元回归与多项式回归

-3.3 损失函数的正则化

- 3.4 逻辑回归

-3.5 程序讲解:使用sklearn进行线性回归和二次回归的比较的程序示例

-第三讲讲义

-第三讲 作业

-附:3.5程序

第四讲 信息熵及梯度计算

-4.1 信息熵

-4.2 反向传播中的梯度

-4.3 感知机

-4.4 程序讲解:正向传播和反向传播的程序示例

-4.5 程序讲解:信息熵和互信息的计算程序示例

-第四讲讲义

-第四讲 作业

-附:4.5程序

第五讲 循环神经网络及其变体

-5.1 循环神经网络

-5.2 长短时记忆网络

-5.3 双向循环神经网络和注意力机制

-5.4 程序讲解:循环神经网络的程序示例

-第五讲 讲义

-第五讲 作业

-附:5.4程序

第六讲 卷积神经网络

-6.1 卷积与卷积神经网络

-6.2 LeNet-5 模型分析

-6.3 程序讲解:卷积神经网络的程序示例

-第六讲 讲义

-第六讲 作业

-附:6.3程序

第七讲 递归神经网络

-7.1 情感分析及传统求解方法

-7.2 词向量

-7.3 递归神经网络及其变体

-第七讲 讲义

-第七讲 作业

第八讲 生成式神经网络

-8.1 自动编码器

-8.2 变分自动编码器

-8.3 生成对抗网络

-8.4 程序讲解:自动编码器程序示例

-第八讲 作业

-第八讲 讲义

-附:8.4程序

附:5.4程序笔记与讨论

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。