torch学习笔记(二)



        在上一个章节,描述了基础的MLP的参数设定,数据集加载,预处理,以及模型的初始化,感觉torch的模型相对caffe来说,的确很麻烦,哈哈,但那时谁让他安装简单并且还有很多的源码学习呢?哈哈,都是个人见解,caffe的源码学习模型也有很多很多的。

       这个章节我们讨论一下对模型的运算。在介绍下面的代码之前。我们首先来看看介个基础的概念。

Evaluators评估数据的时候是按照一个序列进行一次进行处理的,然而,优化模型Optimizer 是首先把数据在shuffle洗牌之后在进行的,这是为了训练数据的随机化,从而提高准确性。

   损失函数loss:这里的损失函数大家都很熟悉,就是作用于训练数据和验证数据集。不多说了。

   feedback:主要是用来计算精度的函数,这里的精度主要是用来控制是否可以比较早的停止迭代并且还可以和其他的model结果进行比较。

   callBack函数:他的调用实在每次的forward和backforward之后调用的来修改一些参数,例如 momentum系数,你可以自己定义适合你的函数 。还有的函数例如epoch_callback函数,主要是用来更新学习率的,学习率的跟新有三种方法,这里就不再详细的说明啦。

        acc_update我也搞得晕里晕乎的。。。

       progess主要是控制是否打印进度条。具体代码如下

      

--[[Propagators]]--
if opt.lrDecay == 'adaptive' then
   ad = dp.AdaptiveDecay{max_wait = opt.maxWait, decay_factor=opt.decayFactor}
elseif opt.lrDecay == 'linear' then
   opt.decayFactor = (opt.minLR - opt.learningRate)/opt.saturateEpoch
end

train = dp.Optimizer{--这是整个优化器,train
   acc_update = opt.accUpdate,
   loss = nn.ModuleCriterion(nn.ClassNLLCriterion(), nil, nn.Convert()
epoch_callback = function(model, report) -- called every epoch你会发现他就是更改学习率的
      -- learning rate decay
      if report.epoch > 0 then  --不同的学习率更改方式,真的好繁琐啊
         if opt.lrDecay == 'adaptive' then
            opt.learningRate = opt.learningRate*ad.decay
            ad.decay = 1
         elseif opt.lrDecay == 'schedule' and opt.schedule[report.epoch] then
            opt.learningRate = opt.schedule[report.epoch]
         elseif opt.lrDecay == 'linear' then 
            opt.learningRate = opt.learningRate + opt.decayFactor
         end
         opt.learningRate = math.max(opt.minLR, opt.learningRate)--学习率不能小于opt.minLR
         if not opt.silent then
            print("learningRate", opt.learningRate)
         end
      end
   end,
   callback = function(model, report) -- called for every batch也是更改参数的
      if opt.accUpdate then
         model:accUpdateGradParameters(model.dpnn_input, model.output, opt.learningRate)
      else
         model:updateGradParameters(opt.momentum) -- affects gradParams
         model:updateParameters(opt.learningRate) -- affects params
      end
      model:maxParamNorm(opt.maxOutNorm) -- affects params
      model:zeroGradParameters() -- affects gradParams 
   end,
   feedback = dp.Confusion(),--结果存放在混淆矩阵种confusion matrix,主要是用来分类的
   sampler = dp.ShuffleSampler{batch_size = opt.batchSize},--对元数据进行洗牌
   progress = opt.progress
}
valid = dp.Evaluator{--验证数据集
   feedback = dp.Confusion(),  
   sampler = dp.Sampler{batch_size = opt.batchSize}--这里并灭有用什么shuffle计数
}
test = dp.Evaluator{--测试数据集
   feedback = dp.Confusion(),
   sampler = dp.Sampler{batch_size = opt.batchSize}
}




       下面。我们说的是Experiment。


      

xp = dp.Experiment{
   model = model,--你可以认为每一个model都有一个唯一的ID表示
   optimizer = train,--训练数据集
   validator = valid,--验证数据集
   tester = test,--测试数据集
   observer = { -- 用于监听前面函数的回掉以及执行
      dp.FileLogger(),--简单的说就是序列化
      dp.EarlyStopper{--当模型最终的准确度不再升涨,错误率不再提升,就可以早早的结束迭代
         error_report = {'validator','feedback','confusion','accuracy'},
         maximize = true,
         max_epochs = opt.maxTries
      },
      ad
   },
   random_seed = os.time(),
   max_epoch = opt.maxEpoch
}




        xp:run(ds)这个模型就可以运行起来了。总之我认为这部分的模型大部分情况下都是固定的。所以写好前面的model才是真正的关键。