[chap 7-2] 심층 신경망
📌 인공 신경망에 층을 여러개 추가하여 데이터셋을 분류하면서 심층 신경망을 만들기 (디벨롬)
1️⃣ 데이터셋 가져오기
from tensorflow import keras
(train_input, train_target), (test_input, test_target) = keras.datasets.fashion_mnist.load_data()
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)
인공 신경망 모델에 층을 2개 추가해 볼 것이다.
2️⃣ 은닉층 추가하기 => 심층 신경망 만들기
앞 장에서는 입력층 ~ 출력층 -> 활성화 함수 이런 식으로 훈련했었는데, 층을 추가하게 된다면 입력층과 출력층 사이에 은닉층 을 추가하게 되는 것이다.
출력층에 적용하는 활성화 함수의 종류는 시그모이드 함수와 소프트맥스 함수로 제한되어 있으나, 은닉층의 활성화 함수는 비교적 자유롭다.
📍 은닉층 추가하는 법 #1
dense1 = keras.layers.Dense(100, activation='sigmoid', input_shape=(784, )) # 은닉층, 100개의 뉴런 포함
dense2 = keras.layers.Dense(10, activation='softmax') # 은닉층, 10개의 뉴런 포함
model = keras.Sequential([dense1, dense2])
model.summary()
>>>
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense (Dense) (None, 100) 78500
dense_1 (Dense) (None, 10) 1010
=================================================================
Total params: 79,510
Trainable params: 79,510
Non-trainable params: 0
_________________________________________________________________
- Output Shape 부분 -> output이 None인 이유: output은 샘플 개수를 나타내는데 아직 케라스 모델의 fit() 메소드에 훈련 데이터를 주입하면 미니 배치 경사 하강법을 사용하기 때문에 샘플 개수를 고정하지 않고, 어떤 배치 크기에도 유연하게 대응할 수 있도록 None으로 설정
📍 은닉층 추가하는 법 #2
model = keras.Sequential([keras.layers.Dense(100, activation='sigmoid', input_shape=(784, ), name='hidden'),
keras.layers.Dense(10, activation='softmax', name='output')], name="패션 MNIST 모델")
-> 추가되는 층을 한눈에 쉽게 알아볼 수 있는 장점이 있다.
📍 은닉층 추가하는 법 #3
model = keras.Sequential()
model.add(keras.layers.Dense(100, activation='sigmoid', input_shape=(784, )))
model.add(keras.layers.Dense(10, activation='softmax'))
-> 한눈에 추가되는 층을 볼 수 있고, 프로그램 실행 시 동적으로 층을 선택하여 추가할 수 있다.
🔮 렐루 함수
시그모이드 함수 -> 0 또는 1로 수렴하는 함수이므로 올바른 출력을 만드는데 신속하게 대응하지 못함 -> sol. 렐루 함수
렐루 함수는 입력이 양수일 때는 활성화 함수가 없는 것처럼 그냥 입력을 통과시키고, 음수일 경우는 0으로 만든다.
- max(0, z) : 같이 사용할 수 있는데, z가 0보다 크면 z를 출력, 아니면 0을 출력
- 이미지 처리에서 좋은 성능을 나타낸다고 알려져 있다.
3️⃣ 렐루 함수를 사용하여서 심층 신경망 만들기
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.summary()
>>>
Model: "sequential_4"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
flatten (Flatten) (None, 784) 0
dense_8 (Dense) (None, 100) 78500
dense_9 (Dense) (None, 10) 1010
=================================================================
Total params: 79,510
Trainable params: 79,510
Non-trainable params: 0
_________________________________________________________________
- Flattern : 입력 차원을 모두 일렬로 펼치는 역할(앞 장에서는 reshape()를 통해서 1차원 배열로 픽셀들의 배치를 바꾸어줌)
(train_input, train_target), (test_input, test_train) = 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)
>>>
Epoch 1/5
1500/1500 [==============================] - 3s 2ms/step - loss: 0.5313 - accuracy: 0.8135
Epoch 2/5
1500/1500 [==============================] - 3s 2ms/step - loss: 0.3905 - accuracy: 0.8596
Epoch 3/5
1500/1500 [==============================] - 3s 2ms/step - loss: 0.3565 - accuracy: 0.8714
Epoch 4/5
1500/1500 [==============================] - 3s 2ms/step - loss: 0.3364 - accuracy: 0.8781
Epoch 5/5
1500/1500 [==============================] - 3s 2ms/step - loss: 0.3212 - accuracy: 0.8860
<keras.callbacks.History at 0x7fe62ecdb390>
model.evaluate(val_scaled, val_target)
>>>
375/375 [==============================] - 1s 1ms/step - loss: 0.3612 - accuracy: 0.8784
[0.3612439036369324, 0.8784166574478149]
❗ 지금까지는 에포크를 5로 지정을 해두었지만, 이 값을 늘려서 더 훈련을 시킬 수 있다. ❗
옵티마이저
케라스의 경우 기본 경사 하강법 알고리즘을 사용했지만, 이를 다양한 종류의 경사 하강법 알고리즘으로 바꿀 수 있다. 이런 알고리즘들을 옵티마이저 라고 부른다.
📍 SGD : 가장 기본 옵티마이저
SGD는 미니 배치 경사 하강법을 사용한다.
model.compile(optimizer='sgd', loss='sparse_categorical_crossentropy', metrics='accuracy')
SGD 클래스의 매개변수
- momentum : 기본값 0, 0보다 큰 값인 경우 모멘텀 최적화를 사용, 일반적으로 0.9 이상 사용
- nesterov : 기본값 False, True로 바꾸면 네스테로프 모멘텀 최적화를 사용.
📍 적응적 학습률을 사용하는 옵티마이저
적응적 학습률이란 모델이 최적점에 가까이 갈수록 학습률을 낮추는 것.
이를 사용하는 대표적 옵티마이저 : Adagrad , RMSprop , Adam (모멘텀 최적화와 RMSprop의 장점 접목)
-> 모두 learning_rate는 0.001을 사용
optimizer=’adam’ 사용하여 훈련해보기
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)
model.evaluate(val_scaled, val_target)
>>>
Epoch 1/5
1500/1500 [==============================] - 3s 2ms/step - loss: 0.5258 - accuracy: 0.8150
Epoch 2/5
1500/1500 [==============================] - 2s 1ms/step - loss: 0.3928 - accuracy: 0.8580
Epoch 3/5
1500/1500 [==============================] - 2s 2ms/step - loss: 0.3555 - accuracy: 0.8697
Epoch 4/5
1500/1500 [==============================] - 2s 2ms/step - loss: 0.3284 - accuracy: 0.8806
Epoch 5/5
1500/1500 [==============================] - 2s 1ms/step - loss: 0.3083 - accuracy: 0.8882
375/375 [==============================] - 1s 1ms/step - loss: 0.3563 - accuracy: 0.8712
[0.3563465178012848, 0.8712499737739563]
87% 정도로 RMSprop보다는 조금 나은 성능을 나타냄
댓글남기기