@@ -41,27 +41,37 @@ def _padded_size(self):
41
41
return self ._input_image_size
42
42
43
43
def _build_model (self ):
44
-
45
44
nms_versions_supporting_dynamic_batch_size = {'batched' , 'v2' , 'v3' }
46
45
nms_version = self .params .task .model .detection_generator .nms_version
47
- if (self ._batch_size is None and
48
- nms_version not in nms_versions_supporting_dynamic_batch_size ):
49
- logging .info ('nms_version is set to `batched` because `%s` '
50
- 'does not support with dynamic batch size.' , nms_version )
46
+ if (
47
+ self ._batch_size is None
48
+ and nms_version not in nms_versions_supporting_dynamic_batch_size
49
+ ):
50
+ logging .info (
51
+ 'nms_version is set to `batched` because `%s` '
52
+ 'does not support with dynamic batch size.' ,
53
+ nms_version ,
54
+ )
51
55
self .params .task .model .detection_generator .nms_version = 'batched'
52
56
53
- input_specs = tf_keras .layers .InputSpec (shape = [
54
- self ._batch_size , * self ._padded_size , 3 ])
57
+ input_specs = tf_keras .layers .InputSpec (
58
+ shape = [self ._batch_size , * self ._padded_size , 3 ]
59
+ )
55
60
56
61
if isinstance (self .params .task .model , configs .maskrcnn .MaskRCNN ):
57
62
model = factory .build_maskrcnn (
58
- input_specs = input_specs , model_config = self .params .task .model )
63
+ input_specs = input_specs , model_config = self .params .task .model
64
+ )
59
65
elif isinstance (self .params .task .model , configs .retinanet .RetinaNet ):
60
66
model = factory .build_retinanet (
61
- input_specs = input_specs , model_config = self .params .task .model )
67
+ input_specs = input_specs , model_config = self .params .task .model
68
+ )
62
69
else :
63
- raise ValueError ('Detection module not implemented for {} model.' .format (
64
- type (self .params .task .model )))
70
+ raise ValueError (
71
+ 'Detection module not implemented for {} model.' .format (
72
+ type (self .params .task .model )
73
+ )
74
+ )
65
75
66
76
return model
67
77
@@ -73,7 +83,8 @@ def _build_anchor_boxes(self):
73
83
max_level = model_params .max_level ,
74
84
num_scales = model_params .anchor .num_scales ,
75
85
aspect_ratios = model_params .anchor .aspect_ratios ,
76
- anchor_size = model_params .anchor .anchor_size )
86
+ anchor_size = model_params .anchor .anchor_size ,
87
+ )
77
88
return input_anchor (image_size = self ._padded_size )
78
89
79
90
def _build_inputs (self , image ):
@@ -85,7 +96,8 @@ def _build_inputs(self, image):
85
96
86
97
# Normalizes image with mean and std pixel values.
87
98
image = preprocess_ops .normalize_image (
88
- image , offset = preprocess_ops .MEAN_RGB , scale = preprocess_ops .STDDEV_RGB )
99
+ image , offset = preprocess_ops .MEAN_RGB , scale = preprocess_ops .STDDEV_RGB
100
+ )
89
101
90
102
image , image_info = preprocess_ops .resize_and_crop_image (
91
103
image ,
@@ -131,20 +143,24 @@ def preprocess(
131
143
132
144
Args:
133
145
images: The images tensor.
146
+
134
147
Returns:
135
148
images: The images tensor cast to float.
136
149
anchor_boxes: Dict mapping anchor levels to anchor boxes.
137
150
image_info: Tensor containing the details of the image resizing.
138
-
139
151
"""
140
152
model_params = self .params .task .model
141
153
with tf .device ('cpu:0' ):
142
154
# Tensor Specs for map_fn outputs (images, anchor_boxes, and image_info).
143
- images_spec = tf .TensorSpec (shape = self ._padded_size + [3 ],
144
- dtype = tf .float32 )
155
+ images_spec = tf .TensorSpec (
156
+ shape = self ._padded_size + [3 ], dtype = tf .float32
157
+ )
145
158
146
- num_anchors = model_params .anchor .num_scales * len (
147
- model_params .anchor .aspect_ratios ) * 4
159
+ num_anchors = (
160
+ model_params .anchor .num_scales
161
+ * len (model_params .anchor .aspect_ratios )
162
+ * 4
163
+ )
148
164
anchor_shapes = []
149
165
for level in range (model_params .min_level , model_params .max_level + 1 ):
150
166
anchor_level_spec = tf .TensorSpec (
@@ -153,7 +169,8 @@ def preprocess(
153
169
math .ceil (self ._padded_size [1 ] / 2 ** level ),
154
170
num_anchors ,
155
171
],
156
- dtype = tf .float32 )
172
+ dtype = tf .float32 ,
173
+ )
157
174
anchor_shapes .append ((str (level ), anchor_level_spec ))
158
175
159
176
image_info_spec = tf .TensorSpec (shape = [4 , 2 ], dtype = tf .float32 )
@@ -163,9 +180,14 @@ def preprocess(
163
180
tf .map_fn (
164
181
self ._build_inputs ,
165
182
elems = images ,
166
- fn_output_signature = (images_spec , dict (anchor_shapes ),
167
- image_info_spec ),
168
- parallel_iterations = 32 ))
183
+ fn_output_signature = (
184
+ images_spec ,
185
+ dict (anchor_shapes ),
186
+ image_info_spec ,
187
+ ),
188
+ parallel_iterations = 32 ,
189
+ ),
190
+ )
169
191
170
192
return images , anchor_boxes , image_info
171
193
@@ -174,6 +196,7 @@ def serve(self, images: tf.Tensor):
174
196
175
197
Args:
176
198
images: uint8 Tensor of shape [batch_size, None, None, 3]
199
+
177
200
Returns:
178
201
Tensor holding detection output logits.
179
202
"""
@@ -190,10 +213,15 @@ def serve(self, images: tf.Tensor):
190
213
# [desired_height, desired_width], [y_scale, x_scale],
191
214
# [y_offset, x_offset]]. When input_type is tflite, input image is
192
215
# supposed to be preprocessed already.
193
- image_info = tf .convert_to_tensor ([[
194
- self ._input_image_size , self ._input_image_size , [1.0 , 1.0 ], [0 , 0 ]
195
- ]],
196
- dtype = tf .float32 )
216
+ image_info = tf .convert_to_tensor (
217
+ [[
218
+ self ._input_image_size ,
219
+ self ._input_image_size ,
220
+ [1.0 , 1.0 ],
221
+ [0 , 0 ],
222
+ ]],
223
+ dtype = tf .float32 ,
224
+ )
197
225
input_image_shape = image_info [:, 1 , :]
198
226
199
227
# To overcome keras.Model extra limitation to save a model with layers that
@@ -226,20 +254,23 @@ def serve(self, images: tf.Tensor):
226
254
# point outputs.
227
255
if export_config .cast_num_detections_to_float :
228
256
detections ['num_detections' ] = tf .cast (
229
- detections ['num_detections' ], dtype = tf .float32 )
257
+ detections ['num_detections' ], dtype = tf .float32
258
+ )
230
259
if export_config .cast_detection_classes_to_float :
231
260
detections ['detection_classes' ] = tf .cast (
232
- detections ['detection_classes' ], dtype = tf .float32 )
261
+ detections ['detection_classes' ], dtype = tf .float32
262
+ )
233
263
234
264
final_outputs = {
235
265
'detection_boxes' : detections ['detection_boxes' ],
236
266
'detection_scores' : detections ['detection_scores' ],
237
267
'detection_classes' : detections ['detection_classes' ],
238
- 'num_detections' : detections ['num_detections' ]
268
+ 'num_detections' : detections ['num_detections' ],
239
269
}
240
270
if 'detection_outer_boxes' in detections :
241
- final_outputs ['detection_outer_boxes' ] = (
242
- detections ['detection_outer_boxes' ])
271
+ final_outputs ['detection_outer_boxes' ] = detections [
272
+ 'detection_outer_boxes'
273
+ ]
243
274
else :
244
275
# For RetinaNet model, apply export_config.
245
276
if isinstance (self .params .task .model , configs .retinanet .RetinaNet ):
@@ -250,7 +281,7 @@ def serve(self, images: tf.Tensor):
250
281
detections = self ._normalize_coordinates (detections , keys , image_info )
251
282
final_outputs = {
252
283
'decoded_boxes' : detections ['decoded_boxes' ],
253
- 'decoded_box_scores' : detections ['decoded_box_scores' ]
284
+ 'decoded_box_scores' : detections ['decoded_box_scores' ],
254
285
}
255
286
256
287
if 'detection_masks' in detections .keys ():
0 commit comments