본문 바로가기
데이터 분석

CNN 기초(Tensorflow, Keras)

by JoinInNoetic 2024. 6. 30.

◆ CNN이란

● 합성곱인공신경망(신경망에 들어가는 데이터에 따라(전처리에 따라) CNN, RNN 등으로 갈림)

● 분류, 이미지, 영상, 수학적 알고리즘에서 많이 사용

● 절차는 데이터를 가공 후 신경망에 들어감

● 용어

    - 필터, 커널링 : 합곱셈필터, 이미지 픽셀을 줄이는 역할

                             2*2필터라고 하면 4*4를 3*3으로 만듬 -> 첫번째 픽셀부터 슬라이드하며 진행됨

    - 풀링 : 통계값(최대값, 평균값 등)으로 해당 부분만큼 계산하여 숫자를 뽑아냄, 이미지 픽셀 줄임

    - 패딩 : 필터하는데 이미지 사이즈가 안맞을 수 있는데 이때 테두리에 0으로 채움 - same패딩

● 구성 : 합성곱층, 풀링층, 밀집층(fully-connected, Dense layer)으로 구성됨

    - 합성곱층

        - kernel이라는 이름의 필터를 이용해 이미지를 첫 픽셀부터 슬라이드하며 필터값과 곱한 후 합하여 특성맵(feature map)을 형성

        - 이 층을 통해 이미지의 패턴을 구현할 수 있음 - 필터의 패턴과 유사하면 특성맵의 값이 높고 낮으면 값이 낮음

        - 층이 깊어질수록 복잡한 형태의 패턴을 처리

        - 파라미터

            - size : 필터(커널)의 크기가 작을 수록 특성맵이 커지고 디테일하게 처리 가능하지만 연산량이 많아지므로 적절한 크기를 찾아야함

            - stride(보폭) : 필터가 움직이는 칸(픽셀, 보폭)을 설정 -> 이에따라 특성맵의 크기가 달라짐 = 연산량에 차이가 있음

        - 특성화함수 : 대표적으로 ReLU

    - 풀링층

        - 합성곱층에서 추출된 특성맵의 크기를 줄이는 역할

        - 종류

            - Max Pooling layer

                - 주어진 풀링 윈도우 내의 값 중 최대값을 리턴

            - Average Pooling layer

                - 주어진 풀링 위도우 내의 값의 평균값 리턴

        - 계산 비용을 줄이면서 중요한 특징 보존

    - 밀집층

        - 추출된 feature들을 기반으로 최종 출력 생성

        - 모든 local feature를 1차원으로 만들어주는 flatten 층을 배치한 다음 fully-connected layer로 출력값을 보내 최종 아웃풋 계산

        - fully-connected layer

            - 맨 마지막에 위치

            - local feature는 지역적 특성이 강해 반드시 전체를 고려해야 함

 

◆ CNN model

● 임포트

import tensorflow as tf

tf.keras.utils.set_random_seed(42)

tf.config.experimental.enable_op_determinism()

from tensorflow import keras

from sklearn.model_selection import train_test_split

 

● 데이터 준비

(train_input, train_target), (test_input, test_target) = keras.datasets.fashion_mnist.load_data()

train_scaled = train_input.reshape(-1, 28, 28, 1) / 255.0    # 흑백이미지는 1차원, 컬러이미지는 3차원

train_scaled, val_scaled, train_target, val_target = train_test_split(train_scaled, train_target, test_size=0.2, random_state=42)

 

● 모델 생성

model = keras.Sequential()

model.add(keras.layers.Conv2D(32, kernel_size=3, activation='relu', padding='same', input_shape=(28,28,1)))

model.add(keras.layers.MaxPooling2D(2))

model.add(keras.layers.Conv2D(64, kernel_size=3, activation='relu', padding='same'))

model.add(keras.layers.MaxPooling2D(2))

model.add(keras.layers.Flatten())

model.add(keras.layers.Dense(100, activation='relu'))

model.add(keras.layers.Dropout(0.4))

model.add(keras.layers.Dense(10, activation='softmax'))

 

● 모델 컴파일, 훈련

model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics='accuracy')

checkpoint_cb = keras.callbacks.ModelCheckpoint('best_cnn_model.h5', save_best_only=True)

early_stopping_cb = keras.callbacks.EarlyStopping(patience=2, restore_best_weights=True)

history = model.fit(train_scaled, train_target, epochs=20, validation_data=(val_scaled, val_target), callbacks=[checkpoint_cb, early_stopping_cb])

 

● 모델 평가 및 예측

model.evaluate(val_scaled, val_target)

import matplotlib.pyplot as plt

plt.imshow(val_scaled[0].reshape(28,28), cmap='gray_r')

plt.show()

preds = model.predict(val_scaled[0:1])

 

● 데이터 시각화

plt.bar(range(1,11), preds[0])

plt.xlabel('class')

plt.ylabel('prob')

plt.show()

 

● 예측을 기반으로 분류

classes = ['티셔츠', '바지', '스웨터', '드레스', '코트', '샌달', '셔츠', '스니커즈', '가방', '앵클 부츠']

import numpy as np

print(calsses[np.argmax(preds)])

test_scaled = test_input.reshape(-1, 28, 28, 1) / 255.0

model.evaluate(test_scaled, test_target)