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

Posted

技术标签:

【中文标题】如何将不同的成本函数应用于卷积网络的不同输出通道?【英文标题】:How to apply different cost functions to different output channels of a convolutional network? 【发布时间】:2016-09-23 16:34:49 【问题描述】:

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

所以成本有以下形式:

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 中做到这一点?

【问题讨论】:

【参考方案1】:

SplitTable 和 ParallelCriterion 可能对您的问题有所帮助。

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

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

在cmets之后,我添加了以下代码段解决了原来的问题。

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

【讨论】:

我不认为这是这样做的方法。当我将 nn.SplitTable(2) 添加到我的输出中时,它会给我一个包含 4 个元素的表格。每个元素都包含一个 2D 图像。但是,我想将成本函数应用于表的前两个元素,另一个成本函数应用于第三个通道,另一个成本函数应用于最后一个。你将如何实现它? 让问题更简单一点:假设我有一个卷积解码器网络,它输出一个大小为 [M x C x H x W] 的张量,其中 M 是批量大小,C 是通道数(2 的倍数),H = W 是整数。我想将输出拆分为一个表,其中包含两个元素,每个元素的大小为 [M x C / 2 x H x W]。我认为可以使用 nn.SplitTable() 来完成,但我没有正确地做到这一点。拆分张量后,我想对它们应用两个成本函数(这部分很简单)。你能给我一些提示吗?

以上是关于如何将不同的成本函数应用于卷积网络的不同输出通道?的主要内容,如果未能解决你的问题,请参考以下文章

『TensorFlow』网络操作API

1x1卷积Inception网络

1x1卷积Inception网络

怎么在c++的平台下用opencv做一个对图像的卷积?????

深度可分离卷积(depthwise separable convolution)参数计算

第55篇剪枝算法:通过网络瘦身学习高效卷积网络