Study/class note
딥러닝 / VGG16 동결
chanzae
2022. 4. 30. 17:45
ㅇ vgg16 신경망 동결 시킨것과 동결 시키지 않은것의 차이 (코랩에서 진행)
동결(freezing) 한다는 것운 훈련기간동안 가중치가 업데이드 되지 않도록 막는다는 뜻이다.
# vgg16을 사용해서 학습 시키기 실험
# 필요한 패키지 임폴트 받기
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPool2D, Dense, Flatten, BatchNormalization, Activation, Dropout
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.applications import VGG16 # VGG16 신경망 설계도를 가져옵니다.
#2. cifar10 데이터를 준비합니다.
# 데이터 준비하기
from tensorflow.keras.datasets import cifar10
import numpy as np
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
# 데이터를 표준화 합니다.
# 평균과 표준편차는 채널별로 구해줍니다.
x_mean = np.mean(x_train, axis = (0, 1, 2)) # 평균값을 구합니다.
x_std = np.std(x_train, axis = (0, 1, 2)) # 표준편차를 구합니다.
x_train = (x_train - x_mean) / x_std # 훈련 데이터를 표준화 합니다.
x_test = (x_test - x_mean) / x_std # 테스트 데이터를 표준화 합니다.
# 밑바닥 부터 시작하는 딥러닝 책에서는 min/max 정규화를 사용했었습니다.
# 여기서는 표준화를 하고 있는데 vgg 라고 해서 꼭 표준화를 하는건 아닙니다.
# min/max 정규화를 해도 됩니다.
#3. 훈련 데이터를 검정 데이터로 나눕니다.
from sklearn.model_selection import train_test_split
x_train, x_val, y_train, y_val = train_test_split(x_train, y_train, test_size = 0.1, random_state = 777)
# 훈련 데이터의 일부를 떼서 테스트 데이터(검정 데이터)로 사용하면서 훈련 시킵니다.
#4. vgg16 신경망을 가져옵니다.
# imagenet을 학습한 모델을 불러옵니다.
vgg16 = VGG16(weights = 'imagenet', input_shape = (32, 32, 3), include_top = False) # include_top = False 완전연결계층 알아서 분류 하겠음
vgg16.summary()
1. 동결해제 했을 때
cnt = 0
for layer in vgg16.layers[:]:
layer.trainable = True # False 는 동결 (option), True 는 동결해제(기본값)
print(layer)
cnt = cnt + 1
print(cnt)
#7. vgg16 신경망에 완전 연결계층을 붙입니다.
model = Sequential()
# vgg16 모델을 사용합니다.
model.add(vgg16)
# 분류기를 직접 정의합니다.
model.add(Flatten())
model.add(Dense(256))
model.add(BatchNormalization())
model.add(Dropout(0.4))
model.add(Activation('relu'))
model.add(Dense(10, activation = 'softmax')) #클래스 분류에 따라 출력층 뉴런의 수 달라짐
#8. 모델을 설정합니다.
model.compile(optimizer = Adam(1e-4), # 러닝레이트를 0.0001 로 지정하면서 Adam 을 쓰겠다고 합니다.
loss = 'sparse_categorical_crossentropy',
metrics = ['acc'])
model.summary()
합성곱층 레이어의 가중치도 동결해제했기 때문에 훈련가능한 파라미터 14,849,098
#9. 조기종료 옵션을 지정합니다.
from keras.callbacks import ModelCheckpoint, EarlyStopping
callbacks = [ EarlyStopping(monitor='val_acc', patience=10, verbose=1) ]
#10. 모델을 훈련시킵니다.
history = model.fit(x_train, y_train,epochs = 200, batch_size=100,validation_data = (x_val, y_val),callbacks=callbacks)
2. 동결했을 때
cnt = 0
for layer in vgg16.layers[:]:
layer.trainable = False # False 는 동결 (option), True 는 동결해제(기본값)
print(layer)
cnt = cnt + 1
print(cnt)
#7. vgg16 신경망에 완전 연결계층을 붙입니다.
model = Sequential()
# vgg16 모델을 사용합니다.
model.add(vgg16)
# 분류기를 직접 정의합니다.
model.add(Flatten())
model.add(Dense(256))
model.add(BatchNormalization())
model.add(Dropout(0.4))
model.add(Activation('relu'))
model.add(Dense(10, activation = 'softmax'))
#8. 모델을 설정합니다.
model.compile(optimizer = Adam(1e-4), # 러닝레이트를 0.0001 로 지정하면서 Adam 을 쓰겠다고 합니다.
loss = 'sparse_categorical_crossentropy',
metrics = ['acc'])
model.summary()
동결했을 때 정확도가 훨씬 낮게 나옴. 합성곱층의 가중치를 모두 동결히켰기 때문에 훈련 가능한 파라미터 134.410개.
아래의 코드를 사용해서 vgg16가중치를 동결 혹은 동결해제 했을 때 테스트 결과 동결을 해제하고 다시 새롭게 가중치를 생성한게 더 좋은 결과가 나왔음.
cnt = 0
for layer in vgg16.layers[:]:
layer.trainable = False # False 는 동결 (option), True 는 동결해제(기본값)
print(layer)
cnt = cnt + 1
print(cnt)
아래의 한줄이면 vgg16 모델 설계도를 쉽게 가져올 수 있음.
from tensorflow.keras.applications import VGG16
vgg16 = VGG16(weights = 'imagenet', input_shape = (32,32,3), include_top = False)
반응형