From 2305a0ee23400de6a40fb5da78a5d33b06908397 Mon Sep 17 00:00:00 2001 From: Hunor Laczko Date: Wed, 25 Jan 2023 16:49:01 +0000 Subject: [PATCH] replace backbone with resnet18 --- auto_encoder_static.py | 2 +- configs/review/config_ae_static.py | 53 +++++++ models/base.py | 8 +- models/resnet.py | 243 +++++++++++++++++++++++++++++ 4 files changed, 303 insertions(+), 3 deletions(-) create mode 100644 configs/review/config_ae_static.py create mode 100644 models/resnet.py diff --git a/auto_encoder_static.py b/auto_encoder_static.py index 9de1574..f460a25 100644 --- a/auto_encoder_static.py +++ b/auto_encoder_static.py @@ -1,6 +1,6 @@ import os import sys -from configs.config_ae_static import config +from configs.review.config_ae_static import config os.environ["CUDA_VISIBLE_DEVICES"] = config['gpu'] import tensorflow as tf diff --git a/configs/review/config_ae_static.py b/configs/review/config_ae_static.py new file mode 100644 index 0000000..4d7c59c --- /dev/null +++ b/configs/review/config_ae_static.py @@ -0,0 +1,53 @@ +config = dict() + + +config['batch_size'] = 4 +config['train_dir'] = '/home/workspace/local-data/train' +config['valid_dir'] = '/home/workspace/local-data/valid' +config['test_dir'] = '/home/workspace/data/dataset/test_ready' +config['use_filled'] = False +config['resolution'] = 512 +config['is_skirt'] = False +config['dataset_in_memory'] = True +config['is_cape'] = False +config['remove_global_orientation'] = True + +config['smpl_res'] = 14475 +if config['is_cape']: + config['smpl_res'] = 3638 + +config['latent_dim'] = 128 + +config['cond_ae'] = dict() +config['cond_ae']['is_label'] = False +config['cond_ae']['upscale_output'] = False +config['cond_ae']['latent_dim'] = config['latent_dim'] +config['cond_ae']['kernel_size'] = 7 +config['cond_ae']['bottleneck_size'] = 8 +config['cond_ae']['encoder_depths'] = [3, 3, 3, 27, 3] +config['cond_ae']['encoder_dims'] = [8, 16, 32, 32, config['cond_ae']['bottleneck_size']] +config['cond_ae']['decoder_depths'] = config['cond_ae']['encoder_depths'] +config['cond_ae']['decoder_dims'] = config['cond_ae']['encoder_dims'] +config['cond_ae']['activation'] = 'linear' + + +config['gpu'] = '6' +config['lr'] = 0.0005 +config['name'] = 'static_r7' +config['notes'] = 'convnext + convnext, | \ + \ +| \ + deeper model | \ +linear activation| \ + ' + +config['cond_ae']['upscale_output'] = False +config['pretrained_model'] = '' + + +config['signature_dynamic'] = { 'id': (), 'frame_nr': (), } +config['signature_static'] = { 'uv_static': (512, 256, 3), + 'mesh_static': (config['smpl_res'], 3,), + 'mesh_mask': (config['smpl_res'],), + 'uv_mask': (512, 256,), + } \ No newline at end of file diff --git a/models/base.py b/models/base.py index e9cfd67..aceaa29 100644 --- a/models/base.py +++ b/models/base.py @@ -1,5 +1,7 @@ import tensorflow as tf from convnext.models.convnext_tf import ConvNeXt, ConvNeXtReverse, Block, ConvNeXtReverseLabels +from models.resnet import resnet_18 + class Bottleneck(tf.keras.Model): @@ -150,7 +152,8 @@ class AEEncoderNew(tf.keras.Model): def __init__(self, depths, dims, kernel_size=7, activation='tanh'): super(AEEncoderNew, self).__init__() - self.encoder = ConvNeXt(depths=depths, dims=dims, include_top=False, kernel_size=kernel_size) + # self.encoder = ConvNeXt(depths=depths, dims=dims, include_top=False, kernel_size=kernel_size) + self.encoder = resnet_18() self.act = tf.keras.layers.Activation(activation) @@ -177,7 +180,8 @@ class DecoderNew(tf.keras.Model): self.is_label = is_label if not is_label: - self.decoder = ConvNeXtReverse(depths=depths, dims=dims, kernel_size=kernel_size) + # self.decoder = ConvNeXtReverse(depths=depths, dims=dims, kernel_size=kernel_size) + self.decoder = resnet_18(reversed=True) else: self.decoder = ConvNeXtReverseLabels(depths=depths, dims=dims, nr_of_classes=7) diff --git a/models/resnet.py b/models/resnet.py new file mode 100644 index 0000000..277e64d --- /dev/null +++ b/models/resnet.py @@ -0,0 +1,243 @@ +# taken from https://github.com/calmisential/TensorFlow2.0_ResNet/blob/master/models/resnet.py + +import tensorflow as tf + + +class BasicBlock(tf.keras.layers.Layer): + + def __init__(self, filter_num, stride=1, upsample=False): + super(BasicBlock, self).__init__() + if not upsample: + self.conv1 = tf.keras.layers.Conv2D(filters=filter_num, + kernel_size=(3, 3), + strides=stride, + padding="same") + else: + self.conv1 = tf.keras.layers.Conv2DTranspose(filters=filter_num, + kernel_size=(3, 3), + strides=stride, + padding="same") + self.bn1 = tf.keras.layers.BatchNormalization() + self.conv2 = tf.keras.layers.Conv2D(filters=filter_num, + kernel_size=(3, 3), + strides=1, + padding="same") + self.bn2 = tf.keras.layers.BatchNormalization() + if stride != 1: + if not upsample: + self.updownsample = tf.keras.Sequential() + self.updownsample.add(tf.keras.layers.Conv2D(filters=filter_num, + kernel_size=(1, 1), + strides=stride)) + self.updownsample.add(tf.keras.layers.BatchNormalization()) + else: + self.updownsample = tf.keras.Sequential() + self.updownsample.add(tf.keras.layers.Conv2DTranspose(filters=filter_num, + kernel_size=(1, 1), + strides=stride)) + self.updownsample.add(tf.keras.layers.BatchNormalization()) + else: + self.updownsample = lambda x: x + + def call(self, inputs, training=None, **kwargs): + residual = self.updownsample(inputs) + + x = self.conv1(inputs) + x = self.bn1(x, training=training) + x = tf.nn.relu(x) + x = self.conv2(x) + x = self.bn2(x, training=training) + + output = tf.nn.relu(tf.keras.layers.add([residual, x])) + + return output + + +class BottleNeck(tf.keras.layers.Layer): + def __init__(self, filter_num, stride=1): + super(BottleNeck, self).__init__() + self.conv1 = tf.keras.layers.Conv2D(filters=filter_num, + kernel_size=(1, 1), + strides=1, + padding='same') + self.bn1 = tf.keras.layers.BatchNormalization() + self.conv2 = tf.keras.layers.Conv2D(filters=filter_num, + kernel_size=(3, 3), + strides=stride, + padding='same') + self.bn2 = tf.keras.layers.BatchNormalization() + self.conv3 = tf.keras.layers.Conv2D(filters=filter_num * 4, + kernel_size=(1, 1), + strides=1, + padding='same') + self.bn3 = tf.keras.layers.BatchNormalization() + + self.downsample = tf.keras.Sequential() + self.downsample.add(tf.keras.layers.Conv2D(filters=filter_num * 4, + kernel_size=(1, 1), + strides=stride)) + self.downsample.add(tf.keras.layers.BatchNormalization()) + + def call(self, inputs, training=None, **kwargs): + residual = self.downsample(inputs) + + x = self.conv1(inputs) + x = self.bn1(x, training=training) + x = tf.nn.relu(x) + x = self.conv2(x) + x = self.bn2(x, training=training) + x = tf.nn.relu(x) + x = self.conv3(x) + x = self.bn3(x, training=training) + + output = tf.nn.relu(tf.keras.layers.add([residual, x])) + + return output + + +def make_basic_block_layer(filter_num, blocks, stride=1, upsample=False): + res_block = tf.keras.Sequential() + res_block.add(BasicBlock(filter_num, stride=stride, upsample=upsample)) + + for _ in range(1, blocks): + res_block.add(BasicBlock(filter_num, stride=1)) + + return res_block + + +def make_bottleneck_layer(filter_num, blocks, stride=1): + res_block = tf.keras.Sequential() + res_block.add(BottleNeck(filter_num, stride=stride)) + + for _ in range(1, blocks): + res_block.add(BottleNeck(filter_num, stride=1)) + + return res_block + + +class ResNetTypeI(tf.keras.Model): + def __init__(self, layer_params, reversed=False): + super(ResNetTypeI, self).__init__() + self.reversed = reversed + + if not reversed: + self.conv1 = tf.keras.layers.Conv2D(filters=64, + kernel_size=(7, 7), + strides=2, + padding="same") + self.bn1 = tf.keras.layers.BatchNormalization() + self.pool1 = tf.keras.layers.MaxPool2D(pool_size=(3, 3), + strides=2, + padding="same") + else: + self.conv1 = tf.keras.layers.Conv2DTranspose(filters=3, + kernel_size=(7, 7), + strides=2, + padding="same") + self.bn1 = tf.keras.layers.BatchNormalization() + # self.pool1 = tf.keras.layers.MaxPool2D(pool_size=(3, 3), + # strides=2, + # padding="same") + self.pool1 = tf.keras.layers.UpSampling2D() + + self.layer1 = make_basic_block_layer(filter_num=64, + blocks=layer_params[0], + stride=1 if not reversed else 2, + upsample=reversed) + self.layer2 = make_basic_block_layer(filter_num=128, + blocks=layer_params[1], + stride=2, + upsample=reversed) + self.layer3 = make_basic_block_layer(filter_num=256, + blocks=layer_params[2], + stride=2, + upsample=reversed) + self.layer4 = make_basic_block_layer(filter_num=512, + blocks=layer_params[3], + stride=2 if not reversed else 1, + upsample=reversed) + + def call(self, inputs, training=None, mask=None): + if not self.reversed: + x = self.conv1(inputs) + x = self.bn1(x, training=training) + x = tf.nn.relu(x) + x = self.pool1(x) + x = self.layer1(x, training=training) + x = self.layer2(x, training=training) + x = self.layer3(x, training=training) + x = self.layer4(x, training=training) + else: + x = self.layer4(inputs, training=training) + x = self.layer3(x, training=training) + x = self.layer2(x, training=training) + x = self.layer1(x, training=training) + + x = self.pool1(x) + x = self.bn1(x, training=training) + x = tf.nn.relu(x) + x = self.conv1(x) + + return x + + +class ResNetTypeII(tf.keras.Model): + def __init__(self, layer_params): + super(ResNetTypeII, self).__init__() + self.conv1 = tf.keras.layers.Conv2D(filters=64, + kernel_size=(7, 7), + strides=2, + padding="same") + self.bn1 = tf.keras.layers.BatchNormalization() + self.pool1 = tf.keras.layers.MaxPool2D(pool_size=(3, 3), + strides=2, + padding="same") + + self.layer1 = make_bottleneck_layer(filter_num=64, + blocks=layer_params[0]) + self.layer2 = make_bottleneck_layer(filter_num=128, + blocks=layer_params[1], + stride=2) + self.layer3 = make_bottleneck_layer(filter_num=256, + blocks=layer_params[2], + stride=2) + self.layer4 = make_bottleneck_layer(filter_num=512, + blocks=layer_params[3], + stride=2) + + self.avgpool = tf.keras.layers.GlobalAveragePooling2D() + self.fc = tf.keras.layers.Dense(units=NUM_CLASSES, activation=tf.keras.activations.softmax) + + def call(self, inputs, training=None, mask=None): + x = self.conv1(inputs) + x = self.bn1(x, training=training) + x = tf.nn.relu(x) + x = self.pool1(x) + x = self.layer1(x, training=training) + x = self.layer2(x, training=training) + x = self.layer3(x, training=training) + x = self.layer4(x, training=training) + x = self.avgpool(x) + output = self.fc(x) + + return output + + +def resnet_18(reversed=False): + return ResNetTypeI(layer_params=[2, 2, 2, 2], reversed=reversed) + + +def resnet_34(): + return ResNetTypeI(layer_params=[3, 4, 6, 3]) + + +def resnet_50(): + return ResNetTypeII(layer_params=[3, 4, 6, 3]) + + +def resnet_101(): + return ResNetTypeII(layer_params=[3, 4, 23, 3]) + + +def resnet_152(): + return ResNetTypeII(layer_params=[3, 8, 36, 3]) \ No newline at end of file