과대적합을 피하기위해사용
입력층 => 중간층 사이 ✔"학습하는 동안"✔
모두 다른 선형함수 중 중간층에 어떤 입력층이 영향을 많이 끼쳤는지에 따라 학습이 반복되면 점점더 그 크기가 증가, 또는 감소하는 입력층을 방지한다.
드롭아웃과 마찬가지로 과대적합을 피하기위해 사용
양질의 데이터를 얻기 힘들기에있는 데이터
에서 조금의 편집을 사용해서 개수를 늘린다.
# Dropout 추가
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense, Conv2D, MaxPool2D, Flatten , Dropout
# Flatten 2차원을 1차원으로 만들어줌
model2 = Sequential()
# 입력층, 특징 추출부
model2.add(
Conv2D( # 특징이 될만한 것들 사이즈만큼을 기준으로 찾는다 무작위로
filters = 32, # 찾을 특징의 갯수 = 뉴런
kernel_size = (3,3), # 특징의 크기
input_shape = (150,150,3), # 입력 데이터의 모양(RGB)
padding = 'same',
activation = 'relu'
)
)
model2.add(
MaxPool2D( # 특징이 아닌부분 삭제
pool_size = (2,2) # 기준 크기(2,2)에서 1개의 특징만 가져오기
)
)
model2.add(Dropout(0.3))
#중간층
model2.add(
Conv2D( # 특징이 될만한 것들 사이즈만큼을 기준으로 찾는다 무작위로
filters = 16, # 찾을 특징의 갯수 = 뉴런
kernel_size = (3,3), # 특징의 크기
padding = 'same',
activation = 'relu'
)
)
model2.add(
MaxPool2D( # 특징이 아닌부분 삭제
pool_size = (2,2) # 기준 크기(2,2)에서 1개의 특징만 가져오기
)
)
model2.add(Dropout(0.3))
#✔✔✔✔✔ 특징 추출 끝
model2.add(Flatten()) # 1차원으로 만들어 주기
#✔✔✔✔✔ 분류 시작
model2.add(Dense(units= 64, activation='relu'))
model2.add(Dense(units= 16, activation='relu'))
# 출력층
model2.add(Dense(units = 1,activation='sigmoid'))
model2.summary()
model2.compile(
loss = 'binary_crossentropy',
optimizer = 'adam',
metrics =['accuracy']
)
model2.fit_generator(
generator = train_generator,
epochs=20,
validation_data = val_generator
)
# 데이터 확장
aug_generator = ImageDataGenerator(
rescale = 1./255,
rotation_range = 20,
width_shift_range = 0.1,
height_shift_range = 0.1,
shear_range = 0.1,
zoom_range = 0.1,
horizontal_flip = True,
fill_mode = 'nearest' # 가까운 값으로 채움
)
train_aug_generator = aug_generator.flow_from_directory(
train_dir,
target_size = (150,150),
batch_size = 100,
class_mode = 'binary'
)
model3 = Sequential()
# 입력층, 특징 추출부
model3.add(
Conv2D( # 특징이 될만한 것들 사이즈만큼을 기준으로 찾는다 무작위로
filters = 32, # 찾을 특징의 갯수 = 뉴런
kernel_size = (3,3), # 특징의 크기
input_shape = (150,150,3), # 입력 데이터의 모양(RGB)
padding = 'same',
activation = 'relu'
)
)
model3.add(
MaxPool2D( # 특징이 아닌부분 삭제
pool_size = (2,2) # 기준 크기(2,2)에서 1개의 특징만 가져오기
)
)
model3.add(Dropout(0.3))
#중간층
model3.add(
Conv2D( # 특징이 될만한 것들 사이즈만큼을 기준으로 찾는다 무작위로
filters = 16, # 찾을 특징의 갯수 = 뉴런
kernel_size = (3,3), # 특징의 크기
padding = 'same',
activation = 'relu'
)
)
model3.add(
MaxPool2D( # 특징이 아닌부분 삭제
pool_size = (2,2) # 기준 크기(2,2)에서 1개의 특징만 가져오기
)
)
model3.add(Dropout(0.3))
#✔✔✔✔✔ 특징 추출 끝
model3.add(Flatten()) # 1차원으로 만들어 주기
#✔✔✔✔✔ 분류 시작
model3.add(Dense(units= 64, activation='relu'))
model3.add(Dense(units= 16, activation='relu'))
# 출력층
model3.add(Dense(units = 1,activation='sigmoid'))
model3.summary()
model3.compile(
loss = 'binary_crossentropy',
optimizer = 'adam',
metrics =['accuracy']
)
# fit에서 확장된 데이터가 추가된다
model3.fit_generator(
generator = train_aug_generator,
# steps_per_epoch = 40,
epochs=20,
validation_data = val_generator
)
# 전이 학습
# 다른사람이 유사한 데이터로 학습 해놓은 모델 가져와서 사용하기
from tensorflow.keras.applications import VGG16
conv_base = VGG16(
weights = 'imagenet',
include_top = False, # 분류기 사용할것인가/아닌가
input_shape = (150,150,3)
)
conv_base.summary()
# 동결
# 가중치가 갱신되는것을 막는것
# 학습 가능한 가중치의 개수
# conv * 2
len(conv_base.trainable_weights)
# VGG16 전체 층에 대해 동결
conv_base.trainable = False
len(conv_base.trainable_weights)
# 특성 추출 방식
# 빠른 사용 가능
# 특성 추출이 잘 안되면 성능 저하
# 분류기 직접 설계 / 학습
model4=Sequential()
# conv 13개층 pool 5개층이 추가
model4.add(conv_base)
model4.add(Flatten())
model4.add(Dense(64,activation='relu'))
model4.add(Dense(1,activation='sigmoid'))
model4.summary()
model4.compile(
loss = 'binary_crossentropy',
optimizer = 'adam',
metrics =['accuracy']
)
model4.fit_generator(
generator = train_aug_generator,
# steps_per_epoch = 40,
epochs=20,
validation_data = val_generator
)
# 미세 조정 : 사전 학습된 기본 네트워크 (VGG 16)에 새로운 네트워크 (Dense)를 추가
# 특성 추출부를 조금씩 수정
# 전체층 동결이 선행으로 이루어져야한다.
conv_base.trainable = False
# 전체동결 후 분류기 학습, 분류기의 오차가 발생하지 않는 것을 확인한 후
# block5_conv1, block5_conv2, block5_conv3 학습하기
# 이미 오차가 작은 상황이라 수정이 많이 일어나진 않음 => 오차가 작아지는걸 확인
# block4_conv1, block4_conv2, block4_conv3 학습하기
#
set_trainable = False
for layer in conv_base.layers:
if layer.name == 'block5_conv1':
set_trainable = True
if set_trainable == True:
layer.trainable = True
else:
layer.trainable = False
for layer in conv_base.layers:
print(layer.name)