3. dynamic input, static input
from tensorflow.keras.layers import Layer
import tensorflow as tf
from tensorflow.keras.datasets.mnist import load_data
import numpy as np
class Dense(Layer):
    def __init__(self, out_features, **kwargs):
        super().__init__(**kwargs)
        self.out_features = out_features
        self.w, self.b = None, None
    def build(self, input_shape):
        self.w = tf.Variable(tf.random.normal([input_shape[-1], self.out_features], stddev=0.1), name='w')
        self.b = tf.Variable(tf.zeros([self.out_features]), name='b')
    @tf.function
    def call(self, inputs, activation):
        return activation(tf.matmul(inputs, self.w) + self.b)
class DNN(tf.keras.Model):
    def __init__(self, name=None, **kwargs):
        super().__init__(**kwargs)
        self.dense_1 = Dense(256)
        self.dense_2 = Dense(256)
    def call(self, x):
        x = self.dense_1(x, activation=tf.nn.relu)
        return self.dense_2(x, activation=tf.nn.relu)
if __name__ == '__main__':
    (train_xs, train_ys), (test_xs, test_ys) = load_data()
    train_xs = train_xs.reshape(-1, 784)
    batch_ys = train_ys[:6]
    batch_xs = (train_xs[:6] / 255.).astype(np.float32)
    dense = Dense(256, name='dynamic')
    print(dense(batch_xs, tf.nn.relu))
    # DNN Model
    dnn = DNN('dynamic dnn')
    print(dnn(batch_xs))import tensorflow as tf
import numpy as np
from tensorflow.keras.layers import Layer
from tensorflow.keras.datasets.mnist import load_data
class Dense(Layer):
    def __init__(self, in_features, out_features, **kwargs):
        super().__init__(**kwargs)
        self.out_features = out_features
        self.in_features = in_features
        self.w = tf.Variable(tf.random.normal([self.in_features, self.out_features], stddev=0.1), name='w')
        self.b = tf.Variable(tf.zeros([self.out_features]), name='b')
    @tf.function
    def __call__(self, x, activation):
        return activation(tf.matmul(x, self.w) + self.b)
class DNN(tf.keras.Model):
    def __init__(self, name=None, **kwargs):
        super().__init__(**kwargs)
        self.dense_1 = Dense(in_features=784, out_features=256)
        self.dense_2 = Dense(in_features=256, out_features=2)
    def call(self, x):
        x = self.dense_1(x, activation=tf.nn.relu)
        return self.dense_2(x, activation=tf.nn.relu)
if __name__ == '__main__':
    (train_xs, train_ys), (test_xs, test_ys) = load_data()
    train_xs = train_xs.reshape(-1, 784)
    batch_ys = train_ys[:6]
    batch_xs = (train_xs[:6] / 255.).astype(np.float32)
    # Dense Layer
    dense = Dense(784, 256, name='static')
    print(dense(batch_xs, activation=tf.nn.relu))
    # DNN Model
    dnn = DNN('static dnn')
    print(dnn(batch_xs))
from tensorflow.keras.layers import Layer, Input
import tensorflow as tf
from tensorflow.keras.datasets.mnist import load_data
import numpy as np
class Dense(Layer):
    def __init__(self, out_features, **kwargs):
        super().__init__(**kwargs)
        self.out_features = out_features
        self.w, self.b = None, None
    def build(self, input_shape):
        self.w = tf.Variable(tf.random.normal([input_shape[-1], self.out_features], stddev=0.1), name='w')
        self.b = tf.Variable(tf.zeros([self.out_features]), name='b')
    @tf.function
    def call(self, inputs, activation):
        return activation(tf.matmul(inputs, self.w) + self.b)
class DNN1(tf.keras.Model):
    def __init__(self, name=None, **kwargs):
        super().__init__(**kwargs)
        self.dense_1 = Dense(256)
        self.dense_2 = Dense(256)
    def call(self, x):
        x = self.dense_1(x, activation=tf.nn.relu)
        return self.dense_2(x, activation=tf.nn.relu)
class DNN2(tf.keras.Model):
    def __init__(self, name=None, **kwargs):
        super().__init__(**kwargs)
        self.dense_1 = Dense(256)
        self.dense_2 = Dense(10)
    def call(self, x):
        x = self.dense_1(x, activation=tf.nn.relu)
        return self.dense_2(x, activation=tf.nn.relu)
if __name__ == '__main__':
    (train_xs, train_ys), (test_xs, test_ys) = load_data()
    train_xs = train_xs.reshape(-1, 784)
    batch_ys = train_ys[:6]
    batch_xs = (train_xs[:6] / 255.).astype(np.float32)
    dense = Dense(256, name='dynamic')
    # DNN Model
    input_ = Input(shape=(784,))
    dnn1 = DNN1('dynamic_dnn_1')
    dnn2 = DNN2('dynamic_dnn_2')
    z1 = dnn1(batch_xs)
    z2 = dnn2(z1)
    print(z2) 
 4. Model 이어 붙이기  
from tensorflow.keras.layers import Input, Conv2D, MaxPooling2D, GlobalMaxPooling2D, Reshape
from tensorflow.keras.layers import Conv2DTranspose, UpSampling2D
from tensorflow.keras.models import Model
encoder_input = Input(shape=(28, 28, 1), name="img")
x = Conv2D(16, 3, activation="relu")(encoder_input)
x = Conv2D(32, 3, activation="relu")(x)
x = MaxPooling2D(3)(x)
x = Conv2D(32, 3, activation="relu")(x)
x = Conv2D(16, 3, activation="relu")(x)
encoder_output = GlobalMaxPooling2D()(x)
encoder = Model(encoder_input, encoder_output, name="encoder")
encoder.summary()
x = Reshape((4, 4, 1))(encoder_output)
x = Conv2DTranspose(16, 3, activation="relu")(x)
x = Conv2DTranspose(32, 3, activation="relu")(x)
x = UpSampling2D(3)(x)
x = Conv2DTranspose(16, 3, activation="relu")(x)
decoder_output = Conv2DTranspose(1, 3, activation="relu")(x)
autoencoder = Model(encoder_input, decoder_output, name="autoencoder")
autoencoder.summary()
 
5. Custom Model 이어 붙이기 
from tensorflow.keras.layers import Layer, Input
import tensorflow as tf
from tensorflow.keras.datasets.mnist import load_data
import numpy as np
class Dense(Layer):
    def __init__(self, out_features, **kwargs):
        super().__init__(**kwargs)
        self.out_features = out_features
        self.w, self.b = None, None
    def build(self, input_shape):
        self.w = tf.Variable(tf.random.normal([input_shape[-1], self.out_features], stddev=0.1), name='w')
        self.b = tf.Variable(tf.zeros([self.out_features]), name='b')
    @tf.function
    def call(self, inputs, activation):
        return activation(tf.matmul(inputs, self.w) + self.b)
class DNN1(tf.keras.Model):
    def __init__(self, name=None, **kwargs):
        super().__init__(**kwargs)
        self.dense_1 = Dense(256)
        self.dense_2 = Dense(256)
    def call(self, x):
        x = self.dense_1(x, activation=tf.nn.relu)
        return self.dense_2(x, activation=tf.nn.relu)
class DNN2(tf.keras.Model):
    def __init__(self, name=None, **kwargs):
        super().__init__(**kwargs)
        self.dense_1 = Dense(256)
        self.dense_2 = Dense(10)
    def call(self, x):
        x = self.dense_1(x, activation=tf.nn.relu)
        return self.dense_2(x, activation=tf.nn.relu)
if __name__ == '__main__':
    (train_xs, train_ys), (test_xs, test_ys) = load_data()
    train_xs = train_xs.reshape(-1, 784)
    batch_ys = train_ys[:6]
    batch_xs = (train_xs[:6] / 255.).astype(np.float32)
    dense = Dense(256, name='dynamic')
    # DNN Model
    input_ = Input(shape=(784,))
    dnn1 = DNN1('dynamic_dnn_1')
    dnn2 = DNN2('dynamic_dnn_2')
    z1 = dnn1(batch_xs)
    z2 = dnn2(z1)
    print(z2)