如何将全卷积网络(FCN)应用于二元分类?

huangapple go评论59阅读模式
英文:

How to apply Fully Convolutional Network (FCN) to binary classification?

问题

To change out_put_1.shape to [1, 1], you can modify the FCNDenseNet121_1 model's final classifier layer. Currently, it has a nn.Conv3d layer with a kernel size of 1, which results in the shape [1, 1, 3, 3, 3]. To change it to [1, 1], you should update the kernel size and stride of the nn.Conv3d layer to 3, like this:

self.classifier = nn.Conv3d(out_channels, 1, kernel_size=3, stride=3)

This will produce an output shape of [1, 1].

Regarding whether this is the correct way, it depends on your specific problem and requirements. Using a 3x3x3 convolution with a stride of 3 effectively reduces the spatial dimensions and channel count, resulting in a single-channel output. Whether this is suitable for your binary classification task depends on the nature of your data and the problem you're trying to solve.

As for out_put_2.shape being [1, 1], if it meets your requirements and provides the desired results for your binary classification task, it can be considered a valid approach. However, you should evaluate both models' performance on your dataset to determine which one works better for your specific problem.

英文:

I want to do binary classification with FCN. This is the code I implemented.

import monai
import torch
import torch.nn as nn

#FCN + DenseNet
class FCNDenseNet121_1(nn.Module):
    def __init__(self, spatial_dims:int, in_channels:int, out_channels:int):
        super().__init__()
        self.encoder = monai.networks.nets.DenseNet121(spatial_dims=spatial_dims, in_channels=in_channels, out_channels=out_channels)
        self.encoder.class_layers.pool = nn.AvgPool3d(kernel_size=1, stride=1)
        self.encoder.class_layers.flatten = nn.Identity()
        self.encoder.class_layers.out = nn.Identity()
        self.classifier = nn.Conv3d(out_channels, 1, kernel_size=1, stride=1)

    def forward(self, x):
        x = self.encoder(x)
        x = self.classifier(x)
        return x

class FCNDenseNet121_2(nn.Module):
    def __init__(self, spatial_dims:int, in_channels:int, out_channels:int):
        super().__init__()
        self.encoder = monai.networks.nets.DenseNet121(spatial_dims=spatial_dims, in_channels=in_channels, out_channels=out_channels)
        #self.encoder.class_layers.pool = nn.AvgPool3d(kernel_size=1, stride=1)
        self.encoder.class_layers.flatten = nn.Identity()
        self.encoder.class_layers.out = nn.Identity()
        self.classifier = nn.Conv3d(out_channels, 1, kernel_size=1, stride=1)

    def forward(self, x):
        x = self.encoder(x)
        x = self.classifier(x)
        x = x.view(x.size(0), -1)
        return x

#Built a model, my images are 3 dimensions
model_1 = FCNDenseNet121_1(spatial_dims=3, in_channels=1, out_channels=1024)

model_2 = FCNDenseNet121_2(spatial_dims=3, in_channels=1, out_channels=1024)

loss_function = torch.nn.BCEWithLogitsLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

#The operation verification
x = torch.randn(1,96,96,96)
print(x.shape)  #torch.Size([1, 96, 96, 96])
out_put_1 = model_1(x.unsqueeze(0))
out_put_2 = model_2(x.unsqueeze(0))
print(out_put_1.shape)  #torch.Size([1, 1, 3, 3, 3])
print(out_put_2.shape)  #torch.Size([1, 1])

I want to ask how to change out_put_1.shape to [1,1] to calculate loss.

First of all, is this correct way?

Although out_put_2.shape is [1,1], I don't know if this way of doing it is good.

Which is correct?

答案1

得分: 1

如果您的目标是执行二元分类,并且希望输出具有形状[1, 1],则应该使用 Model 2(FCNDenseNet121_2)。这是因为它已经输出了一个具有所需形状的张量。

但是,为了计算损失,您需要确保目标张量也具有形状[1, 1],以匹配输出张量。例如,如果您的目标张量是y,它也应该具有形状[1, 1]:

y = torch.tensor([[1]])  # 具有形状[1, 1]的示例目标张量
loss = loss_function(out_put_2, y)

请记住,在训练模型时,您还应该修改批量大小,因为您当前使用的批量大小为1。这通常不建议,因为它可能导致训练不稳定。增加批量大小以获得更好的训练性能。

英文:

If your goal is to perform binary classification, and you want your output to have the shape [1, 1], you should use Model 2 (FCNDenseNet121_2). This is because it already outputs a tensor with the desired shape.

However, to calculate the loss, you need to make sure the target tensor also has a shape of [1, 1] to match the output tensor. For instance, if your target tensor is y, it should have a shape of [1, 1] as well:

y = torch.tensor([[1]])  # example target tensor with shape [1, 1]
loss = loss_function(out_put_2, y)

Keep in mind that you should also modify the batch size when training the model, as you're currently using a batch size of 1. This is generally not recommended, as it can lead to unstable training. Increase the batch size for better training performance.

huangapple
  • 本文由 发表于 2023年5月11日 15:36:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/76225158.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定