페이지

2022년 7월 23일 토요일

3.4.1 IMDB 데이터셋

 인터넷 영화 대이터베이서(Internet Movie Database)로 부터 가져온 양극단의 리뷰 5만 개로 이루어진 IMDB 데이터셋을 사용하겠습니다. 이 데이터셋은 훈련 데이터 2만 5,000개의 테스트 데이터 2만 5,000개로 나누어 있고 각각 50%는 부정, 50%는 긍정 리뷰로 구성되어 있습니다.

왜 훈련 데이터와 테스트 데이터를 나눌까요? 같은 데이터에서 머신 러닝 모델을 훈련하고 테스트해서는 절대 안 되기 때문입니다! 모델이 훈련 데이터에서 잘 작동한다는 것이 처음 만난 데이터에서도 잘 작동한다는 것을 보장하지 않습니다. 중요한 것은 새로운 데이터에 대한 모델의 성능입니다(사실 훈련 데이터의 레이블은 이미 알고 있기 때문에 이를 예ㅊ측하는 모델은 필요하지 않습니다). 예를 들어 모델이 훈련 샘플과 타깃 사이의 매핑을 모두 외워 버릴 수 있습니다. 이런 모델은 처음 만나는 데이터에서 타깃을 예측하는 작업에는 쓸모가 없습니다. 다음 장에서 이에 대해 더 자세히 살펴봅니다.

MNIST데이터셋처럼 IMDB 데이터셋도 케라스에 포함되어 있습니다. 이 데이터는 전처리 되어있어 각 리뷰(단어 시퀀스)가 숫자 스퀀스로 변화되어 있습니다. 여기서 각 숫자는 사전에 있는 고유한 단어를 나타냅니다.

다음 코드는 데이터셋을 로드합니다(처음 실행하면 17MB 정도의 데이터를 컴퓨터에 내려받습니다).

    from keras.datasets import imdb

    (train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=10000)


num_words=10000 매개변수는 훈련 데이터에서 가장 자주 나타나는 단어 1만 개만 사용하겠다는 의미입니다. 드물게 나타나는 단어는 무시하겠습니다. 이렇게 하면 적절한 크기의 벡터 데이터를 얻을 수 있습니다.

변수 train_data와 test_data는 리뷰의 목적입니다. 각 리뷰는 단어 인텍스의 리스트입니다(단어 시퀀스가 인코딩된 것입니다). train_labels와 test_labels는 부정을 나타내는 0과 긍정을 나타내는 1의 리스트입니다.

>>> train_data[0]

[1, 14, 22, 16, ... 178, 32]

>>> train_labels[0]

1

가장 자주 등장하는 단어 1만 개로 제한했기 때문에 단어 인덱스는 9.9999를 넘지 않습니다.

>>> max([max(sequence) for sequence in train_data])

9999

재미 삼아 이 리뷰 데이터 하나를 원래 영어 단어로 어떻게 바꾸는지 보겠습니다.

word_index = imdb.get_word_index()  ................. word_index는 단어와 정수 인텍스를 매핑한 딕셔너리입니다.

reverse_word_index = dict(

    [(value, key) for (key, value) in word_index.items()]) ....... 정수 인덱스와 단어 매핑되도록 뒤집습니다.

decoded_review = ' '.join(

    [reverse_word_index.get(i -3, '?') for i in train_data[0]])


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

2종 분류(two-class classification) 또는 이진 분류(binary classification)는 아마도 가장 널리 적용된 머신 러닝 문제일 것입니다. 이 예제에서 리뷰 텍스트를 기반으로 영화 리뷰를 긍정(positive)과 부정(negative)으로 분류하는 방법을 배우겠습니다.


3.2.2 케라스 시작하기: 두 가지 방법

 실제 시작하려면 다음 두 가지 방법 중 하나를 권장 합니다.

1) 공식 EC2 딥러닝 AMI( https://aws.amaxon.com/amaxon-ai/amis)를 사용해서 EC2에서 주피터 노트북으로 케라스 예제를 실행합니다. 로컬 컴퓨터에 GPU가 없을 때 이 방법을 사용합니다. 부록C에 자세한 안내가 있습니다.

2) 로컬 유닉스 컴퓨터에 처음부터 모든 것을 설치합니다. 그 다음 로컬 컴퓨터에서 주피터 노트북을 실행하든지 아니면 일반 파이썬 스크립트를 실행합니다. 이미 고사양 NVIDIA GPU카드가 있을때 이 방법을 사용합니다. 부로 B에 우분투를 사용한 자세한 안내가 있습니다.

두 가지 선택 사항 중 하나를 선택했을 때의 장단점을 자세히 알아보겠습니다.

3.3.1 주피터 노트북: 딥러닝 실험을 위한 최적의 방법

 주피너 노트북(Jupyter Notebook)은 딥러닝 실험, 특히 이 책의 예제 코드를 위한 최적의 방법입니다. 주피터 노트북은 데이터 과학과 머신 러닝 커뮤니티에서 폭넓게 사용됩니다. 노트북은 주피터 노트북 애필리케이션(https://jupyter.org)으로 만든 파일이며 웹 브라우저에서 작성할 수 있습니다. 작업 내용을 기술하기 위해 서식 있는 텍스트 포맷을 지원하며 파이썬 코드를 실행할 수 있는 기능도 있습니다. 노트북에서는 긴 코드를 작께 쪼개 독립적으로 실행할 수 있어 대화식으로 개발이 가능하고, 작업중에 무언가 잘못되었을 때 이전 코드를 모두 재 실행할 필요가 없습니다.

필수적이지는 않지만 케라스를 배울 때 주피터 노트북을 사용할 것을 권장합니다. 하지만 파이참(pyCharm)같은 IDE에서 코드를 실행하거나 독립된 파이썬 스크립트를 실행할 수도 있습니다. 이 책의 모든 코드 예제는 오픈소스 노트북 파일로 제공됩니다. 깃 허브 https://githjub.com/gilbutITbook/006975나 https://github.com/rickiepark/deep-learning-with-python-notebooks에서 내려 받을 수 있습니다.

3.3 딥러닝 컴퓨터 싯팅

 딥러닝 애플리케이션 개발을 시작하기 전에 먼저 컴퓨터를 셋팅해야 합니다. 아주 필수적이지는 않지만 최신 NVIDIA GPU에서 딥러닝 코드를 실행하는 것을 권장합니다. 특히 합성곱 신경망을 사용한 이미지 처리나 순환 신경망을 사용한 시퀀스 처리 같은 일부 애플리케이션을 CPU에서 실행하면 아주 빠른 멀티코어 CPU라도 매우 오래 걸립니다. 실제로 CPU에서 실행할 수 있는 애플리케이션일지라도 최신 GPU를 사용하면 보통 2배나 5배 또는 10배 정도 속도가 빨라집니다. 컴퓨터에 GPU카드를 설치하고 싶지 않다면 대안으로 AWS EC2 GPU인스턴스나 구글 클라우드 플랫폼을 고려해 볼 수 있습니다. 클라우드 GPU 인스턴스는 시간에 따라 비용이 과금되는 점을 유념하세요.

로컬 컴퓨터를 셋팅하는지 또는 클라우드를 사용하는지에 상관없이 유닉스(Unix) 운영체제를 사용하는 것이 좋습니다. 기술적으로 원도에서 케라스를 사용할 수 있지만(3개의 케라스 백엔드 모두 원도를 지원합니다) 권장하지는 않습니다. 부록 B에서는 우분투에서 설치하는 방법을 안내합니다. 원도 사용자라면 가장 간단하게 동일한 실행 환경을 준비하는 방법은 우분투로 듀얼 부트가 되도록 컴퓨터를 셋팅하는 것입니다. 조금 번거로울 수 있지만 우분투를 사용하면 장기적으로 시간이 절약되고 문제가 발생할 가능성이 적습니다.

케라스를 사용하려면 텐서플로 또는 CNTK또는 씨아노를 설치해야 합니다(또는 3개의 백엔드를 서로 바꾸어 가며 작업하려면 이들 모두를 설치합니다). 이 책에서는 텐서플로를 중점적으로 다루곻 씨아노에 대해서는 일부만 소개합니다. CNTK는 다루지 않습니다.


3.2.2 케라스를 사용한 개발: 빠르게 둘러보기

 이미 케라스 메델의 예로 MNIST 예제를 보았습니다. 전형적인 케라스 작업 흐름은 이 예제와 비슷합니다.

1) 입력 텐서와 타깃 텐서로 이루어진 훈련 데이터를 정의합니다.

2) 입력과 타깃을 매핑하는 층으로 이루어진 네트워크(또는 모델)를 정의 합니다.

3) 손실 함수, 옵티마이저, 모니터링하기 위한 측정 지표를 선택하여 학습 과정을 설정합니다.

4) 훈련 데이터에 대해 모델의 fit()메서드를 반복적으로 호출합니다.

모델을 정의하는 방법은 두 가지인데, Sequential 클래스(가장 자주 사용하는 구조인 층을 순서대로 쌓아 올리 네트워크입니다)또는 함수형 API(완전히 임의의 구조를 만들 수 있는 비순환 유향 그래프를 만듭니다)를 사용합니다.

Sequential 클래스를 사용하여 정의한 2개의 층으로 된 모델을 다시 보겠습니다(첫 번째 층에 입력 데이터의 크기가 전달된 점을 주목하세요).


    from keras import models

    from keras import layers

    model = models.Sequential()

    model.add(layers.Dense(32, activation='relu', input_shape=(784,)))

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

같은 모델을 함수형 API를 사용하여 만들어 보겠습니다.

    input_tensor = layers.Input(shape=(784,))

    x = layers.Dense(32, activation='relu')(input_tensor)

    output_tensor = layers.Dense(10, activation='softmax')(x)

    model = model.Model(input_tensor, outputs=output_tensor)

함수형 API를 사용하면 모델이 처리할 데이터 텐서를 만들고 마치 함수처럼 이 텐서에 층을 적용합니다.

모델 구조가 정의된 후에는 Sequential모델을 사용했는지 함수형 API를 사용했는지는 상관 없습니다. 이후 단계는 동일합니다.

컴파일 단계에서 학습 과정이 설정 됩니다. 여기에서 모델이 사용할 옵티마이저와 손실 함수, 훈련하는 동안 모니터링하기 위해 필요한 측정 지표를 지정합니다. 다음이 하나의 손실 함수를 사용하는 가장 흔한 경우의 예입니다.

    from keras import optimizers

    model.compile(optimizer=optimizers.RMSorop(lr=0.01),

                        loss='mse',

                        metrics=['accuracy'])
마지막으로 입력 데이터의 넘파이 배열을 (그리고 이에 상응하는 타깃 데이터를)모델의 fit()메서드에 전달함으로써 학습 과정이 이루어집니다. 이는 사이킷런(Sckit-Learn)이나 몇몇 다른 머신러닝 라이브러리에서 하는 방식과 비슷합니다.

    model.fit(input_tensor, target_tensor, batch_size=128, epochs=10)

다음 몇 개의 장에서 여러 네트워크 구조가 각기 다른 문제에 어떻게 적용되는지, 어떻게 적합한 학습 설정을 선택하는지, 만족할 만한 결과를 얻기 위해 어떻게 모델을 수정하는지 설명하겠습니다. 3.4절, 3.5절, 3.6절에서 이진 분류, 다중 분류, 회귀에 대한 기초적인 세 가지 예를 살펴보겠습니다.

3.2.1 케라스, 텐서를로, 싸아노, CNTK

케라스는 딥러닝 모델을 만들기 위한 고수준의 구성 요소를 제공하는 모델 수준의 라이브러리입니다. 텐서 조작이나 미분 같은 저수준의 연산을 다루지 않습니다. 그 대신 케라스의 백엔트 엔진(backend engine)에서 제공하는 최적화되고 특화된 테서 라이브러리를 사용합니다. 케라스는 하나의 텐서 라이브러리에 국한하여 구현되어 있지 않고 모듈 구조로 구성되어 있습니다. 여러가지 백엔드 엔진이 케라스와 매끄럽게 연동됩니다. 현재는 텐서를로, 씨아노, 마이크로소프트 코그니티브 툴킷(Microsoft Cognitive Toolkit, CNTK) 3개를 백엔드 엔진으로 사용할 수 있습니다. 향후에는 더 많은 딥러닝 엔진을 케라스에 사용할 수 있을 것 입니다.

텐서플로, CNTK, 씨아노는 딥러닝을 위한 주요 플랫품 중 하나입니다. 씨아노(http://deeplearning.net/software/theano)는 몬트리올 대학 MILA 연구소에서 개발했고, 텐서플로(https://www.tensorflow.org)는 구글에서 개발했으면, CNTK(http://github.com/Microsoft/CNTK)는 마이크로 소프트에서 개발했습니다. 케라스로 작성한 모든 코드는 아무런 변경 없이 이런 백엔드 중 하나를 선택해서 실행시킬 수 있습니다. 개발하는 중간에 하나의 벡엔드가 특정 작업에 더 빠르다고 판단되면 언제든지 백엔드를 바꿀 수 있어 아주 유용합니다. 가장 널리 사용되고 확장성이 뛰어나며 사용 제품에 쓸 수 있기 때문에 대부분의 딥러닝 작업에 텐서플로 백엔드가 기본으로권장됩니다.

텐서플로(또는 씨아노나 CNTK)를 사용하기 때문에 케라스는 CPU와 GPU에서 모두 작동할 수 있습니다. CPU에서 실행될 때 텐서를로는 Eigen(http://eigen.tuxfamily.org)이라고 불리는 저수순 텐서 연산 라이브러리를 이용합니다. CPU에서 실행될 때 텐서를로는 Eigen(http://eigen.tuxfamily. org)이라고 부리는 저수준 텐서 연산 라이브러리를 이요합니다. GPU에서는 NVIDIA CUDA 심층 신경망 라이브러리(cuDNN) 라고 불리는 고도로 최적화된 딥러닝 연산 라이브러리를 이용합니다.