손 글씨를 인식해보자
MNIST 데이터는 텐서플로의 케라스 API를 이용해 불러오기 ㄱㄴ
from tensorflow.keras.datasets import mnist
학습에 사용될 부분: X_train, y_train
테스트에 사용될 부분: X_test, y_test
(X_train, y_train), (X_test,y_test) = mnist.load_data()
print("학습셋 이미지 수 : %d개" % (X_train.shape[0]))
print("테스트셋 이미지 수: %d개" % (X_test.shape[0]))
실행결과는
학습셋 이미지 수: 60000개
테스트셋 이미지 수:10000개
맷플롯립 라이브러리를 불러오고 이미지 1개를 출력해서 분석해보자
import matplotlib.pyplot as plt
plt.imshow(X_train[0], cmap = 'Greys')
plt.show()
784개의 픽셀 이미지이고 밝기에 따라 등급을 나눔
for x in X_train[0]:
for i in x:
sys.stdout.write("%-3s"%i)
sys.stdout.write('\n')
28*28=784개의 속성을 이용해 0~9까지의 클래스중 1개를 고르는 문제
2차원 배열을 1차원 배열로 바꾸기 위해 reshape함수 사용
X_train = X_train.reshape(X_train.shape[0],784)
케라스는 데이터를 0~1사이 값으로 변환 후 구동할 때 최적의 성능을 가짐
정규화 데이터의 폭이 클 때 적절한 정도로 바꾸는 과정
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]))
결과로 5가 출력되는 것을 볼 수 있다..!
딥러닝의 분류문제를 해결하기 위해서는 원-핫 인코딩 방식을 적용해야함
우리가 열어 본 이미지 클래스는 5 = [0,0,0,0,0,1,0,0,0,0](원-핫 인코딩)
이를 가능하게 해주는 것이 np_utils.to_categorical()함수
to_categorical(클래스, 클래스의 개수)
y_train = to_categorical(y_train, 10)
y_test = to_categorical(y_test, 10)
print(y_train[0])
실행결과
[0,0,0,0,0,1,0,0,0,0]
from tensorflow.keras.datasets import mnist
from tensorflow.keras.utils import to_categorical
import matplotlib.pyplot as plt
import sys
#MNIST 데이터셋을 불러와 학습셋과 테스트셋으로 저장
(X_train, y_train), (X_test, y_test) = mnist.load_data()
print("학습셋 이미지 수 : %d개" % (X_train.shape[0]))
print("테스트셋 이미지 수: %d개" % (X_test.shape[0]))
plt.imshow(X_train[0], cmap = 'Greys')
plt.show()
for x in X_train[0]:
for i in x:
sys.stdout.write("%-3s"%i)
sys.stdout.write('\n')
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_train = to_categorical(y_train, 10)
y_test = to_categorical(y_test, 10)
print(y_train[0])
6만개의 학습셋과 1만개의 테스트셋을 불러와
속성 값을 지닌 X ,클래스 값을 지닌 y로 구분하는 작업을 정리
from tensorflow.keras.datasets import mnist
#MNIST 데이터셋을 불러와 학습셋과 테스트셋으로 저장
(X_train, y_train), (X_test, y_test) = mnist.load_data()
X_train = X_train.reshape(X_train.shape[0],784).astype('float64') / 255
X_test = X_test.reshape(X_test.shape[0], 784).astype('float64') / 255
y_train = to_categorical(y_train, 10)
y_test = to_categorical(y_test, 10)
딥러닝을 실행하고자 프레임을 설정한다.
model = Sequential()
model.add(Dense(512, input_dim=784, activation = 'relu'))
model.add(Dense(10, activation='softmax'))
입력 값이 784개, 은닉층이 512개 출력이 10개인 모델
활성화 함수로 은닉층에서는 'relu', 출력층에서는 softmax
model.compile(loss='categorical_crossentropy', optimizer = 'adam',metrics =['accuracy'])
오차 함수로 categorical_crossentropy 최적화 함수로 adam
모델의 최적화 단계, 학습 자동중단
from tensorflow.keras.callbacks import ModelCheckpoint, Earlystopping
#모델의 최적화를 위한 설정 구간
modelpath = "./MNIST_MLP.hdf5"
checkpointer = ModelCheckpoint(filepath=modelpath, monitor = 'val_loss', verbpse=1, save_best_only = True)
early_stoppping_callback = EarlyStopping(monitor='val_loss',patience=10)
10번 이상 모델 성능이 향상되지 않으면 자동으로 학습을 중단한다.
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping
from tensorflow.keras.datasets import mnist
from tensorflow.keras.utils import to_categorical
import matplotlib.pyplot as plt
import numpy as np
import os
#MNIST 데이터를 불러온다.
(X_train, y_train), (X_test, y_test) = mnist.load_data()
#차원 변환 후, 테스트셋과 학습셋으로 나눈다.
X_train = X_train.reshape(X_train.shape[0], 784).astype('float32') / 255
X_test = X_test.reshape(X_test.shape[0], 784).astype('float32') / 255
y_train = to_categorical(y_train, 10)
y_test = to_categorical(y_test, 10)
#모델 구조를 설정한다.
model = Sequential()
model.add(Dense(512, input_dim=784, activation='relu'))
model.add(Dense(10, activation='softmax'))
model.summary()
#모델 실행 환경을 설정한다.
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
#모델 최적화를 위한 설정 구간.
modelpath = "./MNIST_MLP.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_split=0.25, 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 = np.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()
23번 실행하고 정확도는 0.9815
프로젝트에 맞추어 옵션을 추가하고 어떤 층을 추가하느냐에 따라 성능이 좋아짐.
컨벌루션 신경망(CNN) :입력된 이미지에서 다시 한 번 특징을 추출하기 위해 커널(슬라이딩 윈도)를 도입하는 기법
입력받은 이미지의 값에 커널을 곱하고 합해서 컨벌루션 층을 만든다.
커널을 여러 개 만들경우 여러 개의 컨볼루션 층이 만들어진다.
케라스에서 컨벌루션 층을 추가하는 함수는 Conv2D()입니다. 컨벌루션 층을 적용해 MNIST 손글씨 인식률을 높여보자.
model.add(Conv2d(32, kernel_size=(3,3), input_shape=(28, 28, 1), activation='relu'))
입력된 인자를 보자
1. 커널을 몇 개 적용할지 정한다. 여기서는 32
2. Kernel_size: 커널의 크기 (행, 렬) 여기서는 3X3
3. input_shape: input_shape=(행, 열, 색상 또는 흑백) 형식 색상 3, 흑백 1
4.activation: 사용할 활성화 함수를 정의
컨벌루션 층을 하나 더 추가
model.add(Conv2D(64, (3,3), activation='relu'))
컨벌루션 층을 통해 이미지 특징을 도출해도 그 결과가 여전히 크고 복잡하면 이를 다시 축소해야함.
이 과정을 풀링 or 서브 샘플링이라고 한다.
정해진 구역에서 최댓값을 뽑아내는 맥스 풀링
평균값을 뽑아내는 평균 풀링 등이 있다.
이미지가 있을 때, 맥스 풀링을 적용, 그후 각 구역에서 가장 큰 값 추출
MaxPooling2D()함수를 사용
model.add(MaxPooling2D(pool_size=(2,2)))
Pool_size는 풀링 창의 크기를 정하는 것 (2,2)는 가로 2 세로 2
은닉층에 배치된 노드 중 일부를 임의로 꺼 주는 것
예를 들어 25%의 노드를 끄려면
model.add(Dropout(0.25))
이러한 과정을 지나고 다시 Dense()함수를 이용해 만들어진 기본 층에 연결
맥스풀링과 컨볼루션 층은 이미지를 2차원 배열인 채 다루기 때문에 이를 1차원 배열로 바꾸어 주어야 활성화 함수가 있는 층에사 사용가능
Flatten()함수를 사용해 2차원 배열을 1차원으로 바꿔야 한다.
model.add(Flatten())
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPooling2D
from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping
from tensorflow.keras.datasets import mnist
from tensorflow.keras.utils import to_categorical
import matplotlib.pyplot as plt
import numpy as np
#데이터를 불러옵니다.
(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 = to_categorical(y_train)
y_test = 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,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'])
#모델 최적화를 위한 설정 구간입니다.
modelpath = "./MNIST_CNN.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_split=0.25, 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 = np.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()
데이터를 정확하게 맞추지는 못했는데 이는 데이터 안에 0~9까지의 숫자가 아닌 다른 그림이 있었기 때문