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

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

新規登録して質問してみよう
ただいま回答率
85.35%
PyTorch

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

2691閲覧

なぜコピペなのに精度が全然違うのか

Ark

総合スコア12

PyTorch

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2022/05/29 13:46

編集2022/06/02 15:58

サイトと同じ精度を実現したい

pytorch初学者です。大学で音声感情認識の研究をしていて、実装がうまく行かなかったので練習に立ち返ることにし、MNISTをCNNで学習させるプログラムをコピペして実行しました。出典はこちらです。

でも実際に動かしてみると、出典サイトでは96%程度のテスト精度が出ていたのに対し、手元の環境では54.6%しか出ませんでした。

データセットも前処理もモデルも同じなのになぜこうも結果に差が出るのかがわからずとてもモヤモヤしています。音声感情認識のモデルを実装したときも、論文のとおりに作っても中々精度が出ず、方向性がわからなくなり練習に戻ってきました。

知りたいこと

・訓練ロスとテストロス、訓練精度とテスト精度の記録を入れた
・torch.to()関数でGPUを利用するようにした
以外はすべてサイトのコピペです。やっていることは同じなのになぜこうも精度が違うのかが知りたいです。問題のコードと、40エポック経過後のロスと精度の推移を添付します。どうかよろしくお願いします。

補足:上記2つの改変を消して実行してみましたが、結果は変わらなかったのでこれらは原因ではないことがわかりました。

実行環境

CPU: Intel® Xeon(R) Silver 4208 CPU @ 2.10GHz × 16
GPU: NVIDIA GeForce RTX 2080 Ti/PCIe/SSE2
OS: Ubuntu 18.04.5 LTS
開発環境: Jupyter Notebook

コード

すべてJupyter Notebook上で実行しました。実行したセルごとにまとめて添付します。

モジュールのインポート

python

1import torch 2import torchvision 3import torchvision.transforms as transforms 4import numpy as np 5import matplotlib.pyplot as plt 6import torch.nn as nn 7import torch.nn.functional as F 8import torch.optim as optim

MNISTをロードする

python

1transform = transforms.Compose( 2 [transforms.ToTensor(), 3 transforms.Normalize((0.5, ), (0.5, ))]) 4 5trainset = torchvision.datasets.MNIST(root='../data', 6 train=True, 7 download=True, 8 transform=transform) 9trainloader = torch.utils.data.DataLoader(trainset, 10 batch_size=100, 11 shuffle=True, 12 num_workers=2) 13 14testset = torchvision.datasets.MNIST(root='../data', 15 train=False, 16 download=True, 17 transform=transform) 18testloader = torch.utils.data.DataLoader(testset, 19 batch_size=100, 20 shuffle=False, 21 num_workers=2) 22 23classes = tuple(np.linspace(0, 9, 10, dtype=np.uint8))

CNNモデルの定義

python

1class Net(nn.Module): 2 def __init__(self): 3 super(Net, self).__init__() 4 self.conv1 = nn.Conv2d(1, 32, 3) # 28x28x32 -> 26x26x32 5 self.conv2 = nn.Conv2d(32, 64, 3) # 26x26x64 -> 24x24x64 6 self.pool = nn.MaxPool2d(2, 2) # 24x24x64 -> 12x12x64 7 self.dropout1 = nn.Dropout2d() 8 self.fc1 = nn.Linear(12 * 12 * 64, 128) 9 self.dropout2 = nn.Dropout2d() 10 self.fc2 = nn.Linear(128, 10) 11 12 def forward(self, x): 13 x = F.relu(self.conv1(x)) 14 x = self.pool(F.relu(self.conv2(x))) 15 x = self.dropout1(x) 16 x = x.view(-1, 12 * 12 * 64) 17 x = F.relu(self.fc1(x)) 18 x = self.dropout2(x) 19 x = self.fc2(x) 20 return x

学習用コード

python

1model = Net().to('cuda') 2 3criterion = nn.CrossEntropyLoss() 4optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9) 5epochs = 40 6 7#ロスと精度記録用のリスト 8train_loss = [] 9test_loss = [] 10train_accuracy = [] 11test_accuracy = [] 12 13for epoch in range(epochs): 14 running_loss = 0.0 15 16 #学習する 17 for i, (inputs, labels) in enumerate(trainloader, 0): 18 # zero the parameter gradients 19 optimizer.zero_grad() 20 21 # forward + backward + optimize 22 inputs = inputs.to('cuda') 23 labels = labels.to('cuda') 24 outputs = model(inputs) 25 loss = criterion(outputs, labels) 26 loss.backward() 27 optimizer.step() 28 # print statistics 29 running_loss += loss.item() 30 if i % 100 == 99: 31 print('[{:d}, {:5d}] loss: {:.3f}' 32 .format(epoch + 1, i + 1, running_loss / 100)) 33 34 train_loss.append(running_loss / i) 35 36 37 correct = 0 38 total = 0 39 # テストデータを一周 40 with torch.no_grad(): 41 running_test_loss = 0 42 for index, (images, labels) in enumerate(testloader): 43 images = images.to('cuda') 44 labels = labels.to('cuda') 45 outputs = model(images) 46 loss = criterion(outputs, labels) 47 running_test_loss += loss.item() 48 _, predicted = torch.max(outputs.data, 1) 49 total += labels.size(0) 50 correct += (predicted == labels).sum().item() 51 52 test_loss.append(running_test_loss / index) 53 test_accuracy.append(correct / total) 54 55 correct = 0 56 total = 0 57 # 訓練データを一周 58 with torch.no_grad(): 59 running_loss = 0 60 for index, (images, labels) in enumerate(trainloader): 61 images = images.to('cuda') 62 labels = labels.to('cuda') 63 outputs = model(images) 64 _, predicted = torch.max(outputs.data, 1) 65 total += labels.size(0) 66 correct += (predicted == labels).sum().item() 67 train_accuracy.append(correct / total) 68 69print('Finished Training')

結果の出力

ロスの出力と結果

python

1plt.plot(train_loss, label='train_loss') 2plt.plot(test_loss, label='test_loss') 3plt.legend() 4plt.plot()

ロスの推移

精度の出力と結果

python

1plt.plot(train_accuracy, label='train_accuracy') 2plt.plot(test_accuracy, label='test_accuracy') 3plt.legend() 4plt.plot()

精度の推移

追記:やってみたこと

・見た感じ、パラメータ数が足りていないのかと思ったので、畳み込み層を1つ追加してみた
→精度は変わらなかった

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

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

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

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

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

jbpb0

2022/05/29 23:46 編集

> 訓練ロスとテストロス、訓練精度とテスト精度の記録を入れた をやらない場合は、質問者さんの環境でも96%くらいになるのでしょうか?
quickquip

2022/05/30 04:03

グラフが2つ、コードが1つ、コードでグラフを書いている様子はない、では、このコードを何だと思って読めばいいのかわかりません。
guest

回答1

0

自己解決

fc1のあとにnn.BatchNorm1dを挿入したところ、精度が98.5%程度まで向上しました。データのスケールって大事ですね。元のサイトが正規化なしでうまく行っている理由はまだわかりませんが、細かい環境などの差だと考えています。

投稿2022/06/02 20:10

Ark

総合スコア12

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問