lua - 如何将不同的成本函数应用于卷积网络的不同输出 channel ?

标签 lua machine-learning neural-network torch conv-neural-network

我有一个卷积神经网络,其输出是 4 channel 2D 图像。我想将 sigmoid 激活函数应用于前两个 channel ,然后使用 BCECriterion 计算生成图像与地面真实图像的损失。我想将平方损失函数应用于最后两个 channel ,最后计算梯度并进行反向传播。我还想将最后两个 channel 的平方损失成本乘以所需的标量。

因此成本具有以下形式:

cost = crossEntropyCh[{1, 2}] + l1 * squaredLossCh_3 + l2 * squaredLossCh_4

我考虑这样做的方式如下:

criterion1 = nn.BCECriterion()
criterion2 = nn.MSECriterion()

error = criterion1:forward(model.output[{{}, {1, 2}}], groundTruth1) + l1 * criterion2:forward(model.output[{{}, {3}}], groundTruth2) + l2 * criterion2:forward(model.output[{{}, {4}}], groundTruth3)

但是,我认为这不是正确的方法,因为我必须执行 3 个单独的反向传播步骤,每个成本项对应一个步骤。所以我想知道,谁能给我一个更好的解决方案来在 Torch 中做到这一点?

最佳答案

SplitTableParallelCriterion可能对您的问题有帮助。

您当前的输出层后面是 nn.SplitTable分割输出 channel 并将输出张量转换为表格。您还可以使用 ParallelCriterion 组合不同的功能以便将每个条件应用于输出表的相应条目。

有关详细信息,我建议您阅读 Torch 关于表的文档。

经过评论,我添加了以下代码段来解决原始问题。

M = 100
C = 4
H = 64
W = 64
dataIn = torch.rand(M, C, H, W)

layerOfTables = nn.Sequential()
-- Because SplitTable discards the dimension it is applied on, we insert
-- an additional dimension.
layerOfTables:add(nn.Reshape(M,C,1,H,W))
-- We want to split over the second dimension (i.e. channels).
layerOfTables:add(nn.SplitTable(2, 5))

-- We use ConcatTable in order to create paths accessing to the data for 
-- numereous number of criterions. Each branch from the ConcatTable will 
-- have access to the data (i.e. the output table).
criterionPath = nn.ConcatTable()
-- Starting from offset 1, NarrowTable will select 2 elements. Since you 
-- want to use this portion as a 2 dimensional channel, we need to combine
-- then by using JoinTable. Without JoinTable, the output will be again a 
-- table with 2 elements. 
criterionPath:add(nn.Sequential():add(nn.NarrowTable(1, 2)):add(nn.JoinTable(2)))
-- SelectTable is simplified version of NarrowTable, and it fetches the desired element.
criterionPath:add(nn.SelectTable(3))
criterionPath:add(nn.SelectTable(4))

layerOfTables:add(criterionPath)

-- Here goes the criterion container. You can use this as if it is a regular
-- criterion function (Please see the examples on documentation page).
criterionContainer = nn.ParallelCriterion()
criterionContainer:add(nn.BCECriterion())
criterionContainer:add(nn.MSECriterion())
criterionContainer:add(nn.MSECriterion())

由于我几乎使用了所有可能的表操作,所以它看起来有点令人讨厌。然而,这是我解决这个问题的唯一方法。我希望它能帮助您和其他遇到同样问题的人。结果如下:

dataOut = layerOfTables:forward(dataIn)
print(dataOut)
{
  1 : DoubleTensor - size: 100x2x64x64
  2 : DoubleTensor - size: 100x1x64x64
  3 : DoubleTensor - size: 100x1x64x64
}

关于lua - 如何将不同的成本函数应用于卷积网络的不同输出 channel ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37447859/

相关文章:

lua - Lua 在 Corona SDK 困惑中的地位

machine-learning - 通过机器学习计算图像中的车辆数量

machine-learning - 如何使用自然语言处理或其他技术从 html 中提取实体

image-processing - 我想知道MS COCO数据集中有没有服装对象类?

matrix - 实现注意力池网络问答的问题

lua - 在 Lua 中,如何从作为参数传递给我的函数的函数中获取函数的参数?

nginx - 如何检查nginx是否使用LuaJit而不是Lua?

syntax - 我可以为自己覆盖 Lua 表的返回值吗?

python - 如何测试我的分类器是否过度拟合?

python - scikit-neuralnetwork 的 mlp 分类器不适用于 xor