teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

1

書式の改善

2021/11/11 06:42

投稿

0afnjosa
0afnjosa

スコア7

title CHANGED
File without changes
body CHANGED
@@ -2,6 +2,7 @@
2
2
  SSDを用いた物体検出を現在行っています。(初心者です)
3
3
  コードは「物体検出とGAN、オートエンコーダー、画像処理入門」という本のダウンロードサービスから拝借しています。
4
4
  #エラーが出たコード
5
+ ```Python
5
6
  %%time
6
7
  '''
7
8
  8. VOC2012データセットをSSDモデルで学習
@@ -14,7 +15,9 @@
14
15
  optimizer, # オプティマイザー
15
16
  num_epochs=num_epochs) # エポック数
16
17
 
18
+ ```
17
19
  ここでtrainは以下のコードで定義しています。
20
+ ```Python
18
21
  '''
19
22
  7. SSDモデルの学習(パラメーターの更新)を行う関数
20
23
  '''
@@ -30,10 +33,10 @@
30
33
  optimizer(object): オプティマイザー
31
34
  num_epochs(object): 学習回数
32
35
  '''
33
- SSDモデルでGPUを使用
36
+ # SSDモデルでGPUを使用
34
37
  net.to(device)
35
38
 
36
- ネットワークの構成に対して最適なアルゴリズムを見つけて高速化させる
39
+ # ネットワークの構成に対して最適なアルゴリズムを見つけて高速化させる
37
40
  torch.backends.cudnn.benchmark = True
38
41
 
39
42
  iteration = 1 # イテレーション(ステップ)カウンター
@@ -41,124 +44,203 @@
41
44
  epoch_val_loss = 0.0 # 検証1エポックごとの損失和
42
45
  logs = [] # 損失のログを記録するリスト
43
46
 
44
- 学習、または検証のエポックごとのループ
47
+ # 学習、または検証のエポックごとのループ
45
48
  for epoch in range(num_epochs):
46
- 開始時刻を保存
49
+ # 開始時刻を保存
47
50
  t_epoch_start = time.time()
48
51
  t_iter_start = time.time()
49
52
 
50
- 現在のエポック数を出力
53
+ # 現在のエポック数を出力
51
54
  print('---------------------------------------')
52
55
  print('Epoch {}/{}'.format(epoch+1, num_epochs))
53
56
  print('---------------------------------------')
54
57
 
55
- エポック10回につき検証を1回行う
58
+ # エポック10回につき検証を1回行う
56
59
  for phase in ['train', 'val']:
57
- エポックが10回に達するまではモデルを訓練モードにする
60
+ # エポックが10回に達するまではモデルを訓練モードにする
58
61
  if phase == 'train':
59
62
  net.train() # モデルを訓練モードにする
60
63
  else:
61
- エポックが10回に達していたらモデルを検証モードにして検証開始
64
+ # エポックが10回に達していたらモデルを検証モードにして検証開始
62
65
  if((epoch+1) % 10 == 0):
63
66
  net.eval() # モデルを検証モードにする
64
67
  print('---------------------------------------')
65
68
  print('(validation)')
66
69
  else:
67
- 10回に達していなければ次のエポックに進む
70
+ # 10回に達していなければ次のエポックに進む
68
71
  continue
69
72
 
70
- 1ステップにおけるミニバッチを使用した学習または検証
73
+ # 1ステップにおけるミニバッチを使用した学習または検証
71
- データローダーをイテレートしてミニバッチを抽出
74
+ # データローダーをイテレートしてミニバッチを抽出
72
75
  for images, targets in dataloaders_dict[phase]:
73
- 画像データにデバイスを割り当てる
76
+ # 画像データにデバイスを割り当てる
74
77
  images = images.to(device)
75
- 教師データ(正解BBoxのアノテーション情報)
78
+ # 教師データ(正解BBoxのアノテーション情報)
76
- (バッチサイズ, 物体数, 5[xmin, ymin, xmax, ymax, label_index])
79
+ # (バッチサイズ, 物体数, 5[xmin, ymin, xmax, ymax, label_index])
77
- にデバイスを割り当てる
80
+ # にデバイスを割り当てる
78
81
  targets = [ann.to(device) for ann in targets]
79
82
 
80
- optimizerが保持する勾配を0で初期化(累積しないように)
83
+ # optimizerが保持する勾配を0で初期化(累積しないように)
81
84
  optimizer.zero_grad()
82
85
 
83
- 順伝搬(forward)とバックプロパゲーション(訓練時のみ)
86
+ # 順伝搬(forward)とバックプロパゲーション(訓練時のみ)
84
87
  with torch.set_grad_enabled(phase == 'train'):
85
- 順伝搬(forward)を行って(loc, conf, dbox_list)を取得
88
+ # 順伝搬(forward)を行って(loc, conf, dbox_list)を取得
86
- ・locの出力(バッチサイズ, 8732, 4[Δcx, Δcy, Δw, Δh])
89
+ # ・locの出力(バッチサイズ, 8732, 4[Δcx, Δcy, Δw, Δh])
87
- ・confの出力(バッチサイズ, 8732, 21)
90
+ # ・confの出力(バッチサイズ, 8732, 21)
88
- ・DBoxの情報(8732, 4[cx, cy, width, height])
91
+ # ・DBoxの情報(8732, 4[cx, cy, width, height])
89
92
  outputs = net(images)
90
93
 
91
- Positive DBoxのオフセット情報の損失平均
94
+ # Positive DBoxのオフセット情報の損失平均
92
- ミニバッチにおけるPositive DBoxの確信度の損失平均
95
+ # ミニバッチにおけるPositive DBoxの確信度の損失平均
93
96
  loss_l, loss_c = criterion(outputs, targets)
94
- 2つの損失を合計する
97
+ # 2つの損失を合計する
95
98
  loss = loss_l + loss_c
96
99
 
97
- 訓練時はバックプロパゲーションによるパラメーター更新を行う
100
+ # 訓練時はバックプロパゲーションによるパラメーター更新を行う
98
101
  if phase == 'train':
99
102
  loss.backward() # バックプロパゲーション
100
103
 
101
- 勾配が大きすぎると不安定になるので
104
+ # 勾配が大きすぎると不安定になるので
102
- clipで勾配の上限を2.0に制限する
105
+ # clipで勾配の上限を2.0に制限する
103
106
  nn.utils.clip_grad_value_(net.parameters(),
104
107
  clip_value=2.0)
105
- 勾配降下法の更新式を適用してバイアス、重みを更新
108
+ # 勾配降下法の更新式を適用してバイアス、重みを更新
106
109
  optimizer.step()
107
110
 
108
- ミニバッチを10個処理(10ステップ)ごとに損失を出力
111
+ # ミニバッチを10個処理(10ステップ)ごとに損失を出力
109
112
  if (iteration % 10 == 0):
110
- 10ステップの所要時間を取得
113
+ # 10ステップの所要時間を取得
111
114
  t_iter_finish = time.time()
112
115
  duration = t_iter_finish - t_iter_start
113
- ステップ数、損失、所要時間を出力
116
+ # ステップ数、損失、所要時間を出力
114
117
  print('ステップ( {} ) loss: {:.4f} -- time: {:.4f} sec.'.format(
115
118
  iteration, loss.item(), duration))
116
119
  t_iter_start = time.time()
117
120
 
118
- エポックの損失をepoch_train_lossに加算する
121
+ # エポックの損失をepoch_train_lossに加算する
119
122
  epoch_train_loss += loss.item()
120
- ステップ数を1増やす
123
+ # ステップ数を1増やす
121
124
  iteration += 1
122
125
 
123
- 検証モードでは順伝播後の損失の記録のみを行う
126
+ # 検証モードでは順伝播後の損失の記録のみを行う
124
127
  else:
125
128
  epoch_val_loss += loss.item()
126
129
 
127
- epochのphaseごとのlossと正解率
130
+ # epochのphaseごとのlossと正解率
128
- エポック終了時の時刻を取得
131
+ # エポック終了時の時刻を取得
129
132
  t_epoch_finish = time.time()
130
133
  print('---------------------------------------')
131
- 訓練データの損失と検証データの損失を出力
134
+ # 訓練データの損失と検証データの損失を出力
132
135
  print('train_loss: {:.4f} - val_loss(Every 10 epochs): {:.4f}'.format(
133
136
  epoch_train_loss, epoch_val_loss))
134
- エポック終了までに要した時間を取得
137
+ # エポック終了までに要した時間を取得
135
138
  print('time: {:.4f} sec.'.format(t_epoch_finish - t_epoch_start))
136
- 次のエポックの開始時刻を取得
139
+ # 次のエポックの開始時刻を取得
137
140
  t_epoch_start = time.time()
138
141
 
139
- エポックごとに損失をdictオブジェクトに保存
142
+ # エポックごとに損失をdictオブジェクトに保存
140
143
  log_epoch = {'epoch': epoch+1,
141
144
  'train_loss': epoch_train_loss,
142
145
  'val_loss': epoch_val_loss}
143
- ログのリストに追加
146
+ # ログのリストに追加
144
147
  logs.append(log_epoch)
145
- ログのリストをデータフレームに変換
148
+ # ログのリストをデータフレームに変換
146
149
  df = pd.DataFrame(logs)
147
- ログファイルに保存
150
+ # ログファイルに保存
148
151
  df.to_csv('/content/drive/MyDrive/Colab Notebooks/ObjectDetection/epoch_loss.csv')
149
152
 
150
- 訓練時の損失和を0で初期化
153
+ # 訓練時の損失和を0で初期化
151
154
  epoch_train_loss = 0.0
152
- 検証時の損失和を0で初期化
155
+ # 検証時の損失和を0で初期化
153
156
  epoch_val_loss = 0.0
154
157
 
155
- 1エポック終了ごとにモデルのパラメーター値を保存
158
+ # 1エポック終了ごとにモデルのパラメーター値を保存
156
159
  if ((epoch+1) % 10 == 0):
157
160
  torch.save(
158
161
  net.state_dict(),
159
162
  '/content/drive/MyDrive/Colab Notebooks/ObjectDetection/weights/ssd_weights' +
160
163
  str(epoch+1) + '.pth')
161
164
  print('--saved weights--')
165
+ ```
166
+ #出たエラー
167
+ ```Python
168
+ /usr/local/lib/python3.7/dist-packages/IPython/core/interactiveshell.py in run_cell_magic(self, magic_name, line, cell)
169
+ 2115 magic_arg_s = self.var_expand(line, stack_depth)
170
+ 2116 with self.builtin_trap:
171
+ -> 2117 result = fn(magic_arg_s, cell)
172
+ 2118 return result
173
+ 2119
174
+
175
+ <decorator-gen-53> in time(self, line, cell, local_ns)
176
+
177
+ /usr/local/lib/python3.7/dist-packages/IPython/core/magic.py in <lambda>(f, *a, **k)
178
+ 186 # but it's overkill for just that one bit of state.
179
+ 187 def magic_deco(arg):
180
+ --> 188 call = lambda f, *a, **k: f(*a, **k)
181
+ 189
182
+ 190 if callable(arg):
183
+
184
+ /usr/local/lib/python3.7/dist-packages/IPython/core/magics/execution.py in time(self, line, cell, local_ns)
185
+ 1191 else:
186
+ 1192 st = clock2()
187
+ -> 1193 exec(code, glob, local_ns)
188
+ 1194 end = clock2()
189
+ 1195 out = None
190
+
191
+ <timed exec> in <module>()
192
+
193
+ <ipython-input-8-dd6592475800> in train(net, dataloaders_dict, criterion, optimizer, num_epochs)
194
+ 53 # 1ステップにおけるミニバッチを使用した学習または検証
195
+ 54 # データローダーをイテレートしてミニバッチを抽出
196
+ ---> 55 for images, targets in dataloaders_dict[phase]:
197
+ 56 # 画像データにデバイスを割り当てる
198
+ 57 images = images.to(device)
199
+
200
+ /usr/local/lib/python3.7/dist-packages/torch/utils/data/dataloader.py in __next__(self)
201
+ 519 if self._sampler_iter is None:
202
+ 520 self._reset()
203
+ --> 521 data = self._next_data()
204
+ 522 self._num_yielded += 1
205
+ 523 if self._dataset_kind == _DatasetKind.Iterable and \
206
+
207
+ /usr/local/lib/python3.7/dist-packages/torch/utils/data/dataloader.py in _next_data(self)
208
+ 559 def _next_data(self):
209
+ 560 index = self._next_index() # may raise StopIteration
210
+ --> 561 data = self._dataset_fetcher.fetch(index) # may raise StopIteration
211
+ 562 if self._pin_memory:
212
+ 563 data = _utils.pin_memory.pin_memory(data)
213
+
214
+ /usr/local/lib/python3.7/dist-packages/torch/utils/data/_utils/fetch.py in fetch(self, possibly_batched_index)
215
+ 42 def fetch(self, possibly_batched_index):
216
+ 43 if self.auto_collation:
217
+ ---> 44 data = [self.dataset[idx] for idx in possibly_batched_index]
218
+ 45 else:
219
+ 46 data = self.dataset[possibly_batched_index]
220
+
221
+ /usr/local/lib/python3.7/dist-packages/torch/utils/data/_utils/fetch.py in <listcomp>(.0)
222
+ 42 def fetch(self, possibly_batched_index):
223
+ 43 if self.auto_collation:
224
+ ---> 44 data = [self.dataset[idx] for idx in possibly_batched_index]
225
+ 45 else:
226
+ 46 data = self.dataset[possibly_batched_index]
227
+
228
+ /content/drive/MyDrive/Colab Notebooks/ObjectDetection/voc.py in __getitem__(self, index)
229
+ 256 # pull_item()にイメージのインデックスを渡して前処理
230
+ 257 # 処理後のイメージデータとBBoxとラベルの2次元配列を返す
231
+ --> 258 im, bl, _, _ = self.pull_item(index)
232
+ 259 return im, bl
233
+ 260
234
+
235
+ /content/drive/MyDrive/Colab Notebooks/ObjectDetection/voc.py in pull_item(self, index)
236
+ 275 img_path = self.img_list[index] # インデックスを指定してイメージのパスを取得
237
+ 276 img = cv2.imread(img_path) # OpenCV2でイメージの[高さ,幅,[B,G,R]]を取得
238
+ --> 277 height, width, _ = img.shape # 配列要素数を数えて高さ,幅のみを取得
239
+ 278
240
+ 279 # アノテーションデータのリストを取得
241
+
242
+ AttributeError: 'NoneType' object has no attribute 'shape'
243
+ ```
162
244
  #知りたいこと
163
245
  このエラーはどういう意味か。
164
246
  どうすれば動くようになるか。