Notice
Recent Posts
Recent Comments
Link
«   2025/09   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
Tags
more
Archives
Today
Total
관리 메뉴

kang's study

17일차 : 신경망 모델 본문

[학습 공간]/[혼공머신러닝]

17일차 : 신경망 모델

보끔밥0302 2022. 3. 3. 06:58

신경망 모델 훈련

In [31]:
from tensorflow import keras
from sklearn.model_selection import train_test_split

(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)
In [32]:
def model_fn(a_layer=None):
    model = keras.Sequential()
    model.add(keras.layers.Flatten(input_shape=(28, 28)))
    model.add(keras.layers.Dense(100, activation='relu'))
    if a_layer:
        model.add(a_layer)
    model.add(keras.layers.Dense(10, activation='softmax'))
    return model
  # 마지막 층은 분류하려는 클래스의 개수와 동일해야 한다
  # 은닉층은 적절한 시행착오 또는 다른 신경망 모형을 찬고하여 정해야한다.
  # 은닉층에 활성화 함수가 필요하다
  # 유닛마다 계산되는 가중치는 각각 다르다 (구분되야 함)
In [33]:
model = model_fn()

model.summary()
 
Model: "sequential_9"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 flatten_9 (Flatten)         (None, 784)               0         
                                                                 
 dense_18 (Dense)            (None, 100)               78500     
                                                                 
 dense_19 (Dense)            (None, 10)                1010      
                                                                 
=================================================================
Total params: 79,510
Trainable params: 79,510
Non-trainable params: 0
_________________________________________________________________
 

손실 곡선

In [34]:
model.compile(loss='sparse_categorical_crossentropy', metrics='accuracy')

history = model.fit(train_scaled, train_target, epochs=5, verbose=0)
In [35]:
print(history.history.keys())
 
dict_keys(['loss', 'accuracy'])
In [36]:
import matplotlib.pyplot as plt

plt.plot(history.history['loss'])
plt.xlabel('epoch')
plt.ylabel('loss')
plt.show()
 
In [37]:
plt.plot(history.history['accuracy'])
plt.xlabel('epoch')
plt.ylabel('accuracy')
plt.show()
 
 
더 많은 에포크
In [38]:
model = model_fn()
model.compile(loss='sparse_categorical_crossentropy', metrics='accuracy')

history = model.fit(train_scaled, train_target, epochs=20, verbose=0)
In [39]:
plt.plot(history.history['loss'])
plt.xlabel('epoch')
plt.ylabel('loss')
plt.show()
 
 

검증 손실

검증 세트 사용하는 방법
In [40]:
model = model_fn()
model.compile(loss='sparse_categorical_crossentropy', metrics='accuracy')

history = model.fit(train_scaled, train_target, epochs=20, verbose=0, 
                    validation_data=(val_scaled, val_target))
In [41]:
print(history.history.keys())
 
dict_keys(['loss', 'accuracy', 'val_loss', 'val_accuracy'])
In [42]:
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.xlabel('epoch')
plt.ylabel('loss')
plt.legend(['train', 'val'])
plt.show()
 
In [43]:
model = model_fn()
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', 
              metrics='accuracy')

history = model.fit(train_scaled, train_target, epochs=20, verbose=0, 
                    validation_data=(val_scaled, val_target))
In [44]:
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.xlabel('epoch')
plt.ylabel('loss')
plt.legend(['train', 'val'])
plt.show()
 
 

드롭아웃

신경망 모델 규제방법 (과대적합 방지)
훈련할 때 랜덤하게 은닉층 뉴런을 꺼버린다 (특정 뉴런에 과도하게 의존하지 않게함)
In [45]:
model = model_fn(keras.layers.Dropout(0.3)) #은닉층 다음에 설정한다.

model.summary()
 
Model: "sequential_13"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 flatten_13 (Flatten)        (None, 784)               0         
                                                                 
 dense_26 (Dense)            (None, 100)               78500     
                                                                 
 dropout_5 (Dropout)         (None, 100)               0         
                                                                 
 dense_27 (Dense)            (None, 10)                1010      
                                                                 
=================================================================
Total params: 79,510
Trainable params: 79,510
Non-trainable params: 0
_________________________________________________________________
In [46]:
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', 
              metrics='accuracy')

history = model.fit(train_scaled, train_target, epochs=20, verbose=0, 
                    validation_data=(val_scaled, val_target))
In [47]:
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.xlabel('epoch')
plt.ylabel('loss')
plt.legend(['train', 'val'])
plt.show()
 
 

모델 저장과 복원

In [48]:
model = model_fn(keras.layers.Dropout(0.3))
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', 
              metrics='accuracy')

history = model.fit(train_scaled, train_target, epochs=10, verbose=0, 
                    validation_data=(val_scaled, val_target))
In [49]:
model.save_weights('model-weights.h5') # 모델 저장 (가중치만 저장)
In [50]:
model.save('model-whole.h5') # 모델 저장 (데이터 구조까지 저장)
In [51]:
!ls -al *.h5
 
'ls'은(는) 내부 또는 외부 명령, 실행할 수 있는 프로그램, 또는
배치 파일이 아닙니다.
In [52]:
model = model_fn(keras.layers.Dropout(0.3))

model.load_weights('model-weights.h5') # 모델 복원

 

In [53]:
import numpy as np

val_labels = np.argmax(model.predict(val_scaled), axis=-1) 
# 마지막 인덱스 여기선 2차원으로 axis=1
# predict로 각 샘플에서 높은 확률를 뽑아 예측클래스로 사용
print(np.mean(val_labels == val_target))
 
0.8784166666666666
In [54]:
model = keras.models.load_model('model-whole.h5') # 모델 적용

model.evaluate(val_scaled, val_target)
 
375/375 [==============================] - 0s 977us/step - loss: 0.3380 - accuracy: 0.8784
Out[54]:
[0.3379617929458618, 0.8784166574478149]
 

콜백

훈련하던 도중에 지정한 작업을 수행
In [55]:
model = model_fn(keras.layers.Dropout(0.3))
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', 
              metrics='accuracy')

checkpoint_cb = keras.callbacks.ModelCheckpoint('best-model.h5', 
                                                save_best_only=True)
# 가장 낮은 손실값이 되는 값의 모델 가중치를 저장해준다.
model.fit(train_scaled, train_target, epochs=20, verbose=0, 
          validation_data=(val_scaled, val_target),
          callbacks=[checkpoint_cb])
Out[55]:
<keras.callbacks.History at 0x1ff4f101220>
In [56]:
model = keras.models.load_model('best-model.h5')

model.evaluate(val_scaled, val_target)
 
375/375 [==============================] - 0s 978us/step - loss: 0.3194 - accuracy: 0.8867
Out[56]:
[0.31939342617988586, 0.8867499828338623]
 
조기종료
In [57]:
model = model_fn(keras.layers.Dropout(0.3))
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', 
              metrics='accuracy')

checkpoint_cb = keras.callbacks.ModelCheckpoint('best-model.h5', 
                                                save_best_only=True)
early_stopping_cb = keras.callbacks.EarlyStopping(patience=2,
                                                  restore_best_weights=True)
# 증가하는 부분을 몇번 에포크까지 참고 기다려볼지
# 가장 낮은 손실의 가중치를 써라
history = model.fit(train_scaled, train_target, epochs=20, verbose=0, 
                    validation_data=(val_scaled, val_target),
                    callbacks=[checkpoint_cb, early_stopping_cb])
In [58]:
print(early_stopping_cb.stopped_epoch) # 몇 번 에포크에서 멈추었나 
# 0부터 patience 제외한 지점에서 훈련을 멈췄다
 
6
In [59]:
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.xlabel('epoch')
plt.ylabel('loss')
plt.legend(['train', 'val'])
plt.show()
 
In [60]:
model.evaluate(val_scaled, val_target)
 
375/375 [==============================] - 0s 1ms/step - loss: 0.3454 - accuracy: 0.8736
Out[60]:
[0.34544962644577026, 0.8735833168029785]
 
지금까지 이미지 데이터를 1차원으로 펼쳐서 사용해봤다.
다음으로 합성곱 신경망을 사용하여 이미지 데이터를 그대로 신경망에 넣어서 효과적으로 학습하는 방법을 배워보자

출처 : 박해선, 『혼자공부하는머신러닝+딥러닝』, 한빛미디어(2021), p392-417

Comments