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

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

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

DataSetは、ADO.NETアーキテクチャのコンポーネントです。データベースから取得したレコードをメモリ領域に格納するクラスを指します。データの保持やテーブル間のリレーション・制約といった保持も可能です。

深層学習

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

PyTorch

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

機械学習

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

Python

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

Q&A

解決済

1回答

1810閲覧

学習途中,epochがかなり進んでから入力batchsizeとラベルのサイズが合わないとエラーが出ます

K.Nakai

総合スコア1

DataSet

DataSetは、ADO.NETアーキテクチャのコンポーネントです。データベースから取得したレコードをメモリ領域に格納するクラスを指します。データの保持やテーブル間のリレーション・制約といった保持も可能です。

深層学習

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

PyTorch

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

機械学習

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

Python

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

0グッド

0クリップ

投稿2021/05/14 03:23

前提・実現したいこと

Pytorchを用いてHAM10000という医療画像クラス分類用データセットで学習しています.
jpg画像ファイルおよび{画像のファイル名:label}となっているcsvファイルを用いて,画像のファイル名を毎回batchsize分取り出し,その都度labelと画像を読み込む形で入力データを構築しています.
日本語のアルゴリズムで書くと以下のような感じです.

for batchsize分のファイル名 in 全画像のファイル名: images, labels = ファイル名から画像およびlabelを読み込み,Tensorにして返す関数(batchsize分のファイル名)

最初はうまく学習してくれるのですが,epoch70や80など(不定,そのまま学習が100まで完了してくれることもあります)学習がかなり進んでから入力のbatchsizeとlabelのbatchsizeが合わないといったErrorが起こるので,これをなんとか解決したいです.

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

以下が発生しているError文です(batchsizeは16です)

epoch : 83 Lerning >>>>>Error size ['ISIC_0028434', 'ISIC_0033912', 'ISIC_0030877_flip', 'ISIC_0029937_flip_mirror', 'ISIC_0029713', 'ISIC_0027190_flip', 'ISIC_0034007_flip_mirror', 'ISIC_0028581', 'ISIC_0029331_flip_mirror', 'ISIC_0029527_mirror', 'ISIC_0034221_mirror', 'ISIC_0025891_flip', 'ISIC_0033993', 'ISIC_0028039', 'ISIC_0031842', 'ISIC_0032860'] images : 7, labels : 16 Traceback (most recent call last): File "train.py", line 113, in <module> loss = criterion(output, labels) File "C:\Users\LabPC_2021\anaconda3\envs\nakai_py37\lib\site-packages\torch\nn\modules\module.py", line 889, in _call_impl result = self.forward(*input, **kwargs) File "C:\Users\LabPC_2021\anaconda3\envs\nakai_py37\lib\site-packages\torch\nn\modules\loss.py", line 1048, in forward ignore_index=self.ignore_index, reduction=self.reduction) File "C:\Users\LabPC_2021\anaconda3\envs\nakai_py37\lib\site-packages\torch\nn\functional.py", line 2690, in cross_entropy return nll_loss(log_softmax(input, 1), target, weight, None, ignore_index, None, reduction) File "C:\Users\LabPC_2021\anaconda3\envs\nakai_py37\lib\site-packages\torch\nn\functional.py", line 2382, in nll_loss "Expected input batch_size ({}) to match target batch_size ({}).".format(input.size(0), target.size(0)) ValueError: Expected input batch_size (7) to match target batch_size (16).

上のエラー文は83epochの途中(真ん中あたり)まで実行がうまく行っていたものです.
最初の方の

Error size ['ISIC_0028434', 'ISIC_0033912', 'ISIC_0030877_flip', 'ISIC_0029937_flip_mirror', 'ISIC_0029713', 'ISIC_0027190_flip', 'ISIC_0034007_flip_mirror', 'ISIC_0028581', 'ISIC_0029331_flip_mirror', 'ISIC_0029527_mirror', 'ISIC_0034221_mirror', 'ISIC_0025891_flip', 'ISIC_0033993', 'ISIC_0028039', 'ISIC_0031842', 'ISIC_0032860'] images : 7, labels : 16

は,自分で中身を詳しく見ようと思い,Errorが起こったときのファイル名,画像のbatchsize(7)およびlabelのbatchsize(16)を表示してみたものです.ただしここも決まったファイル名ではなく,labelは常に16(学習途中なのでこちらはあっていると思うのですが...)で,画像のbatchsizeが毎回不定です.

該当のソースコード

train

1for namelist in train_namelist: 2 images, labels = data_load.main(namelist) 3 images = images.to(device) # to GPU? 4 labels = labels.to(device) 5 6 optimizer.zero_grad() 7 output = net(images) 8 9 if not images.size(0) == labels.size(0): 10 print("Error size") 11 print(namelist) 12 print("images : {}, labels : {}".format(images.size(0), labels.size(0))) 13 14 loss = criterion(output, labels)

2行目のdata_load.mainの中身は以下です.
pandasのread_csv,PILのImageを用いています.

def main(self, namelist, crop_w = 320, crop_h = 320): labels = [] for image_id in namelist: img = Image.open(self.dir_name + 'HAM10000/{}.jpg'.format(image_id)) #img = img.resize((225, 300)) img_w, img_h = img.size img = img.crop(((img_w - crop_w)//2, (img_h - crop_h)//2, (img_w + crop_w)//2, (img_h + crop_h)//2)) img = np.asarray(img) img = torch.tensor(img).to(dtype = torch.float).unsqueeze_(0) img = img.permute(0, 3, 1, 2) try: image_batch = torch.cat((image_batch, img), dim = 0) except: image_batch = img     #self.dfはcsvのシートで,['image_id']が画像名,['dx']がラベルになっています basename_column = self.df[self.df['image_id'] == image_id] label = basename_column['dx'].values[0] #self.assign_number_to_labelsは,strで与えられたlabel名を,0,1,2...など決まった数字に割り振る関数です label = self.assign_numbers_to_labels(label) labels.append(label) labels = torch.Tensor(labels).to(dtype = torch.long) return image_batch, labels

試したこと

取得される全namelistに対応する画像およびlabelがあることは確認しています.
また,ニューラルネットには通さずひたすら画像とラベルを読み込んで,サイズを確認するといったことを10000epoch繰り返すといったことをやっても,結果は同じく途中でsize違いのerrorが出ました.

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

Python 3.7.10
pytorch 1.8.0 py3.7_cuda11.1_cudnn8_0 pytorch
pandas 1.2.3 py37h08fd248_0 conda-forge
pillow 8.1.2 py37h4fa10fc_0

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

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

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

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

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

toast-uz

2021/05/14 10:46

推測が多い話なので、コメント欄に記載します。小さいイメージが混在すると、data_load.mainの中の例外でexcept側に落ち込む実装になっています。その際に、image_batchが少なくなってしまいます。resize文がコメントアウトされていますが、これを有効にすれば回避できるのではと思います。なお、例外のこういう使い方は、エラーを隠蔽してしまうので、好ましくありません。
K.Nakai

2021/05/14 11:42

回答していただきありがとうございます. toast-uzさんの推測をもとに,一度画像サイズの確認およびresizeを有効にして実行してみます. また例外構文の使い方が好ましくないというご意見ですが,勉強不足でそこまで考えが至りませんでした.書き直します. あらためて回答していただき,ありがとうございます.
toast-uz

2021/05/14 12:10 編集

例外を使わずに、image_batchを配列として各imgをappendしていき、最後にimage_batch = torch.stack(できた配列)とするとよいです。labelsの取り回しとほぼ同じです。画像サイズがずれていれば、torch.stackでエラーが出ます。
K.Nakai

2021/05/15 03:16

なるほど,丁寧にアドバイスしていただき,ありがとうございます! 勉強になりました. ひとまずその方法で実行してみて様子を見ます.
K.Nakai

2021/05/19 07:26

実行を行い,ひとまず完了までいけました! batchの読み込みの途中でなぜexceptに入ってしまったかは不明のままですが,そこは今後の課題としてひとまず実験をこのまま勧めてみようと思います. toast_uzさん,本当にありがとうございました.
toast-uz

2021/05/19 12:59

ご確認ありがとうごさいます。正式回答を記述しましたので、クローズをお願いします。
guest

回答1

0

ベストアンサー

推測でコメントしていましたが、質問者様にて問題解消されたそうですので、正式回答として記載します。

現象から、異なるイメージサイズが混在した場合に、以下の部分で例外が処理され、結果としてimage_batchが意図したように作られないため、labelsとサイズ不一致になったものと思われます。

Python

1 try: 2 image_batch = torch.cat((image_batch, img), dim = 0) 3 except: 4 image_batch = img

以下でコメントアウトされているリサイズ文を有効にすることで、イメージサイズが揃うため、回避可能です。

Python

1 #img = img.resize((225, 300))

なお、今回のような場所に例外構文を使うと、必要なエラー発生が抑えられてしまい、バグの温床になります。そのため、以下のように例外を使わないコードにすると、よいでしょう。

Python

1def main(self, namelist, crop_w = 320, crop_h = 320): 2 labels = [] 3 image_batch = [] 4 for image_id in namelist: 5 img = Image.open(self.dir_name + 'HAM10000/{}.jpg'.format(image_id)) 6 img = img.resize((225, 300)) 7 (中略) 8 labels.append(label) 9 image_batch.append(img) 10 labels = torch.Tensor(labels).to(dtype = torch.long) 11 image_batch = torch.stack(image_batch) 12 return image_batch, labels

投稿2021/05/19 12:58

toast-uz

総合スコア3266

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

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

K.Nakai

2021/05/19 13:30

本当にありがとうございました. 助かりました.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問