위 그림은 PyTorch 튜토리알에서 찾아 볼 수 있는 ConvNet 뉴럴 네트워크 다이아그램이다. COncolution+ReLU+Pooling을 2단으로 실행 후 Fully connected 레이어에 의해 최종 Class 학습을 실행한다. 마지막 Output = 10 은 CIFAR-10 예제에서 10개의 Class를 사용하기 때문일 것이다.
PyTorch 와 TensorFlow 머신 러닝과의 차이점은 Graph 생성과정이 별도로 없다는 점이지만 아래의 코드를 관찰해 보면 코드의 구조를 쉽게 파악할 수 있다. PyTorch에서도 Convolution + ReLU + Pooling 작업을 두 번 실시 후 Fully Connected Layer와 연결이 된다. Pooling 또는 Subsampling 은 같은 의미이다. 물론 PyTorch ConvNet 구조가 TensorFlow CNN
과 약간의 차이점이 있을 수 있겠지만 알고리듬은 대동소이한 듯하다.
CrossEntropyLoss() 함수를 불러 cost 함수를 구성한다. 아울러 경사하강법 적용을 위한 optim.SGD 옵티마이저를 부른다. SGD는 Stochasitic Gradient Descent를 뜻한다. 아울러 이 부분에 TensorFlow 와는 다른 파라메터 momentum 이 있음에 유의하자.
optim.SGD 는 Stochasitic Gradient Descent기법으로서 On-line 형 머신 러닝에 적합한 옵티마이저이다. 머신 러닝 코드에서 일반적으로 전체 데이터를 다 읽어 들인 후 cost 함수를 구성하여 컴퓨팅을 하지만 만약에 처리해야 할 데이터가 컴퓨터 연산 속도와 메모리 용량을 위협할 정도로 엄청나게 클 경우 치명적인 문제가 발생할 수밖에 없다.
또는 자율주행 자동차의 경우 카메라에서 포착한 영상들이 무엇인지 쾌속하게 인식하려면 빠른 통신속도로 예를 들자면 120만개의 이미지를 학습였으며 Class 수가 무려 1000 에 달하는 ImageNet과 같은 거대한 데이터베이스와 Online으로 접속 연동하여 머신 러닝 작업을 신속하게 실행해서 그 결과를 돌려받아야 한다. 이러한 경우 그때그때 온라인으로 입력된 데이터 양 만큼 Stochastic Gradient Descent 기법에 의해 업데이트 방식으로 처리하도록 한다. Stochastic Gradient Descent 기법에 의한 머신 러닝에서 학습에 따른 cost 함수의 거동을 관찰해 보면 수렴 패턴이 마이크로하게 다소 들쑥날쑥한 면이 없지는 않으나 평균적으로는 일반 Gradient Descent와 비슷하게 수렴한다. PyTorch의 예제인 CIFAR-10, Neural Networks 및 Transfer Learning에서도 다 optim.SGD 루틴을 사용하고 있다.
이들 예제에서 사용하는 학습 데이터들과 120만개 이미지 데이터를 학습한 ImageNet과 서로 Transfer Leaning을 실시하기 위해서는 결국 ImageNet 조차도 동일하게 optim.SGD로 사전학습(Pretrained)이 되어 있어야 할 것이다.
옵티마이저 설정이 끝났으면 학습 단계이다. TensorFlow 의 Session 단계에 해당하는데 실행하는 내용은 거의 비슷하겠지만 PyTorch 코드 자체 모양은 많이 달라 보인다. 초기화부터 일일이 파이선 코딩하듯이 해 주어야 하는 스타일이다.
원래 이미지 데이터 파일 자체는 대단히 많은 수의 이미지를 포함하고 있지만 모조리 다 학습시키는 것은 아니다. MNIST에서 100개씩 무작위로 선택하여 batch job을 하듯이 여기서도 2000 개 단위로 무작위 선택하여 batch job을 실행시킨다. batch job 한번 실행하는 단위가 epoch 이며 epoch를 여러 번 실행하여 평균을 냄으로서 정밀도가 올라간다는 점을 경험적으로 알고 있다.
GPU 실행 시 걸리는 시간을 측정해 보려면 코드 앞뒤에 시간 측정하는 루틴을 넣어서 실행해 보자. 사실 CIFAR-10 이미지에는 학습을 위한 5만개의 그림파일과 태스트용 이미지 1만개가 들어 있다. 이미지 크기도 MNIST 보다 크고 컬러 채널도 3이므로 그 데이터량이 MNIST 보다 엄청 크므로 구글 Colabo의 GPU를 돌려도 수분 이상의 시간이 충분히 소요된다. 쥬피터 노트북 셀 코드 블록 앞뒤에 다음 코드를 넣어서 실행 시간을 측정해 보자.
import time
start_time = time.time()
∙∙∙
end_time = time.time()
print( "Completed in ", end_time - start_time , " seconds")
미니 배치 2000에 epoch = 2 조건으로 GPU 연산 결과 113초 걸렸으며 정밀도는 54%로 계산되었다.
GPU 계산이 워낙 빠르므로 epoch 값을 2에서 5로 늘려 정밀도가 향상되는지 살펴보자. 시간은 거의 5분에 가까운 283초에 정밀도가 60% 로 향상되었다.
Epoch 값을 다시 5에서 10으로 늘려 정밀도가 향상되는지 살펴보자. 시간은 거의 10분에 육박하는 560초가 걸렸으나 정밀도는 그대로 60%에 머물렀다.
구글 Colabo의 GPU를 사용하여 아주 정상적인 머신 러닝 결과 epoch를 아무리 늘려도 정밀도가 60%가 한계인 듯하다.
이번 내용을 요약해 보면 이 정도의 머신 러닝 정밀도로는 사람이나 개 또는 고양이와 같은 동물들의 인식률에도 훨씬 못 미치는 수준이다. 이런 방식의 머신 러닝이 현 21세기의 머신 러닝의 근간을 이루고 있는데 특별히 잘못된 점은 없지만 그 속도에 그 정도 정밀도라면 자율주행 분야에서는 아직 실용성이 한참 떨어쟈 보인다. 인간이나 동물의 인식률에 접근하려면 쳐다보는 순간 0.1초 내에 인식 결과가 나와야 할 것이다. 스탠포드 대학 및 미국, 캐나다에서 많은 연구를 하고 있는 것으로 알고 있는데 그 결과 성능이 이정도 수준이라면 다소 실망스럽다.
이 정도 속도 성능으로 자율 주행을 실현하기는 요원하다. 보다 효율적인 알고리듬을 찾아 적어도 즉 0.1초 이내에 정밀도가 80∼90%가 되어야 하지는 않을까? 그 다음 주제로 좀 더 이미지 인식이 빨라질 수도 있는 PyTorch Transfer Learning 예제를 다루어 보도록 하자.
'머신러닝' 카테고리의 다른 글
초보자를 위한 선형회귀문제 해설 (0) | 2019.06.26 |
---|---|
초보자를 위한 Anaconda3 선형회귀문제 단순 파이선 코딩 연습문제 (0) | 2019.06.26 |
이미 특이점을 뛰어 넘었던 중국의 슈퍼컴퓨팅 미중무역전쟁으로 허무하게 아작나는가? (0) | 2019.06.22 |
Convolutional Neural Network에서 Pooling 알고리듬에 의한 Edge 특징 추출(featur extraction) (0) | 2019.06.22 |
Convolutional Neural Network에서 특징 추출(featur extraction) 알고리듬과 Transfer Learning과의 관계 (0) | 2019.06.20 |