층마다 적절한 텐서 포맷이 있고, 데이터 처리 방식이 다르다. 에를 들어 2D Tensor는 (Sample, Feature)로 Matrix를 처리하며, keras의 Fully connected layer에 의해 처리 될 수 있으나 이미지, 즉, 4D의 경우는 (Sample, Weight, height, corlor_channel)로 구성이 되어 Convolution layer에 의해 처리가 됨.
다음의 2D .텐서만 입력 받는 층을 보자.
from keras import models
from keras import layers
model = models.Sequential()
model.add(layers.Dense(32,input_shape=(784 ,)))
model.add(layers.Dense(10))
먼저 이 네트워크는 첫번째 차원이 784개인 Tensor만 입력받는 층이고, 32차원으로 변화된 텐서를 출력한다.
그리고 2번째 층은 해당 32차원을 입력 받고 10개의 Tensor를 출력한다.
이렇듯, 케라스에서는 모델에 추가된 층을 자동으로 상위 층의 크기에 맞추어 주기 때문에 호환성을 걱정하지 않아도 된다.
3.1.2 모델: 층의 네트워크
네트워크의 종류에는 여러가지가 있다. 그러나 자주 등장하는 것들은 다음과 같다.
- 가지(Branch)가 2개인 네트워크
- 출력이 여러개인 네트워크
- 인셉션(inception) 블록 -----------------------------------> 추후 설명 추가.
3.1.3 손실 함수와 옵티마이저: 학습과정을 조절하는 열쇠
네트워크 구조를 정의하고 나면 두가지를 더 선택해야 함.
- 손실함수(loss function): 학습 및 훈련하는 동안 최소화 됨 - 주어진 문제에 대한 성공지표
- Optimizer: 특정 종류의 경사학강법을 구현하여 손실함수를 기반으로 네트워크가 어떻게 업데이트 될지 결정.
3.2절은 일반적인 Keras의 소개이며 3.3절은 딥러닝 컴퓨터 세팅인데 이므로 다음에는 바로 3.4절로 넘어가서 이진분류로 바로 실전 코딩으로 넘어가도록 하겠다.
케라스 실습은 원래 주피터 노트북을 사용하려고 했는데 CNN은 GPU를 사용해야 하는데 내 노트북 GPU 사양을 몰라서 그냥 AMAZON GPU를 써볼까 어슬렁서리다 보니 이건 유료라고 해서 PASS.
그래서 또 구글 서칭 해 보니 구글 코랩은 GPU를 제공하는데 무료라고 하십니다. 우아앙 좋다. 게다가 왠만한 머신러닝 라이브러리는 다 깔려 있는 것 같다. 유전자 알고리즘 공부하려고 DEAP 해봤는데 안 되서 이건 설치해야 해서 아쉽긴 하지만 GPU 제공하는 건 좋은 것 같음.
그래서 Google colabolabolatory는 Google에서 Google colab을 치면
이런 사이트를 볼 수 있고 기본적으로 Google drive에 저장이 된다. 따라서 구글 계정이 있으면 좋고 없으면 만들면 된다. github에도 다운받을 수 있고 주피터 노트용 파일이나 .py로도 변환이 된다. [해보진 않음]
오늘은 기본적으로 파일 올리는 방법에 대해서만 포스팅 하도록 하겠다.
드라이브 마운트 버튼 클릭 > 코드 실행 > URL 클릭
계정 선택 화면으로 이동
엑세스 허용
마운트 되었다고 나오면서 실제 드라이브가 아닌 가상드라이브에 마운트됨. 따라서 pd.read_csv나 np.txt로 파일을 열거나 쓰고 싶을 때 같은 경우 파일을 그냥 구글 드라이브가 아닌 해당 가상 드라이브를 마운트한 다음 content/drive로 경로를 잡아줘야 함.
다른 포스팅에서 찾아보도록 하자. activation함수가 차원을 왜곡하고 뭐하고, 여러번 거치면 vector가 가지는 공간영역이 어쩌고 저쩌고 아 머리아파 진다. 넘어가도록 하자.
그런데 신기한 건 우리가 고등학교 때까지, 그리고 일반적으로 알고 있는 수학에서는 각 행렬은 형태가 같아야만 연산이 되는데 여기서는 Wx즉 2D와 1D인 b가 덧셈이 된다는 것이다. 어떻게 된 것일까? 이것은 브로드캐스팅(Broadcating)에 의해 이루어진다. 이에 관해서 2.3.2절에서 살펴 보도록 한다.
2.3.1 원소별 연산
넘파이 내장 함수 구현 코드
2.3.2 브로드캐스팅
모호하지 않고 실행가능하지 않은 경우하라면, 작은 텐서가 큰 텐서의 크기에 맞추어 이루어지는데, 브로드캐스팅은 다음 두 단계로 이루어짐.
- 1. 먼저 큰 텐서의 ndim에 맞도록 작은 텐서에 (브로드캐스팅 축이라고 부르는) 축이 추가된다.
- 2. 작은 텐서가 새 축을 따라서 큰 텐서의 크기에 맞도록 반복 연산된다.
예) X = (32, 10) // y = (10, )의 shape를 취할 때 X와 y의 shape를 같게 하려면?
1 -> 먼저 y에 비어 있는 첫번째 축을 추가 하여 y= (1,10)으로 만듦 (뒤에 축이 비어 있는데???)
2 -> 이를 32번 반복
2.3.3 텐서 점곱
나중에 추가 예정
2.3.4 텐서의 크기 변환(Reshape)
신경망에 주어진 데이터를 전처리 할 때 사용.
텐서의 크기를 변환한다는 것 = 특정 크기에 맞게 행/열을 재배열 한다는 것, [단 변환된 텐서의 원소 개수는 원레의 텐서의 원소 개수와 동일]
- 처음에 3행 2열 배열을 만들었다.
- 그런 다음 이에 해당하는 6개의 원소를 가진 6행 1열의 배열로 Reshape했다. 그리고 이를 출력해 보면 1열애 출력되는 것을 알 수 있다.
자주 사용되는 특별한 종류의 크기 변환에는 전치(transpose)가 있다. (i , j) -->(j , i)으로 숙지하면 된다.
2.3.5 텐서 연산의 기하학적 해석
나중에 추가 예정
2.3.6 딥러닝의 기하학적 해석
3D 공간에서 다음의 비유가 딥러닝을 이해하는데 도움이 될 것임. 하나는 빨간색이고 다른 하나는 파란색인 2개의 색종이가 있다고 가정. 두 장을 겹친 다음 뭉쳐서 다른 공으로 만들면 이 종이 공이 입력 데이터이고 색종이는 분류 문제인 데이터 클래스.
신경망이 해야 할 일은 종이 공을 펼쳐서 두 클래스가 다시 깔끔하게 분리되는 변환을 찾는 것. 손가락으로 종이공을 조금씩 펼치는 것처럼 딥러닝을 사용하여 3D 공간에서 간단한 변환들을 연결하여 이를 구현
> 종이 공을 펼치는 것이 머신러닝이 하는 일. 복잡하고 심하게 꼬여있는 데이터의 매니폴드에 대한 깔끔한 표현을 찾는 일.
- 심층 네트워크의 각 층은 데이터를 조금씩 풀어주는 변환을 적용 > 이런 층을 깊게 쌓으면 아주 복잡한 분해 과정을 처리 할 수 있음.
다음장에서는 경사하강법과 BackPropagation에 대해서 간단하게 살펴본 다음, MNIST에 지금까지 배운 이론과 방법론을 실제로 적용하여 구현해 보도록 하겠습니다. 그럼 안녕히 주무세요. 오늘 제사 다녀와서 매우 피곤하네요. 제대로 포스팅 했는지도 모르겠고.,....공부도 제대로 한건지 모르겠고 ㅎㅎ;;; 빨리 자도 싶습니다....양치해야 하니 이만...
앞으로 실습할 모든것인 Shape, Slicing,[텐서의 조작], Tensor, Vector, 텐서의 핵심 속성 그리고 간단한 그래디언트 기반 최적화를 설명하는 장이다. 따라서 엄밀히 말하면 Numpy에 포스팅해야 하지만 케라스 책에 있으므로 여기에 포스팅한다.
2.1 2장의 도입부 및 MNIST로 인한 전반적인 설명
2.2 신경망을 위한 데이터 표현
신경망은 Tensor라고 불리우는 다차원 넘파이 배열에 데이터를 저장하는 것으로부터 시작된다. 텐서에는 다음과 같은 데이터 형이 존재한다.
2.2.1 스칼라(0D텐서)
하나의 숫자만 담고 있는 텐서이다. 거의 사용하지 않음.
2.2.2 벡터(1D텐서)
하나의 축(행/열 등)을 가진 것을 벡터라고 부름.
2.2.3 행렬 또는 Matrix(2D 텐서)
2개의 축(행/열)을 가지고 있는 데이터 숫자가 채워진 사각 격자임.
2.2.4 3D텐서 이상
3D텐서는 사진 [R,G,B]를 나타내지만 그 이상인 4D, 5D는 Video를 나타낼 때 사용하는데 우리 눈으로 관찰하기는 불가능하다. 2.2.1 ~ 2.2.4를 각각 넘파이로 표현하여서 나타내보면 다음과 같다.
먼저 0D 의 경우 이를 Numpy 배열로 생성하여 보면 하나의 값만 들어 있는 것을 알 수 있음. 또한 축이 몇 개 존재하는 지 알아 보기 위해서 ndim command를 실시 해본 결과 0으로 존재하지 않는 것을 알 수 있음.
1차원 배열의 경우는 다음과 같이 우리가 일반적으로 알고 있는 리스트 형태의 벡터가 만들어지고 축이 하나 존재함을 알 수 있음. 그리고 해당 벡터는 5개의 원소를 가지고 있으므로 5차원 벡터라고 함. 단, 이것은 축이 아니고 5D tensor도 아님을 명심해야 함. [5D Tensor는 Tensor가 5겹으로 놓이는 것임.]
가장 많이 쓰이는 matrix 인 2차원 텐서임. 백터와 달리 축이 하나 더 있어서, 데이터를 더 다양하게 표현 할 수 있음을 알 수 있음.
마지막으로 3차원 Tensor를 표현해 보면 행, 열이 몇 개 쌓여 있는 지 표현하는 값인 z축이 붙었음을 알 수 있음. 나중에 MNIST의 응용과 함께 자세히 알아 볼 것임. 여기까지를 정리해서 신경망의 데이터를 표현하는 Tensor의 핵심속성을 알아보면 다음과 같음.
2.2.5 핵심속성
축의 개수 : 행/열/깊이 : ndim 명령어로 알아 볼 수 있음.
크기(Shape): 텐서의 각 축을 따라 얼마나 많은 차원이 있는지를 나타내는 것. 앞에 나온 2D에서 Shape는 (3,5) - 3행 5열
3D는 (3, 3,5) - 3쌓여 있음 [3행 5열]
이를 구체적으로 확인 해 보기 위해서 MNIST의 dataset을 load히고 확인해 본다.
따라서 data를 로드하고 train_image에 대해서 ndim과 shape를 확인해 보면
축의 개수는 3개인데, 28 행 28열이 60000곂 쌓여 있음을 알 수 있다. [여기서는 이미지이므로 28 by 28 pixel이 60000개 있음] 이를 matplotlib으로 확인해 보면
실제로 이미지를 출력해 볼 수 있고, 형태 또한 이전 우리가 예측했던 것과 같음을 알 수 있다.
지금까지 신경망에 축적되는 데이터의 핵심속성에 대해서 알아 보았고 어떻게 출력해 보는 지 알아 보았다. 기본적으로 데이터를 알더라도 데이터를 적재한 다음에는 무조건 shape나 ndim은 확인해 보는 것이 좋다. 추후에 학습할 때 에러가 날 소지가 다분하기 때문이다.
2.2.6 넘파이로 텐서 조작하기
이전에는 특정 이미지, 즉, 4번째 이미지 train_images[4]를 선택했다. 하지만 더 많은 이미지를 한 번에 선택해보거나 특정 범위로 이미지를 선택하고 싶을 때가 있다. 즉, slicing하고 싶을 때가 있다. 이렇게 특정 원소들을 선택 하는 것을 Slicing이라고 하는 데 다음 연산을 보자. 먼저 다음예는 11 번쟤부터 101번째까지의 값만 60000개 중에서 Slice하여 새로운 값을 my_slice에 저장한다.
:(콜론)이 전체 인덱스를 의미하므로 여기서는 28을 뜻함. [28*28]
10~100 이므로 60000개중에서 11~100의 90개를 선택한다.
주의 할 것은 위의 주석 부분과 같이 :은 생략 가능하다! (하지만 일관되게 써주는 것이 나중에 보는데 편함.)
각 배열의 축(행/열)을 따라 어떠한 인덱스 또는 인덱스 사이도 선택 할 수 있으므로 위와 같이 설정하면 픽셀 에 따른 값을 표현하는 것이 가능하다.
2.2.7 배치 데이터
일반적으로 사람들이 머신러닝을 하면서 그냥 넘어가는(나의 경우 그랬음) 부분이다. 여기서 짚고넘어가면 좋을 듯 하다. 배치데이터란 딥러닝의 용어로서 일반적으로 딥러닝을 할 때 한 번 반복[Epoch: 이것도 딥러닝 용어임]할 때 모든 데이터를 사용하지 않고 데이터의 일부분만 사용한다. 예를 들어 MNIST 에서는 전체 60000개 중에 128개의 배치를 사용한다고 하면 다음과 같다.
이제 2장도 1/3정도 봤습니다. 다음에는 2.3장과 2.4장을 살펴 볼 건데 브로드캐스팅과 텐서의 형태, 그리고 경사하강법의 간단한 이론 정도에 대해서 나오는 것 같습니다. 자세히는 안 봐서 모르겠습니다. 어려운 문제는 없는 것 같으니 함께 포스팅 하는 것으로 하겠습니다.
비교적 최근에 서피스 X가 공개되었고 그램도 2019년형이 나오고 갤럭시 이온이 나오고 내 지름신이 꿈틀거렸으나
재정적 상황은 여의치 않았다. -_-
게다가 수중에는 서피스4가 있으니 이는 서피스 X와 비교해도 일단 외관상으로는 큰 차이가 없다. 물론 내부로 들어가 보면 업그레이드가 많이 이뤄졌지만 그래도 큰 금액을 지불하고 싶지는 않았다. 게다가 개인적으로는 게임도 하지 않고 고사양 그래픽 작업도 하지 않기 떄문이다. 끽해야 코딩 수준인데 음..딥러닝 같은 경우는 일단 영상 처리 같이 어마 무시한 사이즈의 리소스를 요구하는 작업은 하지 않고 GPU를 물려서 하면 아직까지는 버틸만한 수준에서 하고 있다.
그래서 아 발열만 잡으면 괜찮지 않을까? 하고 자기 위로 하면서 차선책으로 언더볼팅을 살펴 보았다. 그냥 쿨러를 사용하거나 선풍기(?)를 이용해도 되긴 하지만 언더볼팅은 CPU자체에 흐르는 전압을 줄여줘서 소모 전력 자체를 줄여주는 것이다. 그러면 당연히 배터리도 오래가게 되고 발열도 줄어들게 된다. 이런 언더볼팅은 기본적으로 제조사에서 CPU를 내놓을 때 수율을 위해서 +- 어느 정도 불량을 나지않기 위해 전압의 안정성을 두기 떄문에 가능하다.
그러니까 우리는 언더볼팅을 함로써 기존에 많이먹이던 밥의 양을 최적의 양만 먹임으로써 다이어트 시킨다고 보면 된다. 그렇다고 해도 바로 실시하기에는 좀 무서워서 인터넷에 좀 알아보니 전압을 줄이는 것으로 CPU의 K 시리즈가 하는 오버클럭(나는 안 해봄)과 완전히 반대되는 개념이므로 일단 언더볼팅은 CPU에는 안전하다고 봐도 좋다고 하는 의견도 있고 너무 전압을 줄이면 오히려 CPU에 부담이 되거나 배터리 수명이 줄어든다는 괴랄한 말도 있지만 일단 본인은 좋은 쪽에 걸고 본인은 오래 쓰면 플리커 현상이 발생하는 이 서피스 프로4에 언더볼팅을 적용하기로 하였다 ㅎㅎ
일단 언더볼팅 소프트웨어 자체는 인텔에서 제공하는데 해당 다운로드 링크는 위와 같으니 참조하자. 그리고 다운로드 한 다음에 설치를 하면 컴퓨터를 재시작 할 거냐고 물어보는데, 재시작 해 주자. 그러면 이제 바탕화면에 Intel Extreme Tuning Utility 라는 아이콘이 생성된 것을 확인 할 수 있을 것이다. 실행해주면 언더볼팅 시 컴퓨터가 손상될 수 있다는 문구가 나오고, 우리는 그것을 알고 실행하고 있는 입장이므로 동의해 준다. 그리고 쓸데 없이 인텔에 정보를 제공해 준다는 문구도 나왔던 거 같은데 해당 메세지를 더 보여주지 않는다는 것에 체크를 해 주자 귀찮다!
그러면 본격적인 설정 화면이 나오는데 매우 간단하다.
컴퓨터 관련 정보는 그냥 패스. 우리는 전압 관련 설정을 해야 하므로, Advanced Tuning으로 이동해서
전압을 설정해야 하므로 core voltage offset을 설정해야 한다. 나는 i5-6300u인데 -0.090을 설정하였다. 참고로 앞에 말했듯이 모든 cpu는 수율에 따라 +-로 가용 전압이 다를 수 있으므로 최적 전압을 정해야 한다. 나는 -0.095에서 뒤에서 언급할 테스트시 재부팅이 되있어서 -0.090으로 설정했다.
전압을 설정했으면 Apply 하고 Profile을 만드려면 apply해야 한다
그리고 언더볼팅된 상태에서 발열과 CPU TEST를 해보기 위해 위와 같이 설정을 한다. 30분 정도 하는 게 좋다고 한다. 이렇게 최적 값을 찾아내면 언더볼팅은 완료되는데 지금까지 한 것에서 문제가 재부팅하게 되면 설정 값이 없어지게 된다는 것이다. 귀찮아도 그냥 클릭 몇 번 하면 되긴 하는데 그냥 자동으로 하는 방법은 없는지 찾아봐야 할 것 같다.
쩝..이상으로 돈 없어서 서피스 프로4의 성능을 조금이라도 높이기 위한 찌질이의 포스팅이었다.