합성곱 신경망 (CNN)
- 음성인식이나 이미지 인식에서 주로 사용되는 신경망의 한 종류
- 수학적 연산을 사용해서 이미지의 특성을 추출하는 레이어를 포함
- 이미지 처리에 탁월한 성능을 보이는 신경망
- 다차원 배열 데이터를 처리하도록 굿ㅇ
- 사진이 입력으로 들어오면 먼저 특징을 추출한다.
- 예를들어, 새의 사진이라면 깃털의 색깔, 부리의 크기, 눈의 모양 등
- 여러가지 특징들로 나누어서 판단한다.
- 이 과정을 컨볼루션이라고 부른다.
특성맵
- 필터를 이용하여 각 위치마다 포개지는 숫자를 곱해서 모두 더한다. -> 해당 컨볼루션 결과를 기록한 것
- 말 그대로 필터의 특성이 입력 사진의 어느 부분에 많이 존재하는지 보여주는 지도
- 특성 맵의 숫자가 높으면 그 위치가 필터와 유사하다는 것을 의미
- 반면에 CNN은 미리 고정된 연결이 없음
- 대신 컨볼루션 과정을 통해 출력을 계산 -> CNN에서 학습하는 것은 바로 필터의 가중
- 사람이 직접 특징 필터를 만듦 -> 모델 스스로 학습을 통해 특징 추출
- 컨볼루션에서 필터의 개수만큼 특성 맵이 나온다.
- 그 다음 맥스 풀링으로 특성 맵의 크기를 줄임
맥스 풀링
- 가장 큰 값만 추출하여 출력을 작게 만드는 방법
- 컨볼루션과 맥스 풀링의 충돌이 끝나면 사진의 고차원적인 패턴이 담긴 특성맵 도출
- 예를들어, 갈색 깃털을 가지고 부리가 크고, 눈 주위가 빨갛다는 특성을 도출
- CNN의 목표는 사진이 무엇인지 맞추는 것
- 컨볼루션 -> ReLu -> 풀링 순으로 진행 이것을 여러번 반복한다. 입력층과 가까운 경우에는 ReLu를, 마지막 계층에는 Softmax를 주로 사용한다.
합성곱 계층
- 이미지와 같은 3차원 데이터를 입력 받으면 다음 계층에도 3차원 데이터로 전달
- 특징맵(Feature MAp) : 합성곱 계층의 입출력 데이터
- 입력 특징맵 : 입력 데이터
- 출력 특징맵 : 출력 데이터
합성곱 연산
- 필터 사이즈 : 출력 크기 조절
- 스트라이드(보폭) : 필터가 이미지에 적용디ㅗㄹ 때 한번에 움직이는 픽셀 설정
- 패딩 : 합성곱 연산을 수행하기 전에 입력 데이터 주변을 특정 값(0, 1 등)으로 채우기
폴링 계층
- 이미지의 크기를 줄여준다.
- 최대 풀링, 평균 풀링이 있다.
- 폴링은 2차원 데이터의 크기를 줄이는 연산이므로 3차원을 결정하는 채널 수는 건드리지 않음
일반화
- Train을 거듭할 수록 training error는 감소, Test error는 그렇지 않음
- Training error와 Test error의 차이를 Generalization performance라고 한다.
- Generalization이 좋다는 의미는 네트워크 성능이 학습 데이터와 비슷하다를 보장한다는 것
- Train error와 Test error의 gap이 적다.
- 애초에 학습 데이터의 퍼포먼스가 좋지 않다면, 아무리 Generalization이 좋다 하더라도 네트워크의 성능이 좋지 않음
컬러 이미지 분류
- 데이터 준비/데이터 표시
- 정규화 처리
- 검증 데이터 분리
- 레이블 데이터 shape 변경
- 원-핫 인코딩
- 넘파이 배열 변환
- 모델 만들기
- 모델 학습
- 시각화/예측
### 1. 데이터 준비 / 표시
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.datasets import cifar10
(X_train, y_train), (X_test, y_test) = cifar10.load_data()
print(X_train.shape, y_train.shape)
print(X_test.shape, y_test.shape)
class_name = ['airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck']
samples = np.random.randint(len(X_train), size=10)
plt.figure(figsize=(12,5))
for i, idx in enumerate(samples):
plt.subplot(2, 5, i+1, xticks=[], yticks=[])
plt.title((class_name[y_train[idx][0]]))
plt.imshow(X_train[idx])
plt.show()
### 2. 정규화 처리 (MIN-MAX)
X_train = X_train.astype('float32') / 255.0
X_test = X_test.astype('float32') / 255.0
### 3. 검증 데이터 분리
from sklearn.model_selection import train_test_split
X_train, X_val, y_train, y_val = train_test_split(
X_train, y_train, test_size=0.3, random_state=42)
print(X_train.shape, y_train.shape)
print(X_val.shape, y_val.shape)
print(X_test.shape, y_test.shape)
### 4. Shape 변경
y_train = y_train.reshape(-1)
y_val = y_val.reshape(-1)
y_test = y_test.reshape(-1)
print(y_train.shape)
print(y_val.shape)
print(y_test.shape)
### 5. 원-핫 인코딩
import tensorflow as tf
y_train_oh = tf.one_hot(y_train, depth=10)
y_val_oh = tf.one_hot(y_val, depth=10)
y_test_oh = tf.one_hot(y_test, depth=10)
print(y_train_oh.shape)
y_train_oh[:5]
### 6. 넘파이 배열로 전환
y_train_oh = y_train_oh.numpy()
y_val_oh = y_val_oh.numpy()
y_test_oh = y_test_oh.numpy()
print(y_train_oh.shape)
print(y_val_oh.shape)
print(y_test_oh.shape)
### 7. 모델 만들기
from tensorflow import keras
from tensorflow.keras import layers
def build_model():
model = keras.Sequential()
model.add(layers.Conv2D(32, 3,
padding='same',
activation='relu',
input_shape=(32,32,3)))
model.add(layers.MaxPooling2D(2))
# model.add(layers.Dropout(0.3))
model.add(layers.Conv2D(64, 3,
padding='same',
activation='relu'))
model.add(layers.MaxPooling2D(2))
# model.add(layers.Dropout(0.3))
model.add(layers.Conv2D(256, 3,
padding='same',
activation='relu'))
model.add(layers.MaxPooling2D(2))
# model.add(layers.Dropout(0.3))
model.add(layers.Flatten())
model.add(layers.Dense(256, activation='relu'))
model.add(layers.Dense(10, activation='softmax'))
return model
model = build_model()
model.summary()
### 8. 모델 학습
EPOCHS = 30
BATCH_SIZE = 256
history = model.fit(X_train, y_train_oh,
epochs=EPOCHS,
batch_size=BATCH_SIZE,
validation_data = (X_val, y_val_oh),
verbose = 1)
### 9. 시각화
import matplotlib.pyplot as plt
import pandas as pd
def plot_history(history):
hist = pd.DataFrame(history.history)
hist['epoch'] = history.epoch
plt.figure(figsize=(16,8))
plt.subplot(1,2,1)
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.plot(hist['epoch'], hist['loss'], label='Train Loss')
plt.plot(hist['epoch'], hist['val_loss'],label = 'Val Loss')
plt.legend()
plt.subplot(1,2,2)
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.plot(hist['epoch'], hist['acc'], label='Train Accuracy')
plt.plot(hist['epoch'], hist['val_acc'], label = 'Val Accuracy')
plt.legend()
plt.show()
plot_history(history)
### 10. 예측
y_pred = model.predict(X_test)
y_pred_argmax = np.argmax(y_pred, axis=1)
y_pred_argmax[:10]
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
def print_score(y_test, y_pred):
print('accuracy: %.3f' % (accuracy_score(y_test, y_pred)))
print('precision: %.3f' % (precision_score(y_test, y_pred,
average='macro')))
print('recall_score: %.3f' % (recall_score(y_test, y_pred,
average='macro')))
print('f1_score: %.3f' % (f1_score(y_test, y_pred,
average='macro')))
print_score(y_test, y_pred_argmax)
### 11. 혼동행렬 시각화
from sklearn.metrics import confusion_matrix
import seaborn as sns
def plot_matrix(y_test, y_pred):
plt.figure(figsize=(10,8))
cm = confusion_matrix(y_test, y_pred_argmax)
s = sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', cbar=False)
s.set(xlabel='Prediction', ylabel='Actual')
plt.show()
plot_matrix(y_test, y_pred_argmax)
'프로그램 > SKT FLY AI' 카테고리의 다른 글
SKT FLY AI : 9일차 - RNN (0) | 2023.07.07 |
---|---|
SKT FLY AI : 8일차 - CNN(2) (0) | 2023.07.05 |
SKT FLY AI : 6일차 - ML(2) (0) | 2023.07.04 |
SKT FLY AI - 번외. 첫날~워크샵 (0) | 2023.07.01 |
SKT FLY AI : 5일차 - ML (0) | 2023.06.30 |