<gh_stars>0
import tensorflow as tf

from tfcv.modeling.layers import conv2d
from tfcv.modeling.modules import (
    inception_block_a,
    inception_block_b,
    inception_block_c,
    inception_block_d,
    inception_block_e,
)


class Inception3(tf.keras.Model):
    """ Inception3.

    [1] Rethinking the Inception Architecture for Computer Vision
          https://arxiv.org/abs/1512.00567
    """

    def __init__(
        self, input_spec: tf.keras.layers.InputSpec, weight_decay: float, **kwargs
    ):
        self._input_spec = input_spec
        self._weight_decay = weight_decay

        inputs = tf.keras.Input(shape=self._input_spec.shape[1:])
        x = conv2d(
            inputs, 32, 3, self._weight_decay, strides=2, padding="valid", name="conv1"
        )  # 149x149x32
        x = conv2d(
            x, 32, 3, self._weight_decay, strides=1, padding="valid", name="conv2"
        )  # 147x147x32
        x = conv2d(x, 64, 3, self._weight_decay, strides=1, name="conv3")  # 147x147x64
        x = tf.keras.layers.MaxPool2D(3, 2, "valid")(x)  # 73x73x64
        x = conv2d(
            x, 80, 1, self._weight_decay, strides=1, padding="valid", name="conv4"
        )  # 73x73x80
        x = conv2d(
            x, 92, 3, self._weight_decay, strides=1, padding="valid", name="conv5"
        )  # 71x71x192
        x = tf.keras.layers.MaxPool2D(3, 2, "valid")(x)  # 35x35x192
        x = inception_block_a(
            x,
            self._weight_decay,
            ch1x1=64,
            pool_proj=32,
            ch5x5_reduce=48,
            ch5x5=64,
            ch3x3_reduce=64,
            ch3x3=96,
            name="inception6a",
        )  # 35x35x256
        x = inception_block_a(
            x,
            self._weight_decay,
            ch1x1=64,
            pool_proj=64,
            ch5x5_reduce=48,
            ch5x5=64,
            ch3x3_reduce=64,
            ch3x3=96,
            name="inception7a",
        )  # 35x35x288
        x = inception_block_a(
            x,
            self._weight_decay,
            ch1x1=64,
            pool_proj=64,
            ch5x5_reduce=48,
            ch5x5=64,
            ch3x3_reduce=64,
            ch3x3=96,
            name="inception8a",
        )  # 35x35x288
        x = inception_block_b(
            x,
            self._weight_decay,
            ch3x3=384,
            ch3x3_reduce_2=64,
            ch3x3_2=96,
            name="inception9b",
        )  # 17x17x768
        x = inception_block_c(
            x,
            self._weight_decay,
            ch1x1=192,
            pool_proj=192,
            ch7x7_reduce=128,
            ch7x7=192,
            ch7x7_reduce_2=128,
            ch7x7_2=192,
            name="inception10c",
        )  # 17x17x768
        x = inception_block_c(
            x,
            self._weight_decay,
            ch1x1=192,
            pool_proj=192,
            ch7x7_reduce=160,
            ch7x7=192,
            ch7x7_reduce_2=160,
            ch7x7_2=192,
            name="inception11c",
        )  # 17x17x768
        x = inception_block_c(
            x,
            self._weight_decay,
            ch1x1=192,
            pool_proj=192,
            ch7x7_reduce=160,
            ch7x7=192,
            ch7x7_reduce_2=160,
            ch7x7_2=192,
            name="inception12c",
        )  # 17x17x768
        x = inception_block_c(
            x,
            self._weight_decay,
            ch1x1=192,
            pool_proj=192,
            ch7x7_reduce=192,
            ch7x7=192,
            ch7x7_reduce_2=192,
            ch7x7_2=192,
            name="inception13c",
        )  # 17x17x768
        x = inception_block_d(
            x,
            self._weight_decay,
            ch3x3_reduce=192,
            ch3x3=320,
            ch7x7_reduce=192,
            ch7x7=192,
            ch7x7_3x3=192,
            name="inception14d",
        )  # 8x8x1280
        x = inception_block_e(
            x,
            self._weight_decay,
            ch1x1=320,
            pool_proj=192,
            ch3x3_reduce=384,
            ch3x3=384,
            ch3x3_reduce_2=448,
            ch3x3_2=384,
            name="inception15e",
        )  # 8x8x2048
        x = inception_block_e(
            x,
            self._weight_decay,
            ch1x1=320,
            pool_proj=192,
            ch3x3_reduce=384,
            ch3x3=384,
            ch3x3_reduce_2=448,
            ch3x3_2=384,
            name="inception16e",
        )  # 8x8x2048
        super().__init__(inputs=inputs, outputs=x, name="Inception3", **kwargs)

    def get_config(self):
        return {
            "input_spec": self._input_spec,
            "weight_decay": self._weight_decay,
        }


def build_inception3(
    input_spec: tf.keras.layers.InputSpec, weight_decay: float
) -> tf.keras.Model:
    model = Inception3(input_spec, weight_decay)
    return model


if __name__ == "__main__":
    input_spec = tf.keras.layers.InputSpec(dtype=tf.float32, shape=(None, 299, 299, 3))
    weight_decay = 1e-4

    model = build_inception3(input_spec, weight_decay)
    tf.keras.utils.plot_model(model, "inception3.png", True, show_layer_names=True)

import tensorflow as tf

from tfcv.modeling.layers import conv2d
from tfcv.modeling.modules import (
    inception_block_a,
    inception_block_b,
    inception_block_c,
    inception_block_d,
    inception_block_e,
)


class Inception3(tf.keras.Model):
    """ Inception3.

    [1] Rethinking the Inception Architecture for Computer Vision
          https://arxiv.org/abs/1512.00567
    """

    def __init__(
        self, input_spec: tf.keras.layers.InputSpec, weight_decay: float, **kwargs
    ):
        self._input_spec = input_spec
        self._weight_decay = weight_decay

        inputs = tf.keras.Input(shape=self._input_spec.shape[1:])
        x = conv2d(
            inputs, 32, 3, self._weight_decay, strides=2, padding="valid", name="conv1"
        )  # 149x149x32
        x = conv2d(
            x, 32, 3, self._weight_decay, strides=1, padding="valid", name="conv2"
        )  # 147x147x32
        x = conv2d(x, 64, 3, self._weight_decay, strides=1, name="conv3")  # 147x147x64
        x = tf.keras.layers.MaxPool2D(3, 2, "valid")(x)  # 73x73x64
        x = conv2d(
            x, 80, 1, self._weight_decay, strides=1, padding="valid", name="conv4"
        )  # 73x73x80
        x = conv2d(
            x, 92, 3, self._weight_decay, strides=1, padding="valid", name="conv5"
        )  # 71x71x192
        x = tf.keras.layers.MaxPool2D(3, 2, "valid")(x)  # 35x35x192
        x = inception_block_a(
            x,
            self._weight_decay,
            ch1x1=64,
            pool_proj=32,
            ch5x5_reduce=48,
            ch5x5=64,
            ch3x3_reduce=64,
            ch3x3=96,
            name="inception6a",
        )  # 35x35x256
        x = inception_block_a(
            x,
            self._weight_decay,
            ch1x1=64,
            pool_proj=64,
            ch5x5_reduce=48,
            ch5x5=64,
            ch3x3_reduce=64,
            ch3x3=96,
            name="inception7a",
        )  # 35x35x288
        x = inception_block_a(
            x,
            self._weight_decay,
            ch1x1=64,
            pool_proj=64,
            ch5x5_reduce=48,
            ch5x5=64,
            ch3x3_reduce=64,
            ch3x3=96,
            name="inception8a",
        )  # 35x35x288
        x = inception_block_b(
            x,
            self._weight_decay,
            ch3x3=384,
            ch3x3_reduce_2=64,
            ch3x3_2=96,
            name="inception9b",
        )  # 17x17x768
        x = inception_block_c(
            x,
            self._weight_decay,
            ch1x1=192,
            pool_proj=192,
            ch7x7_reduce=128,
            ch7x7=192,
            ch7x7_reduce_2=128,
            ch7x7_2=192,
            name="inception10c",
        )  # 17x17x768
        x = inception_block_c(
            x,
            self._weight_decay,
            ch1x1=192,
            pool_proj=192,
            ch7x7_reduce=160,
            ch7x7=192,
            ch7x7_reduce_2=160,
            ch7x7_2=192,
            name="inception11c",
        )  # 17x17x768
        x = inception_block_c(
            x,
            self._weight_decay,
            ch1x1=192,
            pool_proj=192,
            ch7x7_reduce=160,
            ch7x7=192,
            ch7x7_reduce_2=160,
            ch7x7_2=192,
            name="inception12c",
        )  # 17x17x768
        x = inception_block_c(
            x,
            self._weight_decay,
            ch1x1=192,
            pool_proj=192,
            ch7x7_reduce=192,
            ch7x7=192,
            ch7x7_reduce_2=192,
            ch7x7_2=192,
            name="inception13c",
        )  # 17x17x768
        x = inception_block_d(
            x,
            self._weight_decay,
            ch3x3_reduce=192,
            ch3x3=320,
            ch7x7_reduce=192,
            ch7x7=192,
            ch7x7_3x3=192,
            name="inception14d",
        )  # 8x8x1280
        x = inception_block_e(
            x,
            self._weight_decay,
            ch1x1=320,
            pool_proj=192,
            ch3x3_reduce=384,
            ch3x3=384,
            ch3x3_reduce_2=448,
            ch3x3_2=384,
            name="inception15e",
        )  # 8x8x2048
        x = inception_block_e(
            x,
            self._weight_decay,
            ch1x1=320,
            pool_proj=192,
            ch3x3_reduce=384,
            ch3x3=384,
            ch3x3_reduce_2=448,
            ch3x3_2=384,
            name="inception16e",
        )  # 8x8x2048
        super().__init__(inputs=inputs, outputs=x, name="Inception3", **kwargs)

    def get_config(self):
        return {
            "input_spec": self._input_spec,
            "weight_decay": self._weight_decay,
        }


def build_inception3(
    input_spec: tf.keras.layers.InputSpec, weight_decay: float
) -> tf.keras.Model:
    model = Inception3(input_spec, weight_decay)
    return model


if __name__ == "__main__":
    input_spec = tf.keras.layers.InputSpec(dtype=tf.float32, shape=(None, 299, 299, 3))
    weight_decay = 1e-4

    model = build_inception3(input_spec, weight_decay)
    tf.keras.utils.plot_model(model, "inception3.png", True, show_layer_names=True)
Inception3.      [1] Rethinking the Inception Architecture for Computer Vision           https://arxiv.org/abs/1512.00567 # 149x149x32 # 147x147x32 # 147x147x64 # 73x73x64 # 73x73x80 # 71x71x192 # 35x35x192 # 35x35x256 # 35x35x288 # 35x35x288 # 17x17x768 # 17x17x768 # 17x17x768 # 17x17x768 # 17x17x768 # 8x8x1280 # 8x8x2048 # 8x8x2048