前提
ただいま勉強中の未熟者です。
「物体検出とGAN、オートエンコーダー、画像処理入門」の参考書
のソースコードをダウンロードをし
SSDによる物体検出を行っています。
発生している問題・エラーメッセージ
エラーメッセージ --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <timed exec> in <module> <ipython-input-11-f5fd48daba1c> in train(net, dataloaders_dict, criterion, optimizer, num_epochs) 62 63 ---> 64 for images, targets in dataloaders_dict[phase]: 65 # 画像データにデバイスを割り当てる 66 images = images.to(device) /usr/local/lib/python3.7/dist-packages/torch/utils/data/dataloader.py in __next__(self) 679 # TODO(https://github.com/pytorch/pytorch/issues/76750) 680 self._reset() # type: ignore[call-arg] --> 681 data = self._next_data() 682 self._num_yielded += 1 683 if self._dataset_kind == _DatasetKind.Iterable and \ /usr/local/lib/python3.7/dist-packages/torch/utils/data/dataloader.py in _next_data(self) 719 def _next_data(self): 720 index = self._next_index() # may raise StopIteration --> 721 data = self._dataset_fetcher.fetch(index) # may raise StopIteration 722 if self._pin_memory: 723 data = _utils.pin_memory.pin_memory(data, self._pin_memory_device) /usr/local/lib/python3.7/dist-packages/torch/utils/data/_utils/fetch.py in fetch(self, possibly_batched_index) 47 def fetch(self, possibly_batched_index): 48 if self.auto_collation: ---> 49 data = [self.dataset[idx] for idx in possibly_batched_index] 50 else: 51 data = self.dataset[possibly_batched_index] /usr/local/lib/python3.7/dist-packages/torch/utils/data/_utils/fetch.py in <listcomp>(.0) 47 def fetch(self, possibly_batched_index): 48 if self.auto_collation: ---> 49 data = [self.dataset[idx] for idx in possibly_batched_index] 50 else: 51 data = self.dataset[possibly_batched_index] /content/drive/My Drive/Colab Notebooks/ObjectDetection/voc.py in __getitem__(self, index) 256 # pull_item()にイメージのインデックスを渡して前処理 257 # 処理後のイメージデータとBBoxとラベルの2次元配列を返す --> 258 im, bl, _, _ = self.pull_item(index) 259 return im, bl 260 /content/drive/My Drive/Colab Notebooks/ObjectDetection/voc.py in pull_item(self, index) 275 img_path = self.img_list[index] # インデックスを指定してイメージのパスを取得 276 img = cv2.imread(img_path) # OpenCV2でイメージの[高さ,幅,[B,G,R]]を取得 --> 277 height, width, _ = img.shape # 配列要素数を数えて高さ,幅のみを取得 278 279 # アノテーションデータのリストを取得 AttributeError: 'NoneType' object has no attribute 'shape'
該当のソースコード
ソースコード ''' 7. SSDモデルの学習(パラメーターの更新)を行う関数 ''' import time import pandas as pd def train(net, dataloaders_dict, criterion, optimizer, num_epochs): ''' Parameters: net(object): SSDモデル dataloaders_dict(objectのdict): データーローダー criterion(object): 損失関数 optimizer(object): オプティマイザー num_epochs(object): 学習回数 ''' # SSDモデルでGPUを使用 net.to(device) # ネットワークの構成に対して最適なアルゴリズムを見つけて高速化させる torch.backends.cudnn.benchmark = True iteration = 1 # イテレーション(ステップ)カウンター epoch_train_loss = 0.0 # 訓練1エポックごとの損失和 epoch_val_loss = 0.0 # 検証1エポックごとの損失和 logs = [] # 損失のログを記録するリスト # 学習、または検証のエポックごとのループ for epoch in range(num_epochs): # 開始時刻を保存 t_epoch_start = time.time() t_iter_start = time.time() # 現在のエポック数を出力 print('---------------------------------------') print('Epoch {}/{}'.format(epoch+1, num_epochs)) print('---------------------------------------') # エポック10回につき検証を1回行う for phase in ['train', 'val']: # エポックが10回に達するまではモデルを訓練モードにする if phase == 'train': net.train() # モデルを訓練モードにする else: # エポックが10回に達していたらモデルを検証モードにして検証開始 if((epoch+1) % 10 == 0): net.eval() # モデルを検証モードにする print('---------------------------------------') print('(validation)') else: # 10回に達していなければ次のエポックに進む continue # 1ステップにおけるミニバッチを使用した学習または検証 # データローダーをイテレートしてミニバッチを抽出 **for images, targets in dataloaders_dict[phase]:** #ここがエラーメッセージ # 画像データにデバイスを割り当てる images = images.to(device) # 教師データ(正解BBoxのアノテーション情報) # (バッチサイズ, 物体数, 5[xmin, ymin, xmax, ymax, label_index]) # にデバイスを割り当てる targets = [ann.to(device) for ann in targets] # optimizerが保持する勾配を0で初期化(累積しないように) optimizer.zero_grad() # 順伝搬(forward)とバックプロパゲーション(訓練時のみ) with torch.set_grad_enabled(phase == 'train'): # 順伝搬(forward)を行って(loc, conf, dbox_list)を取得 # ・locの出力(バッチサイズ, 8732, 4[Δcx, Δcy, Δw, Δh]) # ・confの出力(バッチサイズ, 8732, 21) # ・DBoxの情報(8732, 4[cx, cy, width, height]) outputs = net(images) # Positive DBoxのオフセット情報の損失平均 # ミニバッチにおけるPositive DBoxの確信度の損失平均 loss_l, loss_c = criterion(outputs, targets) # 2つの損失を合計する loss = loss_l + loss_c # 訓練時はバックプロパゲーションによるパラメーター更新を行う if phase == 'train': loss.backward() # バックプロパゲーション # 勾配が大きすぎると不安定になるので # clipで勾配の上限を2.0に制限する nn.utils.clip_grad_value_(net.parameters(), clip_value=2.0) # 勾配降下法の更新式を適用してバイアス、重みを更新 optimizer.step() # ミニバッチを10個処理(10ステップ)ごとに損失を出力 if (iteration % 10 == 0): # 10ステップの所要時間を取得 t_iter_finish = time.time() duration = t_iter_finish - t_iter_start # ステップ数、損失、所要時間を出力 print('ステップ( {} ) loss: {:.4f} -- time: {:.4f} sec.'.format( iteration, loss.item(), duration)) t_iter_start = time.time() # エポックの損失をepoch_train_lossに加算する epoch_train_loss += loss.item() # ステップ数を1増やす iteration += 1 # 検証モードでは順伝播後の損失の記録のみを行う else: epoch_val_loss += loss.item() # epochのphaseごとのlossと正解率 # エポック終了時の時刻を取得 t_epoch_finish = time.time() print('---------------------------------------') # 訓練データの損失と検証データの損失を出力 print('train_loss: {:.4f} - val_loss(Every 10 epochs): {:.4f}'.format( epoch_train_loss, epoch_val_loss)) # エポック終了までに要した時間を取得 print('time: {:.4f} sec.'.format(t_epoch_finish - t_epoch_start)) # 次のエポックの開始時刻を取得 t_epoch_start = time.time() # エポックごとに損失をdictオブジェクトに保存 log_epoch = {'epoch': epoch+1, 'train_loss': epoch_train_loss, 'val_loss': epoch_val_loss} # ログのリストに追加 logs.append(log_epoch) # ログのリストをデータフレームに変換 df = pd.DataFrame(logs) # ログファイルに保存 df.to_csv('/content/drive/MyDrive/Colab Notebooks/ObjectDetection/epoch_loss.csv') # 訓練時の損失和を0で初期化 epoch_train_loss = 0.0 # 検証時の損失和を0で初期化 epoch_val_loss = 0.0 # 1エポック終了ごとにモデルのパラメーター値を保存 if ((epoch+1) % 10 == 0): torch.save( net.state_dict(), '/content/drive/MyDrive/Colab Notebooks/ObjectDetection/weights/ssd_weights' + str(epoch+1) + '.pth') print('--saved weights--')
試したこと
現在 pdb という公式のデバッカを学びながら確認しています
が、まだ分かっていないところも多いのでご教授して頂けると幸いです。
補足情報(FW/ツールのバージョンなど)
不明点等ございましたら、修正依頼等お願いします。
回答1件
あなたの回答
tips
プレビュー