PytorchでCNNの全結合層の入力サイズ(shape)を確かめる方法

ディープラーニング





PytorchでCNNの全結合層の入力サイズ(shape)を確かめる方法

Pytorchでは、CNNで畳み込み層の最終層の出力=全結合層の入力のサイズ(shape)を自動的に決めてくれません。

Kerasの場合は、自動的に求めてくれるので、楽です。

では、CNNで畳み込み層の最終層の出力のshapeはどのように求めればよいでしょうか。

CNNの畳み込み演算のサイズ変換は次のページで紹介しています。
畳み込み演算のサイズ変換式

実際に学習させるプログラムは、PytorchでCNNで紹介しています。

畳み込み層だけのネットワークで順伝播

畳み込み層だけのネットワークを定義します。

そのあとに、そのネットワークで順伝播させ、その出力から、shapeを確認します。

下のクラスでは、畳み込み層の出力のshapeを確認するためのメソッドも用意しています。

ネットワークの定義

ネットワークの定義は、conv層とdence層に分けて、Sequentialを使って定義します。
そのあと、このconv層を利用して、畳み込み層の出力サイズを確認します。(check_cnn_sizeメソッド)

#ネットワークの定義
class net(nn.Module):
    def __init__(self):
        super(net,self).__init__()
        #畳み込み層
        self.conv_layers = nn.Sequential(
            nn.Conv2d(in_channels = 1, out_channels = 16, kernel_size = 2, stride=1, padding=0),
            nn.Conv2d(in_channels = 16, out_channels = 32, kernel_size = 2, stride=1, padding=0),
        )
        #全結合層
        self.dence = nn.Sequential(

            #ここの入力サイズがわからない。
            nn.Linear('わからない', 128),
            nn.Dropout(p=0.2),
            nn.Linear(128, 64),
            nn.Dropout(p=0.2),
            nn.Linear(64, 10),
        )
        
    #順伝播
    def forward(self,x):
        
        out = self.conv_layers(x)
        #Flatten
        out = out.view(out.size(0), -1)
        #全結合層
        out = self.dence(out)
        
        return out
    
    #畳み込み層の出力サイズのチェック
    def check_cnn_size(self, size_check):
        out = self.conv_layers(size_check)
        
        return out

畳み込み層の出力サイズを確認する

ネットワークの定義で作った、check_cnn_sizeメソッドで、畳み込み層の出力サイズを確認します。

#デバイスの選択
device = 'cuda' if torch.cuda.is_available() else 'cpu'
#ネットワークの初期化
net = net().to(device)

#畳み込み層の入力サイズと同じサイズのデータを用意
size_check = torch.FloatTensor(10, 1, 8, 8)
size_check = size_check.to(device)
#畳み込み層の出力サイズを確認
print(net.check_cnn_size(size_check).size())

以上のプログラムを実行すると、

torch.Size([10, 32, 6, 6])

と出力されます。

CNNのshapeは、(batch_size, channel, W, H)となっています。

全結合層の入力サイズは、channel*W*Hとなることが確認できました。

全結合層の入力サイズを計算する

前の手順で、

畳み込み層サイズ(shape)は、(batch_size, channel, W, H)となっています。

したがって、全結合層の入力サイズは、channel*W*Hとなることが確認できました。

なので、このプログラムにおいて、全結合層の入力サイズは、(32 * 6 * 6)になります。

全結合層の定義を決定しましょう。

#全結合層
        self.dence = nn.Sequential(

            #ここの入力サイズがわからない。
            #nn.Linear('わからない', 128),
            #(32 * 6 * 6)だとわかった!
            nn.Linear(32*6*6, 128),
            nn.Dropout(p=0.2),
            nn.Linear(128, 64),
            nn.Dropout(p=0.2),
            nn.Linear(64, 10),
        )

参考書

タイトルとURLをコピーしました