初めに
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 )
まとめ
以上の情報から画像のサイズのミスマッチが起きているのがわかるのですが、どこをどう編集すればいいのかがわかりません。
正直、パラメータをあんまり考えずに設定してしまったため、ご指摘があればありがたいです。
なにか、不備がありましたらご指摘していただけると助かります。
エラーの解消と、どこをどう編集していけばいいのか教えていただけるとありがたいです。
回答1件
あなたの回答
tips
プレビュー