質問編集履歴
1
書式の改善
test
CHANGED
File without changes
|
test
CHANGED
@@ -6,6 +6,8 @@
|
|
6
6
|
|
7
7
|
#エラーが出たコード
|
8
8
|
|
9
|
+
```Python
|
10
|
+
|
9
11
|
%%time
|
10
12
|
|
11
13
|
'''
|
@@ -30,8 +32,12 @@
|
|
30
32
|
|
31
33
|
|
32
34
|
|
35
|
+
```
|
36
|
+
|
33
37
|
ここでtrainは以下のコードで定義しています。
|
34
38
|
|
39
|
+
```Python
|
40
|
+
|
35
41
|
'''
|
36
42
|
|
37
43
|
7. SSDモデルの学習(パラメーターの更新)を行う関数
|
@@ -62,13 +68,13 @@
|
|
62
68
|
|
63
69
|
'''
|
64
70
|
|
65
|
-
SSDモデルでGPUを使用
|
71
|
+
# SSDモデルでGPUを使用
|
66
72
|
|
67
73
|
net.to(device)
|
68
74
|
|
69
75
|
|
70
76
|
|
71
|
-
ネットワークの構成に対して最適なアルゴリズムを見つけて高速化させる
|
77
|
+
# ネットワークの構成に対して最適なアルゴリズムを見つけて高速化させる
|
72
78
|
|
73
79
|
torch.backends.cudnn.benchmark = True
|
74
80
|
|
@@ -84,11 +90,11 @@
|
|
84
90
|
|
85
91
|
|
86
92
|
|
87
|
-
学習、または検証のエポックごとのループ
|
93
|
+
# 学習、または検証のエポックごとのループ
|
88
94
|
|
89
95
|
for epoch in range(num_epochs):
|
90
96
|
|
91
|
-
開始時刻を保存
|
97
|
+
# 開始時刻を保存
|
92
98
|
|
93
99
|
t_epoch_start = time.time()
|
94
100
|
|
@@ -96,7 +102,7 @@
|
|
96
102
|
|
97
103
|
|
98
104
|
|
99
|
-
現在のエポック数を出力
|
105
|
+
# 現在のエポック数を出力
|
100
106
|
|
101
107
|
print('---------------------------------------')
|
102
108
|
|
@@ -106,11 +112,11 @@
|
|
106
112
|
|
107
113
|
|
108
114
|
|
109
|
-
エポック10回につき検証を1回行う
|
115
|
+
# エポック10回につき検証を1回行う
|
110
116
|
|
111
117
|
for phase in ['train', 'val']:
|
112
118
|
|
113
|
-
エポックが10回に達するまではモデルを訓練モードにする
|
119
|
+
# エポックが10回に達するまではモデルを訓練モードにする
|
114
120
|
|
115
121
|
if phase == 'train':
|
116
122
|
|
@@ -118,7 +124,7 @@
|
|
118
124
|
|
119
125
|
else:
|
120
126
|
|
121
|
-
エポックが10回に達していたらモデルを検証モードにして検証開始
|
127
|
+
# エポックが10回に達していたらモデルを検証モードにして検証開始
|
122
128
|
|
123
129
|
if((epoch+1) % 10 == 0):
|
124
130
|
|
@@ -130,67 +136,67 @@
|
|
130
136
|
|
131
137
|
else:
|
132
138
|
|
133
|
-
10回に達していなければ次のエポックに進む
|
139
|
+
# 10回に達していなければ次のエポックに進む
|
134
140
|
|
135
141
|
continue
|
136
142
|
|
137
143
|
|
138
144
|
|
139
|
-
1ステップにおけるミニバッチを使用した学習または検証
|
145
|
+
# 1ステップにおけるミニバッチを使用した学習または検証
|
140
|
-
|
146
|
+
|
141
|
-
データローダーをイテレートしてミニバッチを抽出
|
147
|
+
# データローダーをイテレートしてミニバッチを抽出
|
142
148
|
|
143
149
|
for images, targets in dataloaders_dict[phase]:
|
144
150
|
|
145
|
-
画像データにデバイスを割り当てる
|
151
|
+
# 画像データにデバイスを割り当てる
|
146
152
|
|
147
153
|
images = images.to(device)
|
148
154
|
|
149
|
-
教師データ(正解BBoxのアノテーション情報)
|
155
|
+
# 教師データ(正解BBoxのアノテーション情報)
|
150
|
-
|
156
|
+
|
151
|
-
(バッチサイズ, 物体数, 5[xmin, ymin, xmax, ymax, label_index])
|
157
|
+
# (バッチサイズ, 物体数, 5[xmin, ymin, xmax, ymax, label_index])
|
152
|
-
|
158
|
+
|
153
|
-
にデバイスを割り当てる
|
159
|
+
# にデバイスを割り当てる
|
154
160
|
|
155
161
|
targets = [ann.to(device) for ann in targets]
|
156
162
|
|
157
163
|
|
158
164
|
|
159
|
-
optimizerが保持する勾配を0で初期化(累積しないように)
|
165
|
+
# optimizerが保持する勾配を0で初期化(累積しないように)
|
160
166
|
|
161
167
|
optimizer.zero_grad()
|
162
168
|
|
163
169
|
|
164
170
|
|
165
|
-
順伝搬(forward)とバックプロパゲーション(訓練時のみ)
|
171
|
+
# 順伝搬(forward)とバックプロパゲーション(訓練時のみ)
|
166
172
|
|
167
173
|
with torch.set_grad_enabled(phase == 'train'):
|
168
174
|
|
169
|
-
順伝搬(forward)を行って(loc, conf, dbox_list)を取得
|
175
|
+
# 順伝搬(forward)を行って(loc, conf, dbox_list)を取得
|
170
|
-
|
176
|
+
|
171
|
-
・locの出力(バッチサイズ, 8732, 4[Δcx, Δcy, Δw, Δh])
|
177
|
+
# ・locの出力(バッチサイズ, 8732, 4[Δcx, Δcy, Δw, Δh])
|
172
|
-
|
178
|
+
|
173
|
-
・confの出力(バッチサイズ, 8732, 21)
|
179
|
+
# ・confの出力(バッチサイズ, 8732, 21)
|
174
|
-
|
180
|
+
|
175
|
-
・DBoxの情報(8732, 4[cx, cy, width, height])
|
181
|
+
# ・DBoxの情報(8732, 4[cx, cy, width, height])
|
176
182
|
|
177
183
|
outputs = net(images)
|
178
184
|
|
179
185
|
|
180
186
|
|
181
|
-
Positive DBoxのオフセット情報の損失平均
|
187
|
+
# Positive DBoxのオフセット情報の損失平均
|
182
|
-
|
188
|
+
|
183
|
-
ミニバッチにおけるPositive DBoxの確信度の損失平均
|
189
|
+
# ミニバッチにおけるPositive DBoxの確信度の損失平均
|
184
190
|
|
185
191
|
loss_l, loss_c = criterion(outputs, targets)
|
186
192
|
|
187
|
-
2つの損失を合計する
|
193
|
+
# 2つの損失を合計する
|
188
194
|
|
189
195
|
loss = loss_l + loss_c
|
190
196
|
|
191
197
|
|
192
198
|
|
193
|
-
訓練時はバックプロパゲーションによるパラメーター更新を行う
|
199
|
+
# 訓練時はバックプロパゲーションによるパラメーター更新を行う
|
194
200
|
|
195
201
|
if phase == 'train':
|
196
202
|
|
@@ -198,31 +204,31 @@
|
|
198
204
|
|
199
205
|
|
200
206
|
|
201
|
-
勾配が大きすぎると不安定になるので
|
207
|
+
# 勾配が大きすぎると不安定になるので
|
202
|
-
|
208
|
+
|
203
|
-
clipで勾配の上限を2.0に制限する
|
209
|
+
# clipで勾配の上限を2.0に制限する
|
204
210
|
|
205
211
|
nn.utils.clip_grad_value_(net.parameters(),
|
206
212
|
|
207
213
|
clip_value=2.0)
|
208
214
|
|
209
|
-
勾配降下法の更新式を適用してバイアス、重みを更新
|
215
|
+
# 勾配降下法の更新式を適用してバイアス、重みを更新
|
210
216
|
|
211
217
|
optimizer.step()
|
212
218
|
|
213
219
|
|
214
220
|
|
215
|
-
ミニバッチを10個処理(10ステップ)ごとに損失を出力
|
221
|
+
# ミニバッチを10個処理(10ステップ)ごとに損失を出力
|
216
222
|
|
217
223
|
if (iteration % 10 == 0):
|
218
224
|
|
219
|
-
10ステップの所要時間を取得
|
225
|
+
# 10ステップの所要時間を取得
|
220
226
|
|
221
227
|
t_iter_finish = time.time()
|
222
228
|
|
223
229
|
duration = t_iter_finish - t_iter_start
|
224
230
|
|
225
|
-
ステップ数、損失、所要時間を出力
|
231
|
+
# ステップ数、損失、所要時間を出力
|
226
232
|
|
227
233
|
print('ステップ( {} ) loss: {:.4f} -- time: {:.4f} sec.'.format(
|
228
234
|
|
@@ -232,17 +238,17 @@
|
|
232
238
|
|
233
239
|
|
234
240
|
|
235
|
-
エポックの損失をepoch_train_lossに加算する
|
241
|
+
# エポックの損失をepoch_train_lossに加算する
|
236
242
|
|
237
243
|
epoch_train_loss += loss.item()
|
238
244
|
|
239
|
-
ステップ数を1増やす
|
245
|
+
# ステップ数を1増やす
|
240
246
|
|
241
247
|
iteration += 1
|
242
248
|
|
243
249
|
|
244
250
|
|
245
|
-
検証モードでは順伝播後の損失の記録のみを行う
|
251
|
+
# 検証モードでは順伝播後の損失の記録のみを行う
|
246
252
|
|
247
253
|
else:
|
248
254
|
|
@@ -250,31 +256,31 @@
|
|
250
256
|
|
251
257
|
|
252
258
|
|
253
|
-
epochのphaseごとのlossと正解率
|
259
|
+
# epochのphaseごとのlossと正解率
|
254
|
-
|
260
|
+
|
255
|
-
エポック終了時の時刻を取得
|
261
|
+
# エポック終了時の時刻を取得
|
256
262
|
|
257
263
|
t_epoch_finish = time.time()
|
258
264
|
|
259
265
|
print('---------------------------------------')
|
260
266
|
|
261
|
-
訓練データの損失と検証データの損失を出力
|
267
|
+
# 訓練データの損失と検証データの損失を出力
|
262
268
|
|
263
269
|
print('train_loss: {:.4f} - val_loss(Every 10 epochs): {:.4f}'.format(
|
264
270
|
|
265
271
|
epoch_train_loss, epoch_val_loss))
|
266
272
|
|
267
|
-
エポック終了までに要した時間を取得
|
273
|
+
# エポック終了までに要した時間を取得
|
268
274
|
|
269
275
|
print('time: {:.4f} sec.'.format(t_epoch_finish - t_epoch_start))
|
270
276
|
|
271
|
-
次のエポックの開始時刻を取得
|
277
|
+
# 次のエポックの開始時刻を取得
|
272
278
|
|
273
279
|
t_epoch_start = time.time()
|
274
280
|
|
275
281
|
|
276
282
|
|
277
|
-
エポックごとに損失をdictオブジェクトに保存
|
283
|
+
# エポックごとに損失をdictオブジェクトに保存
|
278
284
|
|
279
285
|
log_epoch = {'epoch': epoch+1,
|
280
286
|
|
@@ -282,31 +288,31 @@
|
|
282
288
|
|
283
289
|
'val_loss': epoch_val_loss}
|
284
290
|
|
285
|
-
ログのリストに追加
|
291
|
+
# ログのリストに追加
|
286
292
|
|
287
293
|
logs.append(log_epoch)
|
288
294
|
|
289
|
-
ログのリストをデータフレームに変換
|
295
|
+
# ログのリストをデータフレームに変換
|
290
296
|
|
291
297
|
df = pd.DataFrame(logs)
|
292
298
|
|
293
|
-
ログファイルに保存
|
299
|
+
# ログファイルに保存
|
294
300
|
|
295
301
|
df.to_csv('/content/drive/MyDrive/Colab Notebooks/ObjectDetection/epoch_loss.csv')
|
296
302
|
|
297
303
|
|
298
304
|
|
299
|
-
訓練時の損失和を0で初期化
|
305
|
+
# 訓練時の損失和を0で初期化
|
300
306
|
|
301
307
|
epoch_train_loss = 0.0
|
302
308
|
|
303
|
-
検証時の損失和を0で初期化
|
309
|
+
# 検証時の損失和を0で初期化
|
304
310
|
|
305
311
|
epoch_val_loss = 0.0
|
306
312
|
|
307
313
|
|
308
314
|
|
309
|
-
1エポック終了ごとにモデルのパラメーター値を保存
|
315
|
+
# 1エポック終了ごとにモデルのパラメーター値を保存
|
310
316
|
|
311
317
|
if ((epoch+1) % 10 == 0):
|
312
318
|
|
@@ -320,6 +326,164 @@
|
|
320
326
|
|
321
327
|
print('--saved weights--')
|
322
328
|
|
329
|
+
```
|
330
|
+
|
331
|
+
#出たエラー
|
332
|
+
|
333
|
+
```Python
|
334
|
+
|
335
|
+
/usr/local/lib/python3.7/dist-packages/IPython/core/interactiveshell.py in run_cell_magic(self, magic_name, line, cell)
|
336
|
+
|
337
|
+
2115 magic_arg_s = self.var_expand(line, stack_depth)
|
338
|
+
|
339
|
+
2116 with self.builtin_trap:
|
340
|
+
|
341
|
+
-> 2117 result = fn(magic_arg_s, cell)
|
342
|
+
|
343
|
+
2118 return result
|
344
|
+
|
345
|
+
2119
|
346
|
+
|
347
|
+
|
348
|
+
|
349
|
+
<decorator-gen-53> in time(self, line, cell, local_ns)
|
350
|
+
|
351
|
+
|
352
|
+
|
353
|
+
/usr/local/lib/python3.7/dist-packages/IPython/core/magic.py in <lambda>(f, *a, **k)
|
354
|
+
|
355
|
+
186 # but it's overkill for just that one bit of state.
|
356
|
+
|
357
|
+
187 def magic_deco(arg):
|
358
|
+
|
359
|
+
--> 188 call = lambda f, *a, **k: f(*a, **k)
|
360
|
+
|
361
|
+
189
|
362
|
+
|
363
|
+
190 if callable(arg):
|
364
|
+
|
365
|
+
|
366
|
+
|
367
|
+
/usr/local/lib/python3.7/dist-packages/IPython/core/magics/execution.py in time(self, line, cell, local_ns)
|
368
|
+
|
369
|
+
1191 else:
|
370
|
+
|
371
|
+
1192 st = clock2()
|
372
|
+
|
373
|
+
-> 1193 exec(code, glob, local_ns)
|
374
|
+
|
375
|
+
1194 end = clock2()
|
376
|
+
|
377
|
+
1195 out = None
|
378
|
+
|
379
|
+
|
380
|
+
|
381
|
+
<timed exec> in <module>()
|
382
|
+
|
383
|
+
|
384
|
+
|
385
|
+
<ipython-input-8-dd6592475800> in train(net, dataloaders_dict, criterion, optimizer, num_epochs)
|
386
|
+
|
387
|
+
53 # 1ステップにおけるミニバッチを使用した学習または検証
|
388
|
+
|
389
|
+
54 # データローダーをイテレートしてミニバッチを抽出
|
390
|
+
|
391
|
+
---> 55 for images, targets in dataloaders_dict[phase]:
|
392
|
+
|
393
|
+
56 # 画像データにデバイスを割り当てる
|
394
|
+
|
395
|
+
57 images = images.to(device)
|
396
|
+
|
397
|
+
|
398
|
+
|
399
|
+
/usr/local/lib/python3.7/dist-packages/torch/utils/data/dataloader.py in __next__(self)
|
400
|
+
|
401
|
+
519 if self._sampler_iter is None:
|
402
|
+
|
403
|
+
520 self._reset()
|
404
|
+
|
405
|
+
--> 521 data = self._next_data()
|
406
|
+
|
407
|
+
522 self._num_yielded += 1
|
408
|
+
|
409
|
+
523 if self._dataset_kind == _DatasetKind.Iterable and \
|
410
|
+
|
411
|
+
|
412
|
+
|
413
|
+
/usr/local/lib/python3.7/dist-packages/torch/utils/data/dataloader.py in _next_data(self)
|
414
|
+
|
415
|
+
559 def _next_data(self):
|
416
|
+
|
417
|
+
560 index = self._next_index() # may raise StopIteration
|
418
|
+
|
419
|
+
--> 561 data = self._dataset_fetcher.fetch(index) # may raise StopIteration
|
420
|
+
|
421
|
+
562 if self._pin_memory:
|
422
|
+
|
423
|
+
563 data = _utils.pin_memory.pin_memory(data)
|
424
|
+
|
425
|
+
|
426
|
+
|
427
|
+
/usr/local/lib/python3.7/dist-packages/torch/utils/data/_utils/fetch.py in fetch(self, possibly_batched_index)
|
428
|
+
|
429
|
+
42 def fetch(self, possibly_batched_index):
|
430
|
+
|
431
|
+
43 if self.auto_collation:
|
432
|
+
|
433
|
+
---> 44 data = [self.dataset[idx] for idx in possibly_batched_index]
|
434
|
+
|
435
|
+
45 else:
|
436
|
+
|
437
|
+
46 data = self.dataset[possibly_batched_index]
|
438
|
+
|
439
|
+
|
440
|
+
|
441
|
+
/usr/local/lib/python3.7/dist-packages/torch/utils/data/_utils/fetch.py in <listcomp>(.0)
|
442
|
+
|
443
|
+
42 def fetch(self, possibly_batched_index):
|
444
|
+
|
445
|
+
43 if self.auto_collation:
|
446
|
+
|
447
|
+
---> 44 data = [self.dataset[idx] for idx in possibly_batched_index]
|
448
|
+
|
449
|
+
45 else:
|
450
|
+
|
451
|
+
46 data = self.dataset[possibly_batched_index]
|
452
|
+
|
453
|
+
|
454
|
+
|
455
|
+
/content/drive/MyDrive/Colab Notebooks/ObjectDetection/voc.py in __getitem__(self, index)
|
456
|
+
|
457
|
+
256 # pull_item()にイメージのインデックスを渡して前処理
|
458
|
+
|
459
|
+
257 # 処理後のイメージデータとBBoxとラベルの2次元配列を返す
|
460
|
+
|
461
|
+
--> 258 im, bl, _, _ = self.pull_item(index)
|
462
|
+
|
463
|
+
259 return im, bl
|
464
|
+
|
465
|
+
260
|
466
|
+
|
467
|
+
|
468
|
+
|
469
|
+
/content/drive/MyDrive/Colab Notebooks/ObjectDetection/voc.py in pull_item(self, index)
|
470
|
+
|
471
|
+
275 img_path = self.img_list[index] # インデックスを指定してイメージのパスを取得
|
472
|
+
|
473
|
+
276 img = cv2.imread(img_path) # OpenCV2でイメージの[高さ,幅,[B,G,R]]を取得
|
474
|
+
|
475
|
+
--> 277 height, width, _ = img.shape # 配列要素数を数えて高さ,幅のみを取得
|
476
|
+
|
477
|
+
278
|
478
|
+
|
479
|
+
279 # アノテーションデータのリストを取得
|
480
|
+
|
481
|
+
|
482
|
+
|
483
|
+
AttributeError: 'NoneType' object has no attribute 'shape'
|
484
|
+
|
485
|
+
```
|
486
|
+
|
323
487
|
#知りたいこと
|
324
488
|
|
325
489
|
このエラーはどういう意味か。
|