SubClass 모델링 : SubClass 및 모델구현

2025. 4. 7. 20:21·Bootcamp_zerobase/Tensorflow

2025.04.03

 

Part.11 텐서플로

Chapter 04. Modeling

  • 05_subClass 모델링
  • 06_subClass 모델링 ResNet 구현

 

 

 

SubClass 모델링

 

모델이란 것은 Input을 Output으로 만들어주는 수식, 함수이다.

해당 기능을 수행하는 두 가지 클래스가 tf.keras.layers.Layer 와 tf.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

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

 

 

Linear Regression을 Layer로 만들기

class LinearRegression(tf.keras.layers.Layer):

    def __init__ (self, units) :
        super(LinearRegression, self).__init__()
        self.units = units

    def build(self, input_shape):
        self.w = self.add_weight(
            shape=(input_shape[-1], self.units),    #feature 개수, 마지막이 라벨인 형태 데이터셋
            initializer = 'random_normal',
            trainable = True
            )
        self.b = tf.Variable(0.0)

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

 

 

가상데이터 만들어서 학습진행 해보기

W_true = np.array([3., 2., 4., 1.]).reshape(4, 1)
B_true = np.array([1.])

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

y = np.matmul(X, W_true) + B_true + noise
opt = tf.keras.optimizers.SGD(learning_rate=0.03)

linear_layer = LinearRegression(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))

    grads = tape.gradient(loss, linear_layer.trainable_weights)
    opt.apply_gradients(zip(grads, linear_layer.trainable_weights))

    if epoch % 10 == 0:
        print("epoch : {}   |   loss : {}".format(epoch, loss))
        
================================================================================
epoch : 0   |   loss : 29.14101219177246
epoch : 10   |   loss : 9.565739631652832
epoch : 20   |   loss : 3.5630762577056885
epoch : 30   |   loss : 1.7035540342330933
epoch : 40   |   loss : 1.1216130256652832
epoch : 50   |   loss : 0.9376567006111145
epoch : 60   |   loss : 0.8789352774620056
epoch : 70   |   loss : 0.8600139617919922
epoch : 80   |   loss : 0.853861927986145
epoch : 90   |   loss : 0.8518450260162354

 

print("학습된 가중치: ", linear_layer.w.numpy())
print("학습된 편향: ", linear_layer.b.numpy())

===============================================
>>
학습된 가중치:  [[2.963016 ]
 [1.9774277]
 [3.9616776]
 [1.0476018]]
학습된 편향:  0.8913154

 

 

 

SubClass로 ResNet 구현

import tensorflow as tf

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

from tensorflow.keras.layers import Input, Dense, Conv2D, Flatten, Add, MaxPool2D
## Residual Block - Layer 구현

class ResidualBlock(tf.keras.layers.Layer): #tf.keras.layers.Layer 기능 상속

    def __init__(self, filters=32, filter_match=False):
        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.block1 = ResidualBlock(64, True) 
        # filter 개수 = 64, In/Out filter size 맞추기위한 True

        self.block2 = 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.block1(x)
        x = self.block2(x)
        x = self.maxp2(x)
        x = self.flat(x)
        
        return self.dense(x)

 

ResNet Layer를 구성하는데 있어서 이전보다 훨씬 더 코드가 간단해진 것을 알 수 있다.

 

 

학습

model = ResNet(10)

 

 

이전과 같이 cifar10 데이터를 불러와서 학습해본다.

일단 이전 시간에는 DataLoader() 클래스 및 함수생성을 통해 바로 데이터를 불러오고, 전처리 및 학습하기를 진행했는데, 우선 이번에는 CIFAR 10이라는 데이터는 무슨 데이터가 저장되어 있는지 확인하고 나머지 전처리 및 학습을 진행한다.

 

 

(X_train, y_train), (X_test, y_test) = tf.keras.datasets.cifar10.load_data()
X_train[1].shape
======================
>> (32, 32, 3)

cifar10_labels = {
    0: "airplane",
    1: "automobile",
    2: "bird",
    3: "cat",
    4: "deer",
    5: "dog",
    6: "frog",
    7: "horse",
    8: "ship",
    9: "truck"
}
plt.figure(figsize=(6, 7))
for i in range(9):
    plt.subplot(3, 3, i+1)
    plt.imshow(X_train[i])
    plt.title(f"Label : {cifar10_labels[int(y_train[i])]}")
    plt.axis('off')

plt.tight_layout()
plt.show()

 

 

 

위와 같이 사진데이터(컬러, 따라서 마지막 채널은 3)가 저장되어 있는 것을 알 수 있다.

이제 학습진행 한다.

 

 

## dataloader

class DataLoader():
    
    def __init__(self):
        (self.train_X, self.train_y), (self.test_X, self.test_y) = tf.keras.datasets.cifar10.load_data()

    def validation_pixel_scale(self, x):
        return 255 >= x.max() and 0 <= x.min()
    
    def scale(self, x):
        return (x/255.0).astype(np.float32)
    
    def preprocess_dataset(self, dataset):
        feature, target = dataset

        validation_x = np.array([x for x in feature if self.validation_pixel_scale(x)])
        validation_y = np.array([y for x, y in zip(feature, target) if self.validation_pixel_scale(x)])

        scaled_x = np.array([self.scale(x) for x in validation_x])
        one_hot_encoding_y = np.array([tf.keras.utils.to_categorical(y, num_classes=10) for y in validation_y])

        return scaled_x, np.squeeze(one_hot_encoding_y, axis=1)

    def get_train_dataset(self):
        return self.preprocess_dataset((self.train_X, self.train_y))
    
    def get_test_datasets(self):
        return self.preprocess_dataset((self.test_X, self.test_y))
lr = 0.003
opt = tf.keras.optimizers.Adam(lr)
loss = tf.keras.losses.categorical_crossentropy

model.compile(optimizer=opt, loss=loss, metrics=['accuracy'])
hist = model.fit(train_X, train_y, epochs=40, batch_size=128, validation_data=(test_X, test_y))

 

plt.figure(figsize=(14, 8))

plt.subplot(121)
plt.plot(hist.history['accuracy'], lw=3)
plt.title('accuracy')
plt.grid("True")

plt.subplot(122)
plt.plot(hist.history['val_accuracy'], lw=3)
plt.title('val_accuracy')
plt.grid("True")

plt.show()

 

 

 

서서히 0.9에 수렴하려고 하는 것이 확인된다.

'Bootcamp_zerobase > Tensorflow' 카테고리의 다른 글

Evaluation : Tensorboard 및 모델의 Save, Load  (0) 2025.04.16
Model 학습 : 텐서플로 모델학습 (fit( ) vs Training Logic)  (0) 2025.04.13
Functional Modeling : Functional API 및 간단한 ResNet 구현  (0) 2025.04.03
CNN (VGGNet) #1  (0) 2025.04.01
Tensorflow #3 : 딥러닝의 흐름, 간단한 Model 학습  (1) 2025.03.31
'Bootcamp_zerobase/Tensorflow' 카테고리의 다른 글
  • Evaluation : Tensorboard 및 모델의 Save, Load
  • Model 학습 : 텐서플로 모델학습 (fit( ) vs Training Logic)
  • Functional Modeling : Functional API 및 간단한 ResNet 구현
  • CNN (VGGNet) #1
Loft_mind
Loft_mind
건축 전공자의 전공 갈아타기
  • Loft_mind
    오늘의 설계
    Loft_mind
  • 공지사항

    • 분류 전체보기 (41) N
      • Bootcamp_zerobase (40) N
        • Pytorch (12)
        • Image Augmentation (2)
        • YOLO & RNN (4)
        • Git & GitHub (2)
        • Tensorflow (11)
        • OpenCV (9) N
      • Architecture (0)
  • 블로그 메뉴

    • 홈
    • 태그
  • 태그

    제로베이스
    역전파
    zerobase
    RE
    VGGNET
    mnist
    PIL
    tensorflow
    정규표현식
    autoencoders
    ResNet
    ComputerVision
    컴퓨터 비전
    opencv
    git
    zerobasel
    deeplearning
    rnn
    CNN
    컴퓨터비전
    bash
    image augmentation
    YOLO
    pytorch
    github
    subclass
  • hELLO· Designed By정상우.v4.10.3
Loft_mind
SubClass 모델링 : SubClass 및 모델구현
상단으로

티스토리툴바