CNN (Convolutional Neural Network) 이미지 처리
CNN (Convolutional Neural Network) 이미지 처리
CNN (Convolutional Neural Network) 이미지 처리
231017 학습한 내용 정리
CNN 개요
정의
- Convolutional Neural Network (합성곱 신경망)
- 이미지 처리에 특화된 딥러닝 모델
- 합성곱 연산을 통해 이미지의 지역적 특징을 추출
특징
- 지역적 특징: 이미지의 지역적 패턴을 효과적으로 학습
- 가중치 공유: 동일한 필터를 전체 이미지에 적용
- 계층적 학습: 저수준 특징부터 고수준 특징까지 계층적 학습
- 변환 불변성: 위치에 상관없이 동일한 특징 인식
장점
- 이미지 특화: 이미지 데이터에 최적화된 구조
- 효율성: 가중치 공유로 파라미터 수 감소
- 성능: 이미지 분류에서 뛰어난 성능
- 확장성: 다양한 이미지 크기에 적용 가능
CNN 기본 구조
1. 합성곱 레이어 (Convolutional Layer)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras import layers, models
from tensorflow.keras.datasets import cifar10
from tensorflow.keras.utils import to_categorical
# CIFAR-10 데이터 로드
(X_train, y_train), (X_test, y_test) = cifar10.load_data()
# 데이터 전처리
X_train = X_train.astype('float32') / 255.0
X_test = X_test.astype('float32') / 255.0
y_train = to_categorical(y_train, 10)
y_test = to_categorical(y_test, 10)
# 기본 CNN 모델
model = models.Sequential([
layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3)),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.Flatten(),
layers.Dense(64, activation='relu'),
layers.Dense(10, activation='softmax')
])
# 모델 컴파일
model.compile(
optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy']
)
# 모델 구조 확인
model.summary()
2. 풀링 레이어 (Pooling Layer)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# 다양한 풀링 레이어 비교
def create_pooling_models():
models = {}
# Max Pooling
models['max_pool'] = models.Sequential([
layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3)),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Flatten(),
layers.Dense(10, activation='softmax')
])
# Average Pooling
models['avg_pool'] = models.Sequential([
layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3)),
layers.AveragePooling2D((2, 2)),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.AveragePooling2D((2, 2)),
layers.Flatten(),
layers.Dense(10, activation='softmax')
])
# Global Average Pooling
models['global_avg_pool'] = models.Sequential([
layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3)),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.GlobalAveragePooling2D(),
layers.Dense(10, activation='softmax')
])
return models
# 풀링 모델들 생성
pooling_models = create_pooling_models()
# 각 모델 컴파일
for name, model in pooling_models.items():
model.compile(
optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy']
)
print(f"{name} 모델 파라미터 수: {model.count_params()}")
3. 드롭아웃과 배치 정규화
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# 드롭아웃과 배치 정규화를 포함한 CNN 모델
model_advanced = models.Sequential([
layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3)),
layers.BatchNormalization(),
layers.Conv2D(32, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Dropout(0.25),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.BatchNormalization(),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Dropout(0.25),
layers.Conv2D(128, (3, 3), activation='relu'),
layers.BatchNormalization(),
layers.Dropout(0.25),
layers.Flatten(),
layers.Dense(512, activation='relu'),
layers.BatchNormalization(),
layers.Dropout(0.5),
layers.Dense(10, activation='softmax')
])
# 모델 컴파일
model_advanced.compile(
optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy']
)
# 모델 구조 확인
model_advanced.summary()
CNN 고급 기법
1. 데이터 증강 (Data Augmentation)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
from tensorflow.keras.preprocessing.image import ImageDataGenerator
# 데이터 증강 설정
datagen = ImageDataGenerator(
rotation_range=20,
width_shift_range=0.2,
height_shift_range=0.2,
horizontal_flip=True,
zoom_range=0.2,
fill_mode='nearest'
)
# 데이터 증강을 적용한 모델 학습
model_augmented = models.Sequential([
layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3)),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.Flatten(),
layers.Dense(64, activation='relu'),
layers.Dense(10, activation='softmax')
])
model_augmented.compile(
optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy']
)
# 데이터 증강을 사용한 학습
history_augmented = model_augmented.fit(
datagen.flow(X_train, y_train, batch_size=32),
epochs=10,
validation_data=(X_test, y_test),
verbose=1
)
2. 전이 학습 (Transfer Learning)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
from tensorflow.keras.applications import VGG16, ResNet50
# VGG16 전이 학습
def create_vgg16_model():
base_model = VGG16(weights='imagenet', include_top=False, input_shape=(32, 32, 3))
# 기본 모델의 가중치 고정
base_model.trainable = False
model = models.Sequential([
base_model,
layers.GlobalAveragePooling2D(),
layers.Dense(128, activation='relu'),
layers.Dropout(0.5),
layers.Dense(10, activation='softmax')
])
return model
# ResNet50 전이 학습
def create_resnet50_model():
base_model = ResNet50(weights='imagenet', include_top=False, input_shape=(32, 32, 3))
# 기본 모델의 가중치 고정
base_model.trainable = False
model = models.Sequential([
base_model,
layers.GlobalAveragePooling2D(),
layers.Dense(128, activation='relu'),
layers.Dropout(0.5),
layers.Dense(10, activation='softmax')
])
return model
# 전이 학습 모델들 생성
vgg16_model = create_vgg16_model()
resnet50_model = create_resnet50_model()
# 모델 컴파일
vgg16_model.compile(
optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy']
)
resnet50_model.compile(
optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy']
)
print("VGG16 모델 파라미터 수:", vgg16_model.count_params())
print("ResNet50 모델 파라미터 수:", resnet50_model.count_params())
3. 커스텀 CNN 아키텍처
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# 커스텀 CNN 아키텍처
class CustomCNN(models.Model):
def __init__(self, num_classes=10):
super(CustomCNN, self).__init__()
# 특징 추출 부분
self.conv1 = layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3))
self.bn1 = layers.BatchNormalization()
self.conv2 = layers.Conv2D(32, (3, 3), activation='relu')
self.pool1 = layers.MaxPooling2D((2, 2))
self.dropout1 = layers.Dropout(0.25)
self.conv3 = layers.Conv2D(64, (3, 3), activation='relu')
self.bn2 = layers.BatchNormalization()
self.conv4 = layers.Conv2D(64, (3, 3), activation='relu')
self.pool2 = layers.MaxPooling2D((2, 2))
self.dropout2 = layers.Dropout(0.25)
self.conv5 = layers.Conv2D(128, (3, 3), activation='relu')
self.bn3 = layers.BatchNormalization()
self.dropout3 = layers.Dropout(0.25)
# 분류 부분
self.flatten = layers.Flatten()
self.dense1 = layers.Dense(512, activation='relu')
self.bn4 = layers.BatchNormalization()
self.dropout4 = layers.Dropout(0.5)
self.dense2 = layers.Dense(num_classes, activation='softmax')
def call(self, inputs, training=None):
x = self.conv1(inputs)
x = self.bn1(x, training=training)
x = self.conv2(x)
x = self.pool1(x)
x = self.dropout1(x, training=training)
x = self.conv3(x)
x = self.bn2(x, training=training)
x = self.conv4(x)
x = self.pool2(x)
x = self.dropout2(x, training=training)
x = self.conv5(x)
x = self.bn3(x, training=training)
x = self.dropout3(x, training=training)
x = self.flatten(x)
x = self.dense1(x)
x = self.bn4(x, training=training)
x = self.dropout4(x, training=training)
x = self.dense2(x)
return x
# 커스텀 모델 생성
custom_model = CustomCNN(num_classes=10)
custom_model.compile(
optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy']
)
# 모델 구조 확인
custom_model.build((None, 32, 32, 3))
custom_model.summary()
CNN 실무 적용 예시
1. 이미지 분류
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# 이미지 분류 모델 학습
def train_image_classifier():
model = models.Sequential([
layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3)),
layers.BatchNormalization(),
layers.Conv2D(32, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Dropout(0.25),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.BatchNormalization(),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Dropout(0.25),
layers.Conv2D(128, (3, 3), activation='relu'),
layers.BatchNormalization(),
layers.Dropout(0.25),
layers.Flatten(),
layers.Dense(512, activation='relu'),
layers.BatchNormalization(),
layers.Dropout(0.5),
layers.Dense(10, activation='softmax')
])
model.compile(
optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy']
)
# 콜백 설정
callbacks = [
tf.keras.callbacks.EarlyStopping(patience=5, restore_best_weights=True),
tf.keras.callbacks.ReduceLROnPlateau(factor=0.5, patience=3)
]
# 모델 학습
history = model.fit(
X_train, y_train,
epochs=50,
validation_data=(X_test, y_test),
callbacks=callbacks,
verbose=1
)
return model, history
# 모델 학습
trained_model, training_history = train_image_classifier()
# 성능 평가
test_loss, test_accuracy = trained_model.evaluate(X_test, y_test, verbose=0)
print(f"테스트 정확도: {test_accuracy:.4f}")
# 예측
predictions = trained_model.predict(X_test)
predicted_classes = np.argmax(predictions, axis=1)
true_classes = np.argmax(y_test, axis=1)
# 혼동 행렬
from sklearn.metrics import confusion_matrix, classification_report
cm = confusion_matrix(true_classes, predicted_classes)
print("혼동 행렬:")
print(cm)
# 분류 보고서
class_names = ['airplane', 'automobile', 'bird', 'cat', 'deer',
'dog', 'frog', 'horse', 'ship', 'truck']
print("\n분류 보고서:")
print(classification_report(true_classes, predicted_classes, target_names=class_names))
2. 특징 맵 시각화
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 특징 맵 시각화
def visualize_feature_maps(model, image, layer_names):
"""특징 맵을 시각화하는 함수"""
# 중간 레이어의 출력을 가져오는 모델 생성
intermediate_outputs = [model.get_layer(name).output for name in layer_names]
intermediate_model = models.Model(inputs=model.input, outputs=intermediate_outputs)
# 특징 맵 추출
feature_maps = intermediate_model.predict(np.expand_dims(image, axis=0))
# 시각화
fig, axes = plt.subplots(len(layer_names), 1, figsize=(15, 5 * len(layer_names)))
if len(layer_names) == 1:
axes = [axes]
for i, (layer_name, feature_map) in enumerate(zip(layer_names, feature_maps)):
# 첫 번째 채널의 특징 맵만 시각화
axes[i].imshow(feature_map[0, :, :, 0], cmap='viridis')
axes[i].set_title(f'{layer_name} - 첫 번째 채널')
axes[i].axis('off')
plt.tight_layout()
plt.show()
# 샘플 이미지 선택
sample_image = X_test[0]
# 특징 맵 시각화
layer_names = ['conv2d', 'conv2d_1', 'conv2d_2']
visualize_feature_maps(trained_model, sample_image, layer_names)
3. Grad-CAM 시각화
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# Grad-CAM 구현
def make_gradcam_heatmap(img_array, model, last_conv_layer_name, pred_index=None):
"""Grad-CAM 히트맵 생성"""
# 마지막 합성곱 레이어와 분류 레이어를 포함한 모델 생성
grad_model = models.Model(
inputs=model.inputs,
outputs=[model.get_layer(last_conv_layer_name).output, model.output]
)
# GradientTape를 사용하여 그래디언트 계산
with tf.GradientTape() as tape:
last_conv_layer_output, preds = grad_model(img_array)
if pred_index is None:
pred_index = tf.argmax(preds[0])
class_channel = preds[:, pred_index]
# 마지막 합성곱 레이어에 대한 그래디언트 계산
grads = tape.gradient(class_channel, last_conv_layer_output)
# 각 채널의 중요도를 나타내는 벡터 계산
pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2))
# 마지막 합성곱 레이어의 출력에 중요도 가중치 적용
last_conv_layer_output = last_conv_layer_output[0]
heatmap = last_conv_layer_output @ pooled_grads[..., tf.newaxis]
heatmap = tf.squeeze(heatmap)
# 히트맵 정규화
heatmap = tf.maximum(heatmap, 0) / tf.math.reduce_max(heatmap)
return heatmap.numpy()
# Grad-CAM 시각화
def display_gradcam(img, heatmap, alpha=0.4):
"""Grad-CAM 결과 시각화"""
# 히트맵을 원본 이미지 크기로 리사이즈
heatmap = tf.image.resize(heatmap[..., tf.newaxis], [img.shape[0], img.shape[1]])
heatmap = tf.squeeze(heatmap)
# 히트맵을 컬러맵으로 변환
heatmap = plt.cm.jet(heatmap)[..., :3]
# 원본 이미지와 히트맵 결합
superimposed_img = heatmap * alpha + img
superimposed_img = tf.clip_by_value(superimposed_img, 0, 1)
# 시각화
fig, axes = plt.subplots(1, 3, figsize=(15, 5))
axes[0].imshow(img)
axes[0].set_title('원본 이미지')
axes[0].axis('off')
axes[1].imshow(heatmap)
axes[1].set_title('Grad-CAM 히트맵')
axes[1].axis('off')
axes[2].imshow(superimposed_img)
axes[2].set_title('결합된 이미지')
axes[2].axis('off')
plt.tight_layout()
plt.show()
# Grad-CAM 적용
sample_image = X_test[0]
heatmap = make_gradcam_heatmap(
np.expand_dims(sample_image, axis=0),
trained_model,
'conv2d_2'
)
display_gradcam(sample_image, heatmap)
CNN 성능 최적화
1. 하이퍼파라미터 튜닝
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import kerastuner as kt
def build_cnn_model(hp):
"""하이퍼파라미터 튜닝을 위한 CNN 모델"""
model = models.Sequential()
# 입력 레이어
model.add(layers.Conv2D(
filters=hp.Int('conv1_filters', min_value=32, max_value=128, step=32),
kernel_size=hp.Choice('conv1_kernel', values=[3, 5]),
activation='relu',
input_shape=(32, 32, 3)
))
# 풀링 레이어
model.add(layers.MaxPooling2D((2, 2)))
# 두 번째 합성곱 레이어
model.add(layers.Conv2D(
filters=hp.Int('conv2_filters', min_value=64, max_value=256, step=64),
kernel_size=hp.Choice('conv2_kernel', values=[3, 5]),
activation='relu'
))
model.add(layers.MaxPooling2D((2, 2)))
# 드롭아웃
model.add(layers.Dropout(
rate=hp.Float('dropout_rate', min_value=0.2, max_value=0.5, step=0.1)
))
# 완전 연결 레이어
model.add(layers.Flatten())
model.add(layers.Dense(
units=hp.Int('dense_units', min_value=128, max_value=512, step=128),
activation='relu'
))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(10, activation='softmax'))
# 컴파일
model.compile(
optimizer=hp.Choice('optimizer', values=['adam', 'rmsprop']),
loss='categorical_crossentropy',
metrics=['accuracy']
)
return model
# 하이퍼파라미터 튜너 생성
tuner = kt.Hyperband(
build_cnn_model,
objective='val_accuracy',
max_epochs=20,
factor=3,
directory='cnn_tuning',
project_name='cnn_hyperparameter_tuning'
)
# 하이퍼파라미터 탐색
tuner.search(
X_train, y_train,
epochs=20,
validation_data=(X_test, y_test),
callbacks=[tf.keras.callbacks.EarlyStopping(patience=5)]
)
# 최적 모델 가져오기
best_model = tuner.get_best_models(num_models=1)[0]
best_hyperparameters = tuner.get_best_hyperparameters(num_trials=1)[0]
print("최적 하이퍼파라미터:")
print(best_hyperparameters.values)
2. 모델 앙상블
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# 여러 CNN 모델 앙상블
def create_ensemble_models():
"""앙상블을 위한 여러 CNN 모델 생성"""
models_list = []
# 모델 1: 기본 CNN
model1 = models.Sequential([
layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3)),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Flatten(),
layers.Dense(64, activation='relu'),
layers.Dense(10, activation='softmax')
])
models_list.append(model1)
# 모델 2: 더 깊은 CNN
model2 = models.Sequential([
layers.Conv2D(64, (3, 3), activation='relu', input_shape=(32, 32, 3)),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(128, (3, 3), activation='relu'),
layers.Conv2D(128, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Flatten(),
layers.Dense(128, activation='relu'),
layers.Dense(10, activation='softmax')
])
models_list.append(model2)
# 모델 3: 배치 정규화 포함
model3 = models.Sequential([
layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3)),
layers.BatchNormalization(),
layers.Conv2D(32, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.BatchNormalization(),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Flatten(),
layers.Dense(64, activation='relu'),
layers.Dense(10, activation='softmax')
])
models_list.append(model3)
return models_list
# 앙상블 모델들 생성
ensemble_models = create_ensemble_models()
# 각 모델 컴파일 및 학습
for i, model in enumerate(ensemble_models):
model.compile(
optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy']
)
print(f"모델 {i+1} 학습 중...")
model.fit(
X_train, y_train,
epochs=10,
validation_data=(X_test, y_test),
verbose=0
)
# 앙상블 예측
def ensemble_predict(models, X):
"""앙상블 모델들의 예측 결과 평균"""
predictions = []
for model in models:
pred = model.predict(X)
predictions.append(pred)
# 예측 결과 평균
ensemble_pred = np.mean(predictions, axis=0)
return ensemble_pred
# 앙상블 예측
ensemble_predictions = ensemble_predict(ensemble_models, X_test)
ensemble_predicted_classes = np.argmax(ensemble_predictions, axis=1)
# 앙상블 성능 평가
ensemble_accuracy = np.mean(ensemble_predicted_classes == np.argmax(y_test, axis=1))
print(f"앙상블 정확도: {ensemble_accuracy:.4f}")
# 개별 모델 성능과 비교
individual_accuracies = []
for model in ensemble_models:
_, accuracy = model.evaluate(X_test, y_test, verbose=0)
individual_accuracies.append(accuracy)
print("개별 모델 정확도:")
for i, acc in enumerate(individual_accuracies):
print(f"모델 {i+1}: {acc:.4f}")
print(f"앙상블 정확도: {ensemble_accuracy:.4f}")
주의사항 및 모범 사례
1. 모델 설계
- 레이어 수: 과적합을 방지하기 위해 적절한 레이어 수 선택
- 필터 크기: 3x3 필터가 일반적으로 효과적
- 풀링: Max Pooling이 일반적으로 Average Pooling보다 성능이 좋음
2. 학습 최적화
- 데이터 증강: 과적합 방지와 성능 향상에 효과적
- 배치 정규화: 학습 안정성과 성능 향상
- 드롭아웃: 과적합 방지에 효과적
3. 성능 모니터링
- 검증 데이터: 검증 데이터를 통한 성능 모니터링
- 콜백: 조기 종료와 학습률 감소 활용
- 시각화: 특징 맵과 Grad-CAM을 통한 모델 해석
마무리
CNN은 이미지 처리에 특화된 딥러닝 모델로, 합성곱 연산을 통해 이미지의 지역적 특징을 효과적으로 추출할 수 있습니다. 적절한 모델 설계, 데이터 증강, 전이 학습 등의 기법을 활용하여 높은 성능의 이미지 분류 모델을 구축할 수 있습니다. 또한 특징 맵 시각화와 Grad-CAM을 통해 모델의 동작을 해석하고 이해할 수 있습니다.
This post is licensed under CC BY 4.0 by the author.