[공학연구실습2/1주차]Keras로 ANN,CNN 구현
colab에서 Keras로 인공신경망 학습하기
1. MNIST handwriting classification example: ANN
colab에서 ANN 모델로 MINST 분류하는 모델을 만든다.
(참고: https://keras.io/examples/vision/mnist_convnet/)
1) 모델을 위한 데이터를 준비한다.
# Model / data parameters
num_classes = 10
input_shape = (28*28,)
# Load the data and split it between train and test sets
(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
x_train = x_train.reshape(-1, 28*28)
x_test = x_test.reshape(-1, 28*28)
# Scale images to the [0, 1] range
x_train = x_train.astype("float32") / 255
x_test = x_test.astype("float32") / 255
# Make sure images have shape (28, 28, 1)
#x_train = np.expand_dims(x_train, -1)
#x_test = np.expand_dims(x_test, -1)
print("x_train shape:", x_train.shape)
print(x_train.shape[0], "train samples")
print(x_test.shape[0], "test samples")
# convert class vectors to binary class matrices
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
내가 사용할 데이터는 필기 숫자 데이터인 MINST이다.
- keras에서 minst를 train data와 test data로 나눠 가져온다. 이때 train data는 모델을 학습시키는데 사용될 데이터이고, test data는 학습된 모델을 검사하는 데이터로 학습될 때 한번도 사용되지 않은 데이터이다. 즉 test data는 모델의 평가 지표가 된다.
- x_train/test, y_train/test의 의미는?
쉽게 말해서 데이터셋에서 label은 feature들로 결정되는데, 이때 freature가 x, label이 y가 된다. 즉 여러 x로 인해 정해지는 데이터가 y가 된다.
- 28x28의 2차원 배열로 데이터를 받았는데, reshape 함수로 각 데이터를 1차원 배열로 바꾼다.
- 그리고 astype 함수로 데이터 각 셀의 숫자 type을 0과 1 사이의 float으로 바꾼다.
- to_categorical 함수로 one-hot 인코딩(10진수 정수 형식을 특수한 2진 바이너리 형식으로 변경)한다. 즉 y_train/test의 정수를 class의 개수만큼 여러 0과 한개의 1로 구별한다.
2) 모델을 구성한다.
model = keras.Sequential(
[
keras.Input(shape=input_shape),
layers.Dense(256, activation="relu"),
layers.Dense(64, activation="relu"),
layers.Dense(num_classes, activation="softmax"),
]
)
model.summary()
모델은 입력값을 받아서 여러 층의 레이어를 거치고 출력값을 생성한다.
- sequential 은 모델을 구성할 때 계층 구조를 작성한 순서 그대로 생성한다.
Dense(8, input_dim = 4, kernel_initializer = 'uniform', activation = 'relu')
(1) 첫번째 인자: 출력 노드 수
(2) input_dim: 입력 노드(뉴런) 수
(3) kernel_initializer: 가중치를 초기화하는 방법 설정
(4) activation: 활성화 함수 선택
- relu: 은닉층에서 주로 쓰임
- sigmond: 이진 분류에서 출력층에 주로 쓰임
- softmax: 다중클래스 분류문제에서 출력층에 주로 쓰임
- liner: 입력값과 가중치로 계산된 결과값이 그대로 출력으로 나옴
3) 모델을 학습시킨다.
batch_size = 128
epochs = 8
model.compile(loss="categorical_crossentropy", optimizer=Adam(learning_rate=0.001), metrics=["accuracy"])
model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, validation_split=0.1)
- batch_size: 전체 train data에서 여러 작은 그룹을 나눴을 때, 한 소그룹의 데이터 수이다. batch 크기만큼 데이터를 활용해 모델이 예측한 값과 실제 정답 간의 오차를 계산하여 parameter를 업데이트한다. 예를 들어 전체 데이터가 3000개 이고 batch_size가 300이라면, 데이터를 300개씩 활용해 모델을 학습시켜 간다.
- epochs: 전체 train data를 학습한 횟수
- iteration: 전체 데이터에 대해 총 batch의 수
- compile 함수로 모델 학습 과정을 설정한다.
(1) loss: 최적화 과정에서 최소화될 손실함수 설정
손실 함수란 학습이 진행되면서 해당 과정이 얼마나 잘 되고 있는지 나타내는 지표이다. 손실 함수의 결과를 통해 학습 파라미터를 조정한다. sparse_categorical_crossentropy, categorical_cross_entropy, binary_crossentropy 등이 있다.
(2) optimizer: 훈련 과정 설정, 손실 함수를 기반으로 모델이 어떻게 업데이트 돼야 하는지 결정한다. SGD, Adam 사용.
(3) metrics: 훈련을 모니터링하는 방식
- fit 함수로 모델을 학습시킨다.
4) 모델을 평가한다.
score = model.evaluate(x_test, y_test, verbose=0)
print("Test loss:", score[0])
print("Test accuracy: ", score[1])
- evaluate 함수로 모델을 평가한다.
loss는 예측값과 실제값이 차이나는 정도로 작을 수록 좋다.
accuracy는 모델의 정확성을 나타낸다.
from keras.models import load_model
model.save('mnist_ann.h5')
ann_model=load_model('minst_ann.h5')
예측할 때마다 모델을 만들기엔 시간이 오래 걸리니까, 모델을 저장하고 불러온다.
전체 코드
import numpy as np
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.optimizers import Adam
from sklearn.metrics import confusion_matrix
from sklearn.metrics import precision_score, recall_score, f1_score
"""
Prepare the data
"""
# Model / data parameters
num_classes = 10
input_shape = (28*28,)
# Load the data and split it between train and test sets
(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
x_train = x_train.reshape(-1, 28*28)
x_test = x_test.reshape(-1, 28*28)
# Scale images to the [0, 1] range
x_train = x_train.astype("float32") / 255
x_test = x_test.astype("float32") / 255
# Make sure images have shape (28, 28, 1)
#x_train = np.expand_dims(x_train, -1)
#x_test = np.expand_dims(x_test, -1)
print("x_train shape:", x_train.shape)
print(x_train.shape[0], "train samples")
print(x_test.shape[0], "test samples")
# convert class vectors to binary class matrices
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
"""
Build the model
"""
model = keras.Sequential(
[
keras.Input(shape=input_shape),
layers.Dense(256, activation="relu"),
layers.Dense(64, activation="relu"),
layers.Dense(num_classes, activation="softmax"),
]
)
model.summary()
"""
Train the model
"""
batch_size = 128
epochs = 8
#model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"])
model.compile(loss="categorical_crossentropy", optimizer=Adam(learning_rate=0.001), metrics=["accuracy"])
model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, validation_split=0.1)
"""
Evaluate the trained model
"""
score = model.evaluate(x_test, y_test, verbose=0)
print("Test loss:", score[0])
print("Test accuracy: ", score[1])
결과
2. MNIST handwriting classification example: CNN
colab에서 CNN 모델로 MINST 분류하는 모델을 만든다.
(참고: https://keras.io/examples/vision/mnist_convnet/)
위의 ann 모델을 학습시키는 과정과 동일하게 진행한다.
1) 모델을 위한 데이터를 준비한다.
# Model / data parameters
num_classes = 10
input_shape = (28, 28, 1)
# Load the data and split it between train and test sets
(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
# Scale images to the [0, 1] range
x_train = x_train.astype("float32") / 255
x_test = x_test.astype("float32") / 255
# Make sure images have shape (28, 28, 1)
x_train = np.expand_dims(x_train, -1)
x_test = np.expand_dims(x_test, -1)
print("x_train shape:", x_train.shape)
print(x_train.shape[0], "train samples")
print(x_test.shape[0], "test samples")
# convert class vectors to binary class matrices
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
2) 모델을 구성한다.
model = keras.Sequential(
[
keras.Input(shape=input_shape),
layers.Conv2D(32, kernel_size=(3, 3), activation="relu"),
layers.MaxPooling2D(pool_size=(2, 2)),
layers.Conv2D(64, kernel_size=(3, 3), activation="relu"),
layers.MaxPooling2D(pool_size=(2, 2)),
layers.Flatten(),
layers.Dropout(0.5),
layers.Dense(num_classes, activation="softmax"),
]
)
model.summary()
- convolutional layer란 일정 크기의 필터(Kernel)를 옆으로 한칸씩 밀면서(striding) 이미지의 특징을 추출해내는 레이어이다. 우리는 2차원 배열 데이터를 사용하므로 Conv2D로 이미지의 특징을 추출한다. 위에선 32개의 크기가 (x, y) 인 kernel을 만든다. (참고: https://devwaffle.tistory.com/10)
- pooling layer란 convolutional layer에서 연산량을 줄이고 특징을 정확히 파악하도록 도와준다. 특정 기준에 따라 데이터의 크기를 줄여 가운데로 모은다. 위에선 가장 강한 특징을 뽑아 내는MaxPooling2D를 사용한다.
- Flatten을 사용해 2차원 데이터를 1차원 데이터로 바꾼다.
- 학습이 진행되다보면 overfitting이 되는데(모델이 학습 데이터에만 맞게 학습됨), 이를 방지하기 위해 학습할 때마다 연결을 끊어주는 과정으로 Dropout을 사용한다.
- Dense로 입력과 출력을 연결한다.
3) 모델을 학습시킨다.
batch_size = 128
epochs = 8
model.compile(loss="categorical_crossentropy", optimizer=Adam(learning_rate=0.001), metrics=["accuracy"])
model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, validation_split=0.1)
4) 모델을 평가한다.
score = model.evaluate(x_test, y_test, verbose=0)
print("Test loss:", score[0])
print("Test accuracy:", score[1])
전체 코드
import numpy as np
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.optimizers import Adam
"""
Prepare the data
"""
# Model / data parameters
num_classes = 10
input_shape = (28, 28, 1)
# Load the data and split it between train and test sets
(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
# Scale images to the [0, 1] range
x_train = x_train.astype("float32") / 255
x_test = x_test.astype("float32") / 255
# Make sure images have shape (28, 28, 1)
x_train = np.expand_dims(x_train, -1)
x_test = np.expand_dims(x_test, -1)
print("x_train shape:", x_train.shape)
print(x_train.shape[0], "train samples")
print(x_test.shape[0], "test samples")
# convert class vectors to binary class matrices
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
"""
Build the model
"""
model = keras.Sequential(
[
keras.Input(shape=input_shape),
layers.Conv2D(32, kernel_size=(3, 3), activation="relu"),
layers.MaxPooling2D(pool_size=(2, 2)),
layers.Conv2D(64, kernel_size=(3, 3), activation="relu"),
layers.MaxPooling2D(pool_size=(2, 2)),
layers.Flatten(),
layers.Dropout(0.5),
layers.Dense(num_classes, activation="softmax"),
]
)
model.summary()
"""
Train the model
"""
batch_size = 128
epochs = 8
#model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"])
model.compile(loss="categorical_crossentropy", optimizer=Adam(learning_rate=0.001), metrics=["accuracy"])
model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, validation_split=0.1)
"""
Evaluate the trained model
"""
score = model.evaluate(x_test, y_test, verbose=0)
print("Test loss:", score[0])
print("Test accuracy:", score[1])
결과