【问题标题】:How to do softmax for pixelwise classification如何为像素级分类做softmax
【发布时间】:2018-11-05 04:00:34
【问题描述】:

我的目标是使用像素分类进行灰度图像分割。所以我有两个标签 0 和 1。我在 pytorch 中创建了一个网络,如下所示。

class Net(nn.Module):

def __init__(self):
    super(Net, self).__init__()

    self.up = nn.Upsample(scale_factor=2, mode='nearest')

    self.conv11 = nn.Conv2d(1, 128, kernel_size=3, padding=1)
    self.conv12 = nn.Conv2d(128, 256, kernel_size=3, padding=1)
    self.conv13 = nn.Conv2d(256, 2, kernel_size=3, padding=1)  



def forward(self, x):
    in_size = x.size(0)

    x = F.relu(self.conv11(x))
    x = F.relu(self.conv12(x))
    x = F.relu(self.conv13(x))

    x = F.softmax(x, 2)

    return x

在最后一层中,我设计了 conv13,使其为每个类生成 2 个通道。

由于我使用的是 softmax,因此我期望 2 个单独通道上相同索引的值的总和等于 1。

例如假设输出图像是 (2{channel}, 4, 4)。所以我很期待

图像[ 通道 1 ][0][0] + 图像[ 通道 2 ][0][0] = 1

但我得到的输出是 0.0015,甚至不接近 1。我如何使用 softmax 来预测通道?

为了检查这一点,我使用了以下代码

for batch, data in enumerate(trainloader, 0):
    inputs , labels = data
    inputs, labels = inputs.to(device), labels.to(device)


    optimizer.zero_grad()
    outputs = net(inputs)
    loss = rmse(outputs, labels)
    loss.backward()
    optimizer.step()
    running_loss += loss.item()


    predicted = outputs.data
    predicted = predicted.to('cpu')
    predicted_img = predicted.numpy()

    predicted_img = np.reshape(predicted_img,(2, 4, 4))

    print(predicted_img[0])
    print(predicted_img[1])

那些印刷品表明了这一点

[[**0.2762002** 0.13305853 0.2510342 0.23114938] [0.26812425 0.28500515 0.05682982 0.15851443] [0.1640967 0.5409352 0.43547812 0.44782472] [0.29157883 0.0410011 0.2566578 0.16251141]]

[[**0.23052207** 0.868455 0.43436486 0.0684725 ] [0.18001427 0.02341573 0.0727293 0.2525512 ] [0.06587404 0.04974682 0.3773188 0.6559266 ] [0.5235896 0.05838248 0.11558701 0.02304965]]

很明显,对应的元素并没有像这样求和为1

0.2762002(索引 0, 0)+ 0.23052207(索引 0, 0)!= 1

我该如何解决?

【问题讨论】:

  • 为什么同时有 tensorflow 和 pytorch 标签?
  • 已编辑!似乎stackoverflow自动建议了标签tensorflow,我过早地提交了问题而没有删除它!

标签: computer-vision image-segmentation pytorch


【解决方案1】:

请检查我的代码的最后一行.. 基本上你的 softmax 维度是错误的。

class Net(nn.Module):

  def __init__(self):
        super(Net, self).__init__()

        self.up = nn.Upsample(scale_factor=2, mode='nearest')

        self.conv11 = nn.Conv2d(1, 128, kernel_size=3, padding=1)
        self.conv12 = nn.Conv2d(128, 256, kernel_size=3, padding=1)
        self.conv13 = nn.Conv2d(256, 2, kernel_size=3, padding=1)  



    def forward(self, x):
        in_size = x.size(0)

        x = F.relu(self.conv11(x))
        x = F.relu(self.conv12(x))
        x = F.relu(self.conv13(x))

        x = F.softmax(x, 1) #this line is changed

        return x

net = Net()
inputs = torch.rand(1,1,4,4)
out = net (Variable(inputs))
print (out)
out.sum(dim=1)

希望对您有所帮助。

【讨论】:

  • 非常感谢。基本上我不久前就想通了。我给了 F.softmax(x, 2) 2 两门课。但是后来意识到参数询问的是在哪个维度上执行softmax,它不询问类的数量。因为我希望它跨越通道,所以值将是 1,因为火炬张量的形状像 [批次、通道、高度、宽度]。
猜你喜欢
  • 1970-01-01
  • 2019-03-08
  • 2019-12-03
  • 1970-01-01
  • 2019-07-20
  • 1970-01-01
  • 1970-01-01
  • 2019-07-24
  • 2020-09-02
相关资源
最近更新 更多