Post

신경망 시작하기

3. 신경망 시작하기

3.1 신경망의 구조

  • 3.1.1 층: 딥러닝의 구성 단위
    • 대부분의 층은 가중치를 가진다.
    • 가중치에는 네트워크가 학습한 지식이 담겨 있다.
    • 층마다 적절한 텐서 포맷과 데이터 처리 방식이 다르다.
    • 케라스에서는 호환 가능한 층들을 엮어 데이터 변환 파이프라인을 구성함으로써 딥러닝 모델을 만든다.
    • 층 호환성(layer compatibility): 각 층이 특정 크기의 입력 텐서만 받고 특정 크기의 출력 텐서만 반환한다는 사실
    • 케라스에서는 모델에 추가된 층을 자동으로 상위 층의 크기에 맞추어 주기 때문에 호환성을 걱정하지 않아도 된다.
  • 3.1.2 모델: 층의 네트워크
    • 딥러닝 모델은 층으로 만든 비순환 유향 그래프(Directly Acyclic Graph, DAG)
    • 네트워크 구조는 가설 공간(hypothesis space)을 정의
  • 3.1.3 손실 함수와 옵티마이저: 학습 과정을 조절하는 열쇠
    • 손실 함수(목적 함수): 훈련하는 동안 최소화돨 값, 주어진 문제에 대한 성공 지표
    • 옵티마이저: 손실 함수를 기반으로 네트워크가 어떻게 업데이트될지 결정, SGD 구현
    • 여러 개의 출력을 내는 신경망은 여러 개의 손실 함수를 가질 수 있다. 그래서 모든 손실을 평균 내서 하나의 스칼라 양으로 합쳐짐
    • 문제에 맞는 올바른 목적 함수를 선택하는 것이 중요

3.2 케라스 소개

  • 케라스 특징
    • 동일한 코드로 CPU와 GPU를 실행 가능
    • 사용하기 쉬운 API를 가지고 있어 딥러닝 모델의 프로토타입을 빠르게 만들 수 있다.
    • 합성곱 신경망, 순환 신경망을 지원하며 이 둘을 자유롭게 조합하여 사용 가능
    • 다중 입력이나 다중 출력 모델, 층의 공유, 모델 공유 등 어떤 네트워크 구조도 만들 수 있다.
  • 3.2.1 케라스, 텐서플로, 씨아노, CNTK
    • 케라스의 백엔드 엔진에서 제공하는 최적화되고 특화된 텐서 라이브러리를 사용
    • 텐서플로, 씨아노, 마이크로소프트 코그니티브 툴킷(CNTK)
    • 케라스로 작성한 모든 코드는 아무런 변경 없이 백엔드 중 하나를 선택해서 실행 가능
    • 텐서플로(또는 씨아노, CNTK)를 사용하기 때문에 케라스는 CPU와 GPU를 모두 작동 가능
  • 3.2.2 케라스를 사용한 개발: 빠르게 둘러보기
    • 케라스 작업 흐름
      1. 입력 텐서와 타깃 텐서로 이루어진 훈련 데이터를 정의
      2. 입력과 타깃을 매핑하는 층으로 이루어진 네트워크를 정의
      3. 손실 함수, 옵티마이저, 모니터링하기 위한 측정 지표를 선택하여 학습 과정을 설정
      4. 훈련 데이터에 대해 모델의 fit() 메서드를 반복적으로 호출
    • 모델을 정의하는 방법은 Sequential 클래스 또는 함수형 API(완전히 임의의 구조를 만들 수 있는 비순환 유향그래프), 2가지가 있다.
    • 컴파일 단계에서 학습 과정 설정

3.3 딥려닝 컴퓨터 셋팅

  • 3.3.1 주피터 노트북: 딥러닝 실험을 위한 최적의 방법
    • 권장함
  • 3.3.2 케라스 시작하기: 두가지 방법
    • EC2 딥러닝 AMI 사용
    • 로컬 유닉스 컴퓨터에 설치
  • 3.3.3 클라우드에서 딥러닝 작업을 수행했을 때 장단점

  • 3.3.4 어떤 GPU 카드가 딥러닝에 최적일까?
    • NVIDIA GPU

3.4 영화 리뷰 분류: 이진 분류 예제

  • 3.4.1 IMDB 데이터셋
    • 훈련 데이터 25000, 테스트 데이터 25000 / 50%긍정, 50%부정
    • 모델이 훈련 데이터에서 잘 작동한다는 것이 처음 만난 데이터에서도 잘 작동한다는 것을 보장하지 않는다.
      1
      2
      
        from keras.datasets import imdb
        (train_data, train_labls), (test_data, test_labels) = imdb.load_data(num_words=10000)
      
    • num_words=10000은 자주 나타나는 단어 1만 개만 사용하겠다는 의미
  • 3.4.2 데이터 준비
    • 리스트를 텐서로 바꾸는 방법
      1. 같은 길이가 되도록 리스트에 패딩을 추가하고 (samples, sequence_length) 크기의 정수 텐서로 변환
      2. 리스트를 원-핫 인코딩하여 0과 1의 벡터로 변환
        1
        2
        3
        4
        5
        6
        7
        8
        
          import numpy as np
          def vectorize_sequences(sequences, dimension=10000):
          results = np.zeros((len(sequences), dimension)) # 크기가 (len(sequences), dimension)이고 모든 원소가 0인 행렬 생성
          for i, sequence in enumerate(sequences):
         results[i, sequence] = 1. # result[i]에서 특정 인덱스의 위치를 1로 만든다
          return results
          x_train = vectorize_sequences(train_data)
          x_test = vectorize_sequences(test_data)
        
  • 3.4.3 신경망 모델 만들기
    • 입력 데이터가 벡터고 레이블은 스칼라
    • 이런 문제에 잘 작동하는 네트워크 종류는 relu 활성화 함수를 사용한 완전 연결 층(Dense(16, activation=’relu’))을 그냥 쌓은 것
    • 은닉 유닛(hidden unit): 층이 나타내는 표현 공간에서 하나의 차원
    • 은닉 유닛을 늘리면 신경망이 더욱 복잡한 표현을 학습할 수 있지만 계산 비용이 커지고 원하지 않는 패턴을 학습할 수도 있다
    • Dense 층을 쌓을 때 두 가지 중요한 구조상의 결정이 필요
      • 얼마나 많은 층을 사용할 것인가?
      • 각 층에 얼마나 많은 은닉 유닛을 둘 것인가?
    • 활성화 함수가 무엇? 필요한 이유?
      • 활성화 함수가 없다면 Dense 층은 선형적인 연산인 점곱과 덧셈 2개로 구성된다.
      • 선형 변환을 하면 깊게 쌓아도 여전히 하나의 선형 연산이기 때문에 장점이 없다(층을 추가해도 가설 공간이 확장되지 않는다.)
      • 그래서 활성화 함수가 필요
    • 확률을 출력하는 모델을 사용할 때는 크로스엔트로피(Crossentropy)가 최선의 선택
  • 3.4.4 훈련 검증
    1
    2
    3
    4
    5
    
      history = model.fit(partial_x_train,
                         partial_y_train,
                         epochs=20,
                         batch_size=512,
                         validation_data=(x_val, y_val))
    
    • 과대적합(overfitting): 훈련 데이터에 과도하게 최적화되어 훈련 데이터에 특화된 표현을 학습하므로 훈련 세트 이외의 데이터에는 일반화되지 못하는 것
  • 3.4.5 훈련된 모델로 새로운 데이터에 대해 예측하기

    • model.predict(x_test)
  • 3.4.6 추가 실험

    • 층 개수 수정, 은닉 유닛 수정, 손실함수 수정 등…
  • 3.4.7 정리
    • 원본 데이터를 신경망에 텐서로 주입하기 위해서는 꽤 많은 전처리가 필요
    • relu 활성화 함수와 함께 Dense 층을 쌓은 네트워크는 여러 종류의 문제에 적용 가능
    • 이진 분류 문제에서 네트워크는 하나의 유닛과 sigmoid 활성화 함수를 가진 Dense 층으로 끝나야 한다.
    • 이진 분류 문제에서 스칼리 시그모이드 출력에 대해 사용할 손실 함수는 binary_cros sentropy
    • rmsprop 옵티마이저는 문제에 상관없이 일반적으로 충분히 좋은 선택
    • 훈련 데이터에 대해 성능이 향상됨에 따라 신경망은 과대적합되기 시작하고 이전에 본적 없는 데이터에서는 결과가 점점 나빠짐

3.5 뉴스 기사 분류: 다중 분류 문제

  • 정리
    • N개의 클래스로 데이터 포인트를 분류하려면 네트워크의 마지막 Dense 층의 크기는 N이어야 한다.
    • 단일 레이블, 다중 분류 문제에서는 N개의 클래스에 대한 확률 분포를 출력하기 위해 softmax 활성화 함수를 사용해야 한다.
    • 범주형 크로스엔트로피 사용
    • 다중 분류에서 레이블을 다루는 두 가지 방법
      • 레이블을 범주형 인코딩으로 인코딩하고 catogorical_crossentropy 사용
      • 레이블을 정수로 인코딩하고 sparse_categorical_entropy 손실 함수 사용
    • 많은 수의 범주를 분류할 때 중간층의 크기가 너무 작아 네트워크에 정보의 병목이 생기지 않도록 해야 한다.

3.6 주택 가격 예측: 회귀 문제

  • 정리
    • 회귀는 분류에서 사용했떤 것과는 다른 손실 함수(평군 제곱 오차(MSE))를 사용
    • 회귀에서 사용되는 평가 지표는 분류와 다름(평균 절대 오차(MAE))
    • 입력 데이터의 특성이 서로 다른 범위를 가지면 전처리 단계에서 각 특성을 개별적으로 스케일 조정해야 함
    • 가용한 데이터가 적다면 k-겹 검증을 사용하는 것이 신뢰할 수 있는 모델 평가 방법
    • 가용한 훈련 데이터가 적다면 과대적합을 피하기 위해 은닉 층의 수를 줄인 모델이 좋다(일반적으로 1개 또는 2개)

3.7 요약

  • 보통 원본 데이터를 신경망에 주입하기 전에 전처리 필요
  • 데이터에 범위가 다른 특성이 있다면 전처리 단계에서 각 특성을 독립적으로 스케일 조정해야 한다.
  • 훈련이 진행됨에 따라 신경망의 과대적합이 시작되고 새로운 데이터에 대해 나쁜 결과를 얻게 됩니다.
  • 훈련 데이터가 많지 않으면 과대적합을 피하기 위해 1개 또는 2개의 은닉 층을 가진 신경망을 사용
  • 데이터가 많은 범주로 나뉘어 있을 때, 중간층이 너무 작으면 정보의 병목이 생길 수 있다.
  • 회귀는 분류와 다른 손실 함수와 평가 지표 사용
  • 적은 데이터를 사용할 때는 k-겹 검증이 신뢰할 수 있는 모델 평가를 도와줌
This post is licensed under CC BY 4.0 by the author.