Skip to content

Commit e419394

Browse files
committed
Sync internal code changes of tflite/tfhub.
Mostly contributed by Yiqi Li ([email protected])
1 parent 890eadd commit e419394

19 files changed

+587
-228
lines changed

efficientdet/README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ You can run inference for a video and show the results online:
238238
// Run eval.
239239
!python main.py --mode=eval \
240240
--model_name=${MODEL} --model_dir=${CKPT_PATH} \
241-
--validation_file_pattern=tfrecord/val* \
241+
--val_file_pattern=tfrecord/val* \
242242
--val_json_file=annotations/instances_val2017.json
243243

244244
You can also run eval on test-dev set with the following command:
@@ -259,7 +259,7 @@ You can also run eval on test-dev set with the following command:
259259
# Also, test-dev has 20288 images rather than val 5000 images.
260260
!python main.py --mode=eval \
261261
--model_name=${MODEL} --model_dir=${CKPT_PATH} \
262-
--validation_file_pattern=tfrecord/testdev* \
262+
--val_file_pattern=tfrecord/testdev* \
263263
--testdev_dir='testdev_output' --eval_samples=20288
264264
# Now you can submit testdev_output/detections_test-dev2017_test_results.json to
265265
# coco server: https://competitions.codalab.org/competitions/20794#participate
@@ -288,8 +288,8 @@ Create a config file for the PASCAL VOC dataset called voc_config.yaml and put t
288288
Finetune needs to use --ckpt rather than --backbone_ckpt.
289289

290290
!python main.py --mode=train_and_eval \
291-
--training_file_pattern=tfrecord/pascal*.tfrecord \
292-
--validation_file_pattern=tfrecord/pascal*.tfrecord \
291+
--train_file_pattern=tfrecord/pascal*.tfrecord \
292+
--val_file_pattern=tfrecord/pascal*.tfrecord \
293293
--model_name=efficientdet-d0 \
294294
--model_dir=/tmp/efficientdet-d0-finetune \
295295
--ckpt=efficientdet-d0 \
@@ -326,8 +326,8 @@ Download efficientdet coco checkpoint.
326326
Finetune needs to use --ckpt rather than --backbone_ckpt.
327327

328328
python main.py --mode=train \
329-
--training_file_pattern=tfrecord/pascal*.tfrecord \
330-
--validation_file_pattern=tfrecord/pascal*.tfrecord \
329+
--train_file_pattern=tfrecord/pascal*.tfrecord \
330+
--val_file_pattern=tfrecord/pascal*.tfrecord \
331331
--model_name=efficientdet-d0 \
332332
--model_dir=/tmp/efficientdet-d0-finetune \
333333
--ckpt=efficientdet-d0 \
@@ -358,7 +358,7 @@ To train this model on Cloud TPU, you will need:
358358
Then train the model:
359359

360360
!export PYTHONPATH="$PYTHONPATH:/path/to/models"
361-
!python main.py --tpu=TPU_NAME --training_file_pattern=DATA_DIR/*.tfrecord --model_dir=MODEL_DIR --strategy=tpu
361+
!python main.py --tpu=TPU_NAME --train_file_pattern=DATA_DIR/*.tfrecord --model_dir=MODEL_DIR --strategy=tpu
362362

363363
# TPU_NAME is the name of the TPU node, the same name that appears when you run gcloud compute tpus list, or ctpu ls.
364364
# MODEL_DIR is a GCS location (a URL starting with gs:// where both the GCE VM and the associated Cloud TPU have write access.

efficientdet/dataloader_test.py

Lines changed: 4 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -13,63 +13,19 @@
1313
# limitations under the License.
1414
# ==============================================================================
1515
"""Data loader and processing test cases."""
16-
import os
17-
import tempfile
16+
1817
import tensorflow as tf
1918

2019
import dataloader
2120
import hparams_config
22-
from dataset import tfrecord_util
21+
from brain_automl.efficientdet import test_util
22+
2323
from keras import anchors
2424
from object_detection import tf_example_decoder
2525

2626

2727
class DataloaderTest(tf.test.TestCase):
2828

29-
def _make_fake_tfrecord(self):
30-
tfrecord_path = os.path.join(tempfile.mkdtemp(), 'test.tfrecords')
31-
writer = tf.io.TFRecordWriter(tfrecord_path)
32-
encoded_jpg = tf.io.encode_jpeg(tf.ones([512, 512, 3], dtype=tf.uint8))
33-
example = tf.train.Example(
34-
features=tf.train.Features(
35-
feature={
36-
'image/height':
37-
tfrecord_util.int64_feature(512),
38-
'image/width':
39-
tfrecord_util.int64_feature(512),
40-
'image/filename':
41-
tfrecord_util.bytes_feature('test_file_name.jpg'.encode(
42-
'utf8')),
43-
'image/source_id':
44-
tfrecord_util.bytes_feature('123456'.encode('utf8')),
45-
'image/key/sha256':
46-
tfrecord_util.bytes_feature('qwdqwfw12345'.encode('utf8')),
47-
'image/encoded':
48-
tfrecord_util.bytes_feature(encoded_jpg.numpy()),
49-
'image/format':
50-
tfrecord_util.bytes_feature('jpeg'.encode('utf8')),
51-
'image/object/bbox/xmin':
52-
tfrecord_util.float_list_feature([0.1]),
53-
'image/object/bbox/xmax':
54-
tfrecord_util.float_list_feature([0.1]),
55-
'image/object/bbox/ymin':
56-
tfrecord_util.float_list_feature([0.2]),
57-
'image/object/bbox/ymax':
58-
tfrecord_util.float_list_feature([0.2]),
59-
'image/object/class/text':
60-
tfrecord_util.bytes_list_feature(['test'.encode('utf8')]),
61-
'image/object/class/label':
62-
tfrecord_util.int64_list_feature([1]),
63-
'image/object/difficult':
64-
tfrecord_util.int64_list_feature([]),
65-
'image/object/truncated':
66-
tfrecord_util.int64_list_feature([]),
67-
'image/object/view':
68-
tfrecord_util.bytes_list_feature([]),
69-
}))
70-
writer.write(example.SerializeToString())
71-
return tfrecord_path
72-
7329
def test_parser(self):
7430
tf.random.set_seed(111111)
7531
params = hparams_config.get_detection_config('efficientdet-d0').as_dict()
@@ -81,7 +37,7 @@ def test_parser(self):
8137
anchor_labeler = anchors.AnchorLabeler(input_anchors, params['num_classes'])
8238
example_decoder = tf_example_decoder.TfExampleDecoder(
8339
regenerate_source_id=params['regenerate_source_id'])
84-
tfrecord_path = self._make_fake_tfrecord()
40+
tfrecord_path = test_util.make_fake_tfrecord(self.get_temp_dir())
8541
dataset = tf.data.TFRecordDataset([tfrecord_path])
8642
value = next(iter(dataset))
8743
reader = dataloader.InputReader(tfrecord_path, True)

efficientdet/dataset/create_pascal_tfrecord.py

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -33,19 +33,6 @@
3333

3434
from dataset import tfrecord_util
3535

36-
flags.DEFINE_string('data_dir', '', 'Root directory to raw PASCAL VOC dataset.')
37-
flags.DEFINE_string('set', 'train', 'Convert training set, validation set or '
38-
'merged set.')
39-
flags.DEFINE_string('annotations_dir', 'Annotations',
40-
'(Relative) path to annotations directory.')
41-
flags.DEFINE_string('year', 'VOC2007', 'Desired challenge year.')
42-
flags.DEFINE_string('output_path', '', 'Path to output TFRecord and json.')
43-
flags.DEFINE_string('label_map_json_path', None,
44-
'Path to label map json file with a dictionary.')
45-
flags.DEFINE_boolean('ignore_difficult_instances', False, 'Whether to ignore '
46-
'difficult instances')
47-
flags.DEFINE_integer('num_shards', 100, 'Number of shards for output file.')
48-
flags.DEFINE_integer('num_images', None, 'Max number of imags to process.')
4936
FLAGS = flags.FLAGS
5037

5138
SETS = ['train', 'val', 'trainval', 'test']
@@ -79,6 +66,24 @@
7966
GLOBAL_ANN_ID = 0 # global annotation id.
8067

8168

69+
def define_flags():
70+
"""Define the flags."""
71+
flags.DEFINE_string('data_dir', '',
72+
'Root directory to raw PASCAL VOC dataset.')
73+
flags.DEFINE_string('set', 'train', 'Convert training set, validation set or '
74+
'merged set.')
75+
flags.DEFINE_string('annotations_dir', 'Annotations',
76+
'(Relative) path to annotations directory.')
77+
flags.DEFINE_string('year', 'VOC2007', 'Desired challenge year.')
78+
flags.DEFINE_string('output_path', '', 'Path to output TFRecord and json.')
79+
flags.DEFINE_string('label_map_json_path', None,
80+
'Path to label map json file with a dictionary.')
81+
flags.DEFINE_boolean('ignore_difficult_instances', False, 'Whether to ignore '
82+
'difficult instances')
83+
flags.DEFINE_integer('num_shards', 100, 'Number of shards for output file.')
84+
flags.DEFINE_integer('num_images', None, 'Max number of imags to process.')
85+
86+
8287
def get_image_id(filename):
8388
"""Convert a string to a integer."""
8489
# Warning: this function is highly specific to pascal filename!!
@@ -101,10 +106,9 @@ def get_ann_id():
101106

102107

103108
def dict_to_tf_example(data,
104-
dataset_directory,
109+
images_dir,
105110
label_map_dict,
106111
ignore_difficult_instances=False,
107-
image_subdirectory='JPEGImages',
108112
ann_json_dict=None):
109113
"""Convert XML derived dict to tf.Example proto.
110114
@@ -114,12 +118,10 @@ def dict_to_tf_example(data,
114118
Args:
115119
data: dict holding PASCAL XML fields for a single image (obtained by running
116120
tfrecord_util.recursive_parse_xml_to_dict)
117-
dataset_directory: Path to root directory holding PASCAL dataset
121+
images_dir: Path to the directory holding raw images.
118122
label_map_dict: A map from string label names to integers ids.
119123
ignore_difficult_instances: Whether to skip difficult instances in the
120124
dataset (default: False).
121-
image_subdirectory: String specifying subdirectory within the PASCAL dataset
122-
directory holding the actual image data.
123125
ann_json_dict: annotation json dictionary.
124126
125127
Returns:
@@ -128,8 +130,7 @@ def dict_to_tf_example(data,
128130
Raises:
129131
ValueError: if the image pointed to by data['filename'] is not a valid JPEG
130132
"""
131-
img_path = os.path.join(data['folder'], image_subdirectory, data['filename'])
132-
full_path = os.path.join(dataset_directory, img_path)
133+
full_path = os.path.join(images_dir, data['filename'])
133134
with tf.io.gfile.GFile(full_path, 'rb') as fid:
134135
encoded_jpg = fid.read()
135136
encoded_jpg_io = io.BytesIO(encoded_jpg)
@@ -297,9 +298,10 @@ def main(_):
297298
xml = etree.fromstring(xml_str)
298299
data = tfrecord_util.recursive_parse_xml_to_dict(xml)['annotation']
299300

301+
img_dir = os.path.join(FLAGS.data_dir, data['folder'], 'JPEGImages')
300302
tf_example = dict_to_tf_example(
301303
data,
302-
FLAGS.data_dir,
304+
img_dir,
303305
label_map_dict,
304306
FLAGS.ignore_difficult_instances,
305307
ann_json_dict=ann_json_dict)
@@ -316,4 +318,5 @@ def main(_):
316318

317319

318320
if __name__ == '__main__':
321+
define_flags()
319322
app.run(main)

efficientdet/dataset/create_pascal_tfrecord_test.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,9 @@ def test_dict_to_tf_example(self):
7373
'notperson': 2,
7474
}
7575

76-
example = create_pascal_tfrecord.dict_to_tf_example(
77-
data, self.get_temp_dir(), label_map_dict, image_subdirectory='')
76+
example = create_pascal_tfrecord.dict_to_tf_example(data,
77+
self.get_temp_dir(),
78+
label_map_dict)
7879
self._assertProtoEqual(
7980
example.features.feature['image/height'].int64_list.value, [256])
8081
self._assertProtoEqual(

efficientdet/dataset/tfrecord_util.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ def recursive_parse_xml_to_dict(xml):
7272
Python dictionary holding XML contents.
7373
"""
7474
if not xml:
75-
return {xml.tag: xml.text}
75+
return {xml.tag: xml.text if xml.text else ''}
7676
result = {}
7777
for child in xml:
7878
child_result = recursive_parse_xml_to_dict(child)

efficientdet/hparams_config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ def default_detection_configs():
204204
h.max_level = 7
205205
h.num_scales = 3
206206
# ratio w/h: 2.0 means w=1.4, h=0.7. Can be computed with k-mean per dataset.
207-
h.aspect_ratios = [1.0, 2.0, 0.5] #[[0.7, 1.4], [1.0, 1.0], [1.4, 0.7]]
207+
h.aspect_ratios = [1.0, 2.0, 0.5] # [[0.7, 1.4], [1.0, 1.0], [1.4, 0.7]]
208208
h.anchor_scale = 4.0
209209
# is batchnorm training mode
210210
h.is_training_bn = True

efficientdet/keras/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ Create a config file for the PASCAL VOC dataset called voc_config.yaml and put t
245245
Finetune needs to use --pretrained_ckpt.
246246

247247
!python train.py
248-
--training_file_pattern=tfrecord/pascal*.tfrecord \
248+
--train_file_pattern=tfrecord/pascal*.tfrecord \
249249
--val_file_pattern=tfrecord/pascal*.tfrecord \
250250
--val_file_pattern=tfrecord/*.json \
251251
--model_name=efficientdet-d0 \
@@ -273,7 +273,7 @@ To train this model on Cloud TPU, you will need:
273273
Then train the model:
274274

275275
!export PYTHONPATH="$PYTHONPATH:/path/to/models"
276-
!python train.py --tpu=TPU_NAME --training_file_pattern=DATA_DIR/*.tfrecord --model_dir=MODEL_DIR --strategy=tpu
276+
!python train.py --tpu=TPU_NAME --train_file_pattern=DATA_DIR/*.tfrecord --model_dir=MODEL_DIR --strategy=tpu
277277

278278
# TPU_NAME is the name of the TPU node, the same name that appears when you run gcloud compute tpus list, or ctpu ls.
279279
# MODEL_DIR is a GCS location (a URL starting with gs:// where both the GCE VM and the associated Cloud TPU have write access.

0 commit comments

Comments
 (0)