지금, 나는 

Art is anything you can get away with.

Programming/혼공머신 8기.py

혼자 공부하는 머신러닝 + 딥러닝 [6주차]_fin

hyuckee 2022. 8. 15. 16:02
반응형

07-1   인공신경망

드디어 딥러닝이다.

여기서는 MNIST라는 딥러닝에서 유명한 데이터셋과 

텐서플로(케라스)라는 구글에서 만든 유명한 딥러닝 라이브러리를 이용한다.

 

딥러닝 라이브러리는 머신러닝 라이브러리와 다르게

벡터와 행렬 연산에 매우 최적화되어 있는

그래픽 처리장치인 GPU를 사용하여

인공 신경망을 훈련한다.

 

우리가 다룰 데이터는 28*28크기의 이미지 60,000개이다.

0~9까지의 10가지 종류로 이루어진 패션 MNIST를 사용한다.

(6장에서와 같이 이미지는 모두 흑백)

 

넘파이 unique() 함수로 레이블 당 샘플 개수를 확인해 볼 수 있다.

훈련 샘플이 60,000개나 되기 때문에

6장에서처럼 전체 데이터를 한꺼번에 사용해 모델을 훈련하는 것보다

하나씩 꺼내서 모델을 훈련하는 방법이 더 효율적으로 보인다.

따라서 확률적 경사 하강법을 사용할 것이다.


4장에서 분류모델로

로지스틱 손실 함수를 최소화하는 확률적 경사 하강법을 만들었었다.

이때 손실 함수를 위해 데이터를 표준화 전처리하는 과정을 거쳤다.

 

여기서도 0~255 사이의 정수값을 가지는 픽셀에 대해

0~1사이의 값으로 정규화하고

SGDClassifier를 위해 샘플을 1차원 배열로 만들어야 한다.

 

이렇게 만든 모델을 그림으로 나타내면 다음과 같다.

출처: https://blog.naver.com/mds_0104/222613033319

각 입력층에 대해 각각 가중치를 곱하고 절편과 함께 합하면 하나의 출력으로 나온다.

(28*28크기의 이미지이므로 784개의 입력층과 10가지 종류이므로 10개의 출력층을 가진다)

 

각 출력층에 대해 서로 다른 방정식이 생성되므로 각각 가중치와 절편이 모두 다르다.

그리고 각 출력층에 대해 소프트맥스 함수를 적용하면

전체 합이 1인 각각의 확률값으로 변환된다.

.

그림을 보면 뉴런(신경세포)와 형태로도, 기능으로도 닮은 것을 알 수 있다.

그래서 이름이 인공신경망(ANN)이다.

각 출력(z 값을 계산하는 단위)을 뉴런이나 유닛이라고 부른다.

 

입력층과 출력층 사이의 선으로 빼곡한 부분을 밀집층이라고 부른다.

이 부분은 뉴런 단위의 중간 계산이 이루어지는 부분으로

모델 파라미터가 생성되는 장소이다.

(입력층이 100개이고 뉴런이 10개라면 가중치와 절편에 해당하는 모델파라미터는 100*10 + 10으로 1010개) #1번 문제

 

케라스의 Dense 클래스를 사용해 밀집층을 만들 수 있다.

(뉴런의 개수, activation='뉴런의 출력에 적용할 함수', input_shape=(입력의 크기))를 매개변수로 받는다.

만약 이진 분류라면 activation='sigmoid'로 설정해 시그모이드 함수를 사용한다. #2번 문제

뉴런의 선형 방정식 계산 결과에 적용되는 함수를 활성화 함수라고 부른다.

 

그리고 Sequential 클래스에 dense를 매개변수로 전달해 객체를 만들면

신경망 모델이 완성된다.


케라스 모델은 훈련하기 전에 설정 단계가 있다.

compile() 메서드에서 손실함수의 종류를 필수적으로 지정해야 한다. #3번 문제

4장에서 살펴봤듯 크로스 엔트로피 손실함수가 있다.

 

이진 크로스 엔트로피 손실을 위해서는 -log(예측확률)에 타깃값을 곱했었다.

하지만 음성 클래스에 대해서는 값이 0이 되어버리기에

-log(1-a) x (1-타깃값)을 통해 음성 클래스에 대한 손실도 계산하게 한다.

 

다중 분류의 경우 출력층에 10개의 뉴런이 있다면 10개의 클래스에 대한 확률을 출력한다.

하지만 손실함수는 각 뉴런별로 적용되어야 한다.

따라서 타깃에 해당하는 확률만 남겨놓기 위해 나머지 확률에는 모두 0을 곱한다.

이렇게 만드는 것을 원-핫 인코딩이라고 부른다.

.

텐서플로에서는 이런 과정 없이 정수값 하나만 사용할 수 있게

loss='sparse_categorial_crossentropy'로 매개변수를 지정할 수 있다. #4번 문제

 

이렇게 지정하면 에포크마다 손실값을 출력하는데

추가적으로 metrics='accuracy' 매개변수를 지정하면 정확도도 함께 출력된다.

훈련

로지스틱 회귀에서는 교차 검증을 사용해 모델을 평가했지만

인공 신경망에서는 교차 검증 없이 검증 세트를 별도로 덜어내서 사용한다.

데이터셋이 충분히 커서 검증 점수가 안정적이고

교차 검증하기에는 시간이 너무 오래 걸리기 때문이다.


07-2   심층 신경망

입력층과 출력층 사이의 밀집층은 여러 개 들어갈 수 있다.

입력과 출력 사이에 통과되는 함수를 늘린다는 느낌이다.

더 딥~해지기에 심층 신경망(DNN)이라 불린다.

층을 추가하면 연속적인 학습을 진행할 수 있다.

.

입력층과 출력층 사이의 모든 층을 은닉층이라고 부른다.

중간 산출물이라고 생각하면 편하다.

 

은닉층 역시 밀집층이라 표현할 수 있으므로 dense 클래스로 만들 수 있다.

여담으로

이전처럼 직접 1차원으로 펼치지 않고 Flatten 클래스를 이용하면

자동으로 1차원으로 만들 수 있고

summary에서 모델의 전체 모습을 볼 수 있어 편리하다.

.

은닉층 뉴런의 개수는 기준이 없고 정말 자유롭다.

하지만 출력층보다 적다면 부족한 정보가 전달될 것이다.

반대로 너무 증폭시키면 노이즈가 생겨 원하는 결과에 맞지 않을 수 있다.

 

주의해야 할 것은

은닉층에는 활성화 함수를 적용해야 한다.


만약 그냥 선형방정식을 여러개 통과한다면 그저 사칙연산을 나누어 실행한 것이다.

따라서 선형 계산을 적당하게 비선형적으로 비틀어 주어야 한다.

그래야 나름의 역할이 주어진다.

.

은닉층의 활성화 함수는 출력층에 비해

적용할 수 있는 종류가 비교적 자유롭다.

(많이 사용하는 활성화 함수는 시그모이드 함수이다.)

.

시그모이드 함수의 경우 양 끝으로 갈수록 그래프가 누워 있다.

따라서 출력에 신속하게 대응하지 못한다.

특히 층이 많아질수록 효과가 누적되어 학습을 더 어렵게 만든다.

이를 개선하는 다른 종류의 활성화 함수로는 렐루 함수가 있다.

 

음수의 경우 값을 0으로 만들고

0이상이라면 그 값을 그대로 통과시킨다.

max(0, z)로 표현할 수 있다.


중간중간 짐작했겠지만

정말 많은 하이퍼 파라미터가 사이사이에 있다.

뉴런의 개수, 활성화 함수 종류, 층의 종류, 미니배치 개수, 에포크 수 등

 

또, compile() 메서드에서 케라스의 다양한 종류의 경사 하강법 알고리즘이 제공된다.

이들을 옵티마이저라고 부르는데 이것도 하이퍼 파라미터이다.

 

가장 기본적인 경사 하강법은 SGD이다.

여기서 파생돼 그레디언트를 가속도로 사용하는 

모멘텀 최적화나 네스테로프 모멘텀 최적화를 적용할 수 있고,

 

최적점에 가까이 갈수록 학습률을 낮출 수 있는 적응적 학습률을 사용하는

RMSpropAdagrad를 적용할 수도 있다.

 

심지어 모멘텀 최적화와 RMSprop의 장점을 접목한 Adam도 있다.

.

이렇게 다양한 API가 케라스에 내장되어 있다.

따라서 직접 사용해보면서 알맞는 걸 찾아

모델의 성능을 높여야 한다...


07-3   신경망 모델 훈련

fit() 메서드는 훈련 과정에서 계산한 손실과 정확도 값이 반환된다.

이를 에포크 순으로 맷플롯립을 사용하면 시각화할 수 있다.

.

기본적으로 에포크마다 손실이 감소하고 정확도가 향상하는 것은 알 수 있다.

하지만 이전에 과대/과소적합과 에포크 사이의 관계를 알아봤었다.

 

검증 세트와 훈련 세트에 대해 손실 함수 값을 확인해 적절한 에포크를 찾아야 한다.

즉, 손실은 줄이면서(에포크를 늘리면서) 과대적합을 막아야 한다.

 

옵티마이저를 포함한 여러 하이퍼 파라미터를 조정할 수 있지만

신경망에 특화된 규제 방법을 사용할 수도 있다.


드롭 아웃

훈련 과정에서 층에 있는 일부 뉴런을 랜덤하게 꺼서

(뉴런의 출력을 0으로 만들어)

특정 뉴런에 과대하게 의존하는 것을 줄임으로써 과대 적합을 막는다는 방식.

출처: https://blog.naver.com/kkang9901/221789358198

각 에포크마다 이렇게 일정 비율 랜덤하게 뉴런을 줄이면 과대적합을 막을 수 있다.

마치 각 에포크마다 다른 신경망을 앙상블하는 것처럼 상상할 수 있다.

이렇게 과대적합을 막은 것을 볼 수 있다.

하지만 여기서 또 최소 손실인 에포크에서 다시 훈련시켜야 한다.

번거롭기 때문에 콜백을 이용해 한 번에 끝내는 게 편하다.


콜백은 훈련 과정 중간에 어떤 작업을 수행할 수 있게 하는 객체이다.

 

ModelCheckpoint 콜백은 기본적으로 에포크마다 모델을 저장한다.

save_best_only=True 매개변수를 지정하면

가장 낮은 검증 점수를 만드는 모델을 저장할 수 있다.

.

하지만 중간에 저장만 될 뿐 처음에 설정한 에포크만큼 계속 실행되기에

자원과 시간을 아끼기 위해 조기 종료시켜야 한다.

훈련 에포크 횟수를 제한하지만 모델의 과대적합을 막는 규제 방법 중 하나이다.

 

케라스에서 EarlyStopping 콜백의 patience=n 매개변수를 지정하면

n번 연속 검증 점수가 향상되지 않으면 훈련을 중지시켜 준다.

 

심지어 restore_best_weights=True를 지정하면

가장 낮은 검증 손실을 낸 모델 파라미터로 되돌린다.

 

이렇게 하면 무리없이 편리하게 원하는 성능의 모델을 얻을 수 있다.


머신러닝부터 딥러닝까지

6주간의 혼공학습단이 끝났다.

 

이번 단원에서 머신러닝을 어느정도 알아야

딥러닝을 익힐 수 있다는 것을 알 수 있다.

 

그렇다고 머신러닝 자체로 쓰임새가 없는 건 또 아니다.

오히려 딥러닝보다 머신러닝이 효과적인 상황도 꽤 있다.

 

어려운 내용들이었지만 아직도 더 깊은 내용들이 많이 남아 있다.

8단원의 합성곱 신경망과 9단원의 순환 신경망까지 하면

딥러닝도 어느정도 안다고 자부할 수 있겠다.

 

책의 내용과 커리큘럼, 그리고 영상 강의 모두 처음 접하는 사람도

충분히 모든 내용을 숙달할 수 있을 정도로 잘 정리되어 있고

 

이 책에서 끝나지 않고 더 뻗어나갈 수 있게

지엽적인 관련 내용들도 첨부되어 있어 입문서로 딱인 것 같다.

(사실 따라갈 수만 있다면 2주면 충분히 완독 가능한 것 같다)

머리 쓰니까 배고프다..

728x90