변수는 영어로 variable입니다. 그래서 DeZero에서 사용하는 변수라는 개념을 Variable이라는 이름의 클래스로 구현하겠습니다. 덧붙여서, 파이썬에서는 클래스 이름의 첫 글자를 보통 대문자로 합니다. 파이썬이 권항하는 코딩 규칙은 PEP8을 참고하세요.
이제 Variable 클래스가 상자가 되도록 구현해보죠. 다음은 이 기능을 최소한의 코드로 작성해본 모습니다.
변수는 영어로 variable입니다. 그래서 DeZero에서 사용하는 변수라는 개념을 Variable이라는 이름의 클래스로 구현하겠습니다. 덧붙여서, 파이썬에서는 클래스 이름의 첫 글자를 보통 대문자로 합니다. 파이썬이 권항하는 코딩 규칙은 PEP8을 참고하세요.
이제 Variable 클래스가 상자가 되도록 구현해보죠. 다음은 이 기능을 최소한의 코드로 작성해본 모습니다.
첫 번째 단계에서는 DeZero의 구성 요소인 '변수'를 만듭니다. 변수는 DeZero에서 가장 중요한 개념입니다. 이번 단계에서는 변수가 어떤 기능을 하는지 이해하고, 그 기능에 맞게 코드로 구현합니다.
미분은 다양한 과학 기술 분야에 사용됩니다. 특히 립러닝을 포한한 머신러닝의 여러 분야에서 중추적인 역할을 합니다. 딥러닝 프레임워크는 말하자면 미분을 계산하기 위한 도구입니다. 그래서 이 책의 주제도 자연스럽게 '미분'과 이어집니다. 즉, 컴퓨터를 사용하여 미분을 계산하는 일이 주요 주제입니다.
지금부터 시작되는 제1고지는 총 10간계로 구성됩니다. 이 고지에서는 미분을 자동으로 계산하는 틀을 만듭니다. '미분을 자동으로 계산한다'라는 말은 미분을 (사람이 아니라)컴퓨터가 계산한다는 뜻입니다. 정확히 말하면, 어떤 계산(함수)을 코드로 구현하면 그 계산의 미분을 컴퓨터가 자동으로 계산해주는 시스템을 가리킵니다.
이번 고지에서는 미분을 자동으로 계산하기 위해 '변수'와 '함수'를 표현하는 두 클래스 Variable과 Function을 만듭니다. 놀랍게도 이 두 클래스만으로 미분 자동 계산의 기반이 완성됩니다. 제1고지가 끝날 무렵에는 간단한 계산(함수)의 미분은 자동으로 계산할 수 있게 됩니다. 그럼 DeZero의 첫 번째 단계로 발을 내디뎌보죠.
특성 추출은 사전에 학습된 네트워크의 표현을 사용하여 새로운 샘플에서 흥미로운 특성을 ㅂ뽀아내는 것입니다. 이런 특성을 사용하여 새로운 분류기를 처음부터 훈련합니다.
앞서 보았듯이 컨브넷은 이미지 분류를 위해 두 부분으로 구성됩니다. 먼저 연속된 합성곱과 풀링 층으로 시작해서 완전 연결 분류기로 끝납니다. 첫 번째 부분을 모델의 합성곱 기반 층(convolutional base)이라고 부르겠습니다. 컨브넷의 경우 특성 추출은 사전에 훈련된 네트워크의 합성곱 기반층을 선택하여 새로운 데이터를 통과시키고, 그 출력으로 새로운 분류기를 훈련합니다.
작은 이미지 데이터셋에 딥러닝을 적용하는 일반적이고 매우 효과적인 방법은 사전 훈련된 네트워크를 사용하는 것입니다. 사전 훈련된 네트워크(pretrained network)는 일반적으로 대규모 이미지 분류 문제를 위해 대량의 데이터셋에서 미리 훈련되어 정장된 네트워크입니다. 원본 데이터셋이 충분히 크고 일반적이라면 사전 훈련된 네트워크에 의해 학습된 특성의 계층 구조는 실제 세상에 대한 일반적인 모델로 효율적인 역할을 할 수 있습니다. 새로운 문제가 원래 작업과 완전히 다른 클래스에 대한 것이라도 이런 특성은 많은 컴퓨터 비전 문제에 유용합니다. 예를 들어(대부분 동물이나 생활 용품으로 이루어진)Image Net 데이터셋에 네트워크를 훈련합니다. 그다음 이 네트워크를 이미지에서 가구 아이템을 식별하는 것 같은 다른 용도로 사용할 수 있습니다. 학습된 특성을 다른 문제에 적용할 수 있는 이런 유연성은 이전의 많은 얕은 학습 방법과 비교했을 때 딥러닝의 핵심 장점입니다. 이런 방식으로 작은 데이터셋을 가진 문제에도 딥러닝이 효율적으로 작동할 수 있습니다.
여기에서는 (1,400만 개의 레이블된 이미지와 1,000개의 클래스로 이루어진)ImageNet데이터셋에서 훈련된 대규모 컨브넷을 사용해 보겠ㅆ브니다. ImageNet 데이터셋은 다양한 종의 강아지와 고양이를 비록하여 많은 동물들을 포함하고 있습니다. 그래서 강아지 vs. 고양이 분류 문제에 좋은 성능을 낼 것 같습니다.
캐런 시몬연(Karen Simonyan)과 앤드류 지서먼(Andrew Zisseman)이 2014년에 개발한 VGG16구조를 사용하겠습니다. VGG16은 간단하고 ImageNet 데이터셋에 널리 사용되는 컨브넷 구조입니다. VGG16은 조금 오래되었고 최고 수준의 성능에는 못 미치며 최근의 다른 모델보다는 조금 무겁습니다. 하지만 이 모델의 구조가 이전에 보았던 것과 비슷해서 새로운 개념을 도입하지 않고 이해하기 쉽기 때문에 선택했습니다. 아마 VGG가 처음 보는 모델 애칭일지 모르겠습니다. 이런 이름에는 VGG, ResNet, Inception, Inception-ResNet, Xception등이 있습니다. 컴퓨터 비전을 위해 딥러닝을 계속 공부하다 보면 이런 이름을 자주 만나게 될 것입니다.
사전 훈련된 네트워크를 사용하는 두 가지 방법이 있습니다. 특성 추출(feature extraction)과 미세 조정(fine tunning)입니다. 이 두 가지를 모두 다루어 보겠습니다.
과대적합은 학습할 샘플이 너무 적어 새로운 데이터에 일반화할 수 있는 모델을 훈련시킬 수 없기 때문에 발생합니다. 무한히 많은 데이터가 주어지면 데이터 분포의 모든 가능한 측면을 모델이 학습할 수 있을 것입니다. 데이터 증식은 기존 훈련 샘플로부터 더 많은 훈련 데이터를 생성하는 방법입니다. 이 방법은 그럴듯한 이미지를 생성하도록 여러 가지 랜덤한 변환을 적용하여 샘플을 늘립니다. 훈련할 때 모델이 정확히 같은 데이터를 두 번 만나지 않도록 하는 것이 목표입니다. 모델이 데이터의 여러 측면을 학습하면 일반화에 도움이 될 것입니다.
케라스에서는 ImageDataGenerator가 읽은 이미지에 여러 종류의 랜덤 변환을 적용하도록 설정할 수 있습니다. 예를 먼저 만들어 보죠.