5장 딥러닝(2) 실습- 전이학습 예제(7단계 추가必)

5장 딥러닝(2) 실습- 전이학습 예제(7단계 추가必)

1. 필요한 라이브러리 호출

2단계. 사전 훈련된 모델 내려받기

- 해당 예제에서 사용할 모델 : 사전 훈련된 ResNet50

model = ResNet50 ( include_top =True,

weights ="imagenet",

input_tensor =None,

input_shape =None,

pooling =None,

classes =1000)

ⓐ include_top : 네트워크(사전 훈련된 모델) 상단에 '완전연결층을 포함'할지의 여부를 지정(기본값: True)

//완전연결층 : 합성곱층, 풀링층을 거쳐 차원이 축소된 특성맵을 전달받음, 이미지를 3차원 벡터에서 1차원 벡터로 펼침

ⓑ weights : 가중치. None(무작위 초기화)과 'imagenet'(ImageNet에서 사전 훈련된 값)을 지정 가능

ⓒ input_tensor : 입력 데이터의 텐서(layers.Input()의 출력)

//텐서 : 데이터의 배열

ⓓ input_shape : 입력 이미지에 대한 텐서 크기

ⓔ pooling : 풀링(sub sampling, 특징 추출)에서 사용할 수 있는 값의 종류

- None : 모델의 출력이 마지막 합성곱층

- avg : 마지막 합성곱층에 글로벌 '평균' 풀링이 추가됨(나누는 과정X, 각 특성 맵에 대해 모든 값을 더하는 단순 합으로 대체)

- max : 마지막 합성곱층에 글로벌 '최대' 풀링이 추가됨

ⓕ classes : 이미지를 분류할 클래스의 선택적 수

- weights로 'imagenet'사용하려면 classes 값이 1000이어야함

(다른 값을 사용하고 싶다면 None으로 지정)

✔ResNet50

- 계층 50개로 구성된 합성곱 신경망

- ImageNet 데이터베이스의 100만 개가 넘는 영상을 이용하여 훈련된 신경망으로, 전이 학습에 사용되도록 사전 훈련된 모델을 제공

- 단점 : 입력 제약이 매우 크고, 충분한 메모리(RAM)가 없으면 학습 속도가 느릴 수 있다

2*단계. 내려받은 ResNet50 네트워크 구조 확인

✔ResNet50 네트워크는 유지, 여기에 추가 계층을 생성해 사용할 것

model.summary()

3단계. 사전 훈련된 합성곱층의 가중치를 고정, 시그모이드 활성화 함수가 포함된 밀집층(완전연결층)을 추가

model. trainable = False

model = Sequential([model,

Dense( 2 , activation= 'sigmoid' )]) #시그모이드 함수가 포함된 밀집층 추가

model.summary()

3단계 실행 결과

ⓐ model.trainable : 훈련 가능/불가능(동결) 지정

ⓑ Sequential() : 순차적으로 레이어층을 더해주는 모델. 각 레이어에 정확히 하나의 입력 텐서와 하나의 출력 텐서가 있는 일반 레이어 스택에 적합

+ Dense() : 밀집층, 입력과 출력을 연결

- 첫번째 인자 : 출력 노드(뉴런)의 수

- activation : 활성화 함수를 설정. ( 'sigmoid' : 이진 분류 문제에서 출력 층에 주로 쓰임)

ⓒ model.summary() 해석

- Layer(type) : 레이어의 이름과 타입(알아서 레이어의 이름을 지정해줌)

- Output Shape: (None, 2)이라는 뜻은 None개의 행과 2개의 아웃풋 값이 주어졌다는 것.

✔행이 None으로 지정되는 이유 : 데이터의 갯수는 계속해서 추가될 수 있기 때문에

딥러닝 모델에서는 주로 행을 무시하고 열의 shape을 맞추어주는 작업을 많이 수행함

- Param: 파라미터의 수, 즉 각 입력노드와 출력노드에 대해 연결된 간선의 수

인풋이 1개, 아웃풋이 5개인 경우, 1*5=5개의 간선이 존재

인풋에 Bias(b) 노드가 추가된 경우, 입력값(1)+바이어스노드(1)=2 총 2개의 인풋 노드 ⇒ 파라미터의 갯수: 2*5 = 10개의 간선

4단계. 훈련에 사용될 환경 설정(활성화함수, 손실함수, 평가지표)

5단계. 모델 훈련(개와 고양이 이미지 데이터셋 이용)

train = ImageDataGenerator(rescale=1./255,

rotation_range=10,

width_shift_range=0.1,

height_shift_range=0.1,

shear_range=0.1,

zoom_range=0.1) ------ ①

train_generator = train.flow_from_directory(train_dir,

target_size=(image_height, image_width),

color_mode="rgb",

batch_size=BATCH_SIZE,

seed=1,

shuffle=True,

class_mode="categorical") ------ ②

valid = ImageDataGenerator(rescale=1.0/255.0)

valid_generator = valid.flow_from_directory(valid_dir,

target_size=(image_height, image_width),

color_mode="rgb",

batch_size=BATCH_SIZE,

seed=7,

shuffle=True,

class_mode="categorical")

history = model.fit(train_generator,

epochs=10,

validation_data = valid_generator,

verbose=2) ------ ③

① ImageDataGenerator : 쉽게 데이터 전처리를 할 수 있음 + 데이터를 증가시킴(augmentation, 기존 데이터에서 새로 생성 된 합성 데이터를 추가 ⇒ 정규화 역할을하며 기계 학습 모델을 학습할 때 과적합을 줄이는 데 도움줌)

ⓐ rescale : 원본 영상은 0~255의 RGB 계수로 구성되는데, 1/255로 스케일링하여 0~1 범위로 변환(원본 값은 모델을 효과적으로 학습시키기에 너무 높음)

ⓑ rotation_range : 이미지 회전 범위. rotation_range=10은 0~10도 범위 내에서 임의로 원본 이미지를 회전하겠다는 의미

ⓒ width_shift_range, height_shift_range : 그림을 수평/수직으로 랜덤하게 평행 이동시키는 범위

값이 0.1, 전체 높이가 100일 경우, 0.1의 값을 적용하면서 10픽셀 내외로 이미지를 좌우/상하로 이동하겠다는 의미

ⓓ shear_range : 원본 이미지를 임의로 변형(전단)시키는 범위(늘이기)

shear_range.0.1은 0.1라디안 내외로 시계 반대 방향으로 이미지를 변환시키겠다는 의미

shear_range : 이미지 전단

ⓔ zoom_range : 임의 확대/축소 범위. zoom_range.0.1은 0.9에서 1.1배의 크기로 이미지를 변환시키겠다는 의미

zoom_range : 확대/축소

② flow_from_directory : 폴더 구조를 그대로 가져와서 ImageDataGenerator에 실제 데이터를 채워줌

ⓐ 첫번째 파라미터 : 훈련 이미지 경로

ⓑ target_size : 이미지 크기(모든 이미지에 적용)

ⓒ color_mode : 이미지가 그레이스케일이면 'grayscale', 색상이 있으면 'rgb' 사용

ⓓ batch_size : 한 배치당 generator에서 생성할 이미지 개수

ⓔ seed : 이미지를 임의로 섞기 위한 랜덤 숫자

ⓕ shuffle : 이미지를 섞어서 사용할지의 여부를 지정

ⓖ class_mode : 예측할 클래스가 두 개뿐이면 'binary', 그렇지 않으면 'categorical'을 선택

③ 모델을 훈련시키기

ⓐ 첫번째 파라미터 : 학습에 사용되는 데이터셋

ⓑ validation_data : 검증 데이터셋 설정

③ verbose : 훈련의 진행과정을 보여줌 (0: 출력X, 1: 훈련 진행도 표시위한 진행 막대 표시, 2: 미니 배치마다 훈련 정보 출력)

6단계. 모델의 정확도를 시각화

plt.rcParams["font.family"] = font_family

accuracy = history.history['accuracy'] ------ ①

val_accuracy = history.history['val_accuracy']

loss = history.history['loss']

val_loss = history.history['val_loss']

epochs = range(len(accuracy))

plt.plot(epochs, accuracy, label="훈련 데이터셋")

plt.plot(epochs, val_accuracy, label="검증 데이터셋")

plt.legend()

plt.title('정확도')

plt.figure()

plt.plot(epochs, loss, label="훈련 데이터셋")

plt.plot(epochs, val_loss, label="검증 데이터셋")

plt.legend()

plt.title('오차')

ⓐ plt.rcParams : 차트 figure의 기본 설정 지정

ⓑ plt.legend() : 그래프에 범례를 표시

① history 객체가 가진 정보(model.fit() 메서드에 대한 반환값으로 history 객체를 얻음)

- accuracy: 매 에포크에 대한 훈련의 정확도

- loss: 매 에포크에 대한 훈련의 손실값

- val_accuracy: 매 에포크에 대한 검증의 정확도

- val_loss: 매 에포크에 대한 검증의 손실값

7단계. 훈련된 모델의 예측

3단계 참고 : https://ebbnflow.tistory.com/124

ImageDataGenerator 사진 출처 : https://ichi.pro/ko/keras-mich-tensorflowleul-sayonghan-imiji-deiteo-jeungdae-tamsaeg-184813206747204

from http://markme-inur.tistory.com/34 by ccl(A) rewrite - 2021-08-04 17:26:23