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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

PyTorch

PyTorchは、オープンソースのPython向けの機械学習ライブラリ。Facebookの人工知能研究グループが開発を主導しています。強力なGPUサポートを備えたテンソル計算、テープベースの自動微分による柔軟なニューラルネットワークの記述が可能です。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Q&A

解決済

1回答

7520閲覧

pytorchの画像分類でRuntimeError: size mismatch, が出るんですがどうすればいいでしょうか?

oinari03

総合スコア59

Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

PyTorch

PyTorchは、オープンソースのPython向けの機械学習ライブラリ。Facebookの人工知能研究グループが開発を主導しています。強力なGPUサポートを備えたテンソル計算、テープベースの自動微分による柔軟なニューラルネットワークの記述が可能です。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

0グッド

0クリップ

投稿2020/09/02 19:07

編集2020/09/03 01:46

初めに

pytorchを使用して画像分類をしようとしています。
私のデータセットは256×256×3で構成されていて、100枚ほど入ってると思われます。
以下ディレクトリ構成です。

├─animal_dataset ├─train │ ├─cat(70枚くらい) │ └─dog(70枚くらい) └─val ├─cat(30枚くらい) └─dog(30枚くらい)

エラー文

以下はtrain.pyを実行したら起きたものです。

RuntimeError: Expected 4-dimensional input for 4-dimensional weight [16, 3, 3, 3], but got 2-dimensional input of size [32, 196608] instead

コード

train.py(実行したコード)です。まだ完成されていませんが、lossやaccの精度なんかを見ようとしてます。

python

1import torch 2import torch.nn as nn 3import torch.nn.functional as F 4 5import torch.optim as optim 6import model,dataset 7from model import * 8 9from tqdm import tqdm 10from torch.autograd import Variable 11 12 13 14 15#一つの機能を作ったら→pritで確認 16device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') 17 18 19# 上でgpuの設定device 20if __name__ == "__main__": 21 # modelの定義 22 model = model.Net() 23 24 25 # optimizerの定義 26 optimizer = torch.optim.SGD( 27 model.parameters(), lr=0.001, momentum=0.9, weight_decay=0.0001) 28 29 # datasetの定義 30 # training 31 train_dataset = dataset.MyDatasets( 32 root_dir="./animal_dataset", 33 key="train", 34 ) 35 train_loader = torch.utils.data.DataLoader( 36 train_dataset, 37 batch_size=32, 38 shuffle= True 39 ) 40 41 # validation 42 valid_dataset = dataset.MyDatasets( 43 root_dir="./animal_dataset", 44 key="val", 45 ) 46 47 valid_loader = torch.utils.data.DataLoader( 48 valid_dataset, 49 batch_size=32, 50 shuffle= True 51 ) 52 53 # batch = len(next(iter(train_loader))) #2 54 # for i in train_loader: 55 # print(i) 56 # for i in valid_loader: 57 # print(i) 58 59 # iterationの確定 60 sample_size = len(train_dataset) #129 61 num_iters = sample_size // 32 #129 / 32 = 4.03 62 63 #loss 64 criterion = nn.CrossEntropyLoss() 65 66 #start epoch 67 #2エポック 68 num_epochs = 2 69 70 #最後にlossとaccuracyのグラフをプロットするためのリスト 71 train_loss_list = [] 72 train_acc_list = [] 73 val_loss_list = [] 74 val_acc_list = [] 75 76 for epoch in range(num_epochs): 77 #エポックごとに初期化 78 train_loss = 0 79 train_acc = 0 80 val_loss = 0 81 val_acc = 0 82 #train============================== 83 #訓練モードへ切り替え 84 model.train() 85 #ミニバッチで分割して読み込む 86 for i, (images, labels) in enumerate(train_loader): 87 #viewで縦横32ピクセルで3チャンネルの画像を1次元に変換 88 #toでgpuに転送 89 images, labels = images.view(images.shape[0], -1).to(device), labels.to(device) 90 91 #勾配をリセット 92 optimizer.zero_grad() 93 #順伝播の計算 94 outputs = model(images) 95 #lossの計算 96 loss = criterion(outputs, labels) 97 #lossのミニバッチ分を溜め込む 98 train_loss += loss.item() 99 #accuracyをミニバッチ分を溜め込む 100 #正解ラベル(labels)と予測値のtop1(outputs.max(1))が合っている場合に1が返ってきます。 101 train_acc += (outputs.max(1)[1] == labels).sum().item() 102 #逆伝播の計算 103 loss.backward() 104 #重みの更新 105 optimizer.step() 106 #平均lossと平均accuracyを計算 107 avg_train_loss = train_loss / len(train_loader.dataset) 108 avg_train_acc = train_acc / len(train_loader.dataset) 109 110 #val============================== 111 #評価モードへ切り替え 112 model.eval() 113 #評価するときに必要のない計算が走らないようにtorch.no_gradを使用しています。 114 with torch.no_grad(): 115 for images, labels in valid_loader: 116 images, labels = images.view(-1, 32*32*3).to(device), labels.to(device) 117 outputs = model(images) 118 loss = criterion(outputs, labels) 119 val_loss += loss.item() 120 val_acc += (outputs.max(1)[1] == labels).sum().item() 121 avg_val_loss = val_loss / len(valid_loader.dataset) 122 avg_val_acc = val_acc / len(valid_loader.dataset) 123 124 #訓練データのlossと検証データのlossとaccuracyをログで出しています。 125 print ('Epoch [{}/{}], Loss: {loss:.4f}, val_loss: {val_loss:.4f}, val_acc: {val_acc:.4f}' 126 .format(epoch+1, num_epochs, i+1, loss=avg_train_loss, val_loss=avg_val_loss, val_acc=avg_val_acc)) 127 #最後にグラフをプロットするようにリストに格納 128 train_loss_list.append(avg_train_loss) 129 train_acc_list.append(avg_train_acc) 130 val_loss_list.append(avg_val_loss) 131 val_acc_list.append(avg_val_acc)

以下はmodelの実装です。おそらく、こちらでミスしていると思うのですが、同編集すればいいのか...
model.pyです。

python

1class Net(nn.Module): 2 3 def __init__(self): 4 super(Net, self).__init__() 5 self.relu = nn.ReLU() 6 7 # input: RGB 3 ,output : 16, kernel 3(default) 8 self.conv1 = nn.Conv2d(3, 16, 3) 9 # print(self.conv1.weight) 10 self.pool1 = nn.MaxPool2d(2,stride=2) 11 12 self.conv2 = nn.Conv2d(16, 32, 3) 13 self.pool2 = nn.MaxPool2d(2,stride=2) 14 15 self.conv3 = nn.Conv2d(32, 64, 3) 16 self.pool3 = nn.MaxPool2d(2,stride=2) 17 18 self.conv4 = nn.Conv2d(64, 128, 3) 19 self.pool4 = nn.MaxPool2d(2,stride=2) 20 21 self.conv5 = nn.Conv2d(128, 256, 3) 22 self.pool5 = nn.MaxPool2d(2,stride=2) 23 24 25 26 # an affine operation: y = Wx + b 27 # linearにおけるout_featuresとはなんだろうか 28 self.fc1 = nn.Linear(256 * 3 * 3, 120) 29 self.fc2 = nn.Linear(120, 84) 30 self.fc3 = nn.Linear(84, 2) 31 32 def forward(self, x): 33 # conv relu poolの流れを実行してみる 34 35 x = self.conv1(x) 36 x = self.relu(x) 37 x = self.pool1(x) 38 39 x = self.conv2(x) 40 x = self.relu(x) 41 x = self.pool2(x) 42 43 x = self.conv3(x) 44 x = self.relu(x) 45 x = self.pool3(x) 46 47 x = self.conv4(x) 48 x = self.relu(x) 49 x = self.pool4(x) 50 51 x = self.conv5(x) 52 x = self.relu(x) 53 x = self.pool5(x) 54 55 x = x.view(x.size()[0], -1) 56 x = self.fc1(x) 57 x = self.relu(x) 58 x = self.fc2(x) 59 x = self.relu(x) 60 x = self.fc3(x) 61 62 return F.log_softmax(x,dim=1) 63 64 65 66if __name__ == "__main__": 67 68 net = Net() 69 print(net) 70

model.pyの出力結果を示します。
ここでは最後のLinearでの数値とあっていないように思えます。

Net( (relu): ReLU() (conv1): Conv2d(3, 16, kernel_size=(3, 3), stride=(1, 1)) (pool1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False) (conv2): Conv2d(16, 32, kernel_size=(3, 3), stride=(1, 1)) (pool2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False) (conv3): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1)) (pool3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False) (conv4): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1)) (pool4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False) (conv5): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1)) (pool5): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False) (fc1): Linear(in_features=2304, out_features=120, bias=True) (fc2): Linear(in_features=120, out_features=84, bias=True) (fc3): Linear(in_features=84 )

まとめ

以上の情報から画像のサイズのミスマッチが起きているのがわかるのですが、どこをどう編集すればいいのかがわかりません。

正直、パラメータをあんまり考えずに設定してしまったため、ご指摘があればありがたいです。
なにか、不備がありましたらご指摘していただけると助かります。

エラーの解消と、どこをどう編集していけばいいのか教えていただけるとありがたいです。

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

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

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

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

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

tiitoi

2020/09/03 01:57 編集

なぜ CNN モデルなのに入力を images.view(images.shape[0], -1) で1次元にしているのでしょうか?
oinari03

2020/09/03 02:01

ご指摘ありがとうございます。自分が.viewの使い方を理解してなかったためにどこかの記事にある通りにしてしまったからです。cnnで一次元にしないとなると通常どのように設定すればいいのでしょうか....
guest

回答1

0

ベストアンサー

RuntimeError: Expected 4-dimensional input for 4-dimensional weight [16, 3, 3, 3], but got 2-dimensional input of size [32, 196608] instead

4次元配列の入力を期待しているのに、2次元配列が入力として与えられたというエラーです。
原因は images.view(images.shape[0], -1) で4次元配列を2次元配列にしていることです。

cnnで一次元にしないとなると通常どのように設定すればいいのでしょうか....

.view(images.shape[0], -1) を削除すればいいと思います。

diff

1- images, labels = images.view(images.shape[0], -1).to(device), labels.to(device) 2+ images, labels = images.to(device), labels.to(device)

参考リンク

Pytorch - 事前学習モデルを使ってクラス分類モデルを学習する方法

投稿2020/09/03 02:06

編集2020/09/03 02:06
tiitoi

総合スコア21956

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

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

oinari03

2020/09/03 03:25 編集

ありがとうございます。 これでひとまず解消できました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問