Open njs03332 opened 1 year ago
assign roles -s 0726 -c 14.5 14.6 14.7
0 | 1 | 2 | |
---|---|---|---|
member | 김유리 | 한단비 | 주선미 |
chapter | 14.5 | 14.6 | 14.7 |
충분하지 않은 데이터로 이미지 분류기를 훈련하려면 사전훈련된 하위층을 사용하는 것이 좋음
import tensorflow_datasets as tfds
dataset, info = tfds.load("tf_flowers", as_supervised=True, with_info=True) dataset_size = info.splits["train"].num_examples class_names = info.features["label"].names # ["dandelion", "daisy", ] n_classes = info.features["label"].num_classes
- 데이터셋의 처음 10%를 테스트 세트로, 15%를 검증 세트로, 나머지 75%를 훈련 세트로 나눔
```python
test_set_raw, valid_set_raw, train_set_raw = tfds.load(
"tf_flowers",
split=["train[:10%]", "train[10%:25%]", "train[25%:]"],
as_supervised=True)
다음으로 이미지 크기를 224 X 224로 조정, 이 CNN 모델의 입력값에 맞추기 위함
def preprocess(image, label):
resized_image = tf.image.resize(image, [224, 224])
final_image = keras.applications.xception.preprocess_input(resized_image)
return final_image, label
배치 크기를 지정하고, 프리페치를 적용
batch_size = 32
train_set = train_set_raw.shuffle(1000).repeat()
train_set = train_set.map(partial(preprocess, randomize=True)).batch(batch_size).prefetch(1)
valid_set = valid_set_raw.map(preprocess).batch(batch_size).prefetch(1)
test_set = test_set_raw.map(preprocess).batch(batch_size).prefetch(1)
사전 훈련된 Xception 모델을 로드, include=False로 지정하여 네트워크 최상층에 해당하는 전역 평균 풀링 층과 밀집 출력 층을 제외
base_model = keras.applications.xception.Xception(weights="imagenet", include_top=False)
avg = keras.layers.GlobalAveragePooling2D()(base_model.output)
output = keras.layers.Dense(n_classes, activation="softmax")(avg)
model = keras.models.Model(inputs=base_model.input, outputs=output)
훈련 초기에는 사전훈련된 층의 가중치를 고정
그리고 모델을 컴파일하고 훈련
for layer in base_model.layers:
layer.trainable = False
optimizer = keras.optimizers.SGD(learning_rate=0.2, momentum=0.9, decay=0.01) model.compile(loss="sparse_categorical_crossentropy", optimizer=optimizer, metrics=["accuracy"]) history = model.fit(train_set, steps_per_epoch=int(0.75 dataset_size / batch_size), validation_data=valid_set, validation_steps=int(0.15 dataset_size / batch_size), epochs=5)
- 몇 번의 에포크동안 검증 정확도가 75% ~ 80%에 도달하고, 더 나아지지 않을 것 => 이는 새로 추가한 최상위 층이 잘 훈련된 것
- 이제 고정했던 것을 해제하고 훈련을 계속 함, 이때 사전 훈련된 가중치가 훼손되는 것을 피하기 위해 훨씬 작은 학습률을 이용
```python
for layer in base_model.layers:
layer.trainable = True
optimizer = keras.optimizers.SGD(learning_rate=0.01, momentum=0.9,
nesterov=True, decay=0.001)
model.compile(loss="sparse_categorical_crossentropy", optimizer=optimizer,
metrics=["accuracy"])
history = model.fit(train_set,
steps_per_epoch=int(0.75 * dataset_size / batch_size),
validation_data=valid_set,
validation_steps=int(0.15 * dataset_size / batch_size),
epochs=40)
keras.applications
패키지에 준비되어있음
model = keras.applications.resnet50.ResNet50(weights="imagenet")
images_resized = tf.image.resize(images, [224,224])
inputs = keras.applications.resnet50.preprocess_input(images_resized * 255)
Y_proba = model.predict(inputs)
ResidualUnit 층
class ResidualUnit(keras.layers.Layer):
def __init__ (self,filters,strides=1,activation='relu',**kwargs):
super(). __init__(**kwargs)
self.activation=keras.activations.get(activation)
self.main_layers=[
keras.layers.Conv2D(filters,3,strides=strides,
padding='same',use_bias=False),
keras.layers.BatchNormalization(),
self.activation,
keras.layers.Conv2D(filters,3,strides=1,
padding='same',use_bias=False),
keras.layers.BatchNormalization(),
self.activation,
keras.layers.Conv2D(filters,3,strides=1,
padding='same',use_bias=False),
keras.layers.BatchNormalization()
]
self.skip_layers=[]
if strides>1:
self.skip_layers=[
keras.layers.Conv2D(filters,1,strides=strides,
padding='same',use_bias=False),
keras.layers.BatchNormalization()]
def call(self,inputs):
z=inputs
for layer in self.main_layers:
z=layer(z)
skip_z=inputs
for layer in self.skip_layers:
skip_z=layer(skip_z)
return self.activation(z+skip_z)
skip_layers
= 왼쪽 모듈, main_layers
= 오른쪽 모듈
call 메서드에서 입력을 main_layers, skip_layers에 통과시킨 후 두 출력을 더해 함수를 적용함
Sequential 클래스를 이용해 ResNet-34 모델 만들기
model= keras.models.Sequential()
model.add(keras.layers.Conv2D(64,7,strides=2,input_shape=[224,224,3],padding='same',use_bias=False))
model.add(keras.layers.BatchNormalization())
model.add(keras.layers.Activation('relu'))
model.add(keras.layers.MaxPool2D(pool_size=3,strides=2,padding='same'))
prev_filters=64
for filters in [64] * 3 + [128] * 4 + [256] * 6 + [512] * 3:
strides=1 if filters==prev_filters else 2
model.add(ResidualUnit(filters,strides=strides))
prev_filters=filters
model.add(keras.layers.GlobalAvgPool2D()) model.add(keras.layers.Flatten()) model.add(keras.layers.Dense(10,activation='softmax'))
- for 루프 - 처음 3개 RU는 64개 필터, 그 다음 4개 RU는 128개 필터를 가짐
- 필터 개수가 이전 RU와 동일할 경우 스트라이드를 1로 설정하고, 아니면 2로 설정
- 그 다음 `ResidualUnit`을 더하고 마지막에 `prev_filters`를 업데이트함