Comments (10)
Note that this is a Python 3 implementation as clearly stated in the README. I've just trained an SSD7 on Pascal VOC for one epoch (using BatchGenerator
) and was not able to reproduce your error in Python 3.
The shape of the array that the batch generator passes to fit_generator()
indicates that you are producing empty batches. Beyond that, the information you provided is not enough to do meaningful error search.
- Are you using
BatchGenerator
? - Does your dataset contain images of varying size or constant size?
- If your dataset contains images of varying size, are you using any of the batch generator's cropping/padding/resizing options to make all images the same size? If not, then this is where your error comes from.
from ssd_keras.
I solved this problem by adding "convert_to_3_channels=True" in generator.
However, now while starting training I am getting this following error
Epoch 1/10
Exception in thread Thread-6:
Traceback (most recent call last):
File "C:\Users\Vinod\AppData\Local\conda\conda\envs\tensorflow-gpu\lib\threading.py", line 914, in _bootstrap_inner
self.run()
File "C:\Users\Vinod\AppData\Local\conda\conda\envs\tensorflow-gpu\lib\threading.py", line 862, in run
self._target(*self._args, **self._kwargs)
File "C:\Users\Vinod\AppData\Local\conda\conda\envs\tensorflow-gpu\lib\site-packages\keras\utils\data_utils.py", line 560, in data_generator_task
generator_output = next(self._generator)
File "C:\Users\Vinod\Downloads\OCR\ssd_keras\ssd_batch_generator.py", line 1211, in generate
batch_y_true = ssd_box_encoder.encode_y(batch_y, diagnostics=False) # Encode the labels into the `y_true` tensor that the SSD loss function needs.
File "C:\Users\Vinod\Downloads\OCR\ssd_keras\ssd_box_encode_decode_utils.py", line 920, in encode_y
for i in range(y_encode_template.shape[0]): # For each batch item...
AttributeError: 'tuple' object has no attribute 'shape'
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
<ipython-input-20-c11959bac2a8> in <module>()
21 cooldown=0)],
22 validation_data = val_generator,
---> 23 validation_steps = ceil(n_val_samples/batch_size))
24
25
~\AppData\Local\conda\conda\envs\tensorflow-gpu\lib\site-packages\keras\legacy\interfaces.py in wrapper(*args, **kwargs)
85 warnings.warn('Update your `' + object_name +
86 '` call to the Keras 2 API: ' + signature, stacklevel=2)
---> 87 return func(*args, **kwargs)
88 wrapper._original_function = func
89 return wrapper
~\AppData\Local\conda\conda\envs\tensorflow-gpu\lib\site-packages\keras\engine\training.py in fit_generator(self, generator, steps_per_epoch, epochs, verbose, callbacks, validation_data, validation_steps, class_weight, max_queue_size, workers, use_multiprocessing, initial_epoch)
1807 batch_index = 0
1808 while steps_done < steps_per_epoch:
-> 1809 generator_output = next(output_generator)
1810
1811 if not hasattr(generator_output, '__len__'):
StopIteration:
I am also using python3.
Are you using BatchGenerator?
-Yes
Does your dataset contain images of varying size or constant size?
-varying size
This is my training and validation generator.
train_generator = train_dataset.generate(batch_size=batch_size,
shuffle=True,
train=True,
ssd_box_encoder=ssd_box_encoder,
convert_to_3_channels=True,
equalize=False,
brightness=(0.5, 2, 0.5),
flip=0.5,
translate=False,
scale=False,
max_crop_and_resize=(img_height, img_width, 1, 3), # This one is important because the Pascal VOC images vary in size
random_pad_and_resize=(img_height, img_width, 1, 3, 0.5), # This one is important because the Pascal VOC images vary in size
random_crop=False,
crop=False,
resize=False,
gray=False,
limit_boxes=True, # While the anchor boxes are not being clipped, the ground truth boxes should be
include_thresh=0.4)
val_generator = valid_dataset.generate(batch_size=batch_size,
shuffle=True,
train=True,
ssd_box_encoder=ssd_box_encoder,
convert_to_3_channels=True,
equalize=False,
brightness=True,
flip=True,
translate=False,
scale=False,
max_crop_and_resize=(img_height, img_width, 1, 3), # This one is important because the Pascal VOC images vary in size
random_pad_and_resize=(img_height, img_width, 1, 3, 0.5), # This one is important because the Pascal VOC images vary in size
random_crop=False,
crop=False,
resize=False,
gray=False,
limit_boxes=True,
include_thresh=0.4)
from ssd_keras.
I solved this problem by adding "convert_to_3_channels=True" in generator.
It's strange that this option solved the original problem, because it is set to True
by default anyway, so it was always "on" unless you manually disabled it. Which of the following is true for your dataset:
- All single-channel (grayscale) images
- All 3-channel (color) images
- Mix of single-channel (grayscale) and 3-channel (color) images
I am also using python3.
Are you certain? Because your stack trace above says you're using Python 2.7 and your new error looks like an error that is caused by the wrong Python version. It claims that y_encode_template
in encode_y()
is a tuple, but it is a Numpy array.
from ssd_keras.
Yeah previously I didn't add "convert_to_3_channels=True" because in
SSD7 Training Tutorial.ipynb its not been used.
Sorry the first post was based on python 2.7 but now I am using python 3 the recent error is based on python 3.
from ssd_keras.
Can you execute this from within the notebook and let me know the output just to be sure:
import sys
print(sys.version)
print(sys.version_info)
I cannot reproduce your second error and it is an error that does not seem to depend on your specific dataset. One more thing that would be helpful: Can you add the following lines right below line 912 in ssd_box_encode_decode_utils
(i.e. in encode_y()
below the call to generate_encode_template()
and then restart the kernel in your notebook (very important) and run the training again:
print("y_encode_template:", y_encode_template)
print("type(y_encode_template):", type(y_encode_template))
print("type(y_encode_template[0]):", type(y_encode_template[0]))
Let me know what it prints.
from ssd_keras.
3.5.4 |Anaconda, Inc.| (default, Sep 30 2017, 11:07:29) [MSC v.1900 64 bit (AMD64)]
sys.version_info(major=3, minor=5, micro=4, releaselevel='final', serial=0)
The second set of print statements
y_encode_template: (array([[[ 0., 0., 0., ..., 1., 1., 1.],
[ 0., 0., 0., ..., 1., 1., 1.],
[ 0., 0., 0., ..., 1., 1., 1.],
...,
[ 0., 0., 0., ..., 1., 1., 1.],
[ 0., 0., 0., ..., 1., 1., 1.],
[ 0., 0., 0., ..., 1., 1., 1.]],
[[ 0., 0., 0., ..., 1., 1., 1.],
[ 0., 0., 0., ..., 1., 1., 1.],
[ 0., 0., 0., ..., 1., 1., 1.],
...,
[ 0., 0., 0., ..., 1., 1., 1.],
[ 0., 0., 0., ..., 1., 1., 1.],
[ 0., 0., 0., ..., 1., 1., 1.]],
[[ 0., 0., 0., ..., 1., 1., 1.],
[ 0., 0., 0., ..., 1., 1., 1.],
[ 0., 0., 0., ..., 1., 1., 1.],
...,
[ 0., 0., 0., ..., 1., 1., 1.],
[ 0., 0., 0., ..., 1., 1., 1.],
[ 0., 0., 0., ..., 1., 1., 1.]],
...,
[[ 0., 0., 0., ..., 1., 1., 1.],
[ 0., 0., 0., ..., 1., 1., 1.],
[ 0., 0., 0., ..., 1., 1., 1.],
...,
[ 0., 0., 0., ..., 1., 1., 1.],
[ 0., 0., 0., ..., 1., 1., 1.],
[ 0., 0., 0., ..., 1., 1., 1.]],
[[ 0., 0., 0., ..., 1., 1., 1.],
[ 0., 0., 0., ..., 1., 1., 1.],
[ 0., 0., 0., ..., 1., 1., 1.],
...,
[ 0., 0., 0., ..., 1., 1., 1.],
[ 0., 0., 0., ..., 1., 1., 1.],
[ 0., 0., 0., ..., 1., 1., 1.]],
[[ 0., 0., 0., ..., 1., 1., 1.],
[ 0., 0., 0., ..., 1., 1., 1.],
[ 0., 0., 0., ..., 1., 1., 1.],
...,
[ 0., 0., 0., ..., 1., 1., 1.],
[ 0., 0., 0., ..., 1., 1., 1.],
[ 0., 0., 0., ..., 1., 1., 1.]]]), [(array([ 4.16, 12.48, 20.8 , 29.12, 37.44, 45.76, 54.08,
62.4 , 70.72, 79.04, 87.36, 95.68, 104. , 112.32,
120.64, 128.96, 137.28, 145.6 , 153.92, 162.24, 170.56,
178.88, 187.2 , 195.52, 203.84, 212.16, 220.48, 228.8 ,
237.12, 245.44, 253.76, 262.08, 270.4 , 278.72, 287.04,
295.36, 303.68, 312. , 320.32, 328.64, 336.96, 345.28,
353.6 , 361.92, 370.24, 378.56, 386.88, 395.2 , 403.52,
411.84]), array([ 4.16, 12.48, 20.8 , 29.12, 37.44, 45.76, 54.08,
62.4 , 70.72, 79.04, 87.36, 95.68, 104. , 112.32,
120.64, 128.96, 137.28, 145.6 , 153.92, 162.24, 170.56,
178.88, 187.2 , 195.52, 203.84, 212.16, 220.48, 228.8 ,
237.12, 245.44, 253.76, 262.08, 270.4 , 278.72, 287.04,
295.36, 303.68, 312. , 320.32, 328.64, 336.96, 345.28,
353.6 , 361.92, 370.24, 378.56, 386.88, 395.2 , 403.52,
411.84])), (array([ 8.66666667, 26. , 43.33333333, 60.66666667,
78. , 95.33333333, 112.66666667, 130. ,
147.33333333, 164.66666667, 182. , 199.33333333,
216.66666667, 234. , 251.33333333, 268.66666667,
286. , 303.33333333, 320.66666667, 338. ,
355.33333333, 372.66666667, 390. , 407.33333333]), array([ 8.66666667, 26. , 43.33333333, 60.66666667,
78. , 95.33333333, 112.66666667, 130. ,
147.33333333, 164.66666667, 182. , 199.33333333,
216.66666667, 234. , 251.33333333, 268.66666667,
286. , 303.33333333, 320.66666667, 338. ,
355.33333333, 372.66666667, 390. , 407.33333333])), (array([ 18.90909091, 56.72727273, 94.54545455, 132.36363636,
170.18181818, 208. , 245.81818182, 283.63636364,
321.45454545, 359.27272727, 397.09090909]), array([ 18.90909091, 56.72727273, 94.54545455, 132.36363636,
170.18181818, 208. , 245.81818182, 283.63636364,
321.45454545, 359.27272727, 397.09090909])), (array([ 52., 156., 260., 364.]), array([ 52., 156., 260., 364.]))], [array([[ 29.4156421 , 58.83128419],
[ 41.6 , 41.6 ],
[ 72.05331359, 72.05331359],
[ 58.83128419, 29.4156421 ]]), array([[ 88.24692629, 176.49385258],
[ 124.8 , 124.8 ],
[ 161.1161072 , 161.1161072 ],
[ 176.49385258, 88.24692629]]), array([[ 147.07821049, 294.15642097],
[ 208. , 208. ],
[ 246.10891898, 246.10891898],
[ 294.15642097, 147.07821049]]), array([[ 205.90949468, 411.81898936],
[ 291.2 , 291.2 ],
[ 330.18976362, 330.18976362],
[ 411.81898936, 205.90949468]])], [(8.3200000000000003, 8.3200000000000003), (17.333333333333332, 17.333333333333332), (37.81818181818182, 37.81818181818182), (104.0, 104.0)], [(0.5, 0.5), (0.5, 0.5), (0.5, 0.5), (0.5, 0.5)])
type(y_encode_template): <class 'tuple'>
type(y_encode_template[0]): <class 'numpy.ndarray'>
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-20-7949424aa2ad> in <module>()
----> 1 print (next(train_generator))
~\Downloads\OCR\ssd_keras\ssd_batch_generator.py in generate(self, batch_size, shuffle, train, ssd_box_encoder, returns, convert_to_3_channels, equalize, brightness, flip, translate, scale, max_crop_and_resize, random_pad_and_resize, random_crop, crop, resize, gray, limit_boxes, include_thresh, subtract_mean, divide_by_stddev, swap_channels, keep_images_without_gt)
1209 batch_y_true, batch_matched_anchors = ssd_box_encoder.encode_y(batch_y, diagnostics=True) # Encode the labels into the `y_true` tensor that the SSD loss function needs.
1210 else:
-> 1211 batch_y_true = ssd_box_encoder.encode_y(batch_y, diagnostics=False) # Encode the labels into the `y_true` tensor that the SSD loss function needs.
1212
1213 # Compile the output.
~\Downloads\OCR\ssd_keras\ssd_box_encode_decode_utils.py in encode_y(self, ground_truth_labels, diagnostics)
921 class_vector = np.eye(self.n_classes) # An identity matrix that we'll use as one-hot class vectors
922
--> 923 for i in range(y_encode_template.shape[0]): # For each batch item...
924 available_boxes = np.ones((y_encode_template.shape[1])) # 1 for all anchor boxes that are not yet matched to a ground truth box, 0 otherwise
925 negative_boxes = np.ones((y_encode_template.shape[1])) # 1 for all negative boxes, 0 otherwise
AttributeError: 'tuple' object has no attribute 'shape'
And also note that I am training this model from scratch not using any pre-trained weights.
from ssd_keras.
The problem is that you set diagnostics = True
in line 911 of ssd_box_encode_decode_utils.py
, so you caused this error yourself. It must be diagnostics = False
.
from ssd_keras.
Correct.
Unfortunately, this also throws error in last batch of first epoch.
21/22 [===========================>..] - ETA: 2s - loss: 17.8976y_encode_template: [[[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]
...,
[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]]
[[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]
...,
[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]]
[[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]
...,
[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]]
...,
[[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]
...,
[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]]
[[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]
...,
[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]]
[[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]
...,
[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]]]
type(y_encode_template): <class 'numpy.ndarray'>
type(y_encode_template[0]): <class 'numpy.ndarray'>
Exception in thread Thread-7:
Traceback (most recent call last):
File "C:\Users\Vinod\AppData\Local\conda\conda\envs\tensorflow-gpu\lib\threading.py", line 914, in _bootstrap_inner
self.run()
File "C:\Users\Vinod\AppData\Local\conda\conda\envs\tensorflow-gpu\lib\threading.py", line 862, in run
self._target(*self._args, **self._kwargs)
File "C:\Users\Vinod\AppData\Local\conda\conda\envs\tensorflow-gpu\lib\site-packages\keras\utils\data_utils.py", line 560, in data_generator_task
generator_output = next(self._generator)
File "C:\Users\Vinod\Downloads\OCR\ssd_keras\ssd_batch_generator.py", line 880, in generate
if p >= (1-brightness[2]):
TypeError: 'bool' object is not subscriptable
y_encode_template: [[[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]
...,
[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]]
[[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]
...,
[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]]
[[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]
...,
[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]]
...,
[[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]
...,
[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]]
[[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]
...,
[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]]
[[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]
...,
[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]
[ 0. 0. 0. ..., 1. 1. 1.]]]
type(y_encode_template): <class 'numpy.ndarray'>
type(y_encode_template[0]): <class 'numpy.ndarray'>
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
<ipython-input-14-c11959bac2a8> in <module>()
21 cooldown=0)],
22 validation_data = val_generator,
---> 23 validation_steps = ceil(n_val_samples/batch_size))
24
25
~\AppData\Local\conda\conda\envs\tensorflow-gpu\lib\site-packages\keras\legacy\interfaces.py in wrapper(*args, **kwargs)
85 warnings.warn('Update your `' + object_name +
86 '` call to the Keras 2 API: ' + signature, stacklevel=2)
---> 87 return func(*args, **kwargs)
88 wrapper._original_function = func
89 return wrapper
~\AppData\Local\conda\conda\envs\tensorflow-gpu\lib\site-packages\keras\engine\training.py in fit_generator(self, generator, steps_per_epoch, epochs, verbose, callbacks, validation_data, validation_steps, class_weight, max_queue_size, workers, use_multiprocessing, initial_epoch)
1860 max_queue_size=max_queue_size,
1861 workers=workers,
-> 1862 use_multiprocessing=use_multiprocessing)
1863 else:
1864 # No need for try/except because
~\AppData\Local\conda\conda\envs\tensorflow-gpu\lib\site-packages\keras\legacy\interfaces.py in wrapper(*args, **kwargs)
85 warnings.warn('Update your `' + object_name +
86 '` call to the Keras 2 API: ' + signature, stacklevel=2)
---> 87 return func(*args, **kwargs)
88 wrapper._original_function = func
89 return wrapper
~\AppData\Local\conda\conda\envs\tensorflow-gpu\lib\site-packages\keras\engine\training.py in evaluate_generator(self, generator, steps, max_queue_size, workers, use_multiprocessing)
1953
1954 while steps_done < steps:
-> 1955 generator_output = next(output_generator)
1956 if not hasattr(generator_output, '__len__'):
1957 raise ValueError('Output of generator should be a tuple '
StopIteration:
from ssd_keras.
That's because you passed True
for the brightness
argument in valid_dataset.generate()
. This argument expects a 3-tuple, not a boolean.
from ssd_keras.
yes I was about to say that.
Now the training is working.
Thanks for the prompt support.
Cheers,
Vinod
from ssd_keras.
Related Issues (20)
- InvalidArgumentError when compiling model with ssd_loss HOT 1
- WARNING:tensorflow:Gradients do not exist for variables ['conv4_3/bias:0',...] when minimizing the loss. HOT 1
- "Invalid argument: Index out of range using input dim 0; input has only 0 dims" during ssd300 model training
- load weight
- ValueError: Error when checking input: expected input_3 to have 4 dimensions, but got array with shape
- While training I got training terminate error . Epoch 00001: LearningRateScheduler setting learning rate to 0.001. 1/10 [==>...........................] - ETA: 4:08 - loss: nanBatch 0: Invalid loss, terminating training Epoch 00001: saving model to ssd512_URPC2018_epoch-01.h5 Process finished with exit code 0
- ValueError: An operation has `None` for gradient. Please make sure that all of your ops have a gradient defined (i.e. are differentiable). Common ops without gradient: K.argmax, K.round, K.eval.
- ValueError: Layer model expects 1 input(s), but it received 2 input tensors. Inputs received: [<tf.Tensor 'IteratorGetNext:0' shape=(None, None, None, None) dtype=uint8>, <tf.Tensor 'IteratorGetNext:1' shape=(None, None, None) dtype=float32>] HOT 23
- Parameters of the model HOT 1
- Bouding boxes predictions are concentrated in left top corner HOT 1
- Ambiguous dimension while trying to load weights.
- Urgent!! Invalid Loss HOT 4
- What are the requirements to run this code?. HOT 1
- Pascal VOC Training Person Detection
- The device being used is CPU while capturing image from webcam. How do I use my GPU for processing instead?
- Label error during Coco Training HOT 1
- TypeError: Expected any non-tensor type, got a tensor instead.
- Changes make the code work in 2023 HOT 2
- custom SSD300 model
- error while training with custom dataset in COCO format
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ssd_keras.