【问题标题】:Torch: back-propagation from loss computed over a subset of the outputTorch:从输出的子集上计算的损失的反向传播
【发布时间】:2017-06-20 08:54:19
【问题描述】:

我有一个简单的卷积神经网络,它的输出是一个单通道 4x4 特征图。在训练期间,(回归)损失只需要在 16 个输出中的单个值上计算。 这个值的位置将在前向传递之后决定。我如何计算仅来自这个输出的损失,同时确保所有不相关的梯度在反向传播期间被清零。 p>

假设我在 Torch 中有以下简单模型:

require 'nn'

-- the input
local batch_sz = 2
local x = torch.Tensor(batch_sz, 3, 100, 100):uniform(-1,1)

-- the model
local net = nn.Sequential()
net:add(nn.SpatialConvolution(3, 128, 9, 9, 9, 9, 1, 1))
net:add(nn.SpatialConvolution(128, 1, 3, 3, 3, 3, 1, 1))
net:add(nn.Squeeze(1, 3))

print(net)

-- the loss (don't know how to employ it yet)
local loss = nn.SmoothL1Criterion()

-- forward'ing x through the network would result in a 2x4x4 output
y = net:forward(x)

print(y)

我查看了 nn.SelectTable,如果我将输出转换为表格形式,我似乎能够实现我想要的?

【问题讨论】:

    标签: neural-network torch


    【解决方案1】:

    这是我目前的解决方案。它的工作原理是将输出拆分为一个表格,然后使用 nn.SelectTable():backward() 获得完整的渐变:

    require 'nn'
    
    -- the input
    local batch_sz = 2
    local x = torch.Tensor(batch_sz, 3, 100, 100):uniform(-1,1)
    
    -- the model
    local net = nn.Sequential()
    net:add(nn.SpatialConvolution(3, 128, 9, 9, 9, 9, 1, 1))
    net:add(nn.SpatialConvolution(128, 1, 3, 3, 3, 3, 1, 1))
    net:add(nn.Squeeze(1, 3))
    
    -- convert output into a table format
    net:add(nn.View(1, -1))         -- vectorize
    net:add(nn.SplitTable(1, 1))    -- split all outputs into table elements
    
    print(net)
    
    -- the loss
    local loss = nn.SmoothL1Criterion()
    
    -- forward'ing x through the network would result in a (2)x4x4 output
    y = net:forward(x)
    
    print(y)
    
    -- returns the output table's index belonging to specific location
    function get_sample_idx(feat_h, feat_w, smpl_idx, feat_r, feat_c)
        local idx = (smpl_idx - 1) * feat_h * feat_w
        return idx + feat_c + ((feat_r - 1) * feat_w)
    end
    
    -- I want to back-propagate the loss of this sample at this feature location
    local smpl_idx = 2
    local feat_r = 3
    local feat_c = 4
    -- get the actual index location in the output table (for a 4x4 output feature map)
    local out_idx = get_sample_idx(4, 4, smpl_idx, feat_r, feat_c)
    
    -- the (fake) ground-truth
    local gt = torch.rand(1)
    
    -- compute loss on the selected feature map location for the selected sample
    local err = loss:forward(y[out_idx], gt)
    -- compute loss gradient, as if there was only this one location
    local dE_dy = loss:backward(y[out_idx], gt)
    -- now convert into full loss gradient (zero'ing out irrelevant losses)
    local full_dE_dy = nn.SelectTable(out_idx):backward(y, dE_dy)
    -- do back-prop through who network
    net:backward(x, full_dE_dy)
    
    print("The full dE/dy")
    print(table.unpack(full_dE_dy))
    

    如果有人指出一种更简单或更有效的方法,我将不胜感激。

    【讨论】:

      猜你喜欢
      • 2021-03-27
      • 1970-01-01
      • 1970-01-01
      • 2020-09-10
      • 2021-08-26
      • 2018-12-23
      • 2019-10-19
      • 1970-01-01
      • 2022-01-18
      相关资源
      最近更新 更多