Commit e43d75f3 authored by anivegesana's avatar anivegesana
Browse files

Lint YOLO backbone and building block code

parent 5122a448
......@@ -6,11 +6,13 @@ from official.modeling import hyperparams
from official.vision.beta.configs import backbones
@dataclasses.dataclass
class DarkNet(hyperparams.Config):
"""DarkNet config."""
model_id: str = "darknet53"
@dataclasses.dataclass
class Backbone(backbones.Backbone):
darknet: DarkNet = DarkNet()
......@@ -5,8 +5,10 @@ import collections
from official.vision.beta.modeling.backbones import factory
from official.vision.beta.projects.yolo.modeling import building_blocks as nn_blocks
# builder required classes
class BlockConfig(object):
def __init__(self, layer, stack, reps, bottleneck, filters, kernel_size,
strides, padding, activation, route, output_name, is_output):
'''
......@@ -34,40 +36,48 @@ class BlockConfig(object):
self.is_output = is_output
return
def build_block_specs(config):
specs = []
for layer in config:
specs.append(BlockConfig(*layer))
return specs
def darkconv_config_todict(config, kwargs):
dictvals = {
"filters" : config.filters,
"kernel_size" : config.kernel_size,
"strides" : config.strides,
"padding" : config.padding
"filters": config.filters,
"kernel_size": config.kernel_size,
"strides": config.strides,
"padding": config.padding
}
dictvals.update(kwargs)
return dictvals
def darktiny_config_todict(config, kwargs):
dictvals = {
"filters" : config.filters,
"strides" : config.strides}
dictvals = {"filters": config.filters, "strides": config.strides}
dictvals.update(kwargs)
return dictvals
def maxpool_config_todict(config, kwargs):
return {"pool_size": config.kernel_size,
return {
"pool_size": config.kernel_size,
"strides": config.strides,
"padding": config.padding,
"name": kwargs["name"]}
"name": kwargs["name"]
}
class layer_registry(object):
def __init__(self):
self._layer_dict = {"DarkTiny": (nn_blocks.DarkTiny, darktiny_config_todict),
self._layer_dict = {
"DarkTiny": (nn_blocks.DarkTiny, darktiny_config_todict),
"DarkConv": (nn_blocks.DarkConv, darkconv_config_todict),
"MaxPool": (tf.keras.layers.MaxPool2D, maxpool_config_todict)}
"MaxPool": (tf.keras.layers.MaxPool2D, maxpool_config_todict)
}
return
def _get_layer(self, key):
......@@ -78,8 +88,14 @@ class layer_registry(object):
param_dict = get_param_dict(config, kwargs)
return layer(**param_dict)
# model configs
LISTNAMES = ["default_layer_name", "level_type", "number_of_layers_in_level", "bottleneck", "filters", "kernal_size", "strides", "padding", "default_activation", "route", "level/name", "is_output"]
LISTNAMES = [
"default_layer_name", "level_type", "number_of_layers_in_level",
"bottleneck", "filters", "kernal_size", "strides", "padding",
"default_activation", "route", "level/name", "is_output"
]
CSPDARKNET53 = {
"list_names": LISTNAMES,
"splits": {"backbone_split": 106,
......@@ -134,25 +150,30 @@ DARKNETTINY = {
]
}
BACKBONES = {"darknettiny": DARKNETTINY,
BACKBONES = {
"darknettiny": DARKNETTINY,
"darknet53": DARKNET53,
"cspdarknet53": CSPDARKNET53,
"cspdarknettiny": CSPDARKNETTINY}
"cspdarknettiny": CSPDARKNETTINY
}
@ks.utils.register_keras_serializable(package='yolo')
class Darknet(ks.Model):
def __init__(self,
def __init__(
self,
model_id="darknet53",
input_shape=tf.keras.layers.InputSpec(shape = [None, None, None, 3]),
min_size = None,
max_size = 5,
activation = None,
use_sync_bn = False,
norm_momentum = 0.99,
norm_epsilon = 0.001,
kernel_initializer = 'glorot_uniform',
kernel_regularizer = None,
bias_regularizer = None,
input_shape=tf.keras.layers.InputSpec(shape=[None, None, None, 3]),
min_size=None,
max_size=5,
activation=None,
use_sync_bn=False,
norm_momentum=0.99,
norm_epsilon=0.001,
kernel_initializer='glorot_uniform',
kernel_regularizer=None,
bias_regularizer=None,
config=None,
**kwargs):
......@@ -175,14 +196,16 @@ class Darknet(ks.Model):
self._activation = activation
self._weight_decay = kernel_regularizer
self._default_dict = {"kernel_initializer": self._kernel_initializer,
self._default_dict = {
"kernel_initializer": self._kernel_initializer,
"weight_decay": self._weight_decay,
"bias_regularizer": self._bias_regularizer,
"norm_momentum": self._norm_momentum,
"norm_epsilon": self._norm_epislon,
"use_sync_bn": self._use_sync_bn,
"activation": self._activation,
"name": None}
"name": None
}
inputs = ks.layers.Input(shape=self._input_shape.shape[1:])
output = self._build_struct(layer_specs, inputs)
......@@ -225,7 +248,8 @@ class Darknet(ks.Model):
config,
name=f"{config.layer}_{i}")
stack_outputs.append(x_pass)
if (config.is_output and self._min_size == None):# or isinstance(config.output_name, str):
if (config.is_output and
self._min_size == None): # or isinstance(config.output_name, str):
endpoints[config.output_name] = x
elif self._min_size != None and config.output_name >= self._min_size and config.output_name <= self._max_size:
endpoints[config.output_name] = x
......@@ -250,13 +274,12 @@ class Darknet(ks.Model):
scale_filters = 2
self._default_dict["activation"] = self._get_activation(config.activation)
self._default_dict["name"] = f"{name}_csp_down"
x, x_route = nn_blocks.CSPDownSample(filters = config.filters,
filter_reduce = csp_filter_reduce,
x, x_route = nn_blocks.CSPDownSample(filters=config.filters,
filter_reduce=csp_filter_reduce,
**self._default_dict)(inputs)
for i in range(config.repetitions):
self._default_dict["name"] = f"{name}_{i}"
x = nn_blocks.DarkResidual(
filters=config.filters // scale_filters,
x = nn_blocks.DarkResidual(filters=config.filters // scale_filters,
filter_scale=residual_filter_reduce,
**self._default_dict)(x)
......@@ -280,14 +303,12 @@ class Darknet(ks.Model):
def _residual_stack(self, inputs, config, name):
self._default_dict["activation"] = self._get_activation(config.activation)
self._default_dict["name"] = f"{name}_residual_down"
x = nn_blocks.DarkResidual(
filters = config.filters,
downsample = True,
x = nn_blocks.DarkResidual(filters=config.filters,
downsample=True,
**self._default_dict)(inputs)
for i in range(config.repetitions - 1):
self._default_dict["name"] = f"{name}_{i}"
x = nn_blocks.DarkResidual(
filters = config.filters,
x = nn_blocks.DarkResidual(filters=config.filters,
**self._default_dict)(x)
self._default_dict["activation"] = self._activation
self._default_dict["name"] = None
......@@ -313,6 +334,7 @@ class Darknet(ks.Model):
splits = BACKBONES[name]["splits"]
return build_block_specs(backbone), splits
@factory.register_backbone_builder('darknet')
def build_darknet(
input_specs: tf.keras.layers.InputSpec,
......
......@@ -5,6 +5,7 @@ from ._DarkConv import DarkConv
@ks.utils.register_keras_serializable(package='yolo')
class CSPConnect(ks.layers.Layer):
def __init__(
self,
filters,
......
......@@ -5,6 +5,7 @@ from ._DarkConv import DarkConv
@ks.utils.register_keras_serializable(package='yolo')
class CSPDownSample(ks.layers.Layer):
def __init__(
self,
filters,
......
......@@ -3,23 +3,26 @@ import tensorflow as tf
import tensorflow.keras as ks
from ._DarkConv import DarkConv
@ks.utils.register_keras_serializable(package='yolo')
class CSPTiny(ks.layers.Layer):
def __init__(self,
def __init__(
self,
filters=1,
use_bias=True,
kernel_initializer = 'glorot_uniform',
bias_initializer = 'zeros',
bias_regularizer = None,
weight_decay= None, # default find where is it is stated
kernel_initializer='glorot_uniform',
bias_initializer='zeros',
bias_regularizer=None,
weight_decay=None, # default find where is it is stated
use_bn=True,
use_sync_bn=False,
group_id = 1,
groups = 2,
group_id=1,
groups=2,
norm_momentum=0.99,
norm_epsilon=0.001,
activation='leaky',
downsample = True,
downsample=True,
leaky_alpha=0.1,
**kwargs):
......@@ -31,7 +34,7 @@ class CSPTiny(ks.layers.Layer):
self._bias_regularizer = bias_regularizer
self._use_bn = use_bn
self._use_sync_bn = use_sync_bn
self._weight_decay=weight_decay
self._weight_decay = weight_decay
self._groups = groups
self._group_id = group_id
self._downsample = downsample
......@@ -55,7 +58,7 @@ class CSPTiny(ks.layers.Layer):
use_bias=self._use_bias,
kernel_initializer=self._kernel_initializer,
bias_initializer=self._bias_initializer,
bias_regularizer = self._bias_regularizer,
bias_regularizer=self._bias_regularizer,
weight_decay=self._weight_decay,
use_bn=self._use_bn,
use_sync_bn=self._use_sync_bn,
......@@ -64,15 +67,14 @@ class CSPTiny(ks.layers.Layer):
activation=self._conv_activation,
leaky_alpha=self._leaky_alpha)
self._convlayer2 = DarkConv(filters=self._filters//2,
self._convlayer2 = DarkConv(filters=self._filters // 2,
kernel_size=(3, 3),
strides=(1, 1),
padding='same',
use_bias=self._use_bias,
kernel_initializer=self._kernel_initializer,
bias_initializer=self._bias_initializer,
bias_regularizer = self._bias_regularizer,
bias_regularizer=self._bias_regularizer,
weight_decay=self._weight_decay,
use_bn=self._use_bn,
use_sync_bn=self._use_sync_bn,
......@@ -81,14 +83,14 @@ class CSPTiny(ks.layers.Layer):
activation=self._conv_activation,
leaky_alpha=self._leaky_alpha)
self._convlayer3 = DarkConv(filters=self._filters//2,
self._convlayer3 = DarkConv(filters=self._filters // 2,
kernel_size=(3, 3),
strides=(1, 1),
padding='same',
use_bias=self._use_bias,
kernel_initializer=self._kernel_initializer,
bias_initializer=self._bias_initializer,
bias_regularizer = self._bias_regularizer,
bias_regularizer=self._bias_regularizer,
weight_decay=self._weight_decay,
use_bn=self._use_bn,
use_sync_bn=self._use_sync_bn,
......@@ -104,7 +106,7 @@ class CSPTiny(ks.layers.Layer):
use_bias=self._use_bias,
kernel_initializer=self._kernel_initializer,
bias_initializer=self._bias_initializer,
bias_regularizer = self._bias_regularizer,
bias_regularizer=self._bias_regularizer,
weight_decay=self._weight_decay,
use_bn=self._use_bn,
use_sync_bn=self._use_sync_bn,
......@@ -123,12 +125,12 @@ class CSPTiny(ks.layers.Layer):
def call(self, inputs):
x1 = self._convlayer1(inputs)
x2 = tf.split(x1, self._groups, axis = -1)
x2 = tf.split(x1, self._groups, axis=-1)
x3 = self._convlayer2(x2[self._group_id])
x4 = self._convlayer3(x3)
x5 = tf.concat([x4, x3], axis = -1)
x5 = tf.concat([x4, x3], axis=-1)
x6 = self._convlayer4(x5)
x = tf.concat([x1, x6], axis = - 1)
x = tf.concat([x1, x6], axis=-1)
if self._downsample:
x = self._maxpool(x)
return x, x6
......
......@@ -11,6 +11,7 @@ from yolo.modeling.functions.mish_activation import mish
@ks.utils.register_keras_serializable(package='yolo')
class DarkConv(ks.layers.Layer):
def __init__(
self,
filters=1,
......@@ -122,8 +123,7 @@ class DarkConv(ks.layers.Layer):
epsilon=self._norm_epsilon,
axis=self._bn_axis)
else:
self.bn = ks.layers.BatchNormalization(
momentum=self._norm_moment,
self.bn = ks.layers.BatchNormalization(momentum=self._norm_moment,
epsilon=self._norm_epsilon,
axis=self._bn_axis)
else:
......@@ -135,8 +135,7 @@ class DarkConv(ks.layers.Layer):
elif self._activation == 'mish':
self._activation_fn = mish()
else:
self._activation_fn = ks.layers.Activation(
activation=self._activation)
self._activation_fn = ks.layers.Activation(activation=self._activation)
super(DarkConv, self).build(input_shape)
return
......
......@@ -7,14 +7,15 @@ from ._Identity import Identity
@ks.utils.register_keras_serializable(package='yolo')
class DarkResidual(ks.layers.Layer):
def __init__(self,
filters=1,
filter_scale=2,
use_bias=True,
kernel_initializer='glorot_uniform',
bias_initializer='zeros',
weight_decay= None,
bias_regularizer = None,
weight_decay=None,
bias_regularizer=None,
use_bn=True,
use_sync_bn=False,
norm_momentum=0.99,
......@@ -58,7 +59,7 @@ class DarkResidual(ks.layers.Layer):
self._bias_regularizer = bias_regularizer
self._use_bn = use_bn
self._use_sync_bn = use_sync_bn
self._weight_decay=weight_decay
self._weight_decay = weight_decay
# normal params
self._norm_moment = norm_momentum
......@@ -124,8 +125,7 @@ class DarkResidual(ks.layers.Layer):
leaky_alpha=self._leaky_alpha)
self._shortcut = ks.layers.Add()
self._activation_fn = ks.layers.Activation(
activation=self._sc_activation)
self._activation_fn = ks.layers.Activation(activation=self._sc_activation)
super().build(input_shape)
return
......
......@@ -6,14 +6,16 @@ from ._DarkConv import DarkConv
@ks.utils.register_keras_serializable(package='yolo')
class DarkTiny(ks.layers.Layer):
def __init__(self,
def __init__(
self,
filters=1,
use_bias=True,
strides=2,
kernel_initializer='glorot_uniform',
bias_initializer='zeros',
bias_regularizer = None,
weight_decay= None, # default find where is it is stated
bias_regularizer=None,
weight_decay=None, # default find where is it is stated
use_bn=True,
use_sync_bn=False,
norm_momentum=0.99,
......@@ -28,11 +30,11 @@ class DarkTiny(ks.layers.Layer):
self._use_bias = use_bias
self._kernel_initializer = kernel_initializer
self._bias_initializer = bias_initializer
self._bias_regularizer=bias_regularizer
self._bias_regularizer = bias_regularizer
self._use_bn = use_bn
self._use_sync_bn = use_sync_bn
self._strides = strides
self._weight_decay=weight_decay
self._weight_decay = weight_decay
# normal params
self._norm_moment = norm_momentum
......
......@@ -4,4 +4,3 @@ from ._DarkTiny import DarkTiny
from ._CSPConnect import CSPConnect
from ._CSPDownSample import CSPDownSample
from ._CSPTiny import CSPTiny
......@@ -8,6 +8,7 @@ from official.vision.beta.projects.yolo.modeling.building_blocks import CSPConne
class CSPConnect(tf.test.TestCase, parameterized.TestCase):
@parameterized.named_parameters(("same", 224, 224, 64, 1),
("downsample", 224, 224, 64, 2))
def test_pass_through(self, width, height, filters, mod):
......@@ -33,8 +34,8 @@ class CSPConnect(tf.test.TestCase, parameterized.TestCase):
path_layer = layer_companion(filters, filter_reduce=mod)
init = tf.random_normal_initializer()
x = tf.Variable(initial_value=init(shape=(1, width, height, filters),
dtype=tf.float32))
x = tf.Variable(
initial_value=init(shape=(1, width, height, filters), dtype=tf.float32))
y = tf.Variable(initial_value=init(shape=(1, int(np.ceil(width // 2)),
int(np.ceil(height // 2)),
filters),
......
......@@ -6,7 +6,9 @@ from absl.testing import parameterized
from official.vision.beta.projects.yolo.modeling.building_blocks import CSPDownSample as layer
from official.vision.beta.projects.yolo.modeling.building_blocks import CSPConnect as layer_companion
class CSPDownSample(tf.test.TestCase, parameterized.TestCase):
@parameterized.named_parameters(("same", 224, 224, 64, 1),
("downsample", 224, 224, 64, 2))
def test_pass_through(self, width, height, filters, mod):
......@@ -17,8 +19,7 @@ class CSPDownSample(tf.test.TestCase, parameterized.TestCase):
print(outx.shape.as_list())
self.assertAllEqual(
outx.shape.as_list(),
[None,
np.ceil(width // 2),
[None, np.ceil(width // 2),
np.ceil(height // 2), (filters / mod)])
return
......@@ -31,8 +32,8 @@ class CSPDownSample(tf.test.TestCase, parameterized.TestCase):
path_layer = layer_companion(filters, filter_reduce=mod)
init = tf.random_normal_initializer()
x = tf.Variable(initial_value=init(shape=(1, width, height, filters),
dtype=tf.float32))
x = tf.Variable(
initial_value=init(shape=(1, width, height, filters), dtype=tf.float32))
y = tf.Variable(initial_value=init(shape=(1, int(np.ceil(width // 2)),
int(np.ceil(height // 2)),
filters),
......
......@@ -5,11 +5,12 @@ from absl.testing import parameterized
from official.vision.beta.projects.yolo.modeling.building_blocks import DarkConv
class DarkConvTest(tf.test.TestCase, parameterized.TestCase):
@parameterized.named_parameters(("valid", (3, 3), "valid", (1, 1)),
("same", (3, 3), "same", (1, 1)),
("downsample", (3, 3), "same", (2, 2)),
("test", (1, 1), "valid", (1, 1)))
@parameterized.named_parameters(
("valid", (3, 3), "valid", (1, 1)), ("same", (3, 3), "same", (1, 1)),
("downsample", (3, 3), "same", (2, 2)), ("test", (1, 1), "valid", (1, 1)))
def test_pass_through(self, kernel_size, padding, strides):
if padding == "same":
pad_const = 1
......@@ -40,8 +41,8 @@ class DarkConvTest(tf.test.TestCase, parameterized.TestCase):
test_layer = DarkConv(filters, kernel_size=(3, 3), padding="same")
init = tf.random_normal_initializer()
x = tf.Variable(
initial_value=init(shape=(1, 224, 224, 3), dtype=tf.float32))
x = tf.Variable(initial_value=init(shape=(1, 224, 224,
3), dtype=tf.float32))
y = tf.Variable(
initial_value=init(shape=(1, 224, 224, filters), dtype=tf.float32))
......
......@@ -7,6 +7,7 @@ from official.vision.beta.projects.yolo.modeling.building_blocks import DarkResi
class DarkResidualTest(tf.test.TestCase, parameterized.TestCase):
@parameterized.named_parameters(("same", 224, 224, 64, False),
("downsample", 223, 223, 32, True),
("oddball", 223, 223, 32, False))
......@@ -39,8 +40,8 @@ class DarkResidualTest(tf.test.TestCase, parameterized.TestCase):
mod = 1
init = tf.random_normal_initializer()
x = tf.Variable(initial_value=init(shape=(1, width, height, filters),
dtype=tf.float32))
x = tf.Variable(
initial_value=init(shape=(1, width, height, filters), dtype=tf.float32))
y = tf.Variable(initial_value=init(shape=(1, int(np.ceil(width / mod)),
int(np.ceil(height / mod)),
filters),
......
......@@ -7,6 +7,7 @@ from official.vision.beta.projects.yolo.modeling.building_blocks import DarkTiny
class DarkTinyTest(tf.test.TestCase, parameterized.TestCase):
@parameterized.named_parameters(("middle", 224, 224, 64, 2),
("last", 224, 224, 1024, 1))
def test_pass_through(self, width, height, filters, strides):
......@@ -17,8 +18,7 @@ class DarkTinyTest(tf.test.TestCase, parameterized.TestCase):
print(outx.shape.as_list())
self.assertEqual(width % strides, 0, msg="width % strides != 0")
self.assertEqual(height % strides, 0, msg="height % strides != 0")
self.assertAllEqual(
outx.shape.as_list(),
self.assertAllEqual(outx.shape.as_list(),
[None, width // strides, height // strides, filters])
return
......@@ -30,8 +30,8 @@ class DarkTinyTest(tf.test.TestCase, parameterized.TestCase):
test_layer = DarkTiny(filters=filters, strides=strides)
init = tf.random_normal_initializer()
x = tf.Variable(initial_value=init(shape=(1, width, height, filters),
dtype=tf.float32))
x = tf.Variable(
initial_value=init(shape=(1, width, height, filters), dtype=tf.float32))
y = tf.Variable(initial_value=init(shape=(1, width // strides,
height // strides, filters),
dtype=tf.float32))
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment