質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
CNN (Convolutional Neural Network)

CNN (Convolutional Neural Network)は、全結合層のみではなく畳み込み層とプーリング層で構成されるニューラルネットワークです。画像認識において優れた性能を持ち、畳み込みニューラルネットワークとも呼ばれています。

Q&A

解決済

1回答

2320閲覧

VGG16でサイズエラーが出てしまう

linpoti

総合スコア1

CNN (Convolutional Neural Network)

CNN (Convolutional Neural Network)は、全結合層のみではなく畳み込み層とプーリング層で構成されるニューラルネットワークです。画像認識において優れた性能を持ち、畳み込みニューラルネットワークとも呼ばれています。

0グッド

0クリップ

投稿2022/10/27 14:52

前提

cifar10のデータセットでVGG16を用いて精度を出したいです。

実現したいこと

サイズエラーになってしまうのでそれを改善したい。

発生している問題・エラーメッセージ

RuntimeError: Calculated padded input size per channel: (1 x 1). Kernel size: (3 x 3). Kernel size can't be greater than actual input size

該当のソースコード

python

1ソースコード 2import os 3import numpy as np 4import matplotlib.pyplot as plt 5 6import torch 7import torch.nn as nn 8import torch.nn.functional as F 9import torch.optim as optim 10import torchvision.transforms as transforms 11 12import torchvision 13from torchvision import models 14train_data_dir = './data/' 15 16pytorch_vgg16 = models.vgg16(pretrained=False) 17 18print(pytorch_vgg16) 19 20 21class myVGG(nn.Module): 22 23 def __init__(self): 24 super(myVGG, self).__init__() 25 26 self.conv01 = nn.Conv2d(3, 64, 3) 27 self.conv02 = nn.Conv2d(64, 64, 3) 28 self.pool1 = nn.MaxPool2d(2, 2) 29 30 self.conv03 = nn.Conv2d(64, 128, 3) 31 self.conv04 = nn.Conv2d(128, 128, 3) 32 self.pool2 = nn.MaxPool2d(2, 2) 33 34 self.conv05 = nn.Conv2d(128, 256, 3) 35 self.conv06 = nn.Conv2d(256, 256, 3) 36 self.conv07 = nn.Conv2d(256, 256, 3) 37 self.pool3 = nn.MaxPool2d(2, 2) 38 39 self.conv08 = nn.Conv2d(256, 512, 3) 40 self.conv09 = nn.Conv2d(512, 512, 3) 41 self.conv10 = nn.Conv2d(512, 512, 3) 42 self.pool4 = nn.MaxPool2d(2, 2) 43 44 self.conv11 = nn.Conv2d(512, 512, 3) 45 self.conv12 = nn.Conv2d(512, 512, 3) 46 self.conv13 = nn.Conv2d(512, 512, 3) 47 self.pool5 = nn.MaxPool2d(2, 2) 48 49 self.avepool1 = nn.AdaptiveAvgPool2d((7, 7)) 50 51 self.fc1 = nn.Linear(512 * 7 * 7, 4096) 52 self.fc2 = nn.Linear(4096, 4096) 53 self.fc3 = nn.Linear(4096, 5) 54 55 self.dropout1 = nn.Dropout(0.5) 56 self.dropout2 = nn.Dropout(0.5) 57 58 59 60 def forward(self, x): 61 x = F.relu(self.conv01(x)) 62 x = F.relu(self.conv02(x)) 63 x = self.pool1(x) 64 65 x = F.relu(self.conv03(x)) 66 x = F.relu(self.conv04(x)) 67 x = self.pool2(x) 68 69 x = F.relu(self.conv05(x)) 70 x = F.relu(self.conv06(x)) 71 x = F.relu(self.conv07(x)) 72 x = self.pool3(x) 73 74 x = F.relu(self.conv08(x)) 75 x = F.relu(self.conv09(x)) 76 x = F.relu(self.conv10(x)) 77 x = self.pool4(x) 78 79 x = F.relu(self.conv11(x)) 80 x = F.relu(self.conv12(x)) 81 x = F.relu(self.conv13(x)) 82 x = self.pool5(x) 83 84 x = self.avepool1(x) 85 86 # 行列をベクトルに変換 87 x = x.view(-1, 512 * 7 * 7) 88 89 x = F.relu(self.fc1(x)) 90 x = self.dropout1(x) 91 x = F.relu(self.fc2(x)) 92 x = self.dropout2(x) 93 x = self.fc3(x) 94 95 return x 96 97net = myVGG() 98 99 100transform_train = torchvision.transforms.Compose([ 101 torchvision.transforms.CenterCrop(224), 102 torchvision.transforms.ToTensor(), 103 torchvision.transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)) 104]) 105 106transform_valid = torchvision.transforms.Compose([ 107 torchvision.transforms.CenterCrop(224), 108 torchvision.transforms.ToTensor(), 109 torchvision.transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)) 110]) 111 112trainset = torchvision.datasets.CIFAR10(root=train_data_dir, 113 train=True, 114 transform=transforms.ToTensor(), 115 download=True) 116validset = torchvision.datasets.CIFAR10(root=train_data_dir, 117 train=False, 118 transform=transforms.ToTensor(), 119 download=True) 120 121 122# training set 123 124trainloader = torch.utils.data.DataLoader(trainset, batch_size=16, shuffle=True) 125 126# validation set 127 128validloader = torch.utils.data.DataLoader(validset, batch_size=16, shuffle=False) 129 130 131device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") 132net.to(device) 133net.train() 134 135criterion = nn.CrossEntropyLoss() 136optimizer = optim.Adam(net.parameters(), lr=0.00001) 137 138# 同じデータを 50 回学習します 139for epoch in range(50): 140 141 # 今回の学習効果を保存するための変数 142 running_loss = 0.0 143 144 for data in trainloader: 145 # データ整理 146 inputs, labels = data 147 inputs = inputs.to(device) 148 labels = labels.to(device) 149 150 # 前回の勾配情報をリセット 151 optimizer.zero_grad() 152 153 # 予測 154 outputs = net(inputs) 155 156 # 予測結果と教師ラベルを比べて損失を計算 157 loss = criterion(outputs, labels) 158 running_loss += loss.item() 159 160 # 損失に基づいてネットワークのパラメーターを更新 161 loss.backward() 162 optimizer.step() 163 164 # このエポックの学習効果 165 print(running_loss) 166 167 168optimizer = optim.Adam(net.parameters(), lr=0.000001) 169 170for epoch in range(50): 171 running_loss = 0.0 172 for data in trainloader: 173 inputs, labels = data 174 inputs = inputs.to(device) 175 labels = labels.to(device) 176 optimizer.zero_grad() 177 outputs = net(inputs) 178 loss = criterion(outputs, labels) 179 running_loss += loss.item() 180 loss.backward() 181 optimizer.step() 182 print(running_loss) 183 184 185# モデルを評価モードにする 186net.eval() 187 188# 全検証データの正しく分類できた枚数を記録 189n_correct = 0 190n_total = 0 191 192for data in validloader: 193 inputs, labels = data 194 inputs = inputs.to(device) 195 labels = labels.to(device) 196 197 # 予測 198 outputs = net(inputs) 199 200 # 予測結果をクラス番号に変換 201 _, predicted = torch.max(outputs.data, 1) 202 203 # 予測結果と実際のラベルを比較して、正しく予測できた枚数を計算 204 res = (predicted == labels) 205 res = res.sum().item() 206 207 208 # 今までに正しく予測できた枚数に計上 209 n_correct = n_correct + res 210 n_total = n_total + len(labels) 211 212 213print(n_correct / n_total) 214 215### 試したこと 216 217色々調査してみたのですがわかりません 218 219### 補足情報(FW/ツールのバージョンなど) 220 221

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jbpb0

2022/10/27 15:24 編集

> RuntimeError: Calculated padded input size per channel: (1 x 1). Kernel size: (3 x 3). Kernel size can't be greater than actual input size CIFAR10の画像のサイズ32x32に対して、畳み込み層の層数が多すぎます 畳み込み層を減らすか、入力画像のサイズを大きくするかしたら、質問のエラーは出なくなります たとえば、下記のようにして画像サイズを256x256にすれば、質問のエラーは出なくなると思います transform = transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.5, ), (0.5,)), transforms.Resize(256) ]) trainset = datasets.CIFAR10(root="./data", train=True, download=True, transform=transform) validset = datasets.CIFAR10(root="./data", train=False, download=True, transform=transform) 画像サイズを変えたくなければ、ネットワーク設計を見直してください 上記を変更したら、それよりも後(下)のところで別のエラーが出ますが、それはこの質問のエラーとは別の内容なので、別の質問にしてください
linpoti

2022/10/28 02:03

datasets is not defined とでました。 trainset = datasets.CIFAR10(root="./data", train=True, download=True, transform=transform) の部分を trainset = torchvision.datasets.CIFAR10(root="./data", train=True, download=True, transform=transform) tとするとこのエラーは出ませんでした。
jbpb0

2022/10/28 02:13

> datasets is not defined 以前 https://teratail.com/questions/ra3upl68o5eonm のコードを動かした時に、エラーが全部出なくなるように直したので、それをそのまま書いたためです > trainset = torchvision.datasets.CIFAR10(root="./data", train=True, download=True, transform=transform) tとするとこのエラーは出ませんでした。 そのあたり変えてるのですね そんなに細かいところは見てないので、今のコードに合わせて直してください
jbpb0

2022/10/28 03:30 編集

この質問のコードを、私の最初のコメントの通りに変更して、さらに > trainset = datasets.CIFAR10(root="./data", train=True, download=True, transform=transform) の部分を trainset = torchvision.datasets.CIFAR10(root="./data", train=True, download=True, transform=transform) と変更して、「validset」も同様に変更して、google colab(gpu有り)で実行したら、この質問のエラー > RuntimeError: Calculated padded input size per channel: (1 x 1). Kernel size: (3 x 3). Kernel size can't be greater than actual input size は出なくなりました 原因が違う別のエラーが「running_loss += loss.item()」の行で出ますが、そのエラーは > TypeError: 'module' object is not callable というエラーが出ました。 とは違うものです 質問者さんの環境で実行したら、上記とは違う結果になるのでしょうか? 【追記】 google colabでgpu無しで実行したら、エラーが出る行が一つ上の「loss = criterion(outputs, labels)」に変わりましたが、そのエラーも > TypeError: 'module' object is not callable というエラーが出ました。 とは違うものでした gpu有り/無しどちらの場合のエラーも原因は同じで、この質問のエラーとは違う内容です
linpoti

2022/10/28 03:42

import os import numpy as np import matplotlib.pyplot as plt import torch import torch.nn as nn import torch.nn.functional as F import torch.optim as optim import torchvision.transforms as transforms import torchvision from torchvision import models train_data_dir = './data/' pytorch_vgg16 = models.vgg16(pretrained=False) print(pytorch_vgg16) class myVGG(nn.Module): def __init__(self): super(myVGG, self).__init__() self.conv01 = nn.Conv2d(3, 64, 3) self.conv02 = nn.Conv2d(64, 64, 3) self.pool1 = nn.MaxPool2d(2, 2) self.conv03 = nn.Conv2d(64, 128, 3) self.conv04 = nn.Conv2d(128, 128, 3) self.pool2 = nn.MaxPool2d(2, 2) self.conv05 = nn.Conv2d(128, 256, 3) self.conv06 = nn.Conv2d(256, 256, 3) self.conv07 = nn.Conv2d(256, 256, 3) self.pool3 = nn.MaxPool2d(2, 2) self.conv08 = nn.Conv2d(256, 512, 3) self.conv09 = nn.Conv2d(512, 512, 3) self.conv10 = nn.Conv2d(512, 512, 3) self.pool4 = nn.MaxPool2d(2, 2) self.conv11 = nn.Conv2d(512, 512, 3) self.conv12 = nn.Conv2d(512, 512, 3) self.conv13 = nn.Conv2d(512, 512, 3) self.pool5 = nn.MaxPool2d(2, 2) self.avepool1 = nn.AdaptiveAvgPool2d((7, 7)) self.fc1 = nn.Linear(512 * 7 * 7, 4096) self.fc2 = nn.Linear(4096, 4096) self.fc3 = nn.Linear(4096, 5) self.dropout1 = nn.Dropout(0.5) self.dropout2 = nn.Dropout(0.5) def forward(self, x): x = F.relu(self.conv01(x)) x = F.relu(self.conv02(x)) x = self.pool1(x) x = F.relu(self.conv03(x)) x = F.relu(self.conv04(x)) x = self.pool2(x) x = F.relu(self.conv05(x)) x = F.relu(self.conv06(x)) x = F.relu(self.conv07(x)) x = self.pool3(x) x = F.relu(self.conv08(x)) x = F.relu(self.conv09(x)) x = F.relu(self.conv10(x)) x = self.pool4(x) x = F.relu(self.conv11(x)) x = F.relu(self.conv12(x)) x = F.relu(self.conv13(x)) x = self.pool5(x) x = self.avepool1(x) # 行列をベクトルに変換 x = x.view(-1, 512 * 7 * 7) x = F.relu(self.fc1(x)) x = self.dropout1(x) x = F.relu(self.fc2(x)) x = self.dropout2(x) x = self.fc3(x) return x net = myVGG() transform_train = torchvision.transforms.Compose([ torchvision.transforms.CenterCrop(224), torchvision.transforms.ToTensor(), torchvision.transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)) ]) transform_valid = torchvision.transforms.Compose([ torchvision.transforms.CenterCrop(224), torchvision.transforms.ToTensor(), torchvision.transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)) ]) transform = transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.5, ), (0.5,)), transforms.Resize(256) ]) trainset = torchvision.datasets.CIFAR10(root=train_data_dir, train=True, transform=transforms.ToTensor(), download=True) validset = torchvision.datasets.CIFAR10(root=train_data_dir, train=False, transform=transforms.ToTensor(), download=True) # training set trainloader = torch.utils.data.DataLoader(trainset, batch_size=16, shuffle=True) # validation set validloader = torch.utils.data.DataLoader(validset, batch_size=16, shuffle=False) device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") net.to(device) net.train() criterion = nn.CrossEntropyLoss() optimizer = optim.Adam(net.parameters(), lr=0.00001) # 同じデータを 50 回学習します for epoch in range(50): # 今回の学習効果を保存するための変数 running_loss = 0.0 for data in trainloader: # データ整理 inputs, labels = data inputs = inputs.to(device) labels = labels.to(device) # 前回の勾配情報をリセット optimizer.zero_grad() # 予測 outputs = net(inputs) # 予測結果と教師ラベルを比べて損失を計算 loss = criterion(outputs, labels) running_loss += loss.item() # 損失に基づいてネットワークのパラメーターを更新 loss.backward() optimizer.step() # このエポックの学習効果 print(running_loss) optimizer = optim.Adam(net.parameters(), lr=0.000001) for epoch in range(50): running_loss = 0.0 for data in trainloader: inputs, labels = data inputs = inputs.to(device) labels = labels.to(device) optimizer.zero_grad() outputs = net(inputs) loss = criterion(outputs, labels) running_loss += loss.item() loss.backward() optimizer.step() print(running_loss) # モデルを評価モードにする net.eval() # 全検証データの正しく分類できた枚数を記録 n_correct = 0 n_total = 0 for data in validloader: inputs, labels = data inputs = inputs.to(device) labels = labels.to(device) # 予測 outputs = net(inputs) # 予測結果をクラス番号に変換 _, predicted = torch.max(outputs.data, 1) # 予測結果と実際のラベルを比較して、正しく予測できた枚数を計算 res = (predicted == labels) res = res.sum().item() # 今までに正しく予測できた枚数に計上 n_correct = n_correct + res n_total = n_total + len(labels) print(n_correct / n_total) 色々変更を加えていま自分のコードが回答者様の言うように変えれているか不安です。今このコードでやってみたところ同じようなサイズエラーがでてしまいました。全くわかっていなくてすいません。もしよろしければ教えていただきたいです。
jbpb0

2022/10/28 04:29 編集

> 色々変更を加えていま自分のコードが回答者様の言うように変えれているか不安 下記のようにやってみてください ・この質問の「該当のソースコード」のコードを、全部そのままコピペ ・先頭の「ソースコード」の行と、最後に近い「色々調査してみたのですがわかりません」の行を削除 ・下記を変更 trainset = torchvision.datasets.CIFAR10(root=train_data_dir, train=True, transform=transforms.ToTensor(), download=True) validset = torchvision.datasets.CIFAR10(root=train_data_dir, train=False, transform=transforms.ToTensor(), download=True) ↓ 変更 transform = transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.5, ), (0.5,)), transforms.Resize(256) ]) trainset = torchvision.datasets.CIFAR10(root=train_data_dir, train=True, download=True, transform=transform) validset = torchvision.datasets.CIFAR10(root=train_data_dir, train=False, download=True, transform=transform) そうすれば、当方でgoogle colabで実行したコードと同じになるので、この質問のエラーは出なくなるはずです
linpoti

2022/10/28 04:30

ご丁寧にありがとうございます。この質問のエラーはなくなりました。 RuntimeError: CUDA error: device-side assert triggered CUDA kernel errors might be asynchronously reported at some other API call,so the stacktrace below might be incorrect. For debugging consider passing CUDA_LAUNCH_BLOCKING=1. 新たにこのようなエラーがでてしまいました。 原因としては ライブラリのVersionが違う ラベル/クラスの数とネットワークの入出力のshapeが異なる Loss関数の入力が正確でない などが挙げられるらしいのですが対処方法がわかりません。
jbpb0

2022/10/28 04:39

> RuntimeError: CUDA error: device-side assert triggered CUDA kernel errors might be asynchronously reported at some other API call,so the stacktrace below might be incorrect. For debugging consider passing CUDA_LAUNCH_BLOCKING=1. の原因は > ラベル/クラスの数とネットワークの入出力のshapeが異なる です device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") ↓ 変更 device = "cpu" と変えてgpuを使わないようにした時のエラーメッセージの方が原因が分かりやすいので、そうしてみてください そのエラーメッセージを見ても原因が分からなければ、この質問のエラーとは別の内容なので、別の質問にしてください
linpoti

2022/10/28 04:44

IndexError: Target 7 is out of bounds. というエラーになりました。
jbpb0

2022/10/28 04:50

> IndexError: Target 7 is out of bounds. の原因は、先のコメントにも書いたように > ラベル/クラスの数とネットワークの入出力のshapeが異なる です 考えても分からなければ、別の質問にしてください
jbpb0

2022/10/28 04:57 編集

あと、入力画像サイズを256x256にしたのは、ネットワーク構造を変えずにエラーが出なくなるようにした対策ですが、それが望ましい対処方法かどうかは、質問者さんの目的に照らし合わせて判断してください 入力画像サイズを32x32から変えずに実行したいのであれば、私の最初のコメントにも書きましたが、ネットワーク設計を見直してください (畳み込み層の層数を減らす等) 【追記】 上記は、今出てる > IndexError: Target 7 is out of bounds. とは関係ありません もともと出てた > RuntimeError: Calculated padded input size per channel: (1 x 1). Kernel size: (3 x 3). Kernel size can't be greater than actual input size の対策の話です
linpoti

2022/10/28 04:54

なるほど。全くわからないので別の質問で投稿させていただきます。
linpoti

2022/10/28 04:57

どの方法が望ましいのかもわからない状態です。 ネットの記事のコードを参考にしているためどのように書き換えるべきかわかっていません。 何度も教えていただいているのに申し訳ないです。
jbpb0

2022/10/28 05:01

> どの方法が望ましいのかもわからない状態です。 全部のエラーが消えて学習できるようになってから考えればいいと思いますよ
guest

回答1

0

ベストアンサー

RuntimeError: Calculated padded input size per channel: (1 x 1). Kernel size: (3 x 3). Kernel size can't be greater than actual input size

CIFAR10の画像のサイズ32x32に対して、畳み込み層の層数が多すぎます
畳み込み層を減らすか、入力画像のサイズを大きくするかしたら、質問のエラーは出なくなると思います

投稿2022/11/03 02:33

jbpb0

総合スコア7651

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問