머신러닝 19일차

ParkJinYoung·2022년 11월 11일
0

드롭아웃

과대적합을 피하기위해사용
입력층 => 중간층 사이 ✔"학습하는 동안"✔
모두 다른 선형함수 중 중간층에 어떤 입력층이 영향을 많이 끼쳤는지에 따라 학습이 반복되면 점점더 그 크기가 증가, 또는 감소하는 입력층을 방지한다.

데이터 확장

드롭아웃과 마찬가지로 과대적합을 피하기위해 사용
양질의 데이터를 얻기 힘들기에 있는 데이터에서 조금의 편집을 사용해서 개수를 늘린다.

# 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)
profile
꾸준히

0개의 댓글