关于 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
论文翻译:2018_Artificial Bandwidth Extension with Memory Inclusion using Semi-supervised Stacked Auto-en
Feature Learning based Deep Supervised Hashing with Pairwise Labels
论文笔记 CReST:A Class-Rebalancing Self-Training Framework for Imbalanced Semi-Supervised Learning