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

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

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

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

Q&A

受付中

Resnet50の制度があがらない

linpoti
linpoti

総合スコア1

CNN (Convolutional Neural Network)

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

1回答

0グッド

0クリップ

339閲覧

投稿2022/11/08 06:48

前提

ここに質問の内容を詳しく書いてください。
ResNet50を用いて学習を行っています。データセットにはcifar10を用いています。
Resnet50のモデル部分のコードに関しては以下のサイトを参考にしました。
https://qiita.com/tchih11/items/377cbf9162e78a639958

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

エラーは発生していないのですが、Resnet50にしては精度が上がらなくて困っています。調査したところ、cifar10を用いた場合、90%ほど精度がでているのですが70%ほどで止まってしまいます。

該当のソースコード

python

1import torch 2import torchvision 3import torch.nn as nn 4import torch.optim as optim 5import torch.nn.functional as F 6import torchvision.transforms as transforms 7import numpy as np 8from matplotlib import pyplot as plt 9 10 11train_dataset = torchvision.datasets.CIFAR10(root='./data/',train=True,transform=transforms.ToTensor(),download=True) 12test_dataset = torchvision.datasets.CIFAR10(root='./data/',train=False,transform=transforms.ToTensor(),download=True) 13train_loader = torch.utils.data.DataLoader(dataset=train_dataset,batch_size=256,shuffle=True,num_workers=2) 14test_loader = torch.utils.data.DataLoader(dataset=test_dataset,batch_size=256,shuffle=False,num_workers=2) 15 16 17class block(nn.Module): 18 def __init__(self, first_conv_in_channels, first_conv_out_channels, identity_conv=None, stride=1): 19 """ 20 残差ブロックを作成するクラス 21 Args: 22 first_conv_in_channels : 1番目のconv層(1x1)のinput channel数 23 first_conv_out_channels : 1番目のconv層(1x1)のoutput channel数 24 identity_conv : channel数調整用のconv層 25 stride : 3x3conv層におけるstide数。sizeを半分にしたいときは2に設定 26 """ 27 super(block, self).__init__() 28 29 # 1番目のconv層(1×1) 30 self.conv1 = nn.Conv2d( 31 first_conv_in_channels, first_conv_out_channels, kernel_size=1, stride=1, padding=0) 32 self.bn1 = nn.BatchNorm2d(first_conv_out_channels) 33 34 # 2番目のconv層(3×3) 35 # パターン3の時はsizeを変更できるようにstrideは可変 36 self.conv2 = nn.Conv2d( 37 first_conv_out_channels, first_conv_out_channels, kernel_size=3, stride=stride, padding=1) 38 self.bn2 = nn.BatchNorm2d(first_conv_out_channels) 39 40 # 3番目のconv層(1×1) 41 # output channelはinput channelの4倍になる 42 self.conv3 = nn.Conv2d( 43 first_conv_out_channels, first_conv_out_channels*4, kernel_size=1, stride=1, padding=0) 44 self.bn3 = nn.BatchNorm2d(first_conv_out_channels*4) 45 self.relu = nn.ReLU() 46 47 # identityのchannel数の調整が必要な場合はconv層(1×1)を用意、不要な場合はNone 48 self.identity_conv = identity_conv 49 50 def forward(self, x): 51 52 identity = x.clone() # 入力を保持する 53 54 x = self.conv1(x) # 1×1の畳み込み 55 x = self.bn1(x) 56 x = self.relu(x) 57 x = self.conv2(x) # 3×3の畳み込み(パターン3の時はstrideが2になるため、ここでsizeが半分になる) 58 x = self.bn2(x) 59 x = self.relu(x) 60 x = self.conv3(x) # 1×1の畳み込み 61 x = self.bn3(x) 62 63 # 必要な場合はconv層(1×1)を通してidentityのchannel数の調整してから足す 64 if self.identity_conv is not None: 65 identity = self.identity_conv(identity) 66 x += identity 67 68 x = self.relu(x) 69 70 return x 71 72class ResNet(nn.Module): 73 def __init__(self, block, num_classes=10): 74 super(ResNet, self).__init__() 75 76 # conv1はアーキテクチャ通りにベタ打ち 77 self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3) 78 self.bn1 = nn.BatchNorm2d(64) 79 self.relu = nn.ReLU() 80 self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1) 81 82 # conv2_xはサイズの変更は不要のため、strideは1 83 self.conv2_x = self._make_layer(block, 3, res_block_in_channels=64, first_conv_out_channels=64, stride=1) 84 85 # conv3_x以降はサイズの変更をする必要があるため、strideは2 86 self.conv3_x = self._make_layer(block, 4, res_block_in_channels=256, first_conv_out_channels=128, stride=2) 87 self.conv4_x = self._make_layer(block, 6, res_block_in_channels=512, first_conv_out_channels=256, stride=2) 88 self.conv5_x = self._make_layer(block, 3, res_block_in_channels=1024, first_conv_out_channels=512, stride=2) 89 90 self.avgpool = nn.AdaptiveAvgPool2d((1,1)) 91 self.fc = nn.Linear(512*4, num_classes) 92 93 def forward(self,x): 94 95 x = self.conv1(x) # in:(3,224*224)、out:(64,112*112) 96 x = self.bn1(x) # in:(64,112*112)、out:(64,112*112) 97 x = self.relu(x) # in:(64,112*112)、out:(64,112*112) 98 x = self.maxpool(x) # in:(64,112*112)、out:(64,56*56) 99 100 x = self.conv2_x(x) # in:(64,56*56) 、out:(256,56*56) 101 x = self.conv3_x(x) # in:(256,56*56) 、out:(512,28*28) 102 x = self.conv4_x(x) # in:(512,28*28) 、out:(1024,14*14) 103 x = self.conv5_x(x) # in:(1024,14*14)、out:(2048,7*7) 104 x = self.avgpool(x) 105 x = x.reshape(x.shape[0], -1) 106 x = self.fc(x) 107 108 return x 109 110 def _make_layer(self, block, num_res_blocks, res_block_in_channels, first_conv_out_channels, stride): 111 layers = nn.ModuleList() 112 113 # 1つ目の残差ブロックではchannel調整、及びsize調整が発生する 114 # identifyを足す前に1×1のconv層を追加し、サイズ調整が必要な場合はstrideを2に設定 115 identity_conv = nn.Conv2d(res_block_in_channels, first_conv_out_channels*4, kernel_size=1,stride=stride) 116 layers.append(block(res_block_in_channels, first_conv_out_channels, identity_conv, stride)) 117 118 # 2つ目以降のinput_channel数は1つ目のoutput_channelの4倍 119 in_channels = first_conv_out_channels*4 120 121 # channel調整、size調整は発生しないため、identity_convはNone、strideは1 122 for i in range(num_res_blocks - 1): 123 layers.append(block(in_channels, first_conv_out_channels, identity_conv=None, stride=1)) 124 125 return nn.Sequential(*layers) 126 127device = 'cuda' if torch.cuda.is_available() else 'cpu' 128net = ResNet(block).to(device) 129 130 131#交差エントロピー誤差を使用 132criterion = nn.CrossEntropyLoss() 133#モーメンタム法を使用 134optimizer = optim.SGD(net.parameters(),lr=0.015,momentum=0.9,weight_decay=5e-4) 135 136 137 138# 繰り返し回数 139num_epochs = 50 140train_loss_list = [] 141train_acc_list = [] 142val_loss_list = [] 143val_acc_list = [] 144 145for epoch in range(num_epochs): 146 #値の初期化 147 train_loss = 0 148 train_acc = 0 149 val_loss = 0 150 val_acc = 0 151 # ここから訓練 152 net.train() 153 for i,(images,labels) in enumerate(train_loader): 154 images,labels = images.to(device),labels.to(device) 155 # 勾配を0にする 156 optimizer.zero_grad() 157 # 順伝播の計算 158 outputs = net(images) 159 # 誤差の計算 160 loss = criterion(outputs,labels) 161 # 訓練誤差 162 train_loss += loss.item() 163 # 予測結果と正解ラベルが同じ数(同じ場合に1となる) 164 train_acc += (outputs.max(1)[1]==labels).sum().item() 165 # 誤差の逆伝播 166 loss.backward() 167 # 重みの更新 168 optimizer.step() 169 # 訓練誤差の平均 170 avg_train_loss = train_loss / len(train_loader.dataset) 171 # 正解率(訓練)の平均 172 avg_train_acc = train_acc / len(train_loader.dataset) 173 174 # ここから評価(dropoutやバッチ正規化を定義した場合に必要) 175 net.eval() 176 # 学習モデルを固定 177 with torch.no_grad(): 178 for i,(images,labels) in enumerate(test_loader): 179 images,labels = images.to(device),labels.to(device) 180 # 順伝播の計算 181 outputs = net(images) 182 # 誤差の計算 183 loss = criterion(outputs,labels) 184 # 評価誤差 185 val_loss += loss.item() 186 # 正解率(評価) 187 val_acc += (outputs.max(1)[1]==labels).sum().item() 188 # 評価誤差の平均 189 avg_val_loss = val_loss / len(test_loader.dataset) 190 # 正解率(評価)の平均 191 avg_val_acc = val_acc / len(test_loader.dataset) 192 193 print(f'Epoch[{epoch+1}/{num_epochs}], loss: {avg_train_loss:5f}, acc: {avg_train_acc:.5f}, val_loss: {avg_val_loss:5f}, val_acc: {avg_val_acc:.5f}') 194 195 # プロット用リストへの格納 196 train_loss_list.append(avg_train_loss) 197 train_acc_list.append(avg_train_acc) 198 val_loss_list.append(avg_val_loss) 199 val_acc_list.append(avg_val_acc) 200 201plt.figure() 202plt.plot(range(num_epochs),train_loss_list,label='train_loss', color = "blue") 203plt.plot(range(num_epochs),val_loss_list,label='val_loss', color = "red") 204plt.legend() 205plt.xlabel('epoch') 206plt.ylabel('loss') 207plt.title('Training and Validation loss') 208plt.grid() 209plt.savefig( 'test_3.png' ) 210 211plt.figure() 212plt.plot(range(num_epochs),train_acc_list,label='train_acc', color = "blue") 213plt.plot(range(num_epochs),val_acc_list,label='val_acc', color = "red") 214plt.legend() 215plt.xlabel('epoch') 216plt.ylabel('acc') 217plt.title('Training and Validation accuracy') 218plt.grid() 219plt.savefig( 'test_4.png' ) 220

試したこと

構造に問題があるのかと思って元論文と比較してみたのですがモデルに問題はなかったです。
また、学習率を変えてみたりもしたのですが、あまり変わりませんでした。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

PondVillege

2022/11/08 08:32 編集

論文では「We start with a learning rate of 0.1, divide it by 10 at 32k and 48k iterations, and terminate training at 64k iterations」と言っていることから学習率0.1スタートの32k iterationで0.01,48k iterationで0.001にしてますが,そちらのコードではlr=0.015のままですね,最終的な学習率と比較して15倍もの大きさの学習率を利用してしまっているようです. ネットワークの学習が停滞した場合に有効なのは学習率を低下させることですが,それを実現できていないようです. また, data augmentationも論文ではやったと言っていますので,これも実現すると良いでしょう. さらに,「adopt the weight initialization in [13]」とあることから,重み初期値もHeの初期値を利用したみたいなので,これも反映すると学習速度の上昇につながると思います.
linpoti

2022/11/08 12:06

lr=0.001にしてみました。data augmentationとはどのような処理でしょうか。
linpoti

2022/11/08 12:16

lr=0.001にしてみたところ精度も落ち、lossも増えてしまいました。
PondVillege

2022/11/08 16:08 編集

Data Augmentationに関して論文では We follow the simple data augmentation in [24] for training: 4 pixels are padded on each side, and a 32×32 crop is randomly sampled from the padded image or its horizontal flip. と言っているので,4pixelを上下左右paddingして32x32の領域をランダムに黒にしてしまったり,左右反転したりすることで,ネットワークに与えるデータを増やす操作をやっているのです. https://pytorch.org/vision/stable/transforms.html torchではPadとRandomCropとRandomHorizontalFlipが使えますね. > lr=0.001にしてみたところ精度も落ち、lossも増えてしまいました。 論文通り,学習率を「徐々に」減少させましたか? 初っ端から0.001にすると学習速度が遅いのも相まって50epoch目の精度が低くなるのは当然のことと思います. CIFAR10は50kの教師データと10kの検証データであるから,バッチサイズ256である現状から計算するに,32k iterationはおよそ32k / (50k / 256) = 16epochと同義ですね,同様に48k iterationが25 epoch目になるので,これを境界にして学習率を1/10に減少させるようにしてください. 論文のFigure 6を見て分かる通り,32k iterationで急激に学習が進むのがわかると思います.学習率0.1で学習が停滞していた状態で学習率を0.01に減少させることで,学習が進むようになったと捉えることができます.また48 iterationのときに学習率0.001を減少させても効果が少ないのがわかると思います.この学習率0.001を序盤からやっても全然学習進まないのは,まぁそれはそうとしか言えないです. https://take-tech-engineer.com/pytorch-lr-scheduler/ Learning Rate Schedulerの利用を推奨します.
linpoti

2022/11/09 03:20

optimizer = torch.optim.SGD(net.parameters(),lr=0.1,momentum=0.9,weight_decay=5e-4) scheduler = torch.optim.lr_scheduler.MultiStepLR(optimizer, milestones=[16,25], gamma=0.1) のように変更しました。ですが最初のlrを0.1に設定すると、lossの値がでなくなり、val_accもずっと100%に なってしまいます。
jbpb0

2022/11/09 11:09 編集

https://github.com/kuangliu/pytorch-cifar の「main.py」の下記を変更して、google colabで実行してみました net = SimpleDLA() ↓ 変更 net = ResNet50() 200エポック終わった時のテストデータでの精度は95%くらいでした 上記githubのコードを分析してみたら、いかがでしょうか?
linpoti

2022/11/09 11:52

今回はモデルを書くことを頑張ってみたので、事前学習済のモデルを使わないでやりたいです。 前処理などNormalizeの部分はこちらのコードを参考にさせていただきます。 ですがやはり学習率の部分が0.1だとおかしくなってしまいます。 Epoch[1/50], loss: nan, acc: 0.09996, val_loss: nan, val_acc: 0.10000 このようにlossがでなく精度もおかしくなってしまいます。
jbpb0

2022/11/09 13:31 編集

> 事前学習済のモデルを使わないでやりたい が、私が紹介したgithubのコードのことでしたら、私が実行した時には事前学習の重みファイルをダウンロードしてるっぽい動作には気付きませんでしたので、事前学習無しで学習をスタートしたのだと思ってましたが、コードのどこかに重みを読み込んでるところがありました? ちなみに、初回エポックのテストデータでの精度は20%くらいでした
PondVillege

2022/11/09 13:31

わかりやすくepochで示しましたが,1 iterationは1回のoptimize.update()が相当しますので,そのまま32kと48kを指定したスケジューラにしてください. 最初のlrが0.1で不適であれば,0.05スタートか0.01とかでも良いと思います. また,初期値はちゃんとHeの初期値を利用しているのでしょうか.
linpoti

2022/11/10 03:36

jbpb0さん。このgithubのコードにはconvの記述などがなかったので勝手に事前学習済のモデルかと勘違いしてました。 ps_aux_grepさん。 Heの初期位置とはなんでしょうか。
linpoti

2022/11/10 03:38

>わかりやすくepochで示しましたが,1 iterationは1回のoptimize.update()が相当しますので,そのまま32kと48kを指定したスケジューラにしてください. というのは scheduler = torch.optim.lr_scheduler.MultiStepLR(optimizer, milestones=[32,48], gamma=0.1) ということでしょうか。
PondVillege

2022/11/10 03:47

> Heの初期値とは 一番最初にコメントで申し上げた論文中の「adopt the weight initialization in [13]」の文言のことです.論文中のReferencesの13番目にあるHe氏の論文を見るとわかるはずです.内容は,重み初期値の分散を,2割ることのユニット数にすると学習がうまくいき精度向上に繋がる.というものです.TorchではデフォルトでLeCunの初期値が使われているので一致しません. > スケジューラに関して scheduler = torch.optim.lr_scheduler.MultiStepLR(optimizer, milestones=[32000,48000], gamma=0.1) にしてください.kは1000倍を意味します.
jbpb0

2022/11/10 05:31 編集

> このgithubのコードにはconvの記述などがなかった ネットワークの定義は https://github.com/kuangliu/pytorch-cifar/blob/master/models/resnet.py にあり、 https://github.com/kuangliu/pytorch-cifar/blob/master/main.py の「from models import *」で読み込まれてます 複数のファイルに分かれてはいますが、基本的な構成はこの質問のコードと似てるように見えたので、差異がどこにあるのか分析したら、精度が上がらない原因が分かるかも、と思って紹介しました
linpoti

2022/11/10 05:45

ps_aux_grepさん 重み初期値の分散を,2割ることのユニット数にすると学習がうまくいき精度向上に繋がる.というものです.TorchではデフォルトでLeCunの初期値が使われているので一致しません. ってどの部分でしょうか。 jbpb0さん。ありがとうございます。比較してみます。
linpoti

2022/11/10 06:49

ありがとうございます。 32k iterationはおよそ32k / (50k / 256) = 16epochと同義ですね,同様に48k iterationが25 epoch目 ここの計算が合わないのですが、詳しく教えていただきたいです。
jbpb0

2022/11/10 07:45

> 32k iterationはおよそ32k / (50k / 256) = 16epochと同義ですね, 約160エポックだと思う
linpoti

2022/11/10 07:55

やはりそうですよね。ありがとうございます。
linpoti

2022/11/10 07:56

scheduler = torch.optim.lr_scheduler.MultiStepLR(optimizer, milestones=[A,B], gamma=0.1) AとBの部分にはepoch数を入れると思ってたのですが、違いますか?
linpoti

2022/11/11 15:38

https://github.com/kuangliu/pytorch-cifar/blob/master/utils.py をインポートして初期値の処理をやってみたのですが、 45行目のところで ValueError: not enough values to unpack (expected 2, got 0) というエラーが出てしまいました。引数が足りないのでしょうが、どこの部分かわかりません。
linpoti

2022/11/12 09:27

私が上げたコードにどのように初期値設定を組み込めばいいのかわからないです、、、
linpoti

2022/11/12 09:46

utils.pyのdef_init_paramsの部分をclass ResNetの部分に入れてみました。とりあえず結果待ちます。
jbpb0

2022/11/12 10:02 編集

> utils.pyからはprogress_barをimportしている 質問者さんのコードに「progress_bar」が要るのですか? https://github.com/kuangliu/pytorch-cifar/blob/master/utils.py から、初期値設定の部分だけを質問者さんのコードに取り込もうとしてると思って、 > 45行目以降は初期値設定とは関係無いものなので、削除したらいい と書きましたが、もしかして、 https://github.com/kuangliu/pytorch-cifar/blob/master/main.py をそのまま動かそうとしたら、 > ValueError: not enough values to unpack (expected 2, got 0) というエラーが出るのでしょうか?
linpoti

2022/11/12 12:40

いやmain.pyは使ってないです。自分がこの質問でのせたコードをちょこちょこ変えて使っています。 utils.pyのdef_init_paramsの部分をclass ResNetの部分に入れてみたら、精度が50%になってしまいました、、
jbpb0

2022/11/13 00:49

> utils.pyのdef_init_paramsの部分をclass ResNetの部分に入れてみたら、精度が50%になってしまいました https://github.com/kuangliu/pytorch-cifar をざっと調べたのですが、「utils.py」の「def init_params(net):」は使われてないっぽいです (見落としがあったらごめんなさい) そこで、今回の質問の精度がイマイチ出ない件の主原因は初期値ではないかも、と思ってgoogle colabで確認してみました まず、下記を実行 !git clone https://github.com/kuangliu/pytorch-cifar %cd pytorch-cifar 次に、質問のコードで下記を変更してから実行 (最後の行はインデント有り) net = ResNet(block).to(device) ↓ 変更 import torch.backends.cudnn as cudnn from models import * net = ResNet50().to(device) if device == 'cuda': cudnn.benchmark = True 「utils.py」はインポートしてないので、初期値はデフォルトだと思います 質問のコードからネットワークを変えただけですが、50エポックで「val_acc」は84%になり、 > 70%ほどで止まってしまいます。 より精度が上がりました (1回しか実行してないので、たまたまかもしれないけど) torchvisionのコード https://github.com/pytorch/vision/blob/main/torchvision/models/resnet.py では初期値設定をしてるので、上記で使ったネットワークに初期値設定を追加したら精度がさらに上がるかもしれませんが、試してません
linpoti

2022/11/13 08:25

ありがとうございます。 今回のこの質問の自分のコードを使って、90%ほど出すのはむずかしいでしょうか。
jbpb0

2022/11/13 10:45 編集

https://github.com/kuangliu/pytorch-cifar/blob/master/main.py にさらに近づけるため、私の一つ前のコメントに書いた変更を行った状態から、さらに下記を変更して実行してみました train_dataset = ... test_dataset = ... train_loader = ... test_loader = ... ↓ 変更 https://github.com/kuangliu/pytorch-cifar/blob/master/main.py の30〜50行目のコード (ただし、変数名は質問のコードに合わせる) optimizer = optim.SGD(net.parameters(),lr=0.015,momentum=0.9,weight_decay=5e-4) ↓ 変更 optimizer = optim.SGD(net.parameters(), lr=0.1, momentum=0.9, weight_decay=5e-4) scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=200) num_epochs = 50 ↓ 変更 num_epochs = 200 「for epoch in range(num_epochs):」のループの最後に、インデントを合わせて下記を追加 scheduler.step() 200エポックで「val_acc」は95%になり、 https://github.com/kuangliu/pytorch-cifar/blob/master/main.py を「net = ResNet50()」で実行した時とほぼ同じ結果になりました
jbpb0

2022/11/13 10:52

> 今回のこの質問の自分のコードを使って、90%ほど出すのはむずかしいでしょうか。 私の一つ前のコメントで実行した(200エポックで「val_acc」95%)コードから、下記のみ戻して(他は変更した状態のまま)実行してみました from models import * net = ResNet50().to(device) ↓ 変更を戻す net = ResNet(block).to(device) そうすると、エポックが進んでも「val_acc」はずっと10%(0.10000)のまま変わらず、学習ができませんでした
jbpb0

2022/11/14 11:01 編集

私の二つ前のコメントで実行した(200エポックで「val_acc」95%)コードから、下記を変更して実行してみました from models import * net = ResNet50().to(device) ↓ 変更 net = torchvision.models.resnet50(num_classes=10, weights=None).to(device) 200エポックで「val_acc」は90%になり、 from models import * net = ResNet50().to(device) の場合の95%よりもやや劣る結果になりました > 今回のこの質問の自分のコードを使って、90%ほど出すのはむずかしいでしょうか。 ネットワークを変えただけで、他は同じで、結果は下記の通りでした ・質問のコード:学習できず ・torchvision.models.resnet50:200エポックで90% ・https://github.com/kuangliu/pytorch-cifar/blob/master/models/resnet.py :200エポックで95% ネットワーク構造の差異を調べて、何の違いが学習や精度に効いてるのかを分析したらいかがでしょうか

回答1

0

Resnet50にしては精度が上がらなくて困っています。
調査したところ、cifar10を用いた場合、90%ほど精度がでているのですが70%ほどで止まってしまいます。

質問のコードの下記を変更・追加して実行したら、200エポックで「val_acc」は90%になりました

 

python

1train_dataset = torchvision.datasets.CIFAR10(root='./data/',train=True,transform=transforms.ToTensor(),download=True) 2test_dataset = torchvision.datasets.CIFAR10(root='./data/',train=False,transform=transforms.ToTensor(),download=True) 3train_loader = torch.utils.data.DataLoader(dataset=train_dataset,batch_size=256,shuffle=True,num_workers=2) 4test_loader = torch.utils.data.DataLoader(dataset=test_dataset,batch_size=256,shuffle=False,num_workers=2)

↓ 変更

python

1transform_train = transforms.Compose([ 2 transforms.RandomCrop(32, padding=4), 3 transforms.RandomHorizontalFlip(), 4 transforms.ToTensor(), 5 transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)), 6]) 7transform_test = transforms.Compose([ 8 transforms.ToTensor(), 9 transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)), 10]) 11trainset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform_train) 12testset = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transform_test) 13train_loader = torch.utils.data.DataLoader(trainset, batch_size=128, shuffle=True, num_workers=2) 14test_loader = torch.utils.data.DataLoader(testset, batch_size=100, shuffle=False, num_workers=2)

 

python

1net = ResNet(block).to(device)

↓ 変更

python

1net = torchvision.models.resnet50(num_classes=10, weights=None).to(device) 2if device == 'cuda': 3 torch.backends.cudnn.benchmark = True

 

python

1optimizer = optim.SGD(net.parameters(),lr=0.015,momentum=0.9,weight_decay=5e-4)

↓ 変更

python

1optimizer = optim.SGD(net.parameters(), lr=0.1, momentum=0.9, weight_decay=5e-4) 2scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=200)

 

python

1num_epochs = 50

↓ 変更

python

1num_epochs = 200

 
「for epoch in range(num_epochs):」のループの最後に下記を追加

python

1 scheduler.step()

 
イメージ説明
イメージ説明

 

構造に問題があるのかと思って元論文と比較してみたのですがモデルに問題はなかったです。
また、学習率を変えてみたりもしたのですが、あまり変わりませんでした。

上記の「val_acc」が90%になるコードと、質問のコードとの各相違点が、それぞれどれだけ精度に効いてるか、分析してみるといいと思います

投稿2022/11/22 10:00

jbpb0

総合スコア7514

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
86.02%

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

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

質問する

関連した質問

同じタグがついた質問を見る

CNN (Convolutional Neural Network)

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