前提
Linux
GPU
python3
pytorch
画像データは正方形、サイズ:255*255に揃えたものを使用しています。
実現したいこと
python3とpytorchを用いてCNNによるYESかNOの画像分類を行いたいです。
発生している問題・エラーメッセージ
画像データのサイズをすべて合わせているにもかかわらず、
以下のエラーが発生しています。
画像枚数を増やす前は同様の画像データで実行ができていました。
調べても要因がわからないためどなたか教えていただきたいです。
RuntimeError: stack expects each tensor to be equal size, but got [3, 512, 512] at entry 0 and [3, 1095, 1280] at entry 5
該当のソースコード
#CNN学習 #memo7_GPUより import copy import time import os import tqdm import torchvision.transforms as transforms import torchvision.models as models import torchvision from torchvision import transforms from torch.utils.data import (DataLoader,Dataset,TensorDataset) import torch.optim as optim import torch.nn as nn import torch def saveModel(): path="./sim.pth " #modelを保存するファイル名 torch.save(model.state_dict(),path) data_tr_folder = "./learning98"#data写真データのフォルダ(学習) data_vl_folder = "./test1" #data写真データのフォルダ(テスト) transform_dict = { 'train': transforms.Compose([ #transforms.RandomCrop(127),#画像リサイズいろいろ。ramdomarop以外にもあるから調べてみる transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), ]), 'val': transforms.Compose([ #transforms.CenterCrop(127), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), ])} transform = transform_dict["train"] data_tr = torchvision.datasets.ImageFolder(root=data_tr_folder, transform=transform_dict["train"]) data_vl = torchvision.datasets.ImageFolder(root=data_vl_folder, transform=transform_dict["val"]) train_size = int(len(data_tr)) # int()で整数に。 val_size = int(len(data_vl)) data_size = {"train":train_size, "val":val_size} # =>{"train": 4800, "val":800} #data_train = torch.utils.data.random_split(data_tr,train_size) #data_val = torch.utils.data.random_split(data_vl,val_size) batch_size=32 #バッチサイズ train_loader = torch.utils.data.DataLoader(data_tr, batch_size=batch_size, shuffle=True) #val_loaderをtest_loaderに名前かえてみた test_loader = torch.utils.data.DataLoader(data_vl, batch_size=batch_size, shuffle=True) dataloaders = {"train":train_loader, "val":test_loader} #上記データセット作成 # リスト4.2 2層の畳み込み層と2層のMLPをつなげたCNNを作成 # In[ ]: # (N、C、H、W)形式のTensorを(N, C*H*W)に引き伸ばす層 # 畳み込み層の出力をMLPに渡す際に必要 class FlattenLayer(nn.Module): def forward(self, x): sizes = x.size() return x.view(sizes[0], -1) # size = x.size()[1:] # all dimensions except the batch dimension #num_features = 1 #for s in size: # num_features *= s # return num_features #CNNの本体 conv_net = nn.Sequential( nn.Conv2d(3, 32, 5),#カラーなら3でOK、32は画像のサイズによって変更したらうまくいくかも nn.MaxPool2d(2), nn.ReLU(), nn.BatchNorm2d(32), nn.Dropout2d(0.5), ### nn.Conv2d(32, 64, 5), nn.MaxPool2d(2), nn.ReLU(), nn.BatchNorm2d(64), nn.Dropout2d(0.5), ### nn.Conv2d(64, 128, 5), nn.MaxPool2d(2), nn.ReLU(), nn.BatchNorm2d(128), FlattenLayer() ) # 畳み込みによって最終的にどのようなサイズになっているかを、 # 実際にダミーデータを入れてみて確認する test_input = torch.ones(1, 3, 227, 227) #RGBか。画像のサイズ。 conv_output_size = conv_net(test_input).size()[-1] # 2層のMLP mlp = nn.Sequential( nn.Linear(conv_output_size, 200), nn.ReLU(), nn.BatchNorm1d(200), nn.Dropout(0.5), nn.Linear(200, 10) ) # 最終的なCNN net = nn.Sequential( conv_net, mlp ) # リスト4.3 評価と訓練のヘルパー関数を作成 # In[ ]: # 評価のヘルパー関数 def eval_net(net, data_loader, device="cuda:0"): # DropoutやBatchNormを無効化 net.eval() ys = [] ypreds = [] for x, y in data_loader: # toメソッドで計算を実行するデバイスに転送する x = x.to(device) y = y.to(device) # 確率が最大のクラスを予測(リスト2.14参照) # ここではforward(推論)の計算だけなので自動微分に # 必要な処理はoffにして余計な計算を省く with torch.no_grad(): _, y_pred = net(x).max(1) ys.append(y) ypreds.append(y_pred) # ミニバッチごとの予測結果などを1つにまとめる ys = torch.cat(ys) ypreds = torch.cat(ypreds) # 予測精度を計算 acc = (ys == ypreds).float().sum() / len(ys) return acc.item() # 訓練のヘルパー関数 def train_net(net, train_loader, test_loader, optimizer_cls=optim.Adam, loss_fn=nn.CrossEntropyLoss(), n_iter=10, device="cuda:0"): best_accuracy = 1.0 #save?# train_losses = [] train_acc = [] val_acc = [] optimizer = optimizer_cls(net.parameters(),lr=0.00001) ### for epoch in range(n_iter): running_loss = 0.0 # ネットワークを訓練モードにする net.train() n = 0 n_acc = 0 # 非常に時間がかかるのでtqdmを使用してプログレスバーを出す for i, (xx, yy) in tqdm.tqdm(enumerate(train_loader), total=len(train_loader)): xx = xx.to(device) yy = yy.to(device) h = net(xx) loss = loss_fn(h, yy) optimizer.zero_grad() loss.backward() optimizer.step() running_loss += loss.item() n += len(xx) _, y_pred = h.max(1) n_acc += (yy == y_pred).float().sum().item() train_losses.append(running_loss / i) # 訓練データの予測精度 train_acc.append(n_acc / n) # 検証データの予測精度 val_acc.append(eval_net(net, test_loader, device)) # accuracy = train_losses[-1] # if accuracy < best_accuracy: # saveModel() # best_accuracy=accuracy # このepochでの結果を表示 print(epoch, train_losses[-1], train_acc[-1], val_acc[-1], flush=True) # リスト4.4 全パラメータをGPUに転送して訓練を実行 # In[ ]: # ネットワークの全パラメータをGPUに転送 model=net.to("cuda:0") # 訓練を実行 train_net(model, train_loader, test_loader, n_iter=150, device="cuda:0") saveModel()
試したこと
再起動を何度もしました。
画像データの数を学習用、検証用のYESNOで揃えました。
画像データの大きさが揃っているか何度も確認しました。(512*512jpegに揃えています)
回答1件
あなたの回答
tips
プレビュー