echo -n | openssl s_client -connect 접속하고자하는주소:443 | \
  sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | \
  sudo tee -a '/usr/local/share/ca-certificates/download_01_org.crt'
sudo update-ca-certificates
# summarize history for accuracy
plt.plot(history.history['accuracy'])
plt.plot(history.history['val_accuracy'])
plt.title('model accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper left')
plt.show()
# summarize history for loss
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper left')
plt.show()

다른 AI와는 다르게, 비전과 일부 언어쪽은 헤비한 GPU서버 사용을 요구해서,

AI를 학습하다가, 조금만 깊이 들어가면 노트북으로는 어림도 없는 지경에 이르게 됩니다.

일반적인 데이터분석과는 달리, 이미지 데이터는 이미지 한장만 하더라도 많은 정보를 담고 있어서

상대적으로 학습 데이터의 스케일이 크고, 학습에 필요한 연산의 규모가 어마어마 합니다.

 

 

 

[사전조건]

간단한 파이썬,

주피터 노트북 사전설치

시프트키와 엔트를 동시에 누를 수 있는 두 손.

 

자...이제 한번 해보시죠.

이제부터의 명령어는 주피터 노트북을 실행한 상태에서, 브라우저에서 입력하는 명령어 입니다.

 

0. 개, 고양이 데이터 준비

Datasets : https://www.kaggle.com/c/dogs-vs-cats/data

 

Dogs vs. Cats

Create an algorithm to distinguish dogs from cats

www.kaggle.com

첨부 파일을 다운받아서 아래 구조로 저장을 합니다.

(jupyter notebook파일과 같은 경로에 저장하세요)

-- data ---- train (학습을 위한 고양이, 개사진 25,000장)

            |__ test1 (테스트를 위한 고양이, 개 사진 25,000장)

 

1. 우선 필요한 패키지를 설치 합니다.

keras에 대한 내용은 본 게시판 제 다른글을 읽어보면 개략적으로 나옵니다.

keras는 백엔드로 tensorflow를 사용하기 때문에, tensorflow까지 자동으로 설치가 됩니다.

그리고 학습데이터를 데이터프레임(데이터의 구조가 엑셀같은 표 형태로 구성)형태로 변환하고 연산하기 위한 pandas가 설치 되어야 하고,

배열 연산을 위한 numpy, 이미지 처리를 위한 image 패키지, 그리고 매트릭스를 그래프로 나타내기 위한 matplotlib,

마지막으로 수치연산을 위한 패키지인 scikit-learn을 설치 합니다.

 

2. warning 출력 off

주피터 노트북 셀 실행시 주황색으로 warning이 많이 뜨는데, 보기 싫으니 출력하지 말라고 합니다.

 

3. 필요한 패키지 import

본 알고리즘 실행에 필요한 패키지들을 import하고,

0번에서 압축 푼 데이터가 잘 저장 되어 있는지 확인 합니다.

 

4. 글로벌 변수를 선언 합니다.

앞서 압축 풀어놓은 이미지의 가로크기, 세로크기, 사이즈(128x128)와

채널(칼라 사잔이므로R, G, B세개)을 정의 해 놓습니다.

나중에 convolution연산 시 channel정보가 필요하므로, 미리 정의해 놓습니다.

 

5. 파일명과 정답 설정

압축 푼 디렉토리 중, train디렉토리에는 dogxxx.jpg, catxxx.jpg등, 개와 고양이를 파일 이름으로 구분짓도록

파일이 저장되어 있습니다.

이를 구분하여 개에 해당되는 파일명과 정답('개', 1)을, 그리고 고양이에 해당되는 파일명과 정답('고양이', 0)을

dataframe에 저장해 놓습니다.

 

6. 저장이 잘 되어 있는지 확인해 봅니다.

데이터 셋의 제일 앞 5개와 제일 뒤 5개를 샘플링 해서 살펴봅니다.

파일 이름이 고양이로 시작된건 category가 0으로,

파일 이름이 dog으로 시작되는 파일은 category가 1로 잘 저장이 되어 있군요. :-)

 

7. 데이터 balance확인.

분류 문제이 있어서, 각 category별 데이터가 고루 분포가 되어 있어야 학습이 잘 됩니다.

즉, 데이터 내에 개와 고양이가 균일하게 분포가 되어 있는지 확인을 합니다.

보니까, 고르가 잘 분포가 되어 있는거 같네요.

 

8. Sample데이터 확인

데이터 디렉토리중 임의로 하나를 뽑아서 확인 합니다.

아베...아니, 개가 잘 표시 되는군요.

 

9. 신경망 모델 구성

모델 구성은...기본적인 룰이 있긴 하지만, 여러번 구조를 바꿔가며,

잘 맞추는 모델이 나올때까지 구조를 변경시키는 것 입니다.

물론, 훌륭하신 석학들이 미리 다 해보고 잘 되는 구조를 공개해 놓은걸 가져다 쓰는게 제일 좋습니다.

 

우리에겐 좋은 구조를 찾기 위한 100대이상의 GPU서버를 가진 연구실이 없기 때문이죠.

 

10. 신경망 구조를 살펴봅니다.

아래와 같은 구조로 생겼는데, 약 천이백만개의 파라미트를 학습해야 하는군요.

학습데이터(개, 고양이사진)이 제일 위로 들어와서 제일 아래로 나가는 구조 입니다.

 

제일 처음 conv2d layer의 shape를 보면 (None, 126, 126, 32) 이렇게 되어 있는데,

가운데 126, 126 숫자 두개가 바로 입력되는 개, 고양이 사진의 가로, 세로 크기 입니다.

 

제일 아래 Dense Layer에 보면 shape에 숫자 2가 있는데, 이게 바로 개냐 고양이냐 하는 두가지 케이스가

있기 때문에 shape가 2로 된 것 입니다.

 

11. 콜백 정의

음..콜백은 다 아실거고...

우선 조기종료(Early Stopping)와 학습율 하향조정을 위해 두 콜백 클래스를 import합니다.

 

12. Early Stopping 정의

Early Stopping이 뭐냐 하면...

전체 개, 고양이 데이터가지고 조금씩 나눠서 여러차례 학습을 하는데,

잘 학습되다가 어느시점 지나면 정확도가 오히려 떨어지는 case가 발생합니다.

이때 10번까지 참다가, 10번 지나서도 계속 떨어지면 고만 학습하고 그 결과를 내라는 말 입니다.

 

13. Learning Rate 조정 정의

이 클래스는 학습하는 동안 정확도를 잘 감시하고 있다가 어느 기준이 되면 학습율을 조정해주는 클래스 입니다.

 

14. callback 설정

앞서 정의한 두 콜백 클래스를 callbacks에 담아 놓습니다.

15. 개, 고양이를 string으로 변환

아까 파일이름과 개인지 고양이 인지를 저장해놓은 dataframe에서

category를 개인 경우 1로, 고양이 인 경우 0으로 변경해 줍니다.

나중에 one-hot 인코딩으로 변환을 하기 위해서 입니다.

 

16. train-validation 데이터 분리

이제, train데이터중 20%를 쪼개서 학습중 파라미터 검증을 위한 validation셋을 마련해 놓습니다.

 

17. train데이터의 분포 확인

train데이터에 존재하는 개와 고양이 수를 그래프로 그려 봅니다.

 

18. validation 분포 확인

아까 잘라낸 20%의 데이터에도 개와 고양이의 분포를 확인 합니다.

19. 학습, 검증데이터의 확인

학습데이터 및 validation의 형상을 확인하고,

한번에 학습할 batch의 size를 설정 합니다.

 

20. 학습데이터 뻥튀기

아시다 시피 학습은 데이터가 많을수록 잘 될 가능성이 큽니다.

학습데이터를 augmentation해서 수를 늘립니다.

부풀리기는 이미지를 약간 회전시키거나, 줌을 하거나, 상하/좌우 반전을 시키는 방법으로 늘립니다.

 

21. Validation데이터 뻥튀기

validation이미지도 마찬가지로 작업을 해줍니다.

 

22. 샘플 확인

위에 데이터 부풀리기가 잘 되었는지 확인하기 위한 부풀리기를 수행합니다.

 

23. 이미지 확인

작업된 이미지를 확인 해 봅니다.

자세히 보면 같은 개인데, 좌우 반전이나 줌이 되어 있는걸 볼 수 있죠.

 

24. 학습시작

자, 이제 학습을 해봅시다.

GPU서버에서 한 Epoch당 대략 5분정도가 걸린거 같습니다.

회사에서 지급된 노트북으로는 15분에서 30분 걸립니다. (곱하기 50번을 해야 함)

휴가 갈때 걸어놓고 가시길...

 

학습이 잘 되었고 31번째 Epoch에서 ReduceLROnPlateau콜백이 일어났군요.

1e-50 학습율에 도달한 모양입니다.

 

25. 모델 저장

학습이 끝나면, 제일먼저 할일은 모델을 저장하는 것입니다.

모델을 저장해 놓으면, 다음에 24번의 오래오래 걸리는 학습 단계를 생략할 수 있습니다.

 

26. 학습 내용 확인

이제 그동안 학습시킨 내용을 확인해봐야겠죠.

train loss, validation loss와 train accuracy, validation accuracy 그래프를 그려봅니다.

 

27. 그래프 확인

아주 예쁘게 잘 확인 된거 같습니다.

파란색 그래프는 학습할때의 그래프고, 빨간색은 validation 그래프 입니다.

첫번째 그래프를 보면 처음 학습시점에는 오답율이 높다가, 점점 학습을 지속할 수록

오답이 낮아지죠. 그리고 validation도 잘 낮아지고 있습니다.

 

두번째 그래프는 정확도인데,

마찬가지로 처음 학습 시점에는 정확도가 낮다가 점점 잘 맟춰가는걸 볼 수 있습니다.

 

중간중간 튀는 부분은 아마도, 개같은 고양이나 고양이짓을 하는 개가 섞여있는거 같습니다.

그래도 train, validation의 차이가 크지 않아서 overfitting이 일어나지 않은것 같네요.

학습도 잘 되었구요.

 

 

28. Test

이제 학습된 모델을 가지고 test데이터를 한번 맞춰봅시다.

test1 디렉토리에 있는 개와 고양이 사진으로 한번 평가를 해 봅니다.

 

29. 평가 데이터 준비

테스트 데이터와 validation데이터와 마찬가지로 데이터를 준비 합니다.

 

30. 모델 예측

아까 학습한 모델로, 위에서 생성한 test 셋을 넣어 봅니다.

 

31. 평가 생성

prediction의 결과는 각 record별, 개일확율 얼마, 고양이일 확율 얼마 이런식으로 결과가 담겨져 있습니다.

편의성과 정확도 검증을 위해 개와 고양이일 확률중 보다 큰값에 해당하는 레이블을 선택해서 값을 치환합니다.

(개일 확율 0.73, 고양이일 확률 0.27이면, '개'의 label인 dog을 넣습니다.)

 

 

32. 레이블 변환

평가를 위해서 dog, cat 이렇게 들어가 있던 데이터를 다시 1, 0으로 변경합니다.

 

33. 정답비율 확인

개와 고양이를 어느정도 비율로 예측했는지 한번 살펴 봅니다.

 

34. 정답 확인

예측한 결과를 눈으로 확인해 봅니다.

잘 맞추네요...

 

실제로는 더 좋은 모델을 찾기 위해 인고의 시간(몇시간, 몇일씩)을 반복적으로 참아내며

기다리는 인내의 싸움인거 같습니다.

 

노트북으로 한번 돌려보시면...

AWS나 GCP같은 서비스가 얼마나 고마운지 뼈저리게 느끼실 겁니다. ^^

이번 Tensorflow Summit 2019에서 Tensorflow 2.0 alpha버전이 공개 되었는데요,

기존에 tensorflow를 사용해서 딥러닝을 개발하던 사람이라면,

체감할 수 있는 확 바뀐 부분이 많이 있습니다.

 

이러한 부분에 대해 간단히 소개하고자 합니다.

 

우선, 기본적으로 tensorflow의 동작에 대해 간단히 말씀드리면,

 

1. 학습할 데이터셋 준비

2. 데이터셋을 담을 Computational Graph 준비(tf.placeholder)

3. 가중치랑 바이어스를 담을 Computational Graph 준비(tf.Variable)

4. 손실함수 정의

5. 손실함수를 최소화 해주는 Optimizer정의

6. tf.Session정의

7. Session내에서 파라미터 값 초기화(tf.global_variable_initializer())

8. 학습 수행

9. 평가

10. 예측

 

이러한 단계로 이루어져 있습니다.

 

여기서 computational graph란, 매트릭스 형태의 데이터를 '노드'란 곳에서

계산을 하는 형태를 그래프로 표시한 것 입니다.

 

나름 합리적인 방식이긴 하지만,

여기에는 맹점이 있습니다.

 

바로, define단계에서는 아무것도 실행되지 않는다는 점이죠.

 

아래 예를 볼까요?

 

>> a = 2

>> b = 3

>> c = a + b

 

이 예제에서 a = 2를 정의하는 순간

이미 a라는 변수에는 2의 갑이 할당이 됩니다.

c도 c = a + b 를 수행하는 순간 이미, c에는 5란 값이 들어가겠죠.

 

그런데, 이를 tensorflow의 computational graph로 생성하면,

a = tf.constant(1)

b = tf.constant(2)

 

이런식으로 정의를 하죠.

이때 a의 값을 찍어보면 1이 나오지 않습니다.

그냥 1이란 값이 할당 된 computational graph가 하나 표시될 뿐이죠.

 

Tensor("Const:0", shape=(), dtype=int32)

 

tensorflow에서는 session이란걸 생성해서 실행해야만 해당 되는 연산이 실행 됩니다.

 

이게, '업계'에서는 나름 큰 이슈였습니다.

'지연실행'이라고 하는 문제 입니다.

 

수십계의 계층을 쌓아올린 신경망을 실행할 때,

tensorflow는 이러한 computational graph를 초기에 구성하느라

실행속도가 엄청 느리는 현상이 있었습니다.

 

딥러닝 엔지니어의 불만이 극에 달했었었죠.

 

중원의 딥러닝에는 여러 계보(?)가 있습니다.

 

구글의 텐서플로 파, 프랑소와 숄레의 케라스 파, 그리고 페이스북의 파이토치 파...

이외에도 아파치의 MXNET부터 MS의 CNTK등 ....

수만은 파가 중원에 존재 하고 있습니다.

 

이중 주류는 아무래도 텐서플로, 케라스, 파이토치가 가장 많은 무림의 세력을 차지 하고 있습니다.

텐서플로 >>>>>>>>>>케라스>>>>>>파이토치 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>잡다구리(잡다구리파에겐 죄송합니다...)

대략 개인적으로는 이런 느낌이지 않을까 하는 개인적인 생각입니다.

 

텐서플로는....

아무래도 딥러닝 프레임워크의 초기 주류 이다보니...

그 비급에 아무래도 헛점도 많고, 비급을 익히기에도 기존 프로그래밍의 패러다임과 많이 달라서

익히기에 많은 시간과 내공이 필요했습니다.

 

이에 불만을 품은 프랑소와 숄레는 분파를 결정했죠. 바로 케라스 파 입니다.

처음 딥러닝에 입문하거나 기존 비급을 익히다 주화입마에 걸린 이들도 쉽게 익힐 수 있는,

아주 쉬운 비급을 창시합니다.

 

다만 케라스는 내부적으로는 기존의 텐서플로, 씨아노, CNTK등의 비기를 그대로 이용합니다만,

익히는 사람은 이런걸 알 필요가 없는 신박한 비급이었습니다.

 

텐서플로에는 복잡 다양하고, 입력 데이터의 차원을 맞춰주어야 하는 등

귀찮고 어려운 절차가 있었지만,

케라스는 그냥 턱턱 신경망을 쌓아놓기만 하면 자동으로 알아서 array의 차원을 맟춰주는

신박한 기능이 있습니다.

 

케라스는 나오자 마자 선풍적인 인기를 끌었고, 현재는 대략 중원에서 두번째정도 되는

주류로 급 상승 합니다.

 

그런데!!!

 

텐서플로파의 장로가 케라스의 비급을 수용하기로 한 것입니다. 바로, tensorflow 2.0에서 말이죠.

이제, 텐서플로의 파도 기존의 익히기 힘들고 주화입마에 빠지기 쉬운 비급 대신에,

표준으로 Keras라는 high level API를 그대로 tensorflow에서 쓸수 있게 된 것입니다.

 

아래 예시를 한번 보시죠.

 

먼저 Tensorflow 소스 입니다.

 

 

흐..보기만 해도 주화입마에 걸릴것 같은 복잡함이 있죠.

 

아래는 케라스 소스 입니다.

 

뭔가 나름 깔끔해 보입니다.

 

이러한 접근 용이성과 빠르게 prototyping할 수 있는 강점 때문에,

금번 Tensorflow 2.0에서는 Keras를 표준 API로 확정한 거죠.

 

기존에 Keras파들에겐...

비급을 잘 익히고 있는데 항상 어디가나 비주류라는 핸디캡을 마음속에 안고 살고 있다가

한 순간에 주류로 편입이 되어버린 상황입니다.

이제 주막에 가도 비주류라는 놀림을 받지 않죠.

 

기존의 Keras 소스코드에 tf만 붙이면 대부분 잘 돌아갑니다.

 

예를 들자면,

import keras.layers.Sequential

 

이러한 소스를,

import tf.keras.layers.Sequential

 

이렇게만 바꿔주면 대부분 잘 돌아갑니다.

 

잠깐. 여기서...

위에 글만 보면 keras가 별도의 파 인듯 보입니다.

keras는 단독으로 돌아가는 api가 원래 아니었습니다.

keras 창시 초기부터, backend로는 tensorflow나, 지금은 멸문화 되어가는 theano, cntk 등을 사용하는

api였습니다.

 

무슨말인고 하니, 이전 편에서 얘기한 computational graph, tensor 연산, session등의

저수준 작업들을 wrapping해서, 좀더 우아해보이는 작업으로 잘 포장했다는 말 입니다.

 

keras에서 우아하게 model.fit 하지만,

실제로는 내부적으로는 tensorflow에서 session을 생성하고, global variable들을 초기화 하고, computational graph를

compile하고, session을 실행하는 등의 저수준 작업을을 한다는 말 입니다.

 

좀더 deep해지는 deep learning이나, 가끔은 이러한 저수준 작업을을

직접 제어해야 할 때가 있지만, 평소에는 우아하게 model.fit하는 keras를 사용하면 됩니다.

 

 

음..쓰다보니...

중딩때 수업시간에 몰래보던 영웅문이 생각이나서

무협스럽게 쓰다보니 글이 조잡해졌네요.

 

이번시간에는...진짜로 Tensorflow 2.0에 대해서 바뀐점을 말씀드리겠습니다.

 

1번. 우선!!!

잡스런 API들을 죄다 정리했습니다.

 

기존 1.x 버전에서는 같은 기능을 구현하기 위해서 다양한 구현 방법이 존재했었으나,

2.0에는 구현하는 가장 좋은 방법 하나만을 놔두고 싸그리 정리했습니다.

입문하는 사람이나, 기존에 구현하던 개발자도 다른 구현소스를 보고 혼동이 올 일이

많이 적어졌습니다.

 

다만...기존 사용자를 위해 호환성이 필요한 부분은 남겨뒀습니다.

tf.compat.v1 패키지 아래, 기존에 쓰던 패키지들이 남아 있습니다.

 

2번. Eager Execution 모드 도입

1편에서 잠깐 소개드렸다시피, tensorflow 구버전에서는 뭔가를 실행하거나 하려면

먼저 computational graph를 생성하고, 이를 session을 생성해야만 그 결과를 볼수 있다고

설명드린 바 있습니다.

 

tesorflow 1.x 에서는 덧셈을 아래와 같이 session을 실행해야만 결과를 볼 수 있었습니다.

 

뭔가, 인간의 의식 흐름하고도 잘 안맞죠?

 

tensorflow 2.0에서는 선언 즉시 실행되는 eager execution모드가 default로 되었습니다.

요렇게 간단하게 평상시 파이썬 쓰듯이 쓰면 되죠...

 

이렇게 바뀌면서...

 

기존에 tf.Session()는... 골방(tf.compat.v1)으로 쫓겨났습니다.

기존 방법대로 session을 쓰시고 싶으신 분들은 저기 골방을 찾아 가시면

tf.Session()이 골방을 지키고 있습니다.

 

 

3번. AutoGraph

기존에 session기반의 function은 그대로 사용할 수 있는데,

function 앞에 tf.function 데코레이터만 붙이면, 자동으로 computatioal graph를

생성해 주어, 바로 사용 할 수 있게 됩니다.

 

 

여기서 autograph기능이 나오는데,

Autograph는 funciton 앞에 @tf.function이란 decorator를 붙임으로써

생성이 됩니다. 그런데 단순히 이 function뿐만 아니라,

function 내부에서 call하는 다른 function도 자동으로 computaional graph를 생성해 줍니다.

 

 

deep_next(x)란 function 앞에 @tf.function이란 decorator가 있죠?

저 decorator 덕분에 deep_net은 당연히 computational graph가 자동으로 생성이 되고,

저 deep_net내부에서 호출하는 linear_layer() 함수까지도 자동으로 computational graph를 생성해 줍니다.

 

(저는...이런 방식을 안써봐서 저게 왜 편한지 사실 감이 잘 안옵니다...-_-;;;)

 

4번. High Level API

 

아래 두 소스를 보고 다른점을 찾아보세요.

 

왼쪽은 tesorflow 1.x의 소스이고, 오른쪽은 tensorflow 2.0의 소스 입니다.

 

정답은...

왼쪽은 tensorflow가 high level api를 도입한건 17년 말 부터여서

두 소스는 같습니다만,

 

2.0이 나오기 전 소스는 내부적으로는 tf.Session()을 이용하여 수행이 되고,

오른쪽의 tensorflow 2.0소스는 내부적으로도 eager execution으로 실행이 됩니다.

(tensorflow 2.0 dev summit 2019에서 발표하여 청중들의 웃음을 자아낸 부분 입니다.)

 

그리고, tensorflow가 2.0이 되면서 머신/딥러닝 workflow에도 변화의 바람을 일으켰습니다.

 

1. tf.data를 이용하여 데이터셋 준비

2. tf.keras를 이용하여 모델 생성, 훈련, 검증

3. eager execution을 이용하여 모델 디버깅

4. 분산 traning을 이용하여 distribution strategy 사용

5. savedmodel로 모델 배포

 

아래 그림을 보시면 좀 더 쉽게 이해가 되실 겁니다.

 

 

생성된 모델은 Distribution Strategy에 의해서,

모델을 바꾸지 않고, CPU에서 실행하거나 GPU 또는 TPU에서 실행할 수 있습니다.

 

이러한 분산정책에 의해 생성된 모델은

클라우드에 온프레미스로 제공되는 tensorflow serving으로 배포되거나,

모바일 device를 위한 tensorflow인 tensorflow lite에서 사용하거나,

브라우저 또는 node.js에서 사용하기 위한 tesorflow.js,

그리고 일반적인 개발언어 기반에서 사용할 수 있는 모델로 배포를 할 수 있습니다.

 

이상으로 새로나온 tensorflow 2.0에 대한 소개를 마치겠습니다.

+ Recent posts