[딥러닝]5. 딥러닝 활용 <1>CNN
1. CNN
* MNIST를 이용한 손글씨 인식하기
1) 데이터 전처리
from keras.datasets import mnist
from keras.utils import np_utils
import numpy
import sys
import tensorflow as tf
seed = 0
numpy.random.seed(seed)
tf.random.set_seed(3)
(X_train, Y_train),(X_test, Y_test) = mnist.load_data()
print(X_train.shape[0]) #60000
print(X_test.shape[0] #10000
import matplotlib.pyplot as plt
plt.imshow(X_train[0], cmap='gray')
plt.show()
X_train = X_train.reshape(X_train.shape[0], 784)
X_train = X_train.astype('float64')
X_train = X_train/255
X_test = X_test.reshape(X_test.shape[0], 784).astype('float64')/255
print("class : %d " % (Y_train[0])) #Y 클래스(레이블값) 확인
#class : 5
Y_train = np_utils.to_categorical(Y_train, 10)
Y_test = np_utils.to_categorical(Y_test, 10)
print(Y_train[0])
# [0. 0. 0. 0. 0. 1. 0. 0. 0. 0.]
- mnist 데이터 : 케라스를 이용해서 부를 수 있음
- 미국 국립표준기술원(NIST)이 고등학생과 인구조사국 직원 등이 쓴 손글씨를 이용해 만든 데이터로 구성
- 70,000개의 글자 이미지에 각각 0부터 9까지 이름표를 붙인 데이터셋
- 총 70,000개의 이미지 중 60,000개를 학습용으로, 10,000개를 테스트용으로 미리 구분해 놓음
plt.imshow(X_train[0], cmap='gray')
: 이미지 출력
- imshow() : 이미지 출력
- X_train[0] : 첫 번째 이미지
- cmap='gray' : 이미지 흑백 출력
- 데이터
- X : 이미지 데이터
- X_train : 학습셋 이미지
- X_test : 테스트셋 이미지
- Y : 0부터 9까지 이름표
- Y_train : 학습셋 이미지
- Y_test : 테스트셋 이미지
➡️ 784개의 속성을 이용해 10개 클래스 중 하나를 맞추는 문제임
- 이미지 인식 방법
- 가로 : 28, 세로 : 28 = 총 784개의 픽셀로 구성
- 각 픽셀의 밝기 : 0 ~ 255
- 0 ~ 255로 이루어진 긴 행렬로 이루어져 있음
for x in X_train[0]:
for i in x:
sys.stdout.write('%d\t' % i)
sys.stdout.write('\n')
- ➡️ 2차원 배열(28 X 28 행렬)에서 1차원 배열로 변경해줘야 함
- reshape(총 샘플 수, 1차원 속성의 수)
- 데이터 정규화(normalization) : 데이터 폭이 클 때 적절한 값으로 분산의 정도를 바꿈
- 현재 값인 0~255 ➡️ 0~1사이의 값으로 변경
- astype(float) 후 255로 나눠줌
- 원-핫 인코딩 방식 : 딥러닝 분류 문제 해결
- 0~9까지의 클래스를 0과 1로 이루어진 벡터로 변경
- to_categorical(클래스, 클래스 개수)
2) 딥러닝 기본 프레임 만들기
- 총 784개의 속성, 10개의 클래스로 구성
from keras.datasets import mnist
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers import Dense
from keras.callbacks import ModelCheckpoint,EarlyStopping
import numpy
import sys
import tensorflow as tf
import os
# 모델 프레임 설정
model = Sequential()
model.add(Dense(512, input_dim=784, activation='relu'))
model.add(Dense(10, activation='softmax'))
# 모델 실행환경 설정
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
# 모델 최적화 설정
MODEL_DIR = './model/'
if not os.path.exists(MODEL_DIR):
os.mkdir(MODEL_DIR)
modelpath = "./model/{epoch:02d}-{val_loss:.4f}.hdf5"
checkpoint = ModelCheckpoint(filepath=modelpath, monitor='val_loss', verbose=1, save_best_only=True)
early_stopping_callback = EarlyStopping(monitor='val_loss', patience=10)
# 모델 실행
history = model.fit(X_train, Y_train, validation_data=(X_test, Y_test), epochs=30, batch_size=200, verbose=0,
callbacks=[early_stopping_callback, checkpoint])
model.evaluate(X_test, Y_test)[1]
# 테스트셋의 오차
y_vloss = history.history['val_loss']
# 학습셋의 오차
y_loss = history.history['loss']
x_len = numpy.arange(len(y_loss))
plt.plot(x_len, y_vloss, marker='.', c='red', label='Testset_loss')
plt.plot(x_len, y_loss, marker='.', c='blue', label='Trainset_loss')
plt.legend(loc='upper right')
plt.grid()
plt.xlabel('epoch')
plt.ylabel('loss')
plt.show()
model.add(Dense(512, input_dim=784, activation='relu'))
: 은닉층 512개, 입력값 784개,
- 은닉층의 활성화 함수 : relu, 출력층의 활성화 함수 : softmax
- 10회 이상 모델 성능에 차이가 없으면 학습 중단
history = model.fit(X_train, Y_train, validation_data=(X_test, Y_test), epochs=30, batch_size=200, verbose=0, callbacks=[early_stopping_callback, checkpoint])
: 샘플 200개를 모두 30번 실행하게 설정.
- 학습셋의 오차 그래프 표현 : 오차 = 1 - 정확도
- 베스트 모델 : 10번째 에포크 ➡️ 정확도 98.21%
은닉층이 하나인 딥러닝 모델 도식
3) 컨볼루션 신경망(CNN)
- 입력된 이미지에서 다시 한번 특징을 추출하기 위해 마스크(커널, 필터, 윈도)를 도입함
- 예시
⬆️ 입력된 이미지
⬆️ 마스크 : 각 칸에 가중치있음
⬆️ 마스크를 옮겨가면서 적용 : 적용된 부분은 원래 있던 값에 가중치를 곱하고 그 결과를 합산해서 새로운 값 도출⬇️
➡️ 컨볼루션(합성곱) : 새롭게 만들어진 층. 입력 데이터로부터 더욱 정교한 특징을 추출할 수 있음
여러개의 마스크 대입 시 여러개의 컨볼루션 만들 수 있음.
model.add(Conv2D(32, kernel_size=(3,3), input_shape=(28,28,1), activation='relu')
model.add(Conv2D(64, (3, 3), activation='relu')) #마스크 64개를 적용한 컨볼루션 층 추가
- Conv2D(숫자, kernel_size, input_shape, activation) : 케라스에 컨볼루션 층 추가하는 함수
- 첫 번째 인자 : 마스크를 몇개 적용할지 결정
- 32개의 마스크 적용
- kernel_size : 마스크(커널)의 크기 결정
- 3x3 사이즈의 마스크 사용
- input_shape=(행, 열, 색상 또는 흑백) : 맨 처음 층에 입력되는 값 알려주기
- 입력이미지가 색상인 경우 3, 흑백인 경우 1 선택
4) 맥스 풀링
- 풀링(pooling)(=서브 샘플링(sub sampling)) : 컨볼루션 층으로부터 얻은 특징 결괏값이 여전히 크고 복잡하여 축소함
- 맥스 풀링(max pooling) : 정해진 구역안에서 최댓값을 뽑아냄
- 평균 풀링(average pooling) : 정해진 구역안에서 평균값을 뽑아냄
ex) 맥스 풀링 예시
- 이미지
- 맥스 풀링을 적용하여 구역을 나눔
- 각 구역에서 가장 큰 값 추출 : 불필요한 정보 간추림
model.add(MaxPooling2D(pool_size=2))
- MaxPooling2D() : 맥스 풀링 적용
- pool_size : 풀링 창의 크기 결정
- 2로 설정 : 전체 크기가 반으로 줄어듦
5) 드롭아웃, 플래튼
- 드롭아웃(dropout) : 은닉층에 배치된 노드 중 일부를 임의로 꺼줌 ➡️ 랜덤하게 노드를 끔으로써 학습 데이터에 지나치게 치우쳐서 학습되는 과적합 방지 가능
from keras.datasets import mnist
from keras.utils import np_utils
import numpy
import sys
import tensorflow as tf
seed = 0
numpy.random.seed(seed)
tf.random.set_seed(3)
(X_train, Y_train),(X_test, Y_test) = mnist.load_data()
print(X_train.shape[0]) #60000
print(X_test.shape[0] #10000
import matplotlib.pyplot as plt
plt.imshow(X_train[0], cmap='gray')
plt.show()
X_train = X_train.reshape(X_train.shape[0], 784)
X_train = X_train.astype('float64')
X_train = X_train/255
X_test = X_test.reshape(X_test.shape[0], 784).astype('float64')/255
print("class : %d " % (Y_train[0])) #Y 클래스(레이블값) 확인
#class : 5
Y_train = np_utils.to_categorical(Y_train, 10)
Y_test = np_utils.to_categorical(Y_test, 10)
print(Y_train[0])
# [0. 0. 0. 0. 0. 1. 0. 0. 0. 0.]
- mnist 데이터 : 케라스를 이용해서 부를 수 있음
- 미국 국립표준기술원(NIST)이 고등학생과 인구조사국 직원 등이 쓴 손글씨를 이용해 만든 데이터로 구성
- 70,000개의 글자 이미지에 각각 0부터 9까지 이름표를 붙인 데이터셋
- 총 70,000개의 이미지 중 60,000개를 학습용으로, 10,000개를 테스트용으로 미리 구분해 놓음
plt.imshow(X_train[0], cmap='gray')
: 이미지 출력- imshow() : 이미지 출력
- X_train[0] : 첫 번째 이미지
- cmap='gray' : 이미지 흑백 출력
- 데이터
- X : 이미지 데이터
- X_train : 학습셋 이미지
- X_test : 테스트셋 이미지
- Y : 0부터 9까지 이름표
- Y_train : 학습셋 이미지
- Y_test : 테스트셋 이미지
➡️ 784개의 속성을 이용해 10개 클래스 중 하나를 맞추는 문제임- 이미지 인식 방법
- 이미지 인식 방법
- 가로 : 28, 세로 : 28 = 총 784개의 픽셀로 구성
- 각 픽셀의 밝기 : 0 ~ 255
- 0 ~ 255로 이루어진 긴 행렬로 이루어져 있음
for x in X_train[0]: for i in x: sys.stdout.write('%d\t' % i) sys.stdout.write('\n')
- ➡️ 2차원 배열(28 X 28 행렬)에서 1차원 배열로 변경해줘야 함
- reshape(총 샘플 수, 1차원 속성의 수)
- 현재 값인 0~255 ➡️ 0~1사이의 값으로 변경
- astype(float) 후 255로 나눠줌
- 0~9까지의 클래스를 0과 1로 이루어진 벡터로 변경
- to_categorical(클래스, 클래스 개수)
from keras.datasets import mnist
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers import Dense
from keras.callbacks import ModelCheckpoint,EarlyStopping
import numpy
import sys
import tensorflow as tf
import os
# 모델 프레임 설정
model = Sequential()
model.add(Dense(512, input_dim=784, activation='relu'))
model.add(Dense(10, activation='softmax'))
# 모델 실행환경 설정
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
# 모델 최적화 설정
MODEL_DIR = './model/'
if not os.path.exists(MODEL_DIR):
os.mkdir(MODEL_DIR)
modelpath = "./model/{epoch:02d}-{val_loss:.4f}.hdf5"
checkpoint = ModelCheckpoint(filepath=modelpath, monitor='val_loss', verbose=1, save_best_only=True)
early_stopping_callback = EarlyStopping(monitor='val_loss', patience=10)
# 모델 실행
history = model.fit(X_train, Y_train, validation_data=(X_test, Y_test), epochs=30, batch_size=200, verbose=0,
callbacks=[early_stopping_callback, checkpoint])
model.evaluate(X_test, Y_test)[1]
# 테스트셋의 오차
y_vloss = history.history['val_loss']
# 학습셋의 오차
y_loss = history.history['loss']
x_len = numpy.arange(len(y_loss))
plt.plot(x_len, y_vloss, marker='.', c='red', label='Testset_loss')
plt.plot(x_len, y_loss, marker='.', c='blue', label='Trainset_loss')
plt.legend(loc='upper right')
plt.grid()
plt.xlabel('epoch')
plt.ylabel('loss')
plt.show()
model.add(Dense(512, input_dim=784, activation='relu'))
: 은닉층 512개, 입력값 784개, history = model.fit(X_train, Y_train, validation_data=(X_test, Y_test), epochs=30, batch_size=200, verbose=0, callbacks=[early_stopping_callback, checkpoint])
: 샘플 200개를 모두 30번 실행하게 설정.은닉층이 하나인 딥러닝 모델 도식
- 입력된 이미지에서 다시 한번 특징을 추출하기 위해 마스크(커널, 필터, 윈도)를 도입함
- 예시
⬆️ 입력된 이미지
⬆️ 마스크 : 각 칸에 가중치있음
⬆️ 마스크를 옮겨가면서 적용 : 적용된 부분은 원래 있던 값에 가중치를 곱하고 그 결과를 합산해서 새로운 값 도출⬇️
➡️ 컨볼루션(합성곱) : 새롭게 만들어진 층. 입력 데이터로부터 더욱 정교한 특징을 추출할 수 있음
여러개의 마스크 대입 시 여러개의 컨볼루션 만들 수 있음.
- 예시
model.add(Conv2D(32, kernel_size=(3,3), input_shape=(28,28,1), activation='relu')
model.add(Conv2D(64, (3, 3), activation='relu')) #마스크 64개를 적용한 컨볼루션 층 추가
- 첫 번째 인자 : 마스크를 몇개 적용할지 결정
- 32개의 마스크 적용
- kernel_size : 마스크(커널)의 크기 결정
- 3x3 사이즈의 마스크 사용
- input_shape=(행, 열, 색상 또는 흑백) : 맨 처음 층에 입력되는 값 알려주기
- 입력이미지가 색상인 경우 3, 흑백인 경우 1 선택
- 풀링(pooling)(=서브 샘플링(sub sampling)) : 컨볼루션 층으로부터 얻은 특징 결괏값이 여전히 크고 복잡하여 축소함
- 맥스 풀링(max pooling) : 정해진 구역안에서 최댓값을 뽑아냄
- 평균 풀링(average pooling) : 정해진 구역안에서 평균값을 뽑아냄
ex) 맥스 풀링 예시
- 이미지
- 맥스 풀링을 적용하여 구역을 나눔
- 각 구역에서 가장 큰 값 추출 : 불필요한 정보 간추림
model.add(MaxPooling2D(pool_size=2))
- pool_size : 풀링 창의 크기 결정
- 2로 설정 : 전체 크기가 반으로 줄어듦
- 드롭아웃(dropout) : 은닉층에 배치된 노드 중 일부를 임의로 꺼줌 ➡️ 랜덤하게 노드를 끔으로써 학습 데이터에 지나치게 치우쳐서 학습되는 과적합 방지 가능
model.add(Dropout(0.25)) #25%의 노드 끔
- 플래튼(flatten) : 2차원 배열을 1차원 배열로 바꿔줌
- 컨볼루션 층, 맥스풀링 층 : 2차원 배열
- 입력층 : 1차원배열 필요(활성화 함수 적용 시 필요)
from keras.datasets import mnist
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPooling2D
from keras.callbacks import ModelCheckpoint,EarlyStopping
import matplotlib.pyplot as plt
import numpy
import os
import tensorflow as tf
# seed 값 설정
seed = 0
numpy.random.seed(seed)
tf.random.set_seed(3)
# 데이터 불러오기
(X_train, Y_train), (X_test, Y_test) = mnist.load_data()
X_train = X_train.reshape(X_train.shape[0], 28, 28, 1).astype('float32') / 255
X_test = X_test.reshape(X_test.shape[0], 28, 28, 1).astype('float32') / 255
Y_train = np_utils.to_categorical(Y_train)
Y_test = np_utils.to_categorical(Y_test)
# 컨볼루션 신경망 설정
model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3), input_shape=(28, 28, 1), activation='relu'))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=2))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(10, activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
# 모델 최적화 설정
MODEL_DIR = './model/'
if not os.path.exists(MODEL_DIR):
os.mkdir(MODEL_DIR)
modelpath="./model/{epoch:02d}-{val_loss:.4f}.hdf5"
checkpointer = ModelCheckpoint(filepath=modelpath, monitor='val_loss', verbose=1, save_best_only=True)
early_stopping_callback = EarlyStopping(monitor='val_loss', patience=10)
# 모델의 실행
history = model.fit(X_train, Y_train, validation_data=(X_test, Y_test), epochs=30, batch_size=200, verbose=0, callbacks=[early_stopping_callback,checkpointer])
# 테스트 정확도 출력
print("\n Test Accuracy: %.4f" % (model.evaluate(X_test, Y_test)[1]))
# 테스트셋의 오차
y_vloss = history.history['val_loss']
# 학습셋의 오차
y_loss = history.history['loss']
# 그래프로 표현
x_len = numpy.arange(len(y_loss))
plt.plot(x_len, y_vloss, marker='.', c="red", label='Testset_loss')
plt.plot(x_len, y_loss, marker='.', c="blue", label='Trainset_loss')
# 그래프에 그리드를 주고 레이블을 표시
plt.legend(loc='upper right')
plt.grid()
plt.xlabel('epoch')
plt.ylabel('loss')
plt.show()
Author And Source
이 문제에 관하여([딥러닝]5. 딥러닝 활용 <1>CNN), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@jjaa9292/딥러닝5.-딥러닝-활용저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)