やりたいこと
損失関数の値をできるだけ小さい値に収束させたい
ところが、10,100,300とepochの値を増やしても、同じ位置に収束してしまっていて?、できるだけlossの値を下げようと思っています。
しかし、epochをこれ以上上げるべきなのか、どれだけ上げるべきなのか、はたまた違う要因があるのか、ご指摘くださると幸いです。
<前提>
256x256x3の犬と猫の画像をcnnで分類しています。
pc: gpu
windows
wsl ubuntu18.04
python3.7.7
実行結果(train.py)
epoch=300くらいだったと思います。
大体0.69~ 0.74くらいを行ったり来たりです。
これをもう少し下げたいです。
・ ・ ・ torch.Size([32, 9216]) tensor(0.6920, device='cuda:0', grad_fn=<NllLossBackward>) torch.Size([1, 9216]) tensor(0.7015, device='cuda:0', grad_fn=<NllLossBackward>) torch.Size([32, 9216]) tensor(0.6942, device='cuda:0', grad_fn=<NllLossBackward>) torch.Size([32, 9216]) tensor(0.6942, device='cuda:0', grad_fn=<NllLossBackward>) torch.Size([32, 9216]) tensor(0.6916, device='cuda:0', grad_fn=<NllLossBackward>) torch.Size([32, 9216]) tensor(0.6921, device='cuda:0', grad_fn=<NllLossBackward>) torch.Size([1, 9216]) tensor(0.7015, device='cuda:0', grad_fn=<NllLossBackward>) torch.Size([32, 9216]) tensor(0.6936, device='cuda:0', grad_fn=<NllLossBackward>) torch.Size([32, 9216]) tensor(0.6937, device='cuda:0', grad_fn=<NllLossBackward>) torch.Size([32, 9216]) tensor(0.6931, device='cuda:0', grad_fn=<NllLossBackward>) torch.Size([32, 9216]) tensor(0.6920, device='cuda:0', grad_fn=<NllLossBackward>) torch.Size([1, 9216]) tensor(0.6848, device='cuda:0', grad_fn=<NllLossBackward>)
コード(train.py)
こちらが実行ファイルです。model.pyやdataset.pyを別々に作ってそこから呼び出してlossの値を確認しています。
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().to(device) 23 print(model) 24 25 26 27 # optimizerの定義 28 optimizer = torch.optim.SGD( 29 model.parameters(), lr=0.001, momentum=0.9, weight_decay=0.0001) 30 31 # datasetの定義 32 # training 33 train_dataset = dataset.MyDatasets( 34 root_dir="./animal_dataset", 35 key="train", 36 ) 37 train_loader = torch.utils.data.DataLoader( 38 train_dataset, 39 batch_size=32, 40 shuffle= True 41 ) 42 43 # validation 44 valid_dataset = dataset.MyDatasets( 45 root_dir="./animal_dataset", 46 key="val", 47 ) 48 49 valid_loader = torch.utils.data.DataLoader( 50 valid_dataset, 51 batch_size=32, 52 shuffle= True 53 ) 54 55 56 # iterationの確定 57 sample_size = len(train_dataset) #129 58 num_iters = sample_size // 32 #129 // 32 = 4.03 59 60 #loss 61 criterion = nn.CrossEntropyLoss() 62 63 #start epoch 64 for epoch in range(300): # loop over the dataset multiple times 65 running_loss = 0.0 66 for i, data in enumerate(train_loader, 0): 67 # get the inputs; data is a list of [inputs, labels] 68 inputs, labels = data[0].to(device), data[1].to(device) 69 # zero the parameter gradients 70 optimizer.zero_grad() 71 # forward + backward + optimize 72 outputs = model(inputs) 73 loss = criterion(outputs, labels) 74 print(loss) 75 76 # loss.backward() 77 # optimizer.step() 78 79 # # print statistics 80 # running_loss += loss.item() 81 # if i % 2000 == 1999: # print every 2000 mini-batches 82 # print('[%d, %5d] loss: %.3f' % (epoch + 1, i + 1, running_loss / 2000)) 83 # running_loss = 0.0 84 85 print('Finished Training') 86
cnnのmodel.pyです。
import torch import torch.nn as nn import torch.nn.functional as F """ 入力は256x256のRGB画像 出力は0or1の2次元ベクトルになるはず """ class Net(nn.Module): def __init__(self): super(Net, self).__init__() self.relu = nn.ReLU() # input: RGB 3 ,output : 16, kernel 3(default) self.conv1 = nn.Conv2d(3, 16, 3) # print(self.conv1.weight) self.pool1 = nn.MaxPool2d(2,stride=2) self.conv2 = nn.Conv2d(16, 32, 3) self.pool2 = nn.MaxPool2d(2,stride=2) self.conv3 = nn.Conv2d(32, 64, 3) self.pool3 = nn.MaxPool2d(2,stride=2) self.conv4 = nn.Conv2d(64, 128, 3) self.pool4 = nn.MaxPool2d(2,stride=2) self.conv5 = nn.Conv2d(128, 256, 3) self.pool5 = nn.MaxPool2d(2,stride=2) # an affine operation: y = Wx + b # linearにおけるout_featuresとはなんだろうか self.fc1 = nn.Linear(9216, 120) self.fc2 = nn.Linear(120, 84) self.fc3 = nn.Linear(84, 2) def forward(self, x): # conv relu poolの流れを実行してみる x = self.conv1(x) x = self.relu(x) x = self.pool1(x) x = self.conv2(x) x = self.relu(x) x = self.pool2(x) x = self.conv3(x) x = self.relu(x) x = self.pool3(x) x = self.conv4(x) x = self.relu(x) x = self.pool4(x) x = self.conv5(x) x = self.relu(x) x = self.pool5(x) x = x.view(x.size()[0], -1) print(x.shape) x = self.fc1(x) x = self.relu(x) x = self.fc2(x) x = self.relu(x) x = self.fc3(x) return F.log_softmax(x,dim=1) if __name__ == "__main__": input = torch.randn(1,3,256,256) net = Net() print(net(input)) #動作確認
動作確認用でいろいろ入っていますが....
こんな感じです。cnnの作り方がよろしくないのでしょうか....
まとめ
以上の情報からlossをいかに低い値で収束させることができましたらお願いできますとありがたいです。
どういった原因があるのか、どこを編集すればいい結果が得られるのかがわかりません。
未熟のみであるので、足らない点があればご指摘してくださると助かります。
どうかよろしくお願いいたします。
回答1件
あなたの回答
tips
プレビュー