딥러닝

[딥러닝] 활성화 함수, 최적화 함수(패션데이터)

퓨어맨 2022. 7. 21. 13:57
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from tensorflow.keras.datasets import fashion_mnist

data = fashion_mnist.load_data()
data

(X_train, y_train),(X_test, y_test) = data

print(X_train.shape)
print(y_train.shape)
print(X_test.shape)
print(y_test.shape)
(60000, 28, 28)
(60000,)
(10000, 28, 28)
(10000,)

 

 

y_train_one_hot = pd.get_dummies(y_train)
y_test_one_hot = pd.get_dummies(y_test)

from sklearn.model_selection import train_test_split

X_train, X_val, y_train_one_hot, y_val_one_hot = train_test_split(X_train,
                                                                  y_train_one_hot,
                                                                  random_state=3
                                                                  )
                                                                  
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense, Flatten
# Flatten : 데이터를 1차원으로 자동적으로 펴주는 역할을 하는 모듈

 

활성화함수, 최적화함수 별 비교

  • 1.중간층 활성화함수 : sigmoid, 최적화함수 : SGD
  • 2.중간층 활성화함수 : relu, 최적화함수 : SGD
  • 3.중간층 활성화함수 : relu, 최적화함수 : Adam
# 1. sigmoid+SGD
model = Sequential()

model.add(Flatten(input_shape=(28,28)))

# 중간층
model.add(Dense(200, activation='sigmoid'))
model.add(Dense(100, activation='sigmoid'))
model.add(Dense(50, activation='sigmoid'))

# 출력층 뉴런의 개수는 원핫인코딩 된 컬럼 개수
model.add(Dense(10, activation='softmax'))

# 학습 및 평가방법 설정
# categorical_crossentropy : 다중분류에 사용하는 손실함수
model.compile(loss='categorical_crossentropy',
              optimizer='SGD',   # 최적화함수 : 최근에 가장 많이 사용되는 일반적으로 성능이 좋은 최적화함
              metrics=['acc']    # metrics : 평가방법을 설정(분류문제이기 때문에 정확도를 넣어줌)
              )

# 학습
h = model.fit(X_train, y_train_one_hot, validation_split=0.3,
              epochs=50,
              batch_size=128
              )

 

# 최적화함수 하이퍼파라미터 조정을 위해 임포트
from tensorflow.keras.optimizers import SGD
# 2. relu + SGD
model1 = Sequential()

model1.add(Flatten(input_shape=(28,28)))

# 중간층
model1.add(Dense(200, activation='relu'))
model1.add(Dense(100, activation='relu'))
model1.add(Dense(50, activation='relu'))

# 출력층 뉴런의 개수는 원핫인코딩 된 컬럼 개수
model1.add(Dense(10, activation='softmax'))

# 학습 및 평가방법 설정
# categorical_crossentropy : 다중분류에 사용하는 손실함수
model1.compile(loss='categorical_crossentropy',
              optimizer=SGD(lr=0.001),   # 최적화함수 : 최근에 가장 많이 사용되는 일반적으로 성능이 좋은 최적화함
              metrics=['acc']    # metrics : 평가방법을 설정(분류문제이기 때문에 정확도를 넣어줌)
              )

# 학습
h1 = model1.fit(X_train, y_train_one_hot, validation_split=0.3,
              epochs=50,
              batch_size=128
              )

 

 

#3. relu+Adam
model2 = Sequential()

model2.add(Flatten(input_shape=(28,28)))

# 중간층
model2.add(Dense(200, activation='relu'))
model2.add(Dense(100, activation='relu'))
model2.add(Dense(50, activation='relu'))

# 출력층 뉴런의 개수는 원핫인코딩 된 컬럼 개수
model2.add(Dense(10, activation='softmax'))

# 학습 및 평가방법 설정
# categorical_crossentropy : 다중분류에 사용하는 손실함수
model2.compile(loss='categorical_crossentropy',
              optimizer='Adam',   # 최적화함수 : 최근에 가장 많이 사용되는 일반적으로 성능이 좋은 최적화함
              metrics=['acc']    # metrics : 평가방법을 설정(분류문제이기 때문에 정확도를 넣어줌)
              )

# 학습
h2 = model2.fit(X_train, y_train_one_hot, validation_split=0.3,
              epochs=50,
              batch_size=128
              )

 

 

plt.figure(figsize=(15,10))

# model
plt.plot(h.history['acc'],
         label='sigmoid+SGD'
         )

plt.plot(h.history['val_acc'],
         label='val_sigmoid+SGD'
         )

plt.plot(h1.history['acc'],
         label='relu+SGD'
         )

# val 데이터
plt.plot(h1.history['val_acc'],
         label='val_relu+SGD'
         )

plt.plot(h2.history['acc'],
         label='relu+Adam'
         )

# val 데이터
plt.plot(h2.history['val_acc'],
         label='val_relu+Adam'
         )

plt.legend()
plt.show()

 

최적화 모델 찾기

  • ModelCheckpoint(모델체크포인트) : 기준에 맞는 모델을 저장
  • EarlyStopping(얼리스탑핑) : 조기 학습 중단(과대적합 및 시간낭비 방지)
from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping

# 1. 모델 저장
# 저장 경로 및 파일명 형태 지정
save_path = '/content/drive/MyDrive/Colab Notebooks/빅데이터 13차(딥러닝)/Model/FashionModel_{epoch:03d}_{val_acc:.4f}.hdf5'
# d : 10진수 형태, 03 -> 0이 3개 붙어있는 형태의 자리수(001,002,003...)
# f : 소수점 형태, .4 -> 소수점 4자리 까지 형태의 자리수(0.001, 0.002, 0.003...)
# hdf5 : 저장되는 모델의 확장자명

f_mckp = ModelCheckpoint(filepath = save_path,   # 파일 경로 설정
                         monitor = 'val_acc',    # 해당 값을 기준으로 모델 파일을 저장
                         save_best_only = True,  # monitor값이 가장 최고점 혹은 최저점을 갱신 했을때 모델을 저장
                         mode = 'max',           # save_best_only가 True일 경우 모니터링하는 값의 최대 or 최소를 결정
                         verbose = 1             # 모델이 개선되거나 저장되는 메시지를 표시
                         )
                         
# 2. 학습 조기 중단
f_early = EarlyStopping(monitor='val_acc',
                        # monitor 값의 개선을 몇번이나 기다려줄지 결정
                        patience=5
                        )
# => 모델 학습시 val_acc가 5번의 epochs를 돌 동안 개선되지 않으면 중단시켜주세요
#3. relu+Adam
model3 = Sequential()

model3.add(Flatten(input_shape=(28,28)))

# 중간층
model3.add(Dense(200, activation='relu'))
model3.add(Dense(100, activation='relu'))
model3.add(Dense(50, activation='relu'))

# 출력층 뉴런의 개수는 원핫인코딩 된 컬럼 개수
model3.add(Dense(10, activation='softmax'))

# 학습 및 평가방법 설정
# categorical_crossentropy : 다중분류에 사용하는 손실함수
model3.compile(loss='categorical_crossentropy',
              optimizer='Adam',   # 최적화함수 : 최근에 가장 많이 사용되는 일반적으로 성능이 좋은 최적화함
              metrics=['acc']    # metrics : 평가방법을 설정(분류문제이기 때문에 정확도를 넣어줌)
              )

# 학습
h3 = model3.fit(X_train, y_train_one_hot, validation_split=0.3,
              epochs=50,
              batch_size=128,
              # 모델체크포인트, 얼리스탑핑 설정
              callbacks=[f_mckp, f_early]
              )

 

 

  • 저장된 모델 로딩하기
from tensorflow.keras.models import load_model

best_model = load_model("/content/drive/MyDrive/Colab Notebooks/빅데이터 13차(딥러닝)/Model/FashionModel_011_0.8496.hdf5")

best_model.evaluate(X_test, y_test_one_hot)
313/313 [==============================] - 1s 2ms/step - loss: 0.5077 - acc: 0.8411
[0.507684051990509, 0.8410999774932861]