RNN学习(三)

  1. nn.Recurrent(start, input, feedback, [transfer, rho, merge])
    • start: the size of the output, or a Module that will be inserted between the input and the transfer.
    • input: a module that processes the input tensor.
    • feedback: a module that feedbacks the previous output tensor
    • transfer: a non-linear Module used to process the element-wise sum of the input and feedback module outputs
    • rho: is the maximum amount of back-progragation.
    • merge: a table Module that merges the outputs of the input and feedback.
    • torch学习(六) rnn package
  2. 使用rnn建立一个计时器

    • Torch7 文档torch7
    • 总体思路
      • 输入:000050000000006000000这样100个数字
      • 输出:000001111100000111111这样100个数字
      • 每当输入出现impulse,如5时,输出延迟了1然后输出5个1,要rnn去学习这样的序列
      • rnn定义为hidden_size为20的简单rnn
    • 参考:深度学习笔记(五)用Torch实现RNN来制作一个神经网络计时器
    • 生成数据

      • 准备
      require 'torch'
      require 'gnuplot'
      math.randomseed(1) --[[种子,同一种子产生的随机数序列是相同,的,因此可以使用math.randomseed(os.time())避免随机数重合,参考http://blog.csdn.net/zhangxaochen/article/details/8095007]]
      sample_length = 100
      sample_amount = 10000
      X = torch.zeros(sample_length)
      Y = torch.zeros(sample_length)
      • 生成

        for n=2,sample_amount do
            sample_count = 0
            input = {}--[[Lua中数组,使用[]选择]]
            output = {}
             while sample_count < sample_length do
                t_blank = math.random(1,10)--[[产生1~10之间随机数]]
                t_intense = math.random(1,10)
                for i = 1,t_blank do
                  table插入(input, 0)
                  --[[table插入(table, pos, value), table.insert()函数在table的数组部分指定位置(pos)插入值为value的一个元素. pos参数可选, 默认为数组部分末尾, 参考http://www.cnblogs.com/whiteyun/archive/2009/08/10/1543139.html.]]
                  table插入(output, 0)
                end
                 table插入(input, t_intense)
                 table插入(output, 0)
                for i = 1,t_intense do
                 table插入(input, 0)
                 table插入(output, 1)
                end
                sample_count = sample_count+t_blank+t_intense+1
              end
          input = torch.Tensor(input)
          input = input[{{1, sample_length}}]--从input中取得1~sample_length的长度
          output = torch.Tensor(output)
          output = output[{{1, sample_length}}]
          X = X:cat(input,2)--将X和input连接起来,2是第2维度上连接
          --[[从input中取得1~sample_length的长度,
            如print(torch.cat(torch.ones(3,2),torch.zeros(2,2),1))会输出 
             1  1
             1  1
             1  1
             0  0
             0  0
            X=torch.cat(torch.ones(3),torch.zeros(3),2)会输出
            1  0
            1  0
            1  0
            ]]
          Y = Y:cat(output,2)
        end
      • 画图

        torch.save('data.t7', {X:t(), Y:t()}) --t()是取转置
        gnuplot.pngfigure('/media/majing/work/rnn/examples/torch-practice/rnn-timer/img/timer.png')
        gnuplot.plot({input},{output})
        gnuplot.plotflush()

      取一个X和Y的序列,如图
      这里写图片描述

    • Minibatch

      local MinibatchLoader = {}
      MinibatchLoader.__index = MinibatchLoader
      function MinibatchLoader.create(batch_size)
      -- split_fractions is e.g. {0.9, 0.05, 0.05}
      
      local self = {}
      setmetatable(self, MinibatchLoader)
      --[[
          --定义2个表
              a = {5, 6}
              b = {7, 8}
          --用c来做Metatable
              c = {}
          --重定义加法操作
              c.__add = function(op1, op2)
                 for _, item in ipairs(op2) do
                    table.insert(op1, item)
                 end
                 return op1
              end
          --将a的Metatable设置为c
              setmetatable(a, c)
          --d现在的样子是{5,6,7,8}
              d = a + b
              重定义了2个表的加法操作. 这个例子中将c的__add域改写后将a的Metatable设置为c, 当执行到加法的操作时, Lua首先会检查a是否有Metatable并且Metatable中是否存在__add域, 如果有则调用, 否则将检查b的条件(和a相同), 如果都没有则调用默认加法运算, 而table没有定义默认加法运算, 则会报错.参考http://www.cnblogs.com/simonw/archive/2007/01/17/622032.html
      ]]
      
      self.batch_size = batch_size
      self.batch_idx = 1
      
      local data_filename = 'data.t7'
      
      print('loading data files...')
      self.data = torch.load(data_filename)
      
      self.sample_size = self.data[1]:size(1)
      
      print(string.format('data load done.'))
      collectgarbage()
      return self
      end
      function MinibatchLoader:next_batch()
      
          X = self.data[1]:sub((self.batch_idx-1)*self.batch_size+1, self.batch_idx*self.batch_size)--origin, a batch data
          Y = self.data[2]:sub((self.batch_idx-1)*self.batch_size+1, self.batch_idx*self.batch_size)--target, a batch data
          self.batch_idx = self.batch_idx + 1--next batch
      
          if(self.batch_idx*self.batch_size > self.sample_size) then
              self.batch_idx = 1
          end
      
          table_x = {}
          table_y = {}
      
          for i=1,X:size(2) do
            table插入(table_x, X[{{},{i}}])
            table插入(table_y, Y[{{},{i}}])
          end
      
          return table_x, table_y
      end
      
      return MinibatchLoader
    • train

      require 'rnn'
      require 'gnuplot'
      
      batchSize = 8
      rho = 100
      hiddenSize = 20
      
      -- RNN
      
      batchLoader = require 'MinibatchLoader'
      loader = batchLoader.create(batchSize)
      
      r = nn.Recurrent(
         hiddenSize, nn.Linear(1, hiddenSize), 
         nn.Linear(hiddenSize, hiddenSize), nn.Sigmoid(), 
         rho
      )
      --[[
      隐藏层r的类型是nn.Recurrent。后面跟的参数依次分别是:
      1. 本层中包含的节点个数,为hiddenSize
      2. 前一层(也就是输入层)到本层的连接。这里是一个输入为1,输出为hiddenSize的线性连接。
      3. 本层节点到自身的反馈连接。这里是一个输入为hiddenSize,输出也是hiddenSize的线性连接。
      4. 本层输入和反馈连接所用的激活函数。这里用的是Sigmoid。
      5. Back propagation through time所进行的最大的次数。这里是rho = 100
      ]]
      
      
      rnn = nn.Sequential()
      rnn:add(nn.Sequencer(r))
      rnn:add(nn.Sequencer(nn.Linear(hiddenSize, 1)))
      rnn:add(nn.Sequencer(nn.Sigmoid()))
      --[[ 
      首先定义一个容器,然后添加刚才定义好的隐藏层r。随后添加隐藏层到输出层的连接,在这里用的是输入为20,输出为1的线性连接。最后接上一层Sigmoid函数。
      这里在定义网络的时候,每个具体的模块都是用nn.Sequencer的括号给括起来的。nn.Sequencer是一个修饰模块。所有经过nn.Sequencer包装过的模块都变得可以接受序列的输入。
      举个例子来说,假设有一个模块本来能够接受一个2维的Tensor作为输入,并输出另一个2维的Tensor。如果我们想把一系列的2维Tensor依次输入给这个模块,需要写一个for循环来实现。有了nn.Sequencer的修饰就不用这么麻烦了。只需要把这一系列的2维Tensor统一放到一个大的table里,然后一次性的丢给nn.Sequencer就行了。nn.Sequencer会把table中的Tensor依次放入网络,并将网络输出的Tensor也依次放入一个大的table中返回给你。
      ]]       
      
      
      criterion = nn.SequencerCriterion(nn.MSECriterion())
      --[[定义好了网络,接下来是定义评判标准]]
      
      lr = 0.01
      i = 1
      --[[
      接下来的事情又是例行公事了。向前传播,向后传播,更新参数.
      使用了MinibatchLoader(同目录下的MinibatchLoader.lua文件)来从data.t7中读取数据,每次读取8个序列,每个序列的时间长度是100。那么代码中inputs的类型是table,这个table中有100个元素,每个元素是一个2维8列1行的Tensor。在训练的时候,mini batch中8个序列中的每一个的第一个数据一起进入网络,接下来是8个排在第二的数据一起输入,如此迭代。
      ]]
      for n=1,6000 do
         -- prepare inputs and targets
         local inputs, targets = loader:next_batch()
      
         local outputs = rnn:forward(inputs)
         local err = criterion:forward(outputs, targets)
         print(i, err/rho)
         i = i + 1
         local gradOutputs = criterion:backward(outputs, targets)
         rnn:backward(inputs, gradOutputs)
         rnn:updateParameters(lr)
         rnn:zeroGradParameters()
      end
      
      --[[
      当训练完成之后,用其中的组输入放进网络观察其输出]]
      inputs, targets = loader:next_batch()
      outputs = rnn:forward(inputs)
      
      x={}
      y={}
      for i=1,100 do
         table插入(x,inputs[i][{1,1}])
         table插入(y,outputs[i][{1,1}])
      end
      
      x = torch.Tensor(x)
      y = torch.Tensor(y)
      
      gnuplot.pngfigure('timer.png')
      gnuplot.plot({x},{y})
      gnuplot.plotflush()
      

      结果显示入图这里写图片描述

  3. char-rnn

  4. 4.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在深度学习,强化学习(Reinforcement Learning, RL)、递归神经网络(Recurrent Neural Networks, RNN)和人工神经网络(Artificial Neural Networks, ANN)是个不同的概念。 强化学习是一种机器学习方法,它通过与环境进行交互来学习最优的行为。在强化学习,智能体(Agent)通过观察环境状态、执行动作和接收奖励来学习如何在特定环境做出最优决策。强化学习的目标是通过与环境的交互,使智能体在长期获得最大的累计奖励。 递归神经网络(RNN)是一种特殊类型的神经网络,它在处理序列数据时具有记忆能力。相比于传统的前馈神经网络(Feed Forward Neural Networks, FFNN),RNN在处理具有时间依赖关系的数据时更加高效。RNN的每个神经元会保存一部分历史信息,并将其传递给下一个时间步骤,从而实现对序列数据的建模。 人工神经网络(ANN)是一种用于模拟人类神经系统的数学模型。ANN由大量的神经元和连接权值组成,可以通过学习调整连接权值来实现对输入数据的处理和输出结果的预测。ANN广泛应用于各种机器学习任务,包括分类、回归、聚类等。 综上所述,强化学习、递归神经网络和人工神经网络是深度学习的不同概念。强化学习是一种学习方式,递归神经网络是一种网络结构,而人工神经网络是一种数学模型。它们在深度学习有各自独特的作用和应用场景。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值