플레이데이터 부트캠프 데이터 엔지니어링 트랙 7주차 (7.17~21)

안인균·2023년 7월 23일
0
post-thumbnail

이번 주차에서는"딥러닝"에 대한 학습이 이뤄졌습니다. Tensorflow 모듈을 본격적으로 사용하고 머신러닝 모델과 같이 딥러닝 모델에서의 성능개선, 과적합 개선에 대한 내용을 알 수 있었습니다. 또한 Convolution layer를 활용한 CNN 모델 을 작성하고, 이미지 데이터를 구분하는 과정을 직접 경험할 수 있었습니다. CNN 모델 학습할 때, GPU가 필요하여 Colab을 활용하여 무료 GPU를 사용했습니다.


Liked

  • Tensorflow 모듈을 활용해 tf.Tensor 으로 Dataset을 읽어들이고, 내장되어 있는 각종 메서드들을 활용해서 실습 예제를 학습 모델링하는 과정을 할 수 있어 좋았습니다. 해당 과정 중에 이전에 학습한 내용을 돌아볼 수 있었고, Tensorflow 모듈에 대한 이해도가 높아질 수 있는 좋은 기회였습니다.

  • 각 성능 개선 기법에 대한 개념 학습과 관련 예제 코드를 바로 학습할 수 있어 좋았습니다. 실제로 한다면, '이렇게 코드를 쓸 수 있구나' 라는 걸 느낄 수 있는 좋은 시간이었습니다.

  • 다양한 학습-모델링을 배울 수 있어 좋았습니다. 이전까지, 사용되었던 Dataset들은 전부 숫자로 이루어진 것들이었는데 이번에 학습한 Convolution Neural Network 는 주로 이미지 파일 받아 특징을 추출하고 분류하는 과정으로, 이전보다 흥미로운 주제인 것 같아서 좋았습니다.

  • cifar10 이미지 데이터셋을 이용해 직접 CNN 모델을 만드는 과정을 해볼 수 있어서 좋았습니다. 여러 가지 방법들을 사용하면서 어떻게 하면 더 개선될지에 대한 고민을 한 경험이 매우 좋았습니다.

  • TODO 학습 파일을 통해 딥러닝 학습 모델을 구성하는 과정을 경험할 수 있어 좋았습니다. 직접 구현하는 과정에서,이런저런 layer 들을 추가하거나 여러 번 파라미터 값들을 교체하면서 좋은 성능을 보여줄 수 있는 모델 네트워크를 찾는 과정이 즐겁기도 하고 잘 안나와 짜증 나기도 했지만, 이러한 학습 분야가 이런 과정을 겪는구나 라는 것을 직접 느낄 수 있어 매우 좋았습니다.

  • https://www.kaggle.com/ , 캐글 사이트를 통해 다른 사람들의 코드를 확인하고 학습할 수 있다는 것을 알게되어 좋았습니다.

Lacked

  • 다양한 학습을 하면서 점차 '머신러닝-딥러닝' 을 '실제 원본 데이터로 어떻게 접근할 수 있을까?' 라는 의구심이 들면서 어렵다는 생각이 들었습니다. 여태 실습 코드에서 사용된 데이터들은 기본적으로 잘 정제된 데이터를 원하는 방향에 맞춰서 바꾸는데 어려움이 없었고, 각 학습 목적에 맞춰서 데이터 전처리 방법, 학습 모델 선정 등이 미리 되어 있어 이에 따라 코드를 맞춰서 짜면 됐으나, 실제 원본 데이터에서 원하는 결과를 향해 맞춰가는 분석 방법에 대한 두려움이 생기기도 했었습니다.

  • TODO 학습에서 CNN 모델의 최고 성능을 구현하는 코드를 만들지 못해 아쉬웠습니다. 또한 아직도 모르는 내용들이 많다고 느껴져서 복습의 필요성을 다시 한번 느꼈습니다.

Learned

  • tf.data 모듈 활용

    • 데이터 입력 파이프라인을 위한 모듈
    • 모델 학습/평가를 위한 데이터셋을 제공(feeding)하기 위한 모듈
      • raw dataset 에서 입력을 위한 전처리, 배치 크기 조정, shuffling등을 한번에 처리할 수 있게 한다.
    • tf.data.Dataset 추상클래스에서 상속된 여러가지 클래스들을 제공
      • 입력 소스의 제공 형태, 어떤 처리를 하는지에 따라 다양한 하위클래스들이 제공된다.
  • DataSet 을 생성 -> 대상 raw dataset이 메모리에 있는 ndarray일 경우

=> Raw dataset 으로부터 데이터를 읽어들이는 기능을 제공하는 Dataset 생성.
원본 데이터(raw data)가 어디에 어떤 식으로 저장되어있는 지에 따라 다르다.
이번 경우에는 메모리에 ndarray 형식으로 저장되어 있는 데이터를 읽어 들이는 경우로,
tf.data.Dataset.from_tensor_slices()를 통해 읽어 들였다.
  • tf.Tensor 타입으로 선언된 Dataset에는 순서 존재.

    "tf모듈" 에서 "getitems()" 매직 메서드 를 구현하지 않아 "not subscriptable"
    기본적으로 Tensor는 ndarray타입을 가지고 있기 때문에 순서, index가 존재한다.
    그러나, tf모듈 에서 __getitems()__ 매직 메서드 를 구현되지 않아 [index] 로 조회 시 "not subscriptable" 에러가 뜬다.

  • Tensor 타입에 존재하는 메서드

shuffle()
batch()
repeat()
map()
filter()
  • Tensorflow 모듈을 활용한 실습 예제들
Regression(회귀) : Boston Housing Dataset 활용

분류 (Classification) : Fashion MNIST Dataset - 다중분류(Multi-Class Classification) 문제
  • 딥러닝 모델 성능 개선 :

기본적으로 모델의 성능 저하를 나타내는 '과소 적합' 과 '과대 적합' 의 해결 방법은 다음과 같습니다.

  • 과소적합(Underfitting) 개선
    • 모델의 복잡도를 높인다.
    • 모델 네트워크의 크기를 키운다.
      • Layer나 Unit 개수를 늘린다.
    • Epoch (또는 Step) 수를 늘린다.
      • Train/Validation의 성능이 계속 좋아지는 상태에서 끝난 경우 더 학습을 시킨다.
  • 과대적합(Overfitting) 개선
    • 더 많은 data를 수집
      • 데이터 추가 수집
        • 일반적으로 데이터를 추가 수집하여 늘리는데는 시간과 돈이 많이 들기 때문에 힘들다.
    • 다양한 Upsampling 기법을 이용해 데이터를 증식시킨다.
    • 모델의 복잡도를 낮춰 단순한 모델을 만든다.
      • 네트워크 모델의 크기를 작게 만든다.
      • 모델의 학습을 규제하는 기법을 적용한다.
    • Epoch(또는 step) 수를 줄인다.
      • Validation의 성능 지표가 가장 좋았던 Epoch 까지만 학습시킨다.
  • 과대적합을 방지하기 위한 규제 방식은 모두 모델을 간단하게 만드는 방법들이다.

  • 다양한 성능 개선 기법들
1. 모델의 크기 변경 -> 성능 확인
2. Dropout layer 추가
3. Batch normalization layer 추가

4. 
1️⃣Learning Rate 변화를 통한 성능개선 : 
"Learning rate Decay" (특정 step 마다 learning rate를 변경), 

2️⃣"Callback 을 이용해 학습률 변경" :
(일정 step동안 검증 성능지표가 향상되지 않으면 그때, learning rate를 조정한다.)
  • '신경망 구조' 학습 때, 알게 된 Convolution layer 과 이를 사용한 모델인 CNN(Convolution Neural Network) 에 대해 학습하였습니다.

    구성

    • 이미지로 부터 부분적 특성을 추출하는 Feature Extraction 부분과 분류를 위한 추론 부분으로 나눈다.
    • Feature Extraction 부분에 이미지 특징 추출에 성능이 좋은 Convolution Layer 를 사용한다.
      -> Feature Exctraction : Convolution Layer
      -> 추론 : Dense Layer (Fully connected layer)
  • Convolution(합성곱) 연산 :

    • Convolution Layer 는 이미지와 필터간의 Convolution(합성곱) 연산을 통해 이미지의 특징을 추출해 낸다.
    • 합성곱 연산은 input data와 weight간의 가중합을 구할 때 한번에 구하지 않고 작은 크기의 Filter를 이동시키면서 가중합을 구한다.
    • '상하좌우' 의 공간적인 특성을 그대로 유지한 채 연산이 진행된다. (Dense layer과 차이점)
  • CNN 에서의 Filter

    • Convolution Layer 는 특성을 추출하는 Filter(Kernel) 들로 구성되어 있다.
    • Filter(Kernel) 를 구성하는 값들은 데이터를 학습해 찾아낸다. 그래서 Filter를 구성하는 원소(element)들이 Parameter(weight)가 된다.
    • Layer를 구성하는 Filter들은 Input(input image 또는 feature map) 에서 각각 다른 패턴(특징)들을 찾아낸다.
  • Convolutional Layer 생성 및 작동방식
    : tensorflow.keras.layers.Conv2D 사용
    - Hyper parameter 하이퍼 파라미터

1. Filters : 레이어를 구성하는 filter(kernel)의 개수. Feature map output의 깊이가 된다.

2. kernel_size : Filter의 크기(height, width) 보통 홀수 크기로 잡는다. (3 * 3, 5 * 5). 주로 3 * 3 필터를 사용한다.
height, width가 동일할 경우 하나만 설정한다. Filter의 channel은 Layer의 input의 channel과 동일하게 자동으로 설정된다.

3. padding :  input tensor의 외곽에 특정 값(보통 0)들 둘러 싼다. 
입력과 출력 사이즈를 같게 하기 위해서, input tensor를 0으로 한번 둘러싸는 것.
ex) 4x4 입력 데이터를 패딩 => 6x6 입력 데이터, 끝값들은 0으로 둘러쌈.

4. stride : 연산시 Filter의 이동 크기

5. Feature Map : Filter를 거쳐 나온 결과물. Feature map의 개수는 Filter당 한개가 생성된다.
Feature map의 크기(shape)는 Filter의 크기(shape), Stride, Padding 설정에 따라 달라진다.
  • Max Pooling Layer
    : 해당 영역의 input 중 가장 큰 값을 출력. 일반적으로 2*2 크기에 stride는 2를 사용 (겹치지 않게 한다.)

    - 학습할 weight가 없음
    - 일반적으로 convolutional layer + pooling layer를 하나의 레이어로 취급
    - 정보손실이 있으나 해당 영역을 이루고 있는 특징 값 중 최댓값을 대표값으로 대신한다. 전체 그림의 한 픽셀에 해당하는 부분의 손실이고, 엄청 큰 값이 아니기 때문에 문제없이 사용된다.

강제적인 "downsampling" 효과 :
1. Input의 size를 줄여 계산속도를 높임
2. 특징의 공간적 계층구조를 학습한다 ==> 부분적 특징을 묶어 전체적인 특징의 정보를 표현하게 된다.

  • 추론기
    : 해결하려는 문제에 맞춰 Layer를 추가한다.

    - Feature Extraction layer을 통과해서 나온 Feature map을 입력으로 받아 추론한 최종결과를 출력한다.
    - Dense layer를 많이 사용했으나 지금은 Convolution layer를 사용하기도 한다.
        - Feature Extractor와 추론 layer를 모두 Convolution Layer로 구성한 Network를 Fully Convolution Network(FCN)이라고 한다.
  • CNN 구조 :

    • 일반적으로 "convolutional layer + pooling layer" 구조를 여러 개 쌓는다.

      • 동일한 레이어들의 구조를 반복해서 쌓을 때 그 구조를 Layer block 이라고 한다.
      • convolutionpooling layer를 묶어서 반복한 것을 convolution block 이라고 한다.
    • Bottom단의 Convolution block에서 Top 단의 convolution block으로 진행 될 수록 feature map의 size(height, width)는 작아지고 channel(depth)는 증가한다.

      • Top 단으로 갈수록 다른 convolution layer 들과 동일한 size의 fliter를 이용해 입력 이미지의 더 큰(넓은)영역 특성을 찾아야 하기 때문에 size를 줄인다.
      • Top 단으로 갈수록 더 큰 영역에서 특성을 찾게 되므로 Filter의 개수를 늘려 더 많은 특성을 찾도록 한다.
    • 마지막에 Fully connected layer 를 이용해 추론한다.

  • CNN 모델 네트워크 구현
    Ex)
def get_mnist_cnn_model(lr=0.01):
    model = keras.Sequential()
    # Input Layer
    model.add(layers.InputLayer(input_shape=(28, 28, 1))) # 1 => Gray scale
    # Convolutional layer input data shape => 3rd array (height, width, channel)

    # Feature Extractor -> Convolution Block (Conv + MaxPool) 으로 정의
    # 영상용 Convolutional layer ==> .Conv2D() 사용
    model.add(layers.Conv2D(filters=16,    # filter(kernel) 의 개수. 1필터=1특징 찾음. 16필터=16특징
                           kernel_size=(3,3),
                           strides=(1,1), # default=1 / (좌우, 상하) 이동 크기, 같으면 정수로 설정. =1
                           padding='same', # padding='same' :입력, 출력의 
                                            # size(h,w)가 같아지도록 padding 추가.
                                            # padding='valid' :(default) padding 추가하지 않는다.
                           activation='relu'
                           ))

    # .MaxPooling2D() :Feature map의 size를 줄인다. -> 지정한 크기의 영역에서 max값 하나를 추출.
    model.add(layers.MaxPooling2D(pool_size=(2, 2),
                                  strides=(2, 2), # default = None : pool_size와 동일한 크기
                                  
                                  padding="same" # "same" : 추출하려는 영역의 크기가 
                                               # pool_size보다 작아도 max값 추출
                                            ## "valid" :(default)추출하려는 영역의 
                                            ## 크기가 pool_size보다 작으면 추출X
                                  ))

    # filter 수를 늘리는 방향으로 정의.
    model.add(layers.Conv2D(filters=32, kernel_size=3, padding='same', activation='relu'))
    model.add(layers.MaxPooling2D(padding='same')) # pool_size 생략 => default :2 ==(2,2),
                                                    # strides == defalut pool_size랑 같다.

    model.add(layers.Conv2D(filters=64, kernel_size=3, padding='same', activation='relu'))
    model.add(layers.MaxPooling2D(padding='same'))
#-------------------Feature Extractor (Backbone network, Conv base)⬆


#-------------------추론기 ⬇----------------------------
    # Feature map 3차원 -> 1차원 변환, Dense layer 의 입력은 1차원만 가능하므로.
    model.add(layers.Flatten())

    model.add(layers.Dropout(0.3)) # 과적합, Overfitting 방지
    model.add(layers.Dense(units=256, activation='relu'))

    # 출력 Layer
    ## 다중분류 문제 : unit 수 - class의 개수(10), activation : softmax
    model.add(layers.Dropout(0.3))
    model.add(layers.Dense(units=10, activation='softmax', name='output_layer'))

    # 컴파일
    ## loss - categorical_crossentropy (y가 이미 one-hot encoding이 진행되었다면.)
    model.compile(optimizer=keras.optimizers.Adam(lr),
                  loss='categorical_crossentropy',
                  metrics=['accuracy'])

    return model
  • 학습한 Weight (파라미터) 저장 및 불러오기
model.save_weights("저장경로")
model.load_weights('불러올경로')
  • 전체 모델 저장하고 불러오기
model.save('저장할디렉토리')
tf.keras.models.load_model('저장된디렉토리')
  • Callback을 사용한 모델 저장 및 Early Stopping

    • ModelCheckpoint
      : 각 epoch 마다 학습한 모델과 weight(또는 weight만)를 저장한다. 지정한 평가지표(예:validation loss)가 가장 좋을 때 모델과 weight만 저장할 수 있다.
      - 주요 파라미터
      : save_weights_only=True : True: 파라미터(weight)만 저장한다. False: 모델구조와 파라미터 모두 저장한다.
      save_best_only=True : 학습중 성능이 개선될 때만 저장한다. (False:기본값 - 모든 에폭마다 저장한다.)
    • EarlyStopping
      : Validation set에 대한 평가지표가 더 이상 개선되지 않을 때 학습을 자동으로 멈추는 callback
      - 주요 파라미터
      : monitor : 모니터링할 평가지표 지정. (ex: accuracy)
      patience: epoch 수 지정. validation 평가 지표가 개선이 안되더라도 지정한 epoch만큼 반복한다. 지정한 epoch만큼 반복 후에도 개선이 되지 않으면 중단한다.
  • ImageDataGenerator

tensorflow.keras.preprocessing.image.ImageDataGenerator

Image 제공 데이터파이프라인을 어떻게 만들지 설정한다.
매개변수: 이미지 증식(augmentation) 관련 설정을 정의

    - fill_mode: 이동이나 회전시 생기는 공간을 어떻게 채울 것인지 설정
    - nearest: 빈공간에 가장 가까운 pixel로 채우기 (1,2,3 [3],[3],[3])
    - reflect: 빈공간 근처 공간의 값을 거울로 반사되는 값들으로 채움. (1,2,3 [3],[2],[1])
    - constant: 지정한 값으로 채움. 기본은 0이고 특정값으로 채울때는 cval=100 으로 설정

    - Nomalization 설정
        - rescale: 지정한 값을 각 픽셀에 곱한다. (rescale=1/255.)
        - featurewise_center=True: channel의 평균을 pixel에서 빼서 
        평균 0으로 표준화한다. (channel 별로 처리)
        - featurewise_std_nomalization=True: channel 별로 표준화한다. (평균 0, 표준편차 1)

    - 반전 : horizontal_flip=True: 좌우반전, vertical_flip=True: 상하 반전

    - 회전(rotation) : rotation_range=정수: -정수 ~ +정수 범위로 랜덤 회전 
(rotation_rate=30 : -30 ~ +30도 사이에서 랜덤하게 회전)

    - 이동 : width_shift_range=실수: 상하 이동, height_shift_range=실수: 좌우 이동
실수값: 이동범위지정. 0 ~ 1 이면 이미지 너비, 높이 기준 비율. 1이상이면 pixel.
정수: [-정수, 0, +정수] 범위

    - Zoom : zoom_range: 실수 또는 [lower, upper]
실수: [1-실수값, 1+실수값]
리스트: 원하는 비율류 lower, upper 지정할때. 설정한 값이 1미만이면 확대(zoom in), 1초과면 축소(zoom out)

    - shear(전단변환): 평행사변형 형태로 변환
shear_range: 실수 - 각도 지정

    - 명암 (brightness) : brightness_range : 실수값 2개를 가지는 튜플이나 리스트. 명암 범위
1이 원본. 0에 가까우면 어둡고 1보타 크면 밝아진다.

    - flow 메소드들
: ImageDataGenerator에 Image Data를 연결하여 batch 단위로 공급하는 Iterator 생성해준다.
Raw Image data의 위치에 따라 다양한 메소드를 제공한다.
  • ImageDataGenerator에 dataset을 제공하는 메서드
flow_from_directory ()
flow_from_dataframe()
flow()

Longed for

  • 알고리즘 학습과 코딩 테스트 문제 풀이를 할 예정입니다.
  • 이전 학습에 대한 복습을 진행할 것 입니다.

1개의 댓글

comment-user-thumbnail
2023년 7월 23일

글 잘 봤습니다.

답글 달기

관련 채용 정보