케라스 창시자에게 배우는 딥러닝 - 프랑소와숄레, 박해선, 길벗
읽기전
- 인공지능으로 간단하게 만들어 본게 있는데, Keras(케라스)를 이용해서 만들었다.
- 여러곳을 참고해 보니, 아예 연구자가 아닌 이상 케라스를 이용하면 왠만한건 할 수 있다는 이야기를 보았다.
- 물론 간단하게 만들어 본 것 역시 케라스를 이용해서 만들었다.
- 그래서 케라스 자체를 좀 더 알아 보는게 좋을 것이 생각해서 구매한 책.
기타
- 보통 책과 관련없는 내용은 아랫쪽에 따로 두기도 하는데..
- 책 자체에 역자가 많은 주석을 달아 두었다. 그래서 책을 읽기가 좋다.
- 대부분의 이론들이나, 전망은 걍 생략했다. 이 글을 읽는 사람이 있다면, 자세한 내용은 책을 구매해서 읽으시길...
- 초급용 책을 뗐다면, 이 책을 읽어 보는것을 추천한다. 참고로 초급용 책은 "모두의 딥러닝"을 추천한다.
책읽기
1부 딥러닝의 기초
- 이론적인 내용 생략
1장 딥러닝이란 무엇인가?
- 이론적인 내용 생략
인공지능과 머신 러닝, 딥러닝
- 인공지능 : 보통의 사람이 수행하는 지능적인 작업을 자동화 하기 위한 연구 활동
- 머신러닝 시스템은 명시적으로 프로그램 되는 것이 아니라 훈련(training) 됨
- 데이터 포인트 라는 말이 나오는데, 인공지능 학습에 사용되는 데이터들을 데이터 포인트 라는 용어로 잘 사용하더라. ( 직전에 읽은, 피처 엔지니어링 책에서도 데이터 포인트 라는 용어를 사용했던것 같다. )
- 표현(representation) : 머신러닝과 딥러닝의 핵심 문제ㄴ,ㄴ 입력 데이터를 기반으로 기대 출력에 가깝게 만드는 유용한 표현을 학습하는것.
- 핵심은 데이터를 인코딩하거나 묘사하기 위해 데이터를 바라보는 방법
- 이미지가 RGB 혹은 HSV로 바뀌는것도 표현이 바뀌는것
- 2차원 데이터 포인트들에서, 좌표를 변환하는것.
- 시스템적으로 데이터 포인트를 잘 구분할 수 있도록, "학습"시킬 수 있다.
- 이 과정중 일부는 기계가 "학습"하기 쉽게, 사람이 먼저 "피처 엔지니어링"을 해야 할 수도 있겠다.
- 뉴럴넷은 뇌구조를 이해하는것에 영감을 만들어 진 것이다. 진짜 사람의 뇌가 그렇게 동작한다는 근거는 없다.
딥러닝 이전: 머신 러닝의 간략한 역사
- 확률적 모델링
- 통계학 이론을 데이터 분석에 응용
- 나이브 베이즈 알고리즘
- 입력 데이터의 특성이 모두 독립적이다고 가정
- 고전적인 방법이라, 컴퓨터 등장전에는 수작업으로 적용
- 로지스틱 회귀
- 회귀 알고리즘이 아니라, 분류 알고리즘
- 초창기 신경망
왜 딥러닝일까? 왜 지금일까?
- 20년 후에도 심층 신경망을 사용하고 있을까요? ... 지금부터 20년 후에는 신경망을 사용하지 않을지도 모르지만, 딥러닝과 딥러닝의 핵심 개념에서 직접 파생된 무엇인가를 사용할 것입니다.
2장 시작하기 전에: 신경망의 수학적 구성 요소
- 내용 생략
신경망과의 첫 만남
- 내용 생략
신경망을 위한 데이터 표현
- 내용 생략
신경망의 톱니바퀴: 텐서 연산
- 내용 생략
신경망의 엔진: 그랜디언트 기반 최적화
- 내용 생략
첫 번째 예제 다시 살펴보기
- 내용 생략
요약
- 내용 생략
3장 신경망 시작하기
- 내용 생략
신경망의 구조
- 내용 생략
케라스 소개
- 케라스는 MIT 라이선스를 따르므로 상벚거인 프로젝트에도 자유롭게 사용할 수 있습니다.
- 최근 딥러닝 프레임워크의 순위는 텐서플로우, 케라스 파이토치 순임.
- 케라스는 고수준 구성 요소를 제공. 백엔드로는 텐서플로우, 씨아노, CNTK 3개의 엔진을 골라서 사용할 수 있음.
- 케라스로 모델을 만드는 법
- Sequential 클래스를 이용해서 순차적으로 쌓아 올리는 방법
- 함수형 API를 사용해서, 임의의 구조를 만들 수 있는 방법
딥러닝 컴퓨터 셋팅
- 내용 생략
영화 리뷰 분류: 이진 분류 예제
- 내용 생략
뉴스 기사 분류: 다중 분류 문제
- one hot encoding되어 있는 데이터라면 loss에 categorical_crossentropy를 사용하면 되고, 그렇지 않고 숫자로 라벨링 되어 있는 경우라면, loss에 sparse_categorical_crossentropy를 사용하면 된다. 굳이 바꿀 필요 없음.
- 충분히 큰 중간층을 두어야 하는 이유
- 마지막 출력이 46차원이기 때문에 중간에 히든 유닛이 46개 보다는 많이 적어서는 안된다. 책에서는 중간에 4차원을 두었는데, 이렇게 두어도 아예 안 되진 않지만, 4차원으로는 정보를 충분히 표현할 수 없어 79%에서 71%로 8% 정도 정확도가 감소한다.
- 4차원에 대부분의 정보를 넣었겠지만, 그래도 다 넣지는 못한 것으로 생각할 수 있다.
주택 가격 예측: 회귀 문제
데이터의 피쳐가 여러 범위를 가지고 있다. 이때는 데이터를 균일한 범위로 맞춰 주는것이 중요하다. 안되지는 않겠지만, 피쳐의 중요도를 떠나, 그냥 숫자가 클 경우 곱셈을 하게 되면 큰 변화량을 가지게 될 것이다. ( 피쳐엔지니어링 책 참고 )
데이터를 정규화하는 방법
피처의 평균을 빼고, 표준편차로 나누는 방식
피처의 중앙이 0 근처에 맞추어지고, 표준편차가 1이 된다.
mean = train_data.mean(axis=0) train_data = train_data - mean std = train_data.std(axis=0) train_data = train_data/std test_data = test_data - mean test_data = test_data/std
일반적으로 훈련 데이터의 개수가 적을수록 과대적합(오버피팅)이 더 쉽게 일어나므로 작은 모델을 사용하는 것이 과대적합을 피하는 한 방법입니다.
모델의 마지막은 1개의 유닛을 가지고 있고, 활성화 함수가 없음. 전형적인 스칼라 회귀(하나의 연속적인 값을 예측하는 회귀)를 위한 구성.
loss = mse : 평균 제곱 오차. 회귀 문제에서 널리 사용되는 손실 함수.
metrics = mae: 평균 절대 오차. 예측과 타깃 사이의 거리 절대값. 0.5면 평균적으로 500달러 차이 난다는것.( 1 = $1000 기준 )
데이터량이 너무 작으면, validation set도 아까우니깐, k-겹 검증 적용
- K-fold cross-validation : 데이터를 4덩이로 나눈다면
- 0, 1, 2 는 학습용으로, 3은 검증용으로
- 0, 1, 3 은 학습용으로, 2는 검증용으로
- 0, 2, 3 은 학습용으로, 1은 검증용으로
- 1, 2, 3 은 학습용으로, 0은 검증용으로
- 모두 loop를 돌고 나면 각 검증용으로 사용했던 0, 1, 2, 3 의 결과를 평균내서 검증의 최종 값으로 사용.
- 중요한건, 각 학습을 할 때 validation set의 데이터를 참고하지 않았다는 점이다.*
- 하지만, 코드를 따로 짜야하는 불편함이... 그냥 데이터를 많이 만들어 두고 쓰자. ㅎ.
요약
- 내용 생략
4장 머신 러닝의 기본 요소
머신 러닝의 네 가지 분류
머신 러닝 모델 평가
- 반복 K-겹 교차 검증 : k-겹 교차 검증과 동일하나, 반복시마다 데이터를 섞은 뒤에 다시 k 개로 나누고 학습 시키는것을 반복한다.
- 평가 방식을 선택할 때 다음의 사항을 유의 해야 함.
- 대표성 있는 데이터 : 훈련 세트와, 테스트 세트가 주어진 데이터에 대표성이 있어야 함. 한쪽으로 쏠려 있는 데이터라면 당연히 잘못 훈련이 될 것이고 테스트도 잘못 될 것이다. 일반적으로는 데이터를 무작위로 섞어 쓰는것이 일반적.
- 시간의 방향 : 과거로부터 미래를 예측한다면, 당연히 데이터를 섞으면 안된다.
- 데이터 중복 : 같은 데이터가 여러개가 있는 경우, 데이터를 섞어서 훈련 세트와 테스트 세트로 만들게 되면, 훈련 세트에 있는 데이터와 테스트 세트에 있는 데이터가 동일하게 될 수 있다. 그러면 결국 테스트한 데이터가 학습 데이터에 들어 있다는 말이 된다. 그러므로 이걸 섞이지 않도록 해 주는게 중요하다.
데이터 전처리, 특성 공학, 특성 학습
- 피처 엔지니어링 관련 내용 : 관련 내용은 다른 책을 참고하자. ㅎ
- 벡터화 : 모든 데이터를 숫자형태(int나 float)로 바꿔야 한다.
- 값 정규화 : 스케일이 다른 값들을 일정한 범위로 바꿔 줘야 한다. 스케일이 너무 차이나면 문제가 되기 때문이다. 일반적으로 평균을 0, 표준편차를 1로 만들어주는 작업. 대부분 0 ~ 1 사이의 값을 취하도록 한다.
- 누락된 값 : 데이터가 누락된 경우에는 0이나 평균값, 중간값등으로 처리해도 크게 문제되지 않는다. ( 그 값 자체가 의미가 있지 않다면 말이다. ) 네트워크가 알아서 적당히 처리 할 것이다. (하지만... 확인해 보기 전에는 알 수 없지 않을까??)
- 특성 공학(피처 엔지니어링) : 데이터를 사용하기 전에 먼저 잘 학습되도록 적당히 바꿔 주는것.
- 이미지로 시간을 맞추는것을 한다면, 이미지를 바로 사용한다면 CNN같은걸 써야 겠지만, 단순한 이미지 처리로 바늘두개의 각도를 구할 수 있다면 더 쉽게 학습 시킬 수 있을 것이다.
- 특성을 더 간단한 방식으로 표현하여 문제를 쉽게 만든다. 이럴려면 해당 문제를 아주 잘 이해하고 있어야 한다.
- 딥러닝 이전에는 매우 중요 했음.
- 다행히 최근 딥러닝은 대부분 특성 공학이 필요하지 않습니다. 신경망이 자동으로 원본 데이터에 유용한 특성을 추출할 수 있기 때문입니다. 하지만...
- 좋은 특성은 적은 자원을 사용하여 문제를 더 잘 풀 수 있음. 시계 바늘을 읽는 문제는 굳이 합성곱 신경망(CNN)을 사용할 필요가 없음.
- 좋은 특성은 더 적은 데이터로 문제를 풀 수 있음. 딥러닝 모델은 특성을 학습할때 많은 양의 데이터가 필요함. 샘플의 갯수가 적다면 특성을 잘 뽑아내 주는게 중요함.
과대적합과 과소적합
- 과소적합 : 아직 학습할 껀덕지가 있는 상태
- 과대적합 : 학습 데이터에만 너무 집중되고 있는 상태 ( 자세한건 따로 보셈 ㅋ ). 그러므로 이걸 피해야 한다. 이렇게 피하는걸 규제(regularization)라고 한다.
- 네트워크 크기 축소
- 네트워크의 크기가 크면, 외울 수 있는 capacity가 크고, 그러므로 학습한 데이터를 모두 외워 버릴 수 있을 정도가 될 수 있다.
- 그러므로 일반화 시킬려면 오히려 네트워크를 줄여야 한다.
- 우리가 필요한것은 학습 데이터를 잘 맞추는게 아니라, 다른것도 잘 맞출 수 있도록 일반화 되어야 하기 때문이다.
- 하지만, 그렇다고 네트워크 크기를 팍 줄이면, 기억할 공간이 줄어 들기 때문에 학습이 잘 안될 거다... 그러니 절충점을 잘 찾아야 한다... (그게 쉽나.. T_T)
- 책에 나오는 실제 검증한 그래프를 보면, 네트워크가 크면 더 빨리 과대적합이 나타나게 된다.
- 가중치 규제(Weight regularization)
- 오캄의 면도날 : 어떤 것에 대한 두가지 설명이 있다면 더 적은 가정이 필요한 설명이 더 옳을 것이다.
- 네트워크의 복잡도에 제한을 두어 가중치가 작은 값을 가지도록 강제하는것. 이러면 가중치의 값의 분포가 더 균일하게 된다.
- L1 규제 : 가중치의 절댓값에 비례하는 비용이 추가 됨(가중치의 L1노름-norm). 이 경우에는 일부 가중치 값이 0이 되는 경우가 생길 수도 있음.
- L2 규제 : 가중치의 제곱에 비례하는 비용이 추가 됨(가중차의 L2노름) - 가중치의 파라미터를 모두 제곱하여 더한 후 이 값의 제곱근을 추가, 훈련할 때만 해당 값을 추가. 그러므로 테스트의 loss 값보다, 훈련할때의 loss 값이 더 커질 것임.
- L2 규제를 적용하면 좀 더 과대 적합에 잘 견딤
- L1 규제와 L2 규제를 같이 쓰는것을 엘라스틱넷(ElasticNet)이라고 부름. L1, L2 모두 기본값은 0.01로 되어 있음. 책에서는 0.001을 사용하고 있음.
- 드롭아웃
- 학습시 신경망의 일부를 끄는(출력을 0으로 만듬)것. (자세한것은 생략)
- 네트워크 크기 축소
보편적인 머신 러닝 작업 흐름
- 성공 지표 선택 : "성공이 무엇인가?"를 정의하는게 중요함. 정확도? 정밀도? 재현율? 고객 재방문률? 비즈니스 성공처럼 고수준의 목표와 직접적으로 연결되어 있어야 함.
- 클래스 분포가 균일한 분류 문제에서는 정확도가 ROC AUC가 일반적인 지표
- 클래스 분포가 균일하지 않은 문제에서는 정밀도와 재현율을 사용할 수 있음.
- 랭킹 문제나 다중 레이블 문제에는 평균 정밀도를 사용할 수 있음.
- 모델에 맞는 마지막 층의 활성화 함수와 손실 함수 선택
- 문제 유형, 마지막 층의 활성화 함수, 손실 함수
- 이진 분류, 시그모이드, binary_crossentropy
- 단일 레이블 다중 분류, 소프트맥스, categorial_crossentropy
- 다중 레이블 다중 분류, 시그모이드, binary_crossentropy
- 임의 값에 대한 회귀, 없음, mse
- 0과 1 사이 값에 대한 회귀, 시그모이드, mse 또는 binary_crossentropy
요약
- 생략
2부 실전 딥러닝
- 생략
5장 컴퓨터 비전을 위한 딥러닝
- 생략
합성곱 신경망 소개
- 생략
소규모 데이터셋에서 밑바닥부터 컨브넷 훈련하기
- 데이터가 풍부할때만 작동한다는 말을 들음. 하지만 딥러닝은 특성을 찾는것이다. 그러므로 특성을 쉽게 찾을 수 있다면 많은 데이터가 필요하지 않을 수도 있다.
- 특성 앱의 깊이는 네트워크에서 점진적으로 증가하지만(32에서 128까지), 특성맵의 크기는 감소합니다. ( 150x150 에서 7x7까지 - padding이 0인 경우로 계산하면 150, 148 -> 74, 72 -> 36, 34 -> 17, 15 -> 7 이 된다.). 이는 거의 모든 컨브넷에서 볼 수 있는 전형적인 패턴입니다.
- 케라스에는 이미지를 쉽게 처리하기 위한 유틸리티가 존재한다.
keras.preprocessing.image
keras.preprocessing.image.ImageDataGenerator
Generator
를 만들때batch_size
를 적어 두면, 전체중 그 갯수 만큼이 반환된다.- 나중에
fit_generator
할 때는step_per_epoch
*batch_size
가 전체가 되도록 만들어 주어야 한다. - 리스트와 달리 반복자와 제너레이터는 전체 항목을 미리 만들지 않기 때문에 메모리에 효율적입니다.
- 데이터 증식(data augmentation - 데이터 오그멘테이션)
- 데이터의 숫자가 너무 작으면 데이터 갯수를 늘려주는것이 좋다.
ImageDataGenerator
에서 아래 옵션을 주면, 속성에 맞게 이미지를 더 생성한다.rotation_range
: 랜덤하게 사진을 회전(0~180)width_shift_range
: 이미지를 평행 이동 (1 이하면 비율, 이상이면 pixel)height_shift_range
: 이미지를 수직 이동 (1 이하면 비율, 이상이면 pixel)sher_range
: 이미지를 비뚤게 회전 시킬 각도 범위zoom_range
: 확대할 범위horizontal_flip
: 이미지를 수평 대칭 변환 ( 얼굴, 풍경 등, 글자가 있는것은 수평 대칭 변환하면 안됨 )fill_mode
: 회전, 가로/세로 이동시 새롭고 생긴 픽셀을 채울 전략
- 검증 데이터셋은 데이터 증식(data augmentation)을 하면 안됨. 오직 학습 데이터 셋에서만 할 것.
사전 훈련된 컨브넷 사용하기
- 데이터 셋이 너무 작으면 어차피 잘 안되니깐, 이미 많은 양의 데이터로 만들어진 잘 학습된 모델을 활용해서 해보자는 방법.
- 많은 양의 데이터로 잘 학습된 모델은, 내가 필요로하는 특성을 정확하게 잘 찍어 낼 순 없겠지만, 일반적인 특성은 잘 찍어 낼 수 있을 것이므로 이걸 활용하는것이 더 좋을 것임.
- 실제 필요한것과는 다를지라도, 이론적으로는 효율적임.
- 책에서는 VGG넷을 사용함. VGG16은 최신것도 아니고, 제일 좋은것도 아니지만, 이 모델 구조가 이전에 보았던것과 비슷해 새로운 개념을 도입하지 않고 이해를 쉽게 할 수 있기 때문에 사용.
- 일반적으로는 합성곱(Convolution)부분만 재사용함.
- 합성곱 층은 "학습된 표현이 더 일반적이어서 사용 가능" : 아마도, 합성곱층은 이미지 필터를 거치면서 나오는 특징을 그대로 쓰고, 같은 이미지 필터를 여러곳에서 사용할 수 있기 때문이라고 보임.
- 하위층은 엣지, 색깔, 질감등의 특성을 뽑고,
- 상위측은 눈이나 귀처럼 추상적인 개념을 추출
- 만약, 새로운 데이터셋이 학습된 모델의 데이터셋과 많이 다르다면, 하위층만을 사용하는것도 하나의 방법.
- 재사용시
trainable
값을False
로 줘서, 사전 학습된 표현이 업데이트 되지 않도록 하는것이 중요함.
- 미세 조정(파인튜닝 - fine tuning)
- 이전에는 학습된 모델의 top만 제거하고, 새로운 layer를 붙여서, 새 layer만 학습하는 방식으로 재활용 했다.
- 하지만, 동결 시켜 두었던 부분도 일부를 학습 시키는 방법을 쓸 수도 있다.
- 사전에 훈련된 기반 네트워크 위에 새로운 네트워크 추가
- 기반 네트워크 동결 후, 새로 추가한 네트워크 훈련
- 기반 네트워크에서 일부 층을 동결 해제 한 후, 새로 추가한 네트워크와 같이 학습
- 합성곱의 하위층은 일반적이고, 재사용가능한 특성을 학습하므로 그대로 사용하고, 상위층은 특화된 특성을 인코딩하므로, 이 부분만 다시 학습 시킨다.
- 손실 곡선이 향상되지 않았으나, 정확도가 높이진 이유?
- 손실 값 그래프는, 각 손실의 평균이다. 그러므로 전체의 정확도와는 별개이다. 손실 값이 큰것들은 아예 많이 커져 버리고, 나머지는 손실값을 줄이고 잘 맞추게 업데이트 된다면, 손실 값의 평균은 유지 되면서, 정확도는 높아 질 수 있다.
컨브넷 학습 시각화
- 생략
- CAM 을 사용하면, 이미지의 어느 위치가 분류에 영향을 미쳤는지 알 수 있다.
- 생략
요약
- 생략
6장 텍스트와 시퀀스를 위한 딥러닝
- 텍스트(단어의 시퀀스), 시계열 또는 이반적인 시퀀스를 처리 할 수 있는 모델을 살펴 볼 것임
- 시퀀스 데이터를 처리하는 기본적인 모델
- 순환신경망(recurrent neural network, RNN)
- 1D 컨브넷(1D convnet)
- 시퀀스 데이터 형태로 처리하는 것들
- 문서 분류나 시계열 분류, 글의 주자네 책의 저자 식별
- 시계열 비교, 두 문서의 관련성, 주식 가격의 관련성
- 시퀀스-투-시퀀스 학습, 영어 문장을 프랑스어로 번약하기
- 감성 분석. 트윗이나 영와 리뷰가 긍정적인지 부정적인지 분류하기
- 시계열 예측. 최근 어떤 지역의 날씨가 주어졌을때, 날씨 예측하기
- 책에서는 IMDB의 감정분석과, 기온 예측만 집중하여 볼 것임.
텍스트 데이터 다루기
문서 분류, 감성 분석, 저자 식별, (제한된 범위의) 질문 응답 등에 적합
이런 딥 러닝 모델이 사람처럼 진짜 텍스트를 이해하는것은 아님
문자 언어(written language)에 대한 통계적 구조를 만들어 간단한 텍스트 문제를 해결 하는 것임.
컴퓨터 비전이 픽셀에 적용한 패턴인식인 것처럼, 자연어 처리를 위한 딥러닝은 단어, 문장, 문단에 적용한 패턴 인식
텍스트 역시, 그대로 사용하지 못하고 숫자 형태로 바꿔 줘야 함.
텍스트를 숫자 형태로 바꾸는것을 텍스트 벡터화(vectorizing)이라고 함
- 텍스트를 단어로 나누고, 각 단어를 하나의 벡터로
- 텍스트를 문자로 나누고, 각 문자를 하나의 벡터로
- 텍스트에서 단어나 문자 n개를 뽑은 뒤에, 그 조합을 벡터로
- 텍스트를 일정 기준으로 나눈것을 토큰이라고 함. 이런 토큰을 잘 처리해서 벡터를 만들 수 있음.
원핫인코딩
- 텍스트도, 단어별로 쪼갠 뒤, 각 단어를 원핫인코딩으로 바꿀 수 있다.
- 원핫인코딩으로 바꿀때, 텍스트가 아닌 경우를 대비하여 1개를 비워 두는 센스를 발휘하자.
keras.preprocessing.text.Tokenizer(num_words=1000)
을 사용하면, 가장 빈도가 높은 1000개 단어만 사용하도록 할 수 있음.- 원핫해싱이라고, 인덱스를 따로 설정하지 않고, key를 value의 hash 값을 사용하도록 한다. 바로바로 데이터를 찍을 순 있겠지만, hash 된 값이 겹쳐 버리는 문제가 발생할 수 있다.
단어 임베딩(워드 임베딩, word embedding)
- 책에서는
밀집 단어 벡터(word vector)
이라고 적혀 있는데, 전체를 영어로 적으면dense word vector
이다.dense
를 보통 밀집이라고 해석하는데,의미 없이 공간을 차지하는 정보가 없는
정도로 해석하면 좋겠다. 원핫인코딩의 경우 많은 값들이 0 이고, 딱 1개만 1이기 때문에 0은 의미가 없다(이런 애들을희소(sparse)
하다고 한다). 그러므로, 14번째 위치에 1이 있다고 표현하는 ( 14, 1 ) 이라고 표현하면dense
하게 표현되었다고 볼 수 있다. keras.layers.Embedding(1000,64)
는, 1000개의 단어를 64차원으로 표현하겠다는 것이다.- Embedding을 만들고, dense를 만들어 붙인 후에 데이터를 fit으로 때려 박으면, 알아서 잘 분리한 vector가 만들어 진다.
- 임베딩 알고리즘에는 Word2Vec나 GloVe 같은게 있다.
- 당근, 데이터셋이 작다면, 사전 학습된 모델을 읽어와서 재활용하고, 필요한 부분만 덧붙여 쓰는게 좋다.
순환 신경망 이해하기
- 책에서는
RNN, LSTM 설명, 생략.
순환 신경망의 고급 사용법
- 순환 드롭아웃 : 순환층에서 과대적합을 방지하기 위해 사용. 케라스에 내장되어 있음. ( GRU나 LSTM에
dropout
값을 줄 수 있음 ) - 스태킹 순환 층 : 순환층의 마지막 노드의 결과만 내 뱉는게 아니라, 모든 노드의 결과를 연결해 주는 형태 (
return_sequences
값을 이용해서 처리 할 수 있음 ) - 양방향 순환 층 : 데이터를 a, b, c, d 순으로 입력하던것을 d, c, b, a 순으로도 입력하는 branch 층을 만든다.
컨브넷을 사용한 시퀀스 처리
- 벡터를 RNN으로 계속 순환 시킬것이 아니라, CNN 1D로 계산하는 방식
- CNN으로 계산하면 훨씬 속도가 빨라진다.
- 1D CNN으로 특징을 먼저 뽑아내고, RNN을 돌릴 수도 있다.
7장 딥러닝을 위한 고급 도구
Sequential 모델을 넘어서: 케라스의 함수형 API
기존에는 순차적으로 연결한 모델만 만들 수 있었다.
하지만, 함수형 API를 사용하면, branch를 만들거나, merge 할 수 있다.
일반적인 Sequence Model을 함수형 API로 표현
input_tensor = Input( shape=(64,) ) x = layers.Dense(32, activation='relu')(input_tensor) x = layers.Dense(64, activation='relu')(x) output_tensor = layers.Dense(10, activation='softmax')(x) model = Model(input_tensor, output_tensor)
2개 이상의 vector을 받아서, 1개의 출력으로 내는 경우
text_input = Input( shape=(...) ) embedded_text = layers.Embedding(....)(text_input) encoded_text = layers.LSTM(...)(embedded_text) ques_input = Input( shape=(...) ) embedded_quest = layers.Embedding(....)(ques_input) encoded_ques = layers.LSTM(...)(embedded_ques) concatenated = layers.concatenate([encoded_text, encoded_ques], axis=-1) answer = layers.Dense(64, activation='softmax')(concatenated) model = Model ( [text_input, ques_input] , answer ) model.compile( optimizer='rmsprop', loss='categorical_crossentropy' ) # 1개의 output이므로 optimizer나 loss 는 1개 만 설정하면 된다. model.fit ( [text, ques], answer, ... ) # 2개의 Input과 1개의 Output이다.
2개 이상의 출력을 내는 경우
# 나머지는 비슷하게 하고, 제일 마지막 출력층에 대한 것만... age_predict = layers.Dense(1)(x) income_predict = layers.Dense(100, activation='sfotmax'(x) gender_predict = layers.Dense(1, activation='sigmoid')(x) model = Model ( input, [age_predict, income_redict, gender_predict]) # 1개의 Input과 3개의 Output에 대해서 처리해야 한다. model.compile( optimizer='rmsprop', loss = ['mse'm 'categorical_crossentropy', 'binary_crossentropy'] ) # 3개의 Output에 대한 각각의 정보가 필요하다. # 필요할 경우 compile 옵션으로 loss_weight=[1.0, 0.25, 10.] 등, loss 값에 가중치를 줄 수도 있다. model.fit ( posts, [age_targets, income_targets, gender_targets], ... ) # 입력이 1개, 출력이 3개다.
인센셥 모델의 경우 branch를 따고, 합치는 과정이므로, 이 글에서는 따로 설명하지 않고 pass.
잔차연결(residual connection)
x = layers.Conv2D(...)(x) y = layers.Conv2D(...)(x) y = lqyers.Conv2D(...)(y) y = layers.add( [ y, x ] ) # 마지막 y의 특성에 x의 출력 특성을 더한다.
기존의 모델을 layer 처럼 사용 가능
xception_base = application.Xception(weight=None, include_top=False) input = Input(shape=(250, 250, 3)) features = xeception(input)
케라스 콜백과 텐서보드를 사용한 딥러닝 모델 검사와 모니터링
콜백 : 콜백을 직접 만들 수도 있지만, 이 글에서는 중요한거만...
ModelCheckpoint : epochs 마다 모델을 저장한다.
EarlyStopping : validation loss가 일정 횟수 이상, 줄어 들지 않으면 자동으로 멈춘다.
ReduceLROnPlateau : validation loss가 향상되지 않으면, 학습률을 작게 할 수 있음.
예제
callbacks_list = [ // val_acc 값이 patience 만큼 횟수의 epoch를 돌았는데도, 정확도가 늘지 않으면 멈춘다. keras.callbacks.EarlyStopping( monitor='val_acc', patience=1), // epoch 마다 my_model.h5에 저장한다. 단, val_loss 값이 줄어들지 않으면, 모델을 덮어쓰지 않는다. keras.callbacks.ModelCheckpoint(filepath='my_model.h5' , monitor='val_loss', save_best_only=True), // val_loss 값을 확인해서 10번동안 줄어들지 않으면, 학습률을 1/10 으로 줄인다. keras.callbacks.ReduceLROnPlateau( momitor='val_loss',factor=0.1, patience=10 ); ] // callback에서 val_loss 값을 사용하기 때문에, metrics에 acc 값이 포함되어 있어야 한다. model.compile( optimizer='rmsprop', loss='binary_crossentropy', metrics=['acc'] ) // epoch 마다, callbacks_list에 있는 callback들을 호출한다. 이 callback에서 val_acc 값을 사용하기 때문에, 꼭 validation_data 값이 필요하다. model.fit( x, y, epochs=10, batch_size=32, callbacks = callbacks_list, validation_data=(x_val, y_val))
텐서보드 : 텐서플로우일때만 사용할 수 있자만 참 유용함
TensorBoard : 훈련하는 동안의 지표, 모델 구조 확인, 활성화 출력, 3D 임베딩 등을 쉽게 볼 수 있음
예제
callbacks = [ // 학습 로그는 my_log_dir에 남기며, 1 epoch마다, 활성화 출력과 임베딩 데이터를 기록. keras.callbacks.TensorBoard( log_dir='my_log_dir', histogram_freq=1, embeddings_freq=1 ) ]
python 코드를 실행 시킨 후 shell에서
tensorboard --logdir=my_log_dir
실행후, http://localhost:6006 에 접속하면 볼 수 있음.
모델 시각화
TensorBoard를 사용하면 모델 시각화를 할 수 있지만, tensorflow의 모델 형태로 나오기 때문에 보기가 어렵다.
케라스 모델을 쉽게 볼 수 있게 이미지로 만들 수 있는 방법도 있다.
from keras.utils import plot_model // 케라스 모델인 model을 보기 쉽게 model.png 파일에 이미지로 떨어뜨려 준다. // show_shapes = True, layer의 input과 output의 shape을 같이 보여준다. // show_layers_name = True, layer 이름을 같이 보여 준다. // rankdir = TB | LR, TB면 수직으로, LR 수평으로 그려준다. plot_model ( model, to_file='model.png', show_shapes=True )
모델의 성능을 최대로 끌어올리기
배치 정규화
배치 정규화를 사용하면 더 깊은 네트워크를 구성할 수 있다.
BatchNormalization은 일반적으로, 합성곱이나 환전 연결층 다음에 사용함
conv_model.add( layers.Conv2D(32, 3, activation='relu') ) conv_model.add( layers.BatchNormalization() ) dense_model.add( layers.Dense(32, activation='relu') ) dense_model.add ( layers.BatchNormalization() )
배치 정규화클래스는 특성 축을 지정할 수 있는 axis 매개 변수가 있음. ( 기본값 -1, 입력텐서의 마지막 축 )
data_format을 "channels_last"로 하여, Dense, Conv1D, ENN, Conv2D 층을 사용할 때 맞는 값.
data_format이 "channels_first"라면, 특성축이 1이므로, axis=1 로 주어야 함. ( 0번째 축은 "배치"차원 축 )
깊이별 분리 합성곱 ( depthwise separable convolution )
- Conv2D 보다 가볍고, 빠르다. 성능도 좋다.
- 적은 데이터로도 좋은 표현을 학습하고, 결국 성능이 더 좋은 모델을 만듬. 제한된 데이터로 작은 모델을 만들때 중요.
- 예제는 Conv2D를 사용하는곳에 모두
layers.SeparableConv2D
를 사용하는 형태로만 바꾸면 됨.
하이퍼 파라미터 최적화
- 규칙은 없다. 자동으로 하이퍼 파라미터를 찾아주는건 연구되고 있는 과정
- 관련 라이브러리 : Hyperopt, Hyperas(Hyperopt와 연동하여 keras에서 사용가능), Auto-Keras, auto-sklearn
모델 앙상블(model ensemble)
- 하나의 목적을 가진 여러가지 모델을 만들고, 각 모델별 예측치를 평균하여 찾는 방법
- 한가지 모델은 편향되어 있을 수 있지만, 여러가지 편향을 가진 각 모델을 평균내면 오히려 더 잘 동작할 수도 있다.
8장 생성 모델을 위한 딥러닝
LSTM으로 텍스트 생성하기
- 생략
딥드림
- 내가 별로 관심이 없어서 생략. ㅎ. 책도 대충 읽고 넘김. ㅎ.
뉴럴 스타일 트랜스퍼
- 생략
변이형 오토인코더를 사용한 이미지 생성
- 생략
적대적 생성 신경망 소개
- GAN(Generative Adversarial Netowkrs)
- 모델은 크게 두가지로 나뉨. 한쪽에서는 이미지를 생성, 한쪽에서는 생성된 이미지가 진짜/가짜인지 판단
- 양쪽을 모두 학습 시킨 뒤, 생성 부분만 모델만있으면, 이미지를 생성할 수 있음.
- 대충은 아니깐, 자세한건 생략.