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

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

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

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

Q&A

2回答

5213閲覧

CNN回帰モデルの学習を収束させたい

mkuri

総合スコア10

Python

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

0グッド

0クリップ

投稿2019/03/21 10:41

CNN回帰モデルの学習を収束させたい

以下の画像を入力として数値を出力するCNN回帰モデルを作りたい。
画像の下に記載されている数字がラベルになります。
inputs

このように差がはっきりと分かる入力画像に対してだと、ほぼ100%の正解率になると思っているのですが、
学習結果が収束しません。
改善点をアドバイスいただけるとありがたいです。

発生している問題

損失が以下のように推移し、約60epoch移行は精度が向上しません。
losses
200epoch目の結果は以下のような状態で、正解ラベルが0.1から0.9の間だとすると、ほとんど正解とは言えない状況です。
(outputsがモデルの出力結果、labelsが正解データ)

outputs: tensor([[0.4102]], grad_fn=<AddmmBackward>) labels: tensor([0.9000]) loss: 0.2399456799030304 outputs: tensor([[0.5098]], grad_fn=<AddmmBackward>) labels: tensor([0.1000]) loss: 0.16796395182609558 outputs: tensor([[0.2965]], grad_fn=<AddmmBackward>) labels: tensor([0.6000]) loss: 0.09208495169878006 outputs: tensor([[0.3554]], grad_fn=<AddmmBackward>) labels: tensor([0.3000]) loss: 0.003064962802454829 [200, 4] loss: 0.126

該当のソースコード

  • 画像を一枚ずつロードし、2乗誤差を計算してモデルをアップデート
  • モデルはAlexnetの最後にfc層を付け加えて、回帰モデルにしたもの
  • optimizerはAdamを使用

python

1import pandas as pd 2from PIL import Image 3import matplotlib.pyplot as plt 4import csv 5 6import torch 7import torch.nn as nn 8import torch.optim as optim 9from torchvision import models, transforms 10from torch.utils.data import Dataset, DataLoader, random_split 11 12from models.alexnet_reg import AlexNet 13 14 15class ImageDataset(Dataset): 16 def __init__(self, csv_file, transform=None): 17 self.csv = pd.read_csv(csv_file) 18 self.transform = transform 19 20 def __len__(self): 21 return len(self.csv) 22 23 def __getitem__(self, idx): 24 img_path = self.csv.at[idx.item(), 'img'] 25 label = self.csv.at[idx.item(), 'mu'] 26 img = Image.open(img_path) 27 28 if self.transform: 29 img = self.transform(img) 30 31 return img, label 32 33 34def train(model, train_dataset): 35 n_epoch = 200 36 train_loader = DataLoader(train_dataset, batch_size=1, shuffle=True, num_workers=1) 37 38 criterion = nn.MSELoss() 39 optimizer = optim.Adam(model.parameters()) 40 model.train() 41 losses = [] 42 43 for epoch in range(n_epoch): 44 running_loss = 0.0 45 for i, data in enumerate(train_loader, 0): 46 inputs, labels = data 47 optimizer.zero_grad() 48 labels = labels.type(torch.FloatTensor) 49 50 outputs = model(inputs) 51 print('outputs:', outputs) 52 print('labels:', labels) 53 loss = criterion(outputs, labels) 54 print('loss:', loss.item()) 55 loss.backward() 56 optimizer.step() 57 58 running_loss += loss.item() 59 # if i % 10 == 9: 60 # print('[%d, %5d] loss: %.3f' % 61 # (epoch + 1, i + 1, running_loss / 10)) 62 # running_loss = 0.0 63 64 print('[%d, %5d] loss: %.3f' % 65 (epoch + 1, i + 1, running_loss / 4)) 66 losses.append(running_loss/4) 67 68 with open('losses.csv', 'w') as f: 69 writer = csv.writer(f, lineterminator='/n') 70 writer.writerow(losses) 71 72 plt.plot(losses) 73 plt.title('MSELoss') 74 plt.xlabel('epoch') 75 plt.ylabel('loss') 76 plt.show() 77 78def main(): 79 transform = transforms.Compose( 80 [transforms.Resize(224), 81 transforms.ToTensor()] 82 ) 83 dataset = ImageDataset(csv_file='./data/dataset00/dataset00.csv', transform=transform) 84 85 train_size = int(1.0 * len(dataset)) 86 valid_size = len(dataset) - train_size 87 train_dataset, valid_dataset = random_split(dataset, [train_size, valid_size]) 88 print('train_size:', train_size, ', valid_size:', valid_size) 89 90 model = AlexNet() 91 train(model, train_dataset) 92 93 94if __name__ == '__main__': 95 main() 96

python

1import torch.nn as nn 2from torchvision import models 3 4 5class AlexNet(nn.Module): 6 def __init__(self): 7 super(AlexNet, self).__init__() 8 self.alexnet = models.alexnet(pretrained=True) 9 self.classifier2 = nn.Sequential( 10 nn.Dropout(), 11 nn.Linear(1000, 256), 12 nn.ReLU(inplace=True), 13 nn.Dropout(), 14 nn.Linear(256, 64), 15 nn.ReLU(inplace=True), 16 nn.Dropout(), 17 nn.Linear(64, 16), 18 nn.ReLU(inplace=True), 19 nn.Dropout(), 20 nn.Linear(16, 1) 21 ) 22 23 def forward(self, x): 24 x = self.alexnet(x) 25 x = self.classifier2(x) 26 return x 27

試したこと

ラベルをすべて正の数値にしてみたところ、より発散した。
losses_posi

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

torch==1.0.1.post2
torchvision==0.2.2.post3

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

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

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

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

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

guest

回答2

0

まず問題設定と入力データがうまく適合していないので、このあたりを改善しないとうまくいかないかと思います。具体的には、①本件を他クラス分類とする、②もっと簡単な図形と数値の関係とする(例えば、四角形に占める黒部分に係数を乗じたものを数値とする)、③もっと多数のデータを入手する、といったことが考えられます。

投稿2019/03/23 09:35

R.Shigemori

総合スコア3376

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

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

mkuri

2019/03/26 02:58

①他クラス分類として、最終層の出力を4つにして誤差関数にSoftmax Cross Entropyを使って学習すれば、このモデルでテストデータに関して収束することを確認しています。今回は中間値も出力したいので、回帰問題として扱いたいです。 ②CNN+FC層で出力しているのですが、このような関係とすればうまくいく理由はありますでしょうか? ③まずテストデータだけを使っている状況で収束しません。汎化性能は今は考慮していません。
R.Shigemori

2019/03/26 11:58

中間値が何を意味しているのかわかりませんが、識別モデルの隠れ層の出力値なのであれば、素直に取り出す方法を考えたほうがいいかと思います。 私はpytorchを使ったことがないので何とも言えませんが、tensorflowだとどのレイヤーの値でも学習過程・予測過程に関係なく取り出すことができるので、おそらくできるのではないでしょうか
guest

0

PyTorchはよくわかりませんが。
どれくらいの画像を用意しましたか?
変数labelsに入る具体的な値はなんですか?これ、「ラベル」ではなく、「ラベルのクラス番号」のはずです。ラベルが「犬」「猫」なら、計算できないでしょう??

投稿2019/03/22 05:06

Q71

総合スコア995

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

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

mkuri

2019/03/22 09:43

汎化性能は求めておらず、上記4画像から回帰分析結果(0.1や0.9などの数値)が出力されるモデルをまずは作ってみることを目的にしているため、多数の画像は必要がないかなと思っています。その分epochを回します。 labelsに入る具体的な値は0.1, 0.3, 0.6, 0.9です。分類問題ではなく回帰問題としたいので、正解ラベルをそのまま入力しています。 モデルの最後の全結合層を1つになるまで結合し、損失関数を2乗誤差にすれば回帰問題として扱えると思っています。
Q71

2019/03/27 06:07

何を正解としていますか。ある程度の幅が出るので、どこまでの幅を許容するか、だと思います。 VGGは、自然な写真を元に学習しているので、グラフィックツールで作った境界が発揮知りているものから特徴を抽出するのは苦手かもしれません。可視化手法を使って、判断の元を見るのも、ひとつの調査方法だと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問