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

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

新規登録して質問してみよう
ただいま回答率
85.48%
深層学習

深層学習は、多数のレイヤのニューラルネットワークによる機械学習手法。人工知能研究の一つでディープラーニングとも呼ばれています。コンピューター自体がデータの潜在的な特徴を汲み取り、効率的で的確な判断を実現することができます。

PyTorch

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

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

Q&A

0回答

1266閲覧

pytorchで学習用データセットが100%で評価用データセットが55%っておかしい気がしているので確認してほしい

oinari03

総合スコア59

深層学習

深層学習は、多数のレイヤのニューラルネットワークによる機械学習手法。人工知能研究の一つでディープラーニングとも呼ばれています。コンピューター自体がデータの潜在的な特徴を汲み取り、効率的で的確な判断を実現することができます。

PyTorch

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

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

0グッド

0クリップ

投稿2020/09/15 17:32

編集2020/09/16 04:18

やりたいこと

もともとやろうとしていることは、pytorchを用いた犬と猫の分類問題となっていて、
画像データは256x256x3である。
以下のディレクトリ構成で格納されている。

├─animal_dataset ├─train │ ├─cat(70枚くらい) │ └─dog(70枚くらい) └─val ├─cat(30枚くらい) └─dog(30枚くらい)

学習用データセット(train)と評価用データセット(valid)をdatasetの実装の際に作成した。
それらをもとにモデルを作成し、その後損失関数の収束させるのを確認した、それらをもとに学習後のモデルパラメータを今回のソースコードに埋め込んで評価をしたつもりです。

これらから、validatioの正解率とtrainの正解率を見比べて確かめたい

確かめる方法としては、validとtrainの同時にグラフに起こして、確認できると好ましいのでそれらを同時にグラフにするコードの書き方が知りたい。(epochごとなのかな...)

ただ、そもそも手打ちで精度を見たところtrainが100%ってどういうこと??って状態です....

ソースコード(eval.py)

実行ファイルです。
推論をするためのファイルです。

eval.py

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 13import numpy as np 14from matplotlib import pyplot as plt 15 16 17device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') 18 19if __name__ == "__main__": 20 # modelの定義 21 model = model.Net().to(device) 22 # 推論モード 23 model.eval() 24 25 # optimizerの定義 26 optimizer = torch.optim.SGD( 27 model.parameters(), lr=0.0001, momentum=0.9, weight_decay=0.0001) 28 #パラメータの読み込み 29 model.load_state_dict(torch.load("model_cpu.pth", map_location=device)) 30 31 # training 32 train_dataset = dataset.MyDatasets( 33 root_dir="./animal_dataset", 34 key="train", 35 ) 36 train_loader = torch.utils.data.DataLoader( 37 dataset=train_dataset, 38 batch_size=4, 39 shuffle= True 40 ) 41 42 # validationのデータセット 43 valid_dataset = dataset.MyDatasets( 44 root_dir="./animal_dataset", 45 key="val", 46 ) 47 48 valid_loader = torch.utils.data.DataLoader( 49 dataset=valid_dataset, 50 batch_size=4, 51 shuffle= True 52 ) 53 # 評価関数の作成 54 55 56 57 acc = [] 58 num_epoch = 100 59 for epoch in range(num_epoch): 60 correct = 0 #val_acc 61 total = 0 62 with torch.no_grad(): 63 for data in valid_loader: 64 inputs, labels = data[0].to(device), data[1].to(device) 65 # print("label={}".format(labels)) 66 # print("inputs={}".format(inputs)) 67 68 outputs = model(inputs).to(device) 69 70 # 確率 71 _, predicted = torch.max(outputs.data, 1) 72 total += labels.size(0) 73 correct += (predicted == labels).sum().item() 74 acc.append(float(correct/total)) 75 76 print("Accuracy of the network on the 100 test images: %d/%d = %.1f" % (correct, total, 100*correct/len(valid_loader.dataset))) 77 78 79 80 81 plt.figure() 82 plt.plot(range(num_epoch), acc, color='blue',linestyle='-',label='acc') 83 plt.legend() 84 plt.xlabel('epoch') 85 plt.ylabel('acc') 86 plt.grid() 87 plt.savefig("acc.png") 88 89

実行結果

一応、グラフを作ってみました。(追記)
イメージ説明
以下の部分をvalid_loader(評価用)でループを回したとき

with torch.no_grad(): for data in valid_loader:

かなり精度はあれですが、こんな感じです。

Accuracy of the network on the 100 test images: 30/54 = 55.6

以下の部分をtrain_loader(評価用)でループを回したとき

with torch.no_grad(): for data in train_loader:

100%っておかしくないか....

Accuracy of the network on the 100 test images: 129/129 = 100.0

追記

前処理を行っているdataset.pyの添付ファイルをのせます。

import glob import os from PIL import Image from torch.utils import data as data from torchvision import transforms as transforms transform = transforms.Compose([ transforms.Resize((256, 256)), transforms.ToTensor(), transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5)), # transforms.RandomHorizontalFlip(), # transforms.RandomVerticalFlip(), # transforms.RandomRotation(degrees=30) ]) class MyDatasets(data.Dataset): def __init__(self, root_dir, key): self.transform = transform self.data = [] self.labels = [] name_to_label = {"cat": 0, "dog": 1} target_dir = os.path.join(root_dir, key, "**/*") for path in glob.glob(target_dir): name = os.path.basename(os.path.dirname(path)) label = name_to_label[name] self.data.append(path) self.labels.append(label) def __len__(self): return len(self.data) def __getitem__(self, index): img_path = self.data[index] label = self.labels[index] img = Image.open(img_path).convert("RGB") img = self.transform(img) return img, label if __name__ == "__main__": train_dataset = MyDatasets("./animal_dataset", "train") train_dataloader = data.DataLoader(train_dataset, batch_size=4, shuffle= True) for data, labels in train_dataloader: print(data.shape, labels.shape) datas, labels = iter(train_dataloader).next() # print(datas[0].shape) s=10 pic = transforms.ToPILImage(mode='RGB')(datas[s]) pic.save('./result.jpg') if labels[s].numpy() == 0: print("label: cat") else: print("label: dog")

なんかしっかり前処理できているか不安になりました。

最後に

このような結果になってしまい、動作の正しさを確認したいと思っています。
もしかしたら、ソースコードが間違っているのであれば修正点を教えていただけるとありがたいです。

また、可能でありましたらepochごとのtrainとvalidの精度(accuracy)をグラフに起こした処理の書き方も知れたらうれしいです。

参考にしたソースコードはどれもphase==train or validのようなものだったり、lossと同時に行っていて精度だけを確認できるコードが見つかりません。

もし不足している情報や説明に足り部分がありましたらご指摘くださると感謝します。
どうかよろしくお願いします。

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

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

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

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

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

meg_

2020/09/15 22:11 編集

> ただ、そもそも手打ちで精度を見たところtrainが100%ってどういうこと??って状態です.... どういう状態であることを想定されていたのでしょうか? 一般的に学習データが少ないと過学習を起こしやすいと言われていますので、学習データを増やして改善するか確かめられてはどうでしょうか?
oinari03

2020/09/16 00:13

どういう状態かどうかは想像していませんでしたが、100%になることはないと考えていました。
tiitoi

2020/09/16 03:34

推論時は学習時と同じ前処理を行っているかは念の為確認してください。(学習時に [0, 1] の正規化してるのに推論時は忘れていたなどがないかなど) それに問題ないのであれば、汎化性能に問題がある過学習したモデルができたということです。 > 100%になることはないと考えていました。 ディープラーニングモデルはパラメータ数がものすごく多いため、訓練データに対して正答率100%になることはありえます。
oinari03

2020/09/16 04:09

>推論時は学習時と同じ前処理を行っているかは念の為確認してください。(学習時に [0, 1] の正規化してるのに推論時は忘れていたなどがないかなど) こちらについてですが、どういう処理があると確かめることができますでしょうか。 流れとしてはdatase/dataloaderで画像の前処理を行い→その後モデルのファイルを作成しcnn→その後学習のファイル→推論のファイル を作っていたため、各自引き継いでいると思っています。前処理はdataset/dataloader(のファイル)で行っています。 すべてのソースコードを添付した方がよろしいでしょうか... 100%はあり得るのですね...
tiitoi

2020/09/16 04:14

MyDatasets の中で学習時と推論時で同じテンソルが用意されるようになっているのであれば、その点は大丈夫です。
oinari03

2020/09/16 04:19

一応、前処理を行っているソースコードを添付いたしました。 また、accuracyのグラフを作ってみたものを添付いたしました。 これらから判断できることはありますでしょうか。
tiitoi

2020/09/16 04:43

見ましたがパット見とくに問題なさそうに見えます
oinari03

2020/09/16 04:49 編集

ありがとうございます。 なるほどです。 となると、 >それに問題ないのであれば、汎化性能に問題がある過学習したモデルができたということです。 という点でしょうか。この意味がいまいちわかっていなくどう修正すればいいかわかりかねています。 理解力が乏しく申しわけないですが、かみ砕いた意味を教えていただけるとありがたいです。 また、可能であれば、 追記にグラフを貼っているのですが、まっすぐの直線ではなくしっかりとした曲線になっていると嬉しいのですが、その点のアドバイスを頂けると助かります。
tiitoi

2020/09/16 05:32 編集

過学習は学習するパラメータに対して学習データが少ないと発生します ディープラーニングは基本的に大量のパラメータを大量のデータを使って調整するものなので、データが少ないとディープラーニングは上手くいきません とりあえずモデルは torchvision.resnet18 とか実績のあるモデル構造をつかってはどうでしょうか? あとは画像データを増やすとかですかね 犬、猫画像ならグーグル画像検索で大量に手に入ると思います。
oinari03

2020/09/16 06:10

なるほどです。 モデルを変えてみたり、画像を増やすのを考えてみます。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問