質問編集履歴
1
コード、エラーメッセージ追記、コード、データセットの情報追記
test
CHANGED
File without changes
|
test
CHANGED
@@ -10,12 +10,24 @@
|
|
10
10
|
|
11
11
|
|
12
12
|
|
13
|
+
|
14
|
+
|
13
15
|
### 発生している問題・エラーメッセージ
|
14
16
|
|
15
17
|
|
16
18
|
|
17
19
|
```
|
18
20
|
|
21
|
+
AttributeError Traceback (most recent call last)
|
22
|
+
|
23
|
+
<ipython-input-42-ce81430fdd80> in <module>
|
24
|
+
|
25
|
+
1 model = SSD300(input_shape, num_classes=NUM_CLASSES)
|
26
|
+
|
27
|
+
----> 2 model.load_weights('weights_SSD300.hdf5', by_name=True)
|
28
|
+
|
29
|
+
|
30
|
+
|
19
31
|
AttributeError: 'NoneType' object has no attribute 'load_weights'
|
20
32
|
|
21
33
|
```
|
@@ -28,8 +40,6 @@
|
|
28
40
|
|
29
41
|
```python
|
30
42
|
|
31
|
-
#インポート部分
|
32
|
-
|
33
43
|
import cv2
|
34
44
|
|
35
45
|
from tensorflow import keras
|
@@ -64,12 +74,434 @@
|
|
64
74
|
|
65
75
|
|
66
76
|
|
77
|
+
%matplotlib inline
|
78
|
+
|
79
|
+
plt.rcParams['figure.figsize'] = (8, 8)
|
80
|
+
|
81
|
+
plt.rcParams['image.interpolation'] = 'nearest'
|
82
|
+
|
83
|
+
|
84
|
+
|
85
|
+
np.set_printoptions(suppress=True)
|
86
|
+
|
87
|
+
|
88
|
+
|
89
|
+
# config = tf.ConfigProto()
|
90
|
+
|
91
|
+
# config.gpu_options.per_process_gpu_memory_fraction = 0.9
|
92
|
+
|
93
|
+
# set_session(tf.Session(config=config))
|
94
|
+
|
95
|
+
|
96
|
+
|
97
|
+
from ssd import SSD300
|
98
|
+
|
99
|
+
from ssd_training import MultiboxLoss
|
100
|
+
|
101
|
+
from ssd_utils import BBoxUtility
|
102
|
+
|
103
|
+
|
104
|
+
|
105
|
+
# some constants
|
106
|
+
|
107
|
+
NUM_CLASSES = 21
|
108
|
+
|
109
|
+
input_shape = (300, 300, 3)
|
110
|
+
|
111
|
+
|
112
|
+
|
113
|
+
priors = pickle.load(open('prior_boxes_ssd300.pkl', 'rb'))
|
114
|
+
|
115
|
+
bbox_util = BBoxUtility(NUM_CLASSES, priors)
|
116
|
+
|
117
|
+
|
118
|
+
|
119
|
+
# Annotation
|
120
|
+
|
121
|
+
#gt = pickle.load(open('gt_pascal.pkl', 'rb'))
|
122
|
+
|
123
|
+
gt = pickle.load(open('PASCAL_VOC/VOC2012.pkl','rb'))
|
124
|
+
|
125
|
+
keys = sorted(gt.keys())
|
126
|
+
|
127
|
+
num_train = int(round(0.8 * len(keys)))
|
128
|
+
|
129
|
+
train_keys = keys[:num_train]
|
130
|
+
|
131
|
+
val_keys = keys[num_train:]
|
132
|
+
|
133
|
+
num_val = len(val_keys)
|
134
|
+
|
135
|
+
|
136
|
+
|
137
|
+
class Generator(object):
|
138
|
+
|
139
|
+
def __init__(self, gt, bbox_util,
|
140
|
+
|
141
|
+
batch_size, path_prefix,
|
142
|
+
|
143
|
+
train_keys, val_keys, image_size,
|
144
|
+
|
145
|
+
saturation_var=0.5,
|
146
|
+
|
147
|
+
brightness_var=0.5,
|
148
|
+
|
149
|
+
contrast_var=0.5,
|
150
|
+
|
151
|
+
lighting_std=0.5,
|
152
|
+
|
153
|
+
hflip_prob=0.5,
|
154
|
+
|
155
|
+
vflip_prob=0.5,
|
156
|
+
|
157
|
+
do_crop=True,
|
158
|
+
|
159
|
+
crop_area_range=[0.75, 1.0],
|
160
|
+
|
161
|
+
aspect_ratio_range=[3./4., 4./3.]):
|
162
|
+
|
163
|
+
self.gt = gt
|
164
|
+
|
165
|
+
self.bbox_util = bbox_util
|
166
|
+
|
167
|
+
self.batch_size = batch_size
|
168
|
+
|
169
|
+
self.path_prefix = path_prefix
|
170
|
+
|
171
|
+
self.train_keys = train_keys
|
172
|
+
|
173
|
+
self.val_keys = val_keys
|
174
|
+
|
175
|
+
self.train_batches = len(train_keys)
|
176
|
+
|
177
|
+
self.val_batches = len(val_keys)
|
178
|
+
|
179
|
+
self.image_size = image_size
|
180
|
+
|
181
|
+
self.color_jitter = []
|
182
|
+
|
183
|
+
if saturation_var:
|
184
|
+
|
185
|
+
self.saturation_var = saturation_var
|
186
|
+
|
187
|
+
self.color_jitter.append(self.saturation)
|
188
|
+
|
189
|
+
if brightness_var:
|
190
|
+
|
191
|
+
self.brightness_var = brightness_var
|
192
|
+
|
193
|
+
self.color_jitter.append(self.brightness)
|
194
|
+
|
195
|
+
if contrast_var:
|
196
|
+
|
197
|
+
self.contrast_var = contrast_var
|
198
|
+
|
199
|
+
self.color_jitter.append(self.contrast)
|
200
|
+
|
201
|
+
self.lighting_std = lighting_std
|
202
|
+
|
203
|
+
self.hflip_prob = hflip_prob
|
204
|
+
|
205
|
+
self.vflip_prob = vflip_prob
|
206
|
+
|
207
|
+
self.do_crop = do_crop
|
208
|
+
|
209
|
+
self.crop_area_range = crop_area_range
|
210
|
+
|
211
|
+
self.aspect_ratio_range = aspect_ratio_range
|
212
|
+
|
213
|
+
|
214
|
+
|
215
|
+
def grayscale(self, rgb):
|
216
|
+
|
217
|
+
return rgb.dot([0.299, 0.587, 0.114])
|
218
|
+
|
219
|
+
|
220
|
+
|
221
|
+
def saturation(self, rgb):
|
222
|
+
|
223
|
+
gs = self.grayscale(rgb)
|
224
|
+
|
225
|
+
alpha = 2 * np.random.random() * self.saturation_var
|
226
|
+
|
227
|
+
alpha += 1 - self.saturation_var
|
228
|
+
|
229
|
+
rgb = rgb * alpha + (1 - alpha) * gs[:, :, None]
|
230
|
+
|
231
|
+
return np.clip(rgb, 0, 255)
|
232
|
+
|
233
|
+
|
234
|
+
|
235
|
+
def brightness(self, rgb):
|
236
|
+
|
237
|
+
alpha = 2 * np.random.random() * self.brightness_var
|
238
|
+
|
239
|
+
alpha += 1 - self.saturation_var
|
240
|
+
|
241
|
+
rgb = rgb * alpha
|
242
|
+
|
243
|
+
return np.clip(rgb, 0, 255)
|
244
|
+
|
245
|
+
|
246
|
+
|
247
|
+
def contrast(self, rgb):
|
248
|
+
|
249
|
+
gs = self.grayscale(rgb).mean() * np.ones_like(rgb)
|
250
|
+
|
251
|
+
alpha = 2 * np.random.random() * self.contrast_var
|
252
|
+
|
253
|
+
alpha += 1 - self.contrast_var
|
254
|
+
|
255
|
+
rgb = rgb * alpha + (1 - alpha) * gs
|
256
|
+
|
257
|
+
return np.clip(rgb, 0, 255)
|
258
|
+
|
259
|
+
|
260
|
+
|
261
|
+
def lighting(self, img):
|
262
|
+
|
263
|
+
cov = np.cov(img.reshape(-1, 3) / 255.0, rowvar=False)
|
264
|
+
|
265
|
+
eigval, eigvec = np.linalg.eigh(cov)
|
266
|
+
|
267
|
+
noise = np.random.randn(3) * self.lighting_std
|
268
|
+
|
269
|
+
noise = eigvec.dot(eigval * noise) * 255
|
270
|
+
|
271
|
+
img += noise
|
272
|
+
|
273
|
+
return np.clip(img, 0, 255)
|
274
|
+
|
275
|
+
|
276
|
+
|
277
|
+
def horizontal_flip(self, img, y):
|
278
|
+
|
279
|
+
if np.random.random() < self.hflip_prob:
|
280
|
+
|
281
|
+
img = img[:, ::-1]
|
282
|
+
|
283
|
+
y[:, [0, 2]] = 1 - y[:, [2, 0]]
|
284
|
+
|
285
|
+
return img, y
|
286
|
+
|
287
|
+
|
288
|
+
|
289
|
+
def vertical_flip(self, img, y):
|
290
|
+
|
291
|
+
if np.random.random() < self.vflip_prob:
|
292
|
+
|
293
|
+
img = img[::-1]
|
294
|
+
|
295
|
+
y[:, [1, 3]] = 1 - y[:, [3, 1]]
|
296
|
+
|
297
|
+
return img, y
|
298
|
+
|
299
|
+
|
300
|
+
|
301
|
+
def random_sized_crop(self, img, targets):
|
302
|
+
|
303
|
+
img_w = img.shape[1]
|
304
|
+
|
305
|
+
img_h = img.shape[0]
|
306
|
+
|
307
|
+
img_area = img_w * img_h
|
308
|
+
|
309
|
+
random_scale = np.random.random()
|
310
|
+
|
311
|
+
random_scale *= (self.crop_area_range[1] -
|
312
|
+
|
313
|
+
self.crop_area_range[0])
|
314
|
+
|
315
|
+
random_scale += self.crop_area_range[0]
|
316
|
+
|
317
|
+
target_area = random_scale * img_area
|
318
|
+
|
319
|
+
random_ratio = np.random.random()
|
320
|
+
|
321
|
+
random_ratio *= (self.aspect_ratio_range[1] -
|
322
|
+
|
323
|
+
self.aspect_ratio_range[0])
|
324
|
+
|
325
|
+
random_ratio += self.aspect_ratio_range[0]
|
326
|
+
|
327
|
+
w = np.round(np.sqrt(target_area * random_ratio))
|
328
|
+
|
329
|
+
h = np.round(np.sqrt(target_area / random_ratio))
|
330
|
+
|
331
|
+
if np.random.random() < 0.5:
|
332
|
+
|
333
|
+
w, h = h, w
|
334
|
+
|
335
|
+
w = min(w, img_w)
|
336
|
+
|
337
|
+
w_rel = w / img_w
|
338
|
+
|
339
|
+
w = int(w)
|
340
|
+
|
341
|
+
h = min(h, img_h)
|
342
|
+
|
343
|
+
h_rel = h / img_h
|
344
|
+
|
345
|
+
h = int(h)
|
346
|
+
|
347
|
+
x = np.random.random() * (img_w - w)
|
348
|
+
|
349
|
+
x_rel = x / img_w
|
350
|
+
|
351
|
+
x = int(x)
|
352
|
+
|
353
|
+
y = np.random.random() * (img_h - h)
|
354
|
+
|
355
|
+
y_rel = y / img_h
|
356
|
+
|
357
|
+
y = int(y)
|
358
|
+
|
359
|
+
img = img[y:y+h, x:x+w]
|
360
|
+
|
361
|
+
new_targets = []
|
362
|
+
|
363
|
+
for box in targets:
|
364
|
+
|
365
|
+
cx = 0.5 * (box[0] + box[2])
|
366
|
+
|
367
|
+
cy = 0.5 * (box[1] + box[3])
|
368
|
+
|
369
|
+
if (x_rel < cx < x_rel + w_rel and
|
370
|
+
|
371
|
+
y_rel < cy < y_rel + h_rel):
|
372
|
+
|
373
|
+
xmin = (box[0] - x_rel) / w_rel
|
374
|
+
|
375
|
+
ymin = (box[1] - y_rel) / h_rel
|
376
|
+
|
377
|
+
xmax = (box[2] - x_rel) / w_rel
|
378
|
+
|
379
|
+
ymax = (box[3] - y_rel) / h_rel
|
380
|
+
|
381
|
+
xmin = max(0, xmin)
|
382
|
+
|
383
|
+
ymin = max(0, ymin)
|
384
|
+
|
385
|
+
xmax = min(1, xmax)
|
386
|
+
|
387
|
+
ymax = min(1, ymax)
|
388
|
+
|
389
|
+
box[:4] = [xmin, ymin, xmax, ymax]
|
390
|
+
|
391
|
+
new_targets.append(box)
|
392
|
+
|
393
|
+
new_targets = np.asarray(new_targets).reshape(-1, targets.shape[1])
|
394
|
+
|
395
|
+
return img, new_targets
|
396
|
+
|
397
|
+
|
398
|
+
|
399
|
+
def generate(self, train=True):
|
400
|
+
|
401
|
+
while True:
|
402
|
+
|
403
|
+
if train:
|
404
|
+
|
405
|
+
shuffle(self.train_keys)
|
406
|
+
|
407
|
+
keys = self.train_keys
|
408
|
+
|
409
|
+
else:
|
410
|
+
|
411
|
+
shuffle(self.val_keys)
|
412
|
+
|
413
|
+
keys = self.val_keys
|
414
|
+
|
415
|
+
inputs = []
|
416
|
+
|
417
|
+
targets = []
|
418
|
+
|
419
|
+
for key in keys:
|
420
|
+
|
421
|
+
img_path = self.path_prefix + key
|
422
|
+
|
423
|
+
img = imread(img_path).astype('float32')
|
424
|
+
|
425
|
+
y = self.gt[key].copy()
|
426
|
+
|
427
|
+
if train and self.do_crop:
|
428
|
+
|
429
|
+
img, y = self.random_sized_crop(img, y)
|
430
|
+
|
431
|
+
#img = imresize(img, self.image_size).astype('float32')
|
432
|
+
|
433
|
+
#img = np.array(Image.fromarray(arr).resize(self.image_size,img)).astype('float32')
|
434
|
+
|
435
|
+
img = np.array(Image.fromarray((img * 255).astype(np.uint8)).resize(self.image_size)).astype('float32')
|
436
|
+
|
437
|
+
if train:
|
438
|
+
|
439
|
+
shuffle(self.color_jitter)
|
440
|
+
|
441
|
+
for jitter in self.color_jitter:
|
442
|
+
|
443
|
+
img = jitter(img)
|
444
|
+
|
445
|
+
if self.lighting_std:
|
446
|
+
|
447
|
+
img = self.lighting(img)
|
448
|
+
|
449
|
+
if self.hflip_prob > 0:
|
450
|
+
|
451
|
+
img, y = self.horizontal_flip(img, y)
|
452
|
+
|
453
|
+
if self.vflip_prob > 0:
|
454
|
+
|
455
|
+
img, y = self.vertical_flip(img, y)
|
456
|
+
|
457
|
+
y = self.bbox_util.assign_boxes(y)
|
458
|
+
|
459
|
+
inputs.append(img)
|
460
|
+
|
461
|
+
targets.append(y)
|
462
|
+
|
463
|
+
if len(targets) == self.batch_size:
|
464
|
+
|
465
|
+
tmp_inp = np.array(inputs)
|
466
|
+
|
467
|
+
tmp_targets = np.array(targets)
|
468
|
+
|
469
|
+
inputs = []
|
470
|
+
|
471
|
+
targets = []
|
472
|
+
|
473
|
+
yield preprocess_input(tmp_inp), tmp_targets
|
474
|
+
|
475
|
+
|
476
|
+
|
477
|
+
#画像パス
|
478
|
+
|
479
|
+
path_prefix = 'VOCdevkit/VOC2012/JPEGImages/'
|
480
|
+
|
481
|
+
gen = Generator(gt, bbox_util, 4, path_prefix,
|
482
|
+
|
483
|
+
train_keys, val_keys,
|
484
|
+
|
485
|
+
(input_shape[0], input_shape[1]), do_crop=False)
|
486
|
+
|
487
|
+
|
488
|
+
|
489
|
+
model = SSD300(input_shape, num_classes=NUM_CLASSES)
|
490
|
+
|
491
|
+
model.load_weights('weights_SSD300.hdf5', by_name=True)
|
492
|
+
|
493
|
+
|
494
|
+
|
67
495
|
#エラー発生部分
|
68
496
|
|
69
497
|
model = SSD300(input_shape, num_classes=NUM_CLASSES)
|
70
498
|
|
71
499
|
model.load_weights('weights_SSD300.hdf5', by_name=True)
|
72
500
|
|
501
|
+
|
502
|
+
|
503
|
+
|
504
|
+
|
73
505
|
```
|
74
506
|
|
75
507
|
|
@@ -99,3 +531,21 @@
|
|
99
531
|
初めての質問投稿になります。
|
100
532
|
|
101
533
|
不足している点、記載すべき点等あればご教授いただけると幸いです。
|
534
|
+
|
535
|
+
|
536
|
+
|
537
|
+
**追記**
|
538
|
+
|
539
|
+
コード(文字数制限によりエラー部分以降除く)追記
|
540
|
+
|
541
|
+
エラーメッセージ全文追記
|
542
|
+
|
543
|
+
コードに関しては以下を参考にダウンロード等を行いました。
|
544
|
+
|
545
|
+
https://qiita.com/slowsingle/items/64cc927bb29a49a7af14
|
546
|
+
|
547
|
+
また、KerasがTensorflow v2より同梱さえたことによるコード書き換えは以下を参考にしました。
|
548
|
+
|
549
|
+
https://techblog.cccmk.co.jp/entry/2020/05/11/094834
|
550
|
+
|
551
|
+
データセットはVOC2012を用いています。
|