SpatialDepthWiseConvolution Xception 反向传播错误

我正在尝试实现受 Xception 灵感启发的 NN。 我无法理解我的模型哪里出了问题...

local torch = require 'torch'
local nn = require 'nn'

dofile('GlobalAveragePooling.lua')

local model = nn.Sequential()
-- 输入卷积
model:add( nn.SpatialConvolution(3, 64, 3, 3, 2, 2, 1, 1) )
model:add( nn.SpatialBatchNormalization(64) )
model:add( nn.ReLU() )

-- Xception 单元带有“skip-path”
local seq = nn.Sequential()
seq:add( nn.SpatialDepthWiseConvolution(64, 1, 3, 3, 1, 1, 1, 1) )
seq:add( nn.SpatialConvolution(64, 512, 1, 1, 1, 1, 0, 0) )
seq:add( nn.SpatialBatchNormalization(512) )
seq:add( nn.SpatialMaxPooling(3, 3, 2, 2, 1, 1) )

local con = nn.ConcatTable()
con:add( nn.SpatialConvolution(64, 512, 1, 1, 2, 2, 0, 0) )
con:add( seq )

model:add( con )
model:add( nn.CAddTable() )
model:add( nn.ReLU() )

-- 输出全连接层用于 softmax(3) 输出
model:add( nn.GlobalAveragePooling() )
model:add( nn.Reshape(512) )

model:add( nn.Linear(512, 3) )
model:add( nn.LogSoftMax() )

print(tostring(model))

local X = torch.randn(10, 3, 16, 8)
local Y = torch.LongTensor(10):random(1,3)

local criterion = nn.ClassNLLCriterion()

local Yhat = model:forward(X)

local loss = criterion:forward(Yhat, Y)
local gradLoss = criterion:backward(Yhat, Y)
model:backward(X, gradLoss)

在 forward() 步骤中,该模型运行良好。 但是当它到达 model:backward(X, gradLoss) 时失败,并出现以下错误:

    /nn/THNN.lua:110: Need gradOutput of dimension 5 and gradOutput.size[3] == 8 but got gradOutput to be of shape: [10 x 64 x 1 x 4 x 8] at ../THNN/generic/SpatialDepthWiseConvolution.c:53
stack traceback:
[C]: in function 'v'    ../nn/THNN.lua:110: in function 'SpatialDepthWiseConvolution_updateGradInput'   ../nn/SpatialDepthWiseConvolution.lua:80:
in function 'updateGradInput' ../Module.lua:31:
in function <../nn/Module.lua:29>
[C]: in function 'xpcall'   ../nn/Container.lua:63:
in function 'rethrowErrors'     ../nn/Sequential.lua:88:
in function <../nn/Sequential.lua:78>
[C]: in function 'xpcall'   ../Container.lua:63:
in function 'rethrowErrors'     ../nn/ConcatTable.lua:66:
in function <../ConcatTable.lua:30>
[C]: in function 'xpcall'   ../nn/Container.lua:63:
in function 'rethrowErrors'     ../nn/Sequential.lua:84:
in function 'backward'  test.lua:45:
in main chunk   [C]: at 0x00405d50
点赞
用户420951
用户420951

事实证明,问题出在 torch/nn 的 SpatialDepthWiseConvolution 底层实现。我创建了一个 issue:https://github.com/torch/nn/issues/1307

截至目前为止(2018年3月3日),这个 issue 还没有被解决。 当然,我希望有人能够修正低级实现中的错误。 但是,目前我知道两种方法可以解决这个问题:

  • 通过 torch containers 模拟
  • 使用我的纯 lua 实现

下面是使用 containers ConcatParallel 以及标准 SpatialConvolution 模块模拟该模块的方法:

  local depth_wise_conv = nn.Concat(2)
  for o = 1, nOutputPlane do
    local out = nn.Parallel(2, 2)
    for i = 1, nInputPlane do
      local seq = nn.Sequential()
      local conv = nn.SpatialConvolution(1, 1, kW, kH, dW, dH, pW, pH):noBias()
      seq:add( nn.Reshape(1, inputHeight, inputWidth) )
      seq:add( conv )
      out:add( seq )
    end
    depth_wise_conv:add( out )
  end

注意,上面代码中的 depth_wise_conv 模块应该接受具有 4 个维度的批输入:batchSize x nInputPlane x inputHeight x inputWidth

但我花了一些时间,创建了一个纯 lua 实现的 SpatialDepthWiseConvolution 模块。你可以在这里找到它: https://gist.github.com/diovisgood/36ce5a6c5e9dd4cb20b13dd2a28c1f71

还有:SpatialConvolution 实现和单元测试。 我以 MIT 许可证发布了这些模块,所以任何人都可以使用它们。

请注意,这些模块尚未经过大量测试! 任何帮助或建议都将不胜感激。

还有一件事。有一篇非常好的论文,由 Vincent Dumoulin 和 Francesco Visin 解释了卷积和转置卷积: '深度学习中的卷积算术指南'

2018-03-02 21:13:51