혼자 공부하는 머신러닝+딥러닝 책을 바탕으로 공부한 내용입니다.
CH7 딥러닝 시작 ②
케라스 API를 활용한 심층 신경망
인공 신경망에 층을 여러 개 추가하여 패션 MNIST 데이터셋을 분류하면서 케라스로 심층 신경망을 만드는 법을 자세히 배워보자
▶ 2개의 층
먼저, 데이터셋을 먼저 불러오자
from tensorflow import keras
(train_input, train_target), (test_input, test_target) = keras.datasets.fashion_mnist.load_data()
7-1장에서 했던 것을 똑같이 해보자
from sklearn.model_selection import train_test_split
train_scaled = train_input / 255.0
train_scaled = train_scaled.reshape(-1, 28*28)
train_scaled, val_scaled, train_target, val_target = train_test_split(
train_scaled, train_target, test_size=0.2, random_state=42)
- 이미지의 픽셀값을 0-255 범위에서 0-1 사이로 변환
- 28 X 28 크기의 2차원 배열을 784 크기의 1차원 배열로 펼치기
- 훈련 세트와 검증세트로 나누기
7-1장 인공 신경망의 성능을 더 높이기 위해 이번에는 인공 신경망 모델에 층을 2개 추가할 것이다!
1절에 만들었던 신경망 모델과 다른 점은 입력층과 출력층 사이에 은닉층(밀집층)이 추가된 것이다.
활성화 함수 - 신경망 층의 선형 방정식의 계산 값에 적용하는 함수
(1) 출력층에 적용하는 활성화 함수는 종류가 제한되어 있음
이진 분류 - 시그모이드 함수
다중 분류 - 소프트맥스 함수
(2) 은닉층의 활성화 함수는 비교적 자유로움
대표적으로 시그모이드 함수, 렐루 함수가 있음
시그모이드 활성화 함수를 사용한 은닉층, 소프트맥스 함수를 사용한 출력층을 케라스의 Dense 클래스로 만들어보자
dense1 = keras.layers.Dense(100, activation='sigmoid', input_shape=(784,))
dense2 = keras.layers.Dense(10, activation='softmax')
- dense1은 100개의 뉴런을 가진 은닉층
- dense2는 10개의 뉴런을 가진 출력층
- 케라스에서 신경망의 첫번째 층은 input_shape 매개변수로 입력의 크기를 꼭 지정해주어야 함
▶ 심층 신경망
이제 dense1, dense2 객체를 Sequential 클래스에 추가하여 심층 신경망(DNN)을 만들어보자
리스트로 전달할 때 가장 처음 등장하는 은닉층에서 마지막 출력층 순서로 나열해야 한다.
model = keras.Sequential([dense1, dense2])
model.summary()
▶ 층을 추가하는 다른 방법
Sequential 클래스에 층을 추가하는 다른 방법도 알아보자
(1) Sequential 클래스의 생성자 안에서 바로 Dense 클래스의 객체 만들기
model = keras.Sequential([
keras.layers.Dense(100, activation='sigmoid', input_shape=(784,), name='hidden'),
keras.layers.Dense(10, activation='softmax', name='output')
], name='패션 MNIST 모델')
model.summary()
- 모델 이름, 층 이름을 설정해주었음
(2) Sequential 클래스의 객체를 만들고 add() 메서드를 호출하여 층 추가하기
# add 메서드 사용
model = keras.Sequential()
model.add(keras.layers.Dense(100, activation='sigmoid', input_shape=(784,)))
model.add(keras.layers.Dense(10, activation='softmax'))
model.summary()
- Sequential 클래스에서 층을 추가할 때 가장 널리 사용하는 방법
이제 모델을 훈련해보자
# 모델 훈련
model.compile(loss='sparse_categorical_crossentropy', metrics='accuracy')
model.fit(train_scaled, train_target, epochs=5)
- 훈련 세트에 대한 성능을 보면 추가된 층이 성능을 향상시켰다는 것을 알 수 있다.
- 몇 개의 층을 추가하더라도 compile(), fit() 메서드의 사용법은 동일하다는 것이 케라스 API의 장점이다.
▶ 렐루 함수
- 이미지 분류 모델의 은닉층에서 많이 사용하는 활성화 함수
- 입력이 양수일 경우 입력값을, 음수일 경우에는 0을 만드는 함수이다.
- 심층 신경망에서 뛰어남
model = keras.Sequential()
model.add(keras.layers.Flatten(input_shape=(28, 28)))
model.add(keras.layers.Dense(100, activation='relu'))
model.add(keras.layers.Dense(10, activation='softmax'))
- 앞에서 썼던 reshape()말고 이번에는 Flatten 클래스를 이용했고, 첫번째 Dense 층의 활성화 함수를 'relu'로 바꿔주었다.
- Flatten 클래스는 배치 차원을 제외하고 나머지 입력 차원을 모두 일렬로 펼치는 역할을 한다.
- Flatten 층은 입력층 바로 뒤에 추가한다.
모델의 summary() 메서드를 호출해보자
model.summary()
- 케라스의 Flatten 층을 신경망 모델에 추가하면 입력값의 차원을 짐작할 수 있다는 장점이 있음
- 784개의 입력이 첫번째 은닉층에 전달된다는 것을 알 수 있음 (이전 모델에서는 눈치채기 어려웠음)
이제 훈련 데이터를 다시 준비해서 모델을 훈련해보자
(train_input, train_target), (test_input, test_target) = keras.datasets.fashion_mnist.load_data()
train_scaled = train_input / 255.0
train_scaled, val_scaled, train_target, val_target = train_test_split(
train_scaled, train_target, test_size=0.2, random_state=42)
# 모델 훈련
model.compile(loss='sparse_categorical_crossentropy', metrics='accuracy')
model.fit(train_scaled, train_target, epochs=5)
- 시그모이드 함수를 사용했을 때에 비해 성능이 조금 향상되었다.
검증 세트에서의 성능도 확인해보면
# 검증 세트 성능 확인
model.evaluate(val_scaled, val_target)
- 7-1장의 은닉층을 추가하지 않은 경우보다 몇 퍼센트 성능이 향상 되었다.
▶ 옵티마이저
- 신경망의 가중치와 절편을 학습하기 위한 알고리즘
- 케라스에는 다양한 경사 하강법 알고리즘이 구현되어 있음 (SGD, 네스테로프 모멘텀, RMSprop, Adam 등)
① 우리는 compile() 메서드에서 케라스의 기본 경사 하강법 알고리즘인 RMSprop을 사용했었다.
가장 기본적인 옵티마이저는 확률적 경사 하강법인 SGD이다.
model.compile(optimizer='sgd', loss='sparse_categorical_crossentropy', metrics='accuracy')
sgd = keras.optimizers.SGD()
model.compile(optimizer=sgd, loss='sparse_categorical_crossentropy', metrics='accuracy')
- 이렇게 두 가지 방법으로 SGD 옵티마이저를 사용할 수 있다.
# 학습률
sgd = keras.optimizers.SGD(learning_rate=0.1)
- SGD 클래스의 학습률 기본값은 0.01이고 이렇게 learning_rate 매개변수에 지정하여 바꿀 수 있다.
② SGD 클래스의 momentum 매개변수의 기본값은 0이다.
0보다 큰 값으로 지정하면 이전의 그레이디언트를 가속도처럼 사용하는 모멘텀 최적화를 사용한다.
(보통 0.9 이상으로 지정)
sgd = keras.optimizers.SGD(momentum=0.9, nesterov=True)
- nesterov를 기본값 False에서 True로 바꾸면 네스테로프 모멘텀 최적화를 사용한다.
- 네스테로프 모멘텀은 모멘텀 최적화를 2번 반복하여 구현함
- 대부분의 경우 네스테로프 모멘텀 최적화가 기본 확률적 경사 하강법보다 더 나은 성능을 제공
③ 모델이 최적점에 가까이 갈수록 학습률을 낮출 수 있다.
안정적으로 최적점에 수렴하는 학습률을 적응적 학습률이라 하고, 대표적인 옵티마이저는 Adagrad, RMSprop이다.
adagrad = keras.optimizers.Adagrad()
model.compile(optimizer=adagrad, loss='sparse_categorical_crossentropy', metrics='accuracy')
rmsprop = keras.optimizers.RMSprop()
model.compile(optimizer=rmsprop, loss='sparse_categorical_crossentropy', metrics='accuracy')
- 이렇게 optimizer 변수에 지정하여 쓸 수 있고, optimizer 매개변수의 기본값이 바로 rmsprop이다.
④ 모멘텀 최적화와 RMSprop의 장점을 접목한 것이 Adam이다.
마지막으로 Adam 클래스의 매개변수 기본값을 사용해 패션 MNIST 모델을 훈련해보자
model = keras.Sequential()
model.add(keras.layers.Flatten(input_shape=(28,28)))
model.add(keras.layers.Dense(100, activation='relu'))
model.add(keras.layers.Dense(10, activation='softmax'))
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics='accuracy')
model.fit(train_scaled, train_target, epochs=5)
- compile() 메서드의 optimizer를 adam으로 설정하고 5번의 에포크 동안 훈련
- 기본 RMSprop을 사용했을 때와 adam을 사용했을 때 거의 같은 성능을 보여주는 것을 확인할 수 있다.
마지막으로 검증 세트에서의 성능을 확인해보면
model.evaluate(val_scaled, val_target)
기본 RMSprop보다 조금 나은 성능을 내는 것으로 보인다.
▶ 정리
- 키워드 : 심층 신경망, 렐루 함수, 옵티마이저
- SGD 기본 경사 하강법 옵티마이저 클래스
- momentum 매개변수에 0 이상의 값을 지정하면 모멘텀 최적화를 수행
- nesterov 매개변수를 True로 설정하면 네스테로프 모멘텀 최적화를 수행
- Adagrad 옵티마이저 클래스
- 그레이디언트 제곱을 누적하여 학습률을 나눔
- initial_accumulator_value 매개변수에서 누적 초깃값을 지정할 수 있음 기본값은 0.1
- RMSprop 옵티마이저 클래스
- Adagrad처럼 그레이디언트 제곱으로 학습률을 나누지만 최근의 그레이디언트를 사용하기 위해 지수 감소를 사용
- rho 매개변수에서 감소 비율을 지정하며 기본값은 0.9
- Adam
- 모멘텀 최적화에 있는 그레이디언트의 지수 감소 평균을 조정하기 위해 beta_1 매개변수가 있으며 기본값은 0.9
- RMSprop에 있는 그레이디언트 제곱의 지수 감소 평균을 조절하기 위해 beta_2 매개변수가 있으며 기본값은 0.999
=> SGD, Adagrad, RMSprop, Adam 모두 learning_rate 매개변수로 학습률을 지정하며 기본값은 0.001이다.
'Python > ML & DL 공부' 카테고리의 다른 글
[DL] 08-2 합성곱 신경망을 사용한 이미지 분류 (+ 08-1) (0) | 2022.04.06 |
---|---|
[DL] 07-3 신경망 모델 훈련 (0) | 2022.03.27 |
[DL] 07-1 인공 신경망 (0) | 2022.03.20 |
[ML] 06-3 주성분 분석 (0) | 2022.03.12 |
[ML] 06-2 k-평균 알고리즘 (0) | 2022.03.12 |