关于 tutorials/2_supervised/4_train.lua 上的 feval 函数

Posted

技术标签:

【中文标题】关于 tutorials/2_supervised/4_train.lua 上的 feval 函数【英文标题】:About feval function on tutorials/2_supervised/4_train.lua 【发布时间】:2017-01-27 00:39:59 【问题描述】:

在 gihub 上: https://github.com/torch/tutorials/blob/master/2_supervised/4_train.lua 我们有一个定义训练过程的脚本示例。我对此脚本中 feval 函数的构造很感兴趣。

-- create closure to evaluate f(X) and df/dX
local feval = function(x)
      -- get new parameters
      if x ~= parameters then
         parameters:copy(x)
      end

      -- reset gradients
      gradParameters:zero()

      -- f is the average of all criterions
      local f = 0

      -- evaluate function for complete mini batch
      for i = 1,#inputs do
          -- estimate f
          local output = model:forward(inputs[i])
          local err = criterion:forward(output, targets[i])
          f = f + err

          -- estimate df/dW
          local df_do = criterion:backward(output, targets[i])
          model:backward(inputs[i], df_do)

          -- update confusion
          confusion:add(output, targets[i])
      end

      -- normalize gradients and f(X)
      gradParameters:div(#inputs)
      f = f/#inputs

      -- return f and df/dX
      return f,gradParameters
      end

我尝试通过抑制循环来修改此功能: 对于 i = 1,#inputs 做 ... 因此,我不是通过输入(输入[i])进行前向和后向输入,而是对整个小批量(输入)进行。这确实加快了进程。这是修改脚本:

-- create closure to evaluate f(X) and df/dX
local feval = function(x)
      -- get new parameters
      if x ~= parameters then
         parameters:copy(x)
      end

      -- reset gradients
      gradParameters:zero()

      -- f is the average of all criterions
      local f = 0
      -- evaluate function for complete mini batch

      -- estimate f
      local output = model:forward(inputs)
      local f = criterion:forward(output, targets)

      -- estimate df/dW
      local df_do = criterion:backward(output, targets)

      -- update weight  
      model:backward(inputs, df_do)

      -- update confusion
      confusion:batchAdd(output, targets) 

      -- return f and df/dX
      return f,gradParameters
      end

但是,当我详细检查给定小批量的 feval (f,gradParameters) 的返回时,循环和不循环的结果不同。

所以我的问题是: 1 - 为什么我们有这个循环? 2 - 如果没有这个循环,是否可以获得相同的结果?

问候 山姆

注意:我是 Torch7 的初学者

【问题讨论】:

【参考方案1】:

我相信您已经注意到要获得第二种工作方式需要的不仅仅是更改 feval。 在您的第二个示例中,输入需要是 4D 张量,而不是 3D 张量表(除非自上次更新以来发生了变化)。根据所使用的损失标准/模型,这些张量具有不同的大小。实现这个例子的人一定认为循环是一个更简单的方法。此外,ClassNLLCriterion 似乎不喜欢批处理(通常会使用 CrossEntropy 标准来解决这个问题)。

除此之外,这两种方法应该给出相同的结果。唯一的细微差别是第一个示例使用平均误差/梯度,第二个示例使用总和,如您所见:

                   gradParameters:div(inputs:size(1))
                   f = f/inputs:size(1)

在第二种情况下,f 和 gradParameters 应该与第一种不同,只有一个因素 opt.batchSize。出于优化目的,这些在数学上是等效的。

【讨论】:

感谢 Sander 的回答。我同意,因为抑制循环,我们需要在输入中增加一维。我添加了 CrossEntropy 而不是 ClassNLLCriterion 它可以工作,但它并没有改变很多结果。但是我添加了另一件事,这两种方法的结果似乎更好,但我真的不明白为什么,它是一个 Sequencer: nn.Sequencer(model) criteria = nn.SequencerCriterion(nn.CrossEntropyCriterion(weights) ) 嗨,山姆。我不确定我是否理解这个问题。 CrossEntropy 应该和 LogSoftMax + ClassNLLCriterion 一样,但支持批处理,所以你不会期望结果会改变。 是的 CrossEntropy 不会改变结果。但是 nn.Sequencer 可以。使用 nn.Sequencer 输入数据中的顺序很重要,结果似乎接近循环获得的结果,但我不知道为什么。 啊,我不熟悉那个模块。抱歉,从你的两行代码中我看不出为什么它会给出不同的结果。

以上是关于关于 tutorials/2_supervised/4_train.lua 上的 feval 函数的主要内容,如果未能解决你的问题,请参考以下文章

lazypredict.Supervised.LazyClassifier。 ImportError:无法从“sklearn.utils.deprecation”导入名称“_raise_dep_war

Supervised learning demo

论文翻译:2018_Artificial Bandwidth Extension with Memory Inclusion using Semi-supervised Stacked Auto-en

ROS学习笔记_消息与服务

Feature Learning based Deep Supervised Hashing with Pairwise Labels

论文笔记 CReST:A Class-Rebalancing Self-Training Framework for Imbalanced Semi-Supervised Learning