CNN은 Convolutional Neural Network의 약자로 이미지, 음성 등 다양한 형태의 데이터 처리에 특화된 딥러닝 모델이다.
일반적인 신경망과 달리 CNN은 컨볼루션 및 풀링 레이어를 사용하여 이미지 특징을 추출합니다.
이를 통해 공간 정보를 보존하면서 영상 데이터를 가공할 수 있다.
컨볼루션 레이어는 이미지의 특징을 추출하는 역할을 합니다. 컨벌루션은 이미지의 픽셀 데이터에 대해 일정한 간격으로 필터 또는 커널이라는 작은 창을 이동하여 계산됩니다.
이를 통해 이미지의 다양한 특징(선, 모서리, 질감 등)을 추출합니다.
풀링 레이어는 컨볼루션 레이어를 통해 추출된 특징 맵의 크기를 줄이는 역할을 합니다.
이러한 컨벌루션과 풀링 과정을 반복하여 이미지의 특징을 추출한 후 최종적으로는 일반 신경망에서와 같이 Fully Connected Layer를 사용하여 최종 출력을 계산합니다.
GitHub 코드
https://github.com/seokcode/Simple_CNN_Model
석코드/Simple_CNN_Model
개와 고양이를 분류하는 CNN 모델 구축. GitHub에서 계정을 생성하여 seokcode/Simple_CNN_Model 개발에 기여하십시오.
github.com
참고자료는 여기!
학습 데이터 세트와 테스트 데이터 세트는 데이터 양이 많아 첨부할 수 없습니다.
GitHub에서도 최대 1000개의 복사본을 사용할 수 있습니다.
4000개의 훈련 데이터 세트
1000개의 테스트 시트 데이터 세트
필요한 것이 있으면 이메일을 보내드리겠습니다.
1) 라이브러리 가져오기
import tensorflow as tf
from keras.preprocessing.image import ImageDataGenerator
텐서플로우 사용시 주의사항은 파이썬 버전 3.7~3.9까지 지원하지만 3.8을 권장합니다!
2) Tensor 흐름 버전 확인
tf.__version__
3) 데이터 전처리
part1 – 훈련 데이터 세트 전처리.
# 이미지 데이터를 학습하기 전에 데이터 증강을 수행하는 코드
train_datagen = ImageDataGenerator(rescale = 1./255, # 이미지의 픽셀값을 0과 1 사이의 값으로 조정
shear_range = 0.2, # 이미지를 변형시키는 시어링(Shearing) 강도를 지정(회전)
zoom_range = 0.2, # 이미지를 확대 또는 축소하는 줌(Zoom) 범위를 지정
horizontal_flip = True) # 이미지를 좌우로 뒤집는 수평방향 뒤집기를 수행
# flow_from_directory() 함수를 사용하여 디렉토리에서 이미지 데이터를 읽어와 배치(batch) 단위로 학습할 수 있도록 설정
training_set = train_datagen.flow_from_directory('dataset/training_set', # 학습 데이터셋 디렉토리 경로를 지정
target_size = (64, 64), # 이미지를 지정된 크기(64x64)로 리사이즈
batch_size = 32, # 한 번에 학습할 배치(batch) 크기를 지정(이미지의 장수 32는 기본값)
class_mode="binary") # 이진 분류(Binary classification) 문제로 설정
part2 – 테스트 데이터 세트를 전처리합니다.
test_datagen = ImageDataGenerator(rescale = 1./255)
test_set = test_datagen.flow_from_directory('dataset/test_set',
target_size = (64, 64),
batch_size = 32,
class_mode="binary")
* 테스트 세트가 이미지 확대를 수행하지 않는 이유는 무엇입니까?
테스트 세트에 대해 데이터 증대를 수행하지 않는 이유는 모델의 일반화 성능을 평가하기 위함입니다.
데이터 증대는 훈련 데이터 세트를 증대시키는 데 사용되는 기술입니다. 회전, 확대/축소, 이동, 뒤집기 데이터를 다양한 방식으로 변환하여 데이터의 다양성을 높이는 것입니다.
이를 통해 모델은 보다 일반화된 기능을 학습하고 과적합을 방지할 수 있습니다.
반면에 테스트 세트는 모델의 일반화 성능을 평가하기 위해 사용되는 데이터 세트이므로 훈련 데이터에 최대한 가까운 분포를 가져야 합니다.
따라서 테스트 세트에 데이터 증대를 수행하면 테스트 데이터와 훈련 데이터의 분포 차이가 커지고 모델의 성능 평가 결과가 왜곡될 수 있다.
따라서 테스트 세트에서는 데이터 증대는 하지 않고 이미지 크기를 조절할 정도의 간단한 전처리만 한다.
4) CNN 모델 구축
part1 – CNN 모델 초기화
# 각 레이어가 정확히 하나의 입력 텐서와 하나의 출력 텐서를 갖는 단일 입력 및 출력으로 간단한 모델을 만들 때 유용
# cnn 모델 초기화
cnn = tf.keras.models.Sequential()
part2 – 컨볼루션: 이미지의 특징 추출
# Sequential 모델에 컨볼루션 레이어를 추가 계층에는 커널 크기가 3x3인 32개의 필터가 있으며 사용된 활성화 함수는 ReLU
# 레이어의 입력 모양은 (64, 64, 3)이며 크기가 64x64이고 3개의 색상 채널(RGB)이 있는 입력 이미지
cnn.add(tf.keras.layers.Conv2D(filters=32, kernel_size=3, activation='relu', input_shape=(64, 64, 3)))
* relu를 사용하는 이유: 입력값이 0보다 크거나 같으면 0을 출력하고 입력값이 0보다 작거나 같으면 0을 출력하는 함수.
* 비선형성을 도입하여 모델이 더 복잡한 패턴을 학습하도록 돕습니다.
* 그래서 주로 컨볼루션과 함께 사용합니다.
part3 – Pooling: 컨볼루션 레이어의 출력 결과를 단순화하는 작업
# cnn에 최대 풀링 계층을 추가
# MaxPool2D 계층은 pool_size 및 strides 매개변수로 정의된 크기 창 내에서 최대값을 취하여 입력의 공간적 차원을 줄인다.
# 이 경우 pool_size=2는 풀링 작업에 2x2 윈도우가 사용됨을 의미하고 strides=2는 윈도우가 한 번에 2 단위 이동됨을 의미
# 이 계층의 출력은 입력의 다운샘플링된 버전이며 공간 차원은 2배로 줄었다.
# padding의 기본값은 valid이고 2칸씩 띄었을 때 없는 숫자 칸은 무시 할 수 있고
# padding의 same은 없는 숫자 칸은 0인 가짜 픽셀을 추가 한다.
cnn.add(tf.keras.layers.MaxPool2D(pool_size=2, strides=2))
part3 – 두 번째 컨볼루션 레이어 추가
cnn.add(tf.keras.layers.Conv2D(filters=32, kernel_size=3, activation='relu'))
# 풀링 연산을 수행하여 입력 이미지를 축소하는 레이어를 생성
cnn.add(tf.keras.layers.MaxPool2D(pool_size=2, strides=2))
part4 – Flattening: 입력된 다차원 배열을 1차원 벡터로 변환
# cnn에 평탄화 레이어를 추가
# Flatten 레이어는 이전 레이어의 출력을 가져와 완전 연결 레이어로 전달할 수 있는 1차원 배열로 변환
# 이는 일반적으로 이전 레이어에서 추출한 기능 간의 관계를 학습하고 모델링할 수 있는 네트워크에 조밀한 레이어를 추가하기 전에 수행
cnn.add(tf.keras.layers.Flatten())
part5 – Full Connection: 입력 레이어와 출력 레이어 사이에 위치하며, 입력 레이어의 모든 뉴런이 출력 레이어의 모든 뉴런과 연결됩니다.
# 완전히 연결된 계층을 신경망에 추가
cnn.add(tf.keras.layers.Dense(units=128, activation='relu'))
part6 – 출력 레이어
# 완전히 연결된 계층을 신경망에 추가
# 이진 분류 문제이므로 마지막 계층의 뉴런 수는 1로 설정
cnn.add(tf.keras.layers.Dense(units=1, activation='sigmoid'))
* 시그모이드를 사용하는 이유: 함수는 출력값이 0과 1 사이에 있는 S자 함수입니다.
* 이 함수는 이진 분류 문제의 출력 계층에 사용됩니다.
* 이 함수를 이용하면 모델에서 예측한 값을 확률로 해석할 수 있고, 이를 바탕으로 클래스를 구분할 수 있습니다.
※ 출력 레이어의 컨볼루션 및 활성화
CNN 모델에서는 입력 이미지에서 추출한 특징을 ReLU 함수를 이용하여 비선형적으로 변환하고 마지막으로 시그모이드 함수를 이용하여 이진 분류 문제를 푼다.
이를 통해 모델은 더 복잡한 패턴을 학습하고 이를 기반으로 입력 이미지를 더 정확하게 분류할 수 있습니다.
5) CNN 모델 훈련
part1 – CNN 컴파일
# 'adam' 옵티마이저는 손실 함수의 기울기에 따라 네트워크 가중치를 업데이트하는 데 사용
# 'binary_crossentropy' 손실 함수는 이진 분류 문제에 사용되며 잘못된 예측에 대해 모델에 페널티를 줌
# 학습 및 테스트 중에 모델의 성능을 평가하는 데 사용되는 메트릭은 모델에서 수행한 올바른 예측의 백분율인 정확도
# compile() 함수는 모델을 컴파일하고 학습을 위해 준비하는 데 사용
cnn.compile(optimizer="adam", loss="binary_crossentropy", metrics = ('accuracy'))
part2 – 훈련 데이터 세트로 CNN 모델 훈련 및 테스트 데이터 세트로 모델 평가
# training_set에 지정된 훈련 데이터에서 컴파일된 CNN 모델 cnn을 훈련하고 총 25 에포크 동안 test_set에 지정된 테스트 데이터에서 검증
# 교육 과정에서 모델은 Adam 옵티마이저를 사용하여 이진 교차 엔트로피 손실을 최소화하려고 시도하고 '정확도' 메트릭을 사용하여 모델의 정확도를 모니터링한다.
# 'fit()' 메서드는 모델을 교육 데|이터에 맞추고 지정된 에포크 수 동안 테스트 데이터에서 유효성을 검사하는 데 사용
# 각 에포크 동안 모델은 지정된 배치 크기(이 경우 32개)의 배치에 대해 학습되며 유효성 검사 정확도 및 손실은 각 에포크 후에 계산
# 'fit()' 메서드의 출력은 각 시대의 모델 손실 및 정확도와 같은 교육 프로세스에 대한 정보를 포함하는 'History' 개체
cnn.fit(x = training_set, validation_data = test_set, epochs = 25)
part3 – 단일 예측 결과 확인
# 훈련된 CNN 모델을 사용하여 단일 이미지에 대한 예측을 하기 위한 것
import numpy as np
from keras.utils import load_img, img_to_array
# cnn모델에 입력할 크기로 조절 하면서 이미지를 불러온다.
test_image = load_img('dataset/prediction/dog.jpg', target_size = (64, 64))
# 이미지를 numpy배열로 변환
test_image = img_to_array(test_image)
# 배열의 차원을 cnn 모델의 입력 차원에 맞추기 위해 확장
test_image = np.expand_dims(test_image, axis = 0)
# cnn 모델을 사용하여 이미지에 대한 예측 수행
result = cnn.predict(test_image)
# 에측 결과를 레이블로 매핑하기 위해 훈련 데이터의 클래스 인덱스 를 가져온다.
training_set.class_indices
# 예측 결과가 1 이상인 경우 'dog' 그렇지 않은 경우 'cat'
if result(0)(0) == 1:
prediction = 'dog'
else:
prediction = 'cat'
print(prediction)