픽셀을 독립적인 입력으로 취급
▶ 근처에 있는 픽셀끼리 상관성이 높다는 점을 이용하지 못함, 이미지에 대한 성능 좋지 않음
미리 훈련된 임베딩
임베딩
- 이미지를 저차원 공간에 수학적으로 표현한 것
▷임베딩을 형성하는 16개의 숫자는 전체 이미지의 모든 정보를 표현함
미리 훈련된 모델
매우 큰 범용 데이터 셋으로 사전훈련 ▷분류할 실제 데이터셋에 관한 지식을 전이함 ▶ 모델의 용도를 변경함
예측헤드(Prediction head)라는 마지막 레이어만 교체 가능 (?)
사전 훈련 모델
- 대규모 데이터셋에서 훈련된 모델이며 임베딩을 만드는 데 사용할 수 있음
ex. 모바일 넷의 임베딩을 이용해 효율적인 훈련 가능
이미지넷 (ImageNet) 데이터
<사전 훈련된 모바일넷>
import tensorflow_hub as hub
layers = [
hub.KerasLayer(
"https://tfhub.dev/google/tf2-preview/mobilenet_v2/feature_vector/4",
input_shape=(IMG_HEIGHT, IMG_WIDTH, IMG_CHANNELS),
trainable=False,
name='mobilenet_embedding'),
레이어를 훈련 불가능으로 설정 = 사전 훈련됐음을 표시
trainable=False
전이학습
<모바일넷으로 전이학습>
layers = [
hub.KerasLayer(
"https://tfhub.dev/google/tf2-preview/mobilenet_v2/feature_vector/4",
input_shape=(IMG_HEIGHT, IMG_WIDTH, IMG_CHANNELS),
trainable=False,
name='mobilenet_embedding'),
tf.keras.layers.Dense(num_hidden,
kernel_regularizer=regularizer,
activation='relu',
name='dense_hidden'),
tf.keras.layers.Dense(len(CLASS_NAMES),
kernel_regularizer=regularizer,
activation='softmax',
name='flower_prob')
]
첫번째 레이어 - 약 226만개의 파라미터 존재 (훈련 불가능)
dense_hidden 레이어 - 20,496개 파라미터 존재 (학습 가능)
전이학습
- 입력 레이어를 이미지 임베딩으로 대체함으로써 모델을 훈련하는 과정
- 기존에 사전학습된(pre trained) 모델을 가져와, 사용하고자 하는 학습 데이터를 학습시켜 이용하는 방법
케라스의 사전 훈련 모델
- 이미지를 사전 훈련 모델에서 예상하는 포맷에 맞게 변환해줌
데이터셋이 작을 때 전이학습을 하면 좋음.
전이학습을 하지 않고 처음부터 훈련을 하려면 라벨 당 이미지가 5000장은 되어야함.
파인튜닝
- 훈련 루프에 사전 훈련 레이어를 적용
- 사전 훈련된 가중치를 신경망 가중치의 초깃값으로 사용함
학습률을 너무 높게 설정 - 사전 훈련 가중치가 큰 스텝으로 바뀜 & 사전 훈련 가중치를 잃음
학습률을 너무 낮게 설정 - 너무 늦게 수렴
문제 해결! → 학습률 스케줄, 차등 학습률
학습률 스케줄
처음에 높은 학습률로 시작했다가 훈련을 진행하면서 지수적으로 낮춰감.
사전 훈련 모델을 파인튜닝할 때는 웜업 램프(warm-up ramp) 구간을 추가할 수 있음.
웜업 램프
- 초기 학습률을 매우 작게 설정하고, 점진적으로 증가시켜가는 기법
처음에는 학습률을 작게 하여 최적의 가중치를 찾기 시작하고 점차 학습률을 증가시켜 미세 조정하는 방식
차등 학습률
사전 훈련 레이어에는 낮은 학습률을 적용하되 맞춤 분류 헤드의 학습률은 보통으로 함
레이어 깊이에 따라 달라지는 요소로 학습률을 곱함
mult_by_layer={
# 분류 헤드
'flower_prob': 1.0,
'flower_dense': 1.0,
# 사전 훈련된 레이어
'block_1_': 0.02 * mult,
'block_2_': 0.04 * mult,
'block_3_': 0.06 * mult,
'block_4_': 0.08 * mult,
'block_5_': 0.1 * mult,
'block_6_': 0.15 * mult,
'block_7_': 0.2 * mult,
'block_8_': 0.25 * mult,
'block_9_': 0.3 * mult,
'block_10_': 0.35 * mult,
'block_11_': 0.4 * mult,
'block_12_': 0.5 * mult,
'block_13_': 0.6 * mult,
'block_14_': 0.7 * mult,
'block_15_': 0.8 * mult,
'block_16_': 0.9 * mult,
# 이 레이어들은 tf.keras.applications.MobileNetV2에 안정적인 식별자가 없음
'conv': 0.5 * mult,
'Conv': 0.5 * mult
}
AdamW 라는 오픈소스 파이썬 패키지를 사용
optimizer = tf.keras.optimizers.experimental.AdamW()
104 flowers
- 104종의 꽃 이미지 23,000개 이상이 라벨링 되어있음
▶학습률 램프업, 차등 학습률을 진행했을 때 성능이 제일 좋음
컨볼루션 망
이미지에 대해 2차원 적으로 작용해 형태 정보를 포착함
컨볼루션 필터
컬볼루션(convolution, '합성곱')
이미지 상에서 필터를 움직여 가면서 각 위치의 접곱을 계산함
모든 가중치가 동일한 필터는 창의 각 픽셀이 결과 출력 픽셀에 똑같이 작용함
이미지를 부드럽게 하거나, 가장자리, 강도 검출기를 만들 수 있음.
각각의 출력값은 필터를 생산
출력 = 2차원 값들의 다채널 집합 (3차원 입력 이미지와 동일한 수의 차원을 가짐)
tf.keras.layers.Conv2D(filters,
kernel_size,
strides=(1,1),
padding='valid',
activation=None)
<컨볼루션 레이어 구현>
tf.keras.layers.Conv2D(filters=5, kernel_size=4, padding='same')
[배치, 높이, 너비, 채널]
컨볼루션 레이어 쌓기
풀링 레이어
컨볼루션 레이어에 적용된 필터 수 = 출력의 채널 수
다운 샘플링 (downwsample) 연산
- 각 채널의 정보를 조합하거나 샘플 수를 줄임
▶ 최대 풀링
- 각 그룹에 대해 채널 입력값 4개 중에서 최댓값 하나만을 남김
▶ 평균 풀링
- 네값의 평균을 구함
- 훈련 가능 가중치 없이 순전히 크기만을 조정하는 레이어
- 보폭 (stride)을 넓게 이동해서 다운 샘플링하는 방법도 있음
알렉스넷 (AlexNet)
특징맵
- 입력 이미지를 값들의 직사각형 프리즘으로 변환함
컨볼루션 레이어 - 데이터의 채널 수를 바꿈, 렐루 활성화 함수에 의해 활성화됨
최대 풀링 레이어 - 데이터를 높이 방향과 너비 방향으로 다운샘플링함
flatten - 분류 헤드에서 직전의 특징 맵을 받아서 모든 값을 벡터로 평탄화함
세 개의 완전 연결 레이어 후, 마지막 레이어에는 소프트맥스에 의해 활성화 됨
작은 양수 값으로 편향을 초기화 하여 모든 레이어가 0이 아닌 출력과 0이 아닌 경사를 가지고 있음
11 x 11 컨볼루션 필터로 시작함
model = tf.keras.Sequential([
tf.keras.Input(shape=[*IMAGE_SIZE, 3]),
# 여기에서 int[0,255] 이미지를 float[-1,1] 형식으로 변환하는 것이 모범
# 사례이겠지만, 이 모델은 그렇게 하지 않아도 수렴한다.
tf.keras.layers.Conv2D(filters=96, kernel_size=11, strides=4, activation='relu'),
tf.keras.layers.Conv2D(filters=256, kernel_size=5, activation='relu'),
tf.keras.layers.MaxPool2D(pool_size=2, strides=2),
tf.keras.layers.Conv2D(filters=384, kernel_size=3, activation='relu'),
tf.keras.layers.MaxPool2D(pool_size=2, strides=2),
tf.keras.layers.Conv2D(filters=384, kernel_size=3, activation='relu'),
tf.keras.layers.Conv2D(filters=256, kernel_size=3, activation='relu'),
tf.keras.layers.MaxPool2D(pool_size=2, strides=2),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(4096, activation='relu'),
tf.keras.layers.Dense(4096, activation='relu'),
tf.keras.layers.Dense(len(CLASSES), activation='softmax')
])
깊게, 더 깊게
레이어를 추가하면 분류 정확도가 높아짐
- 표현력설
- 여러 레이어를 쌓으면 연속적인 비선형성이 발생함
일반화설
- 레이어를 많이 쌓아서 만든 네트워크는 입력을 의미론적으로 분해해 특징의 계층적 구조를 만들어냄
인식장설
- 컨볼루션을 충분히 깊게 쌓으면 3x3 또는 5x5 필터로도 128x128 픽셀 영역을 볼 수 있음.
필터 분해
3x3 레이어 2개가 5x5 레이어 하나보다 학습 가능 가중치를 적게 사용하면서도 잘 작동함. (활성화 함수도 2>1개)
<1x1 컨볼루션>
매번 독립적인 가중치 세트로 여러 선형 조합을 수행해 다중 출력 채널을 만듦.
W[1, 1, 10, 5] = W[필터크기, 필터크기, 입력 채널, 필터 개수 = 출력 채널 수]
VGG19
19 레이어로 이뤄짐
맨 마지막 레이어만 소프트 맥스 활성화 사용, 나머지는 모두 렐루
컨볼루션 레이어가 16개, 3x3 컨볼루션 사용
전역 평균 풀링
해결하려는 분류 문제의 클래스 수만큼의 뉴런을 갖춘 소프트 맥스 활성화 완전 연결 레이어로 끝남.
(5-flowers 데이터셋의 경우는 5개의 클래스)
전역 평균 풀링
- 컨볼루션 스택이 정확히 N개의 채널이 있는 최종 특징 맵에서 끝나도록 조정, 각 채널의 값을 평균화함
전역 평균 풀링 뒤에 소프트 맥스 함수를 두어 학습 파라미터가 0인 분류 헤드를 구현함 (?)
'AI > Computer Vision' 카테고리의 다른 글
[Vision Transformer(ViT)] 코드 설명 및 인자 정리 (0) | 2024.09.23 |
---|---|
[Active Learning] 데이터 Pre-training, 학습 진행 (0) | 2024.05.27 |
[실전! 컴퓨터 비전을 위한 머신러닝] 06. 전처리 (1) | 2023.10.28 |
[실전! 컴퓨터 비전을 위한 머신러닝] 04 객체 검출과 이미지 세분화 (1) | 2023.10.08 |
[실전! 컴퓨터 비전을 위한 머신러닝] 03. 이미지 비전 (2) (0) | 2023.10.01 |