簡體   English   中英

Pytorch Conv1D 為 ConvTranspose1d 提供不同的大小

[英]Pytorch Conv1D gives different size to ConvTranspose1d

我正在嘗試為 pytorch/pytorch-lightning 中的一維時間序列數據構建一個基本/淺層 CNN 自動編碼器。

目前,我的編碼塊是:

class encodingBlock(nn.Module):
    def __init__(self):
        super().__init__()
                
        self.conv1d_1 = nn.Conv1d(1, 64, kernel_size=32)
        self.relu = nn.ReLU()
        self.batchnorm = nn.BatchNorm1d(64)
        self.maxpool = nn.MaxPool1d(kernel_size=2, stride=2, return_indices=True)
        self.fc = nn.Linear(64, 4)

    def forward(self, x):
        cnn_out1 = self.conv1d_1(x)
        norm_out1 = self.batchnorm(cnn_out1)
        relu_out1 = self.relu(norm_out1)
        maxpool_out, indices = self.maxpool(relu_out1)
        gap_out = torch.mean(maxpool_out, dim = 2)
        fc_out = self.relu(self.fc(gap_out))
        return fc_out, indices

我的解碼塊是:

class decodingBlock(nn.Module):
    def __init__(self):
        super().__init__()
                
        self.Tconv1d_1 = nn.ConvTranspose1d(64, 1, kernel_size=32, output_padding=1)
        self.relu = nn.ReLU()
        self.batchnorm = nn.BatchNorm1d(1)
        self.maxunpool = nn.MaxUnpool1d(kernel_size=2, stride=2)
        self.upsamp = nn.Upsample(size=59, mode='nearest')
        self.fc = nn.Linear(4, 64)

    def forward(self, x, indices):
        fc_out = self.fc(x)
        relu_out = self.relu(fc_out)
        relu_out = relu_out.unsqueeze(dim = 2)
        upsamp_out = self.upsamp(relu_out)
        maxpool_out = self.maxunpool(upsamp_out, indices)
        cnnT_out = self.Tconv1d_1(maxpool_out)
        norm_out = self.batchnorm(cnnT_out)
        relu_out = self.relu(norm_out)            
        return relu_out

但是,查看輸出:

Input size: torch.Size([1, 1, 150])
Conv1D out size: torch.Size([1, 64, 119])
Maxpool out size: torch.Size([1, 64, 59])
Global average pooling out size: torch.Size([1, 64])
Encoder dense out size: torch.Size([1, 4])
...
Decoder input: torch.Size([1, 4])
Decoder dense out size: torch.Size([1, 64])
Unsqueeze out size: torch.Size([1, 64, 1])
Upsample out size: torch.Size([1, 64, 59])
Decoder maxunpool out size: torch.Size([1, 64, 118])
Transpose Conv out size: torch.Size([1, 1, 149])

MaxUnpool1d 和 ConvTranspose1d 層的輸出不是預期的維度。

我有兩個問題希望得到幫助:

  1. 為什么尺寸不對?
  2. 有沒有比我使用的上采樣程序更好的方法來“反轉”全局平均池化?

1.關於輸入和輸出形狀:
的文檔具有與輸入和輸出大小相關的顯式公式。 對於卷積 在此處輸入圖片說明

池化類似: 在此處輸入圖片說明

對於轉置卷積 在此處輸入圖片說明

對於解池 在此處輸入圖片說明

確保您的 padding 和output_padding值加起來為正確的輸出形狀。

2. 有沒有更好的方法?
正如您已經注意到的那樣,轉置卷積有其缺點。 它還傾向於產生“棋盤偽影”

一種解決方案是使用pixelshuffle :即,為每個低分辨率點預測通道數的兩倍,然后將它們分成具有所需特征數量的兩個點。

或者,您可以使用固定方法從低分辨率interpolate到較高分辨率。 對上采樣的向量應用常規卷積。 如果您選擇這條路徑,您可能會考慮使用ResizeRight而不是 pytorch 的 interpolate - 它可以更好地處理邊緣情況。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM