Sub Class 모델링

yeoni·2023년 6월 27일
0

Tensorflow

목록 보기
9/15
  • 모델 이란 것은 Input을 Output으로 만들어주는 수식이다.
  • 해당 기능을 수행하는 두 가지 클래스가 tf.keras.layers.Layertf.keras.layers.Model 클래스이다.
  • 두 가지 모두 연산을 추상화 하는 것으로 동일한 역할을 하지만, tf.keras.layers.Model 클래스의 경우 모델을 저장 하는 기능과 fit 함수를 사용할 수 있다는 점에서 차이가 있다.
import numpy as np
import pandas as pd
import tensorflow as tf

import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline

np.random.seed(7777)
tf.random.set_seed(7777)

Linear Regression을 Layer로 만들기

class LinearRegression(tf.keras.layers.Layer):
    def __init__(self, units): #units 몇 개 output
        super(LinearRegression, self).__init__() # 부모 상속
        self.units = units

    def build(self, input_shape): # input_shape w크기 결정
        self.w = self.add_weight( # Layer에 있는 add_weight함수
            shape=(input_shape[-1], self.units),
            initializer="random_normal",
            trainable=True,
        )
        self.b = tf.Variable(0.0) #def로 만드는 것을 추천

    def call(self, inputs): # w * x + b
        return tf.matmul(inputs, self.w) + self.b

가상 데이터를 sub class로 모델링

W_true = np.array([[3., 2., 4., 1.]]).reshape((4, 1)) #현재 만들고자 하는 rank 2라서 맞추기
B_true = np.array([1.])

X = tf.random.normal((500, 4)) #feature 4개
noise = tf.random.normal((500, 1))

y = X @ W_true + B_true + noise

opt = tf.keras.optimizers.SGD(learning_rate=3e-2) #0.03


linear_layer = LinearRegression(1) #units=1

for epoch in range(100):
    with tf.GradientTape() as tape:
        y_hat = linear_layer(X)
        loss = tf.reduce_mean(tf.square((y - y_hat))) #mse

    grads = tape.gradient(loss, linear_layer.trainable_weights)

    # w.assign_sub(lr*dw)을 아래 방식으로
    opt.apply_gradients(zip(grads, linear_layer.trainable_weights))

    if epoch % 10 == 0:
        print("epoch : {} loss : {}".format(epoch, loss.numpy()))

ResNet - Sub Class 로 구현 하기

1) Residual Block - Layer
2) ResNet - Model

from tensorflow.keras.layers import Input, Conv2D, MaxPool2D, Flatten, Dense, Add

class ResidualBlock(tf.keras.layers.Layer):
    def __init__(self, filters=32, filter_match=False): #net_1_1 역할
        super(ResidualBlock, self).__init__()

        self.conv1 = Conv2D(filters, kernel_size=1, padding='same', activation='relu')
        self.conv2 = Conv2D(filters, kernel_size=3, padding='same', activation='relu')
        self.conv3 = Conv2D(filters, kernel_size=1, padding='same', activation='relu')
        self.add = Add()

        self.filters = filters
        self.filter_match = filter_match
        if filter_match:
            self.conv_ext = Conv2D(filters, kernel_size=1, padding='same')

    def call(self, inputs):
        net1 = self.conv1(inputs)
        net2 = self.conv2(net1)
        net3 = self.conv3(net2)
        if self.filter_match:
            res = self.add([self.conv_ext(inputs), net3])
        else:
            res = self.add([inputs, net3])
        return res

class ResNet(tf.keras.Model):

    def __init__(self, num_classes):
        super(ResNet, self).__init__()

        self.conv1 = Conv2D(32, kernel_size=3, strides=2, padding='same', activation='relu')
        self.maxp1 =  MaxPool2D()
        self.block_1 = ResidualBlock(64, True)
        self.block_2 = ResidualBlock(64)
        self.maxp2 =  MaxPool2D()
        self.flat = Flatten()
        self.dense = Dense(num_classes)

    def call(self, inputs):
        x = self.conv1(inputs)
        x = self.maxp1(x)
        x = self.block_1(x)
        x = self.block_2(x)
        x = self.maxp2(x)
        x = self.flat(x)
        return self.dense(x)

model = ResNet(num_classes=10)

Reference
1) 제로베이스 데이터스쿨 강의자료

profile
데이터 사이언스 / just do it

0개의 댓글