본문 바로가기
딥러닝/혼공머신

[혼공머신] chapter 8. 이미지를 위한 인공 신경망

by 다이노소어 2023. 3. 13.
혼자 공부하는 머신러닝 + 딥러닝의 Chapter 8을 공부하면서 정리한 내용을 기반으로 작성하였다.

 

 

08-1. 합성곱 신경망


합성곱

유용한 특성만 드러나게 함

→ 2차원 구조를 그대로 사용하기 때문에, CNN을 이미지 처리에 뛰어난 성능을 보인다.

모델 훈련

  • 처음에 가중치와 절편을 랜덤하게 초기화한다.
  • 에포크를 반복하면서 경사 하강법 알고리즘을 사용하여 손실이 낮아지도록 최적의 가중치와 절편을 찾아간다.

특성 맵(feature map)

  • 합성곱 계산을 통해 얻은 출력으로, 활성화 함수를 통과한 값을 나타낸다.
  • 특성 맵의 값은 실수이다.

뉴런(neuron)  = 필터(filter) = 커널(kernel)

  • 합성곱 신경망에서는 뉴런을 필터, 커널이라고 부른다.
  • 합성곱의 필수 하이퍼 파라미터
    • Conv2D의 첫 번째 매개변수 : 필터의 가중치(커널)의 개수
    • Conv2D의 매개변수 kernel_size : 커널의 크기 (tuple로 전달)
  • 입력보다 훨씬 작은 크기의 커널을 사용한다.

패딩(padding)

: 입력 배열의 주위를 가상원소 0으로 채우는 것을 말한다.

  • Conv2D의 매개변수 padding에 'same'이나 'valid'를 지정해서 패딩을 줄지 말지 결정할 수 있다.
  • 세임 패딩(same padding) :입력과 특성 맵의 크기를 동일하게 만들기 위해 입력 주위에 0으로 패딩하는 것
  • 밸리드 패딩(valid padding)
    • 패딩없이 순수한 입력에만 합성곱을 하여 특성 맵을 만드는 것
    • 입력을 이미지라고 본다면 모서리 값보다 가운데 값이 더 많이 합성곱에 참여하기 때문에, 가운데 정보가 보다 두드러지게 표현된다.

스트라이드(stride)

  • 합성곱 연산의 이동 크기를 지정할 수 있다
  • Con2D의 매개변수 strides에 지정할 수 있다. (default : 1)
from tensorflow import keras
keras.layers.Conv2D(10, kernel_size=(3,3), activation='relu', padding= 'same', strides= 1)

 

풀링(pooling)

  • 합성곱 층에서 만든 특성 맵의 가로세로 크기를 줄이는 역할
  • 특성 맵의 개수는 줄이지 않아, 너비와 높이만 줄이는 것이다. (2,2,3)의 특성맵에 풀링이 적용되면 (1,1,3)의 특성맵이 되는 식이다. 즉, 3개의 특성맵에 풀링이 적용되어도 여전히 3개의 특성맵이다.
  • 풀링에는 가중치가 없다.
  • 보통 겹처서 이동하는 합성곱과 달리, 풀링은 풀링의 크기가 스트라이드(stride)는 같기 때문에, 겹쳐서 이동하지 않는다.
  • WHY(풀링을 사용하는 이유)
    • 합성곱에서 스트라이드를 크게 하여 특성맵을 줄이는 것보다 풀링층에서 크기를 줄이는 게 성능이 더 좋다.
  • 종류
    • 최대 풀링(max pooling)
    • 평균 풀링(mean pooling)
keras.layers.MaxPooling2D(2, strides= 2, padding= 'valid') #최대 풀링
keras.layers.AveragePooling2D(2, strides= 2, padding='valid') #평균 풀링

 

합성곱 신경망(convolutional neural network;CNN)

  • 합성곱 층과 풀링층은 세트이다!
  • 너비와 높이는 점점 줄어들고, 깊이는 점점 깊어진다.
  • 층이 깊어질수록 다양하고 구체적인 특징을 감지할 수 있도록 필터의 개수를 늘린다.
  • 2차원 이미지를 그대로 사용하기 때문에, Flatten을 사용해서 일렬로 펼칠 필요가 없다.

 

 

 

08-2. 합성곱 신경망을 사용한 이미지 분류


→ 이전 절에서 합성곱 신경망을 개념적으로 이해해보고자 했다면 이번 절에서는 코드 구현에 초점이 맞춰져 있다.

 

1. 데이터셋 불러오기

  • Conv2D(합성곱 연산층)을 사용하려면, 입력이미지의 깊이(채널)차원이 있어야 한다. - (1)
    • 그렇기에, 2차원 배열(ex. 흑백이미지)의 경우 reshape()를 이용해서 마지막에 채널 차원을 추가해줘야 한다.
    • (#, #, #, #)에서는 순서대로 데이터 샘플 개수, 가로길이, 세로길이, 깊이(채널)을 말한다.
'''
import dataset
'''

from tensorflow import keras
from sklearn.model_selection import train_Test_split 

(train_input, train_target), (test_input, test_target)O \=
	keras.datasets.fashion_mnist.load_data()
 
 train_scaled = train_input.reshape(-1, 28, 28, 1) / 255.0 # (1)
 
 train_scaled, val_scaled, train_target, val_target = train_test_split(
 	train_scaled, train_target, test_size = 0.2)

 

2. 합성곱 신경망 만들기

  • 층을 추가하는 Sequential 객체를 만들고 거기다가 합성곱층 Con2D를 추가한다. - (2)
    • 아래 코드를 빌려 이해해보자면, 필터의 개수와 커널 크기를 각각 32개와 (3,3)으로 지정했고, 순서대로 활성화 함수, 패딩을 지정했다.
    • 또한, 입력층에서는 반드시 입력의 차원을 지정해야 하기에,  input_shape를 앞서 3차원 배열로 바꾼 것 처럼 (28, 28, 1)로 지정해 두었다.
  • plot_model을 통해, 층이 어떻게 구성되어 있는지 그림으로 볼 수 있다 - (3)
    • show_shapes : 입출력 크기 표시 여부
    • to_file : 파일 이름을 지정해서 이미지 파일로 저장가능
    • dpi : 해상도
'''
cnn
'''
 model = keras.Sequential()
 
 model.add(keras.layers.Conv2D(32, kernel_size = 3, activation = 'relu',
 	padding = 'same', input_shape=(28, 28, 1))) # (2)
 model.add(keras.layers.MaxPooling2D(2))
 model.add(keras.layers.Flatten())
 model.add(keras.layers.Dense(100, activation = 'relu'))
 model.ad(keras.layers.Dropout(0.4))
 model.add*keras.layers.Dense(10, activation = 'softmax'))
 
 model.summary()
 
 keras.utils.plot_model(model, show_Shapes = True) # (3)

 

3. 모델 컴파일하고 훈련시키기

  • fit(), evaluate(), predict() 모두 입력의 첫 번째 차원이 배치 차원을 기대한다.
    • 크기가 (28,28,1)인 샘플 하나를 보낸다고 할 때, (1, 28, 28, 1)로 입력해야 한다.
'''
 training model
 '''
 model.compile(optimizer = 'adam', loss= 'sparse_categorical_crossentropy', metrics= 'accuracy')
 checkPoint = keras.callbacks.ModelCheckpoint('best-cnn-model.h5', save_best_only = True)
 earlyStopping = 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, earlyStopping])
                     
'''
검증세트에 대해서 성능평가
'''
model.evaluate(val_scaled, val_target) #컴파일이후 사용가능

'''
예측
'''
pred = model.predict(val_scaled[0:1])

 

 

4. 손실그래프 그려서 확인

 

 

 

 


**참고

[ 완전 연결 신경망의 새로운 정의]

: 완전 연결 신경망은 밀집층만 사용하여 만든 신경망