1. MNIST 딥러닝 네트워크 쌓기
model=keras.models.Sequential()
model.add(keras.layers.Conv2D(16, (3,3), activation='relu', input_shape=(28,28,1)))
model.add(keras.layers.MaxPool2D(2,2))
model.add(keras.layers.Conv2D(32, (3,3), activation='relu'))
model.add(keras.layers.MaxPooling2D((2,2)))
model.add(keras.layers.Flatten())
model.add(keras.layers.Dense(32, activation='relu'))
model.add(keras.layers.Dense(10, activation='softmax'))
print('Model에 추가된 Layer 개수: ', len(model.layers))
Model에 추가된 Layer 개수: 7
네트워크에서 입력으로 필요한 것들이 몇가지 있다. 코드 상에서도 보면 16, (3,3), input_shape 등이 있는 것을 알 수 있다.
네트워크 입력으로는 (데이터 개수, 이미지 크기, 이미지 크기, 채널수)이다. tf 공식문서에서도 (N, W, H, C)로 많이 표현되어 있는 것을 확인할 수 있었다.
input_shape는 (이미지 가로폭 x, 이미지 세로폭 y, 채널수) 를 의미한다. 채널수가 여기서 1인 이유는 MNIST는 앞에서 살펴봤듯이 흑백 영상이기 때문에 1이다. 컬러 이미지 같은 경우엔 채널수는 3이 된다.
Sequential은 각 줄의 출력이 다음 단의 입력으로 들어가도록 하는 함수이다. 모델의 층을 쌓아주는 것이다.
Conv2D, MaxPool2D, Flatten, Dense와 같은 layer들은 tensorflow 공식문서에서 관련 수식이 확인 가능하다. (공식문서: www.tensorflow.org/versions/r2.2/api_docs/python/tf?hl=ko)
위에 네트워크에서 16, 32와 같은 부분은 얼마나 다양한 이미지의 특징을 살펴볼 것인가와 관련된 부분이다. 따라서 입력 이미지가 다양하면 더 많은 특징을 고려해볼 수 있는 것이다. 그리고 Dense Layer에 있는 첫번째 인자 32는 분류기에 사용되는 뉴런의 숫자이다. 분류기 알고리즘을 얼마나 복잡하게 할 것인가에 대한 부분인데 복잡한 문제일수록 수를 늘려보는 것이 좋다. 마지막 Dense Layer에서는 최종적으로 분류기가 구분하고자 하는 class의 수를 의미한다.
여기서 드는 의문, 뉴런이 뭘까? 의학적으로는 신경 세포를 의미하지만 딥러닝에서는 n개의 input signal을 받아 output signal을 내보내는 것을 의미한다. 딥러닝에서는 활성화 함수를 적용함으로서 모든 input signal에 각각의 가중치를 곱하는 곳이며 해당 계산값을 다음 뉴런으로 보내느 역할을 수행한다고 생각하면 된다.
또 꼬리로는 활성화 함수가 뭐지? 라는 생각이 들텐데 이 부분은 이후에 나올 거 같아서 여기서는 pass..
model.summary()
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d (Conv2D) (None, 26, 26, 16) 160
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 13, 13, 16) 0
_________________________________________________________________
conv2d_1 (Conv2D) (None, 11, 11, 32) 4640
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 5, 5, 32) 0
_________________________________________________________________
flatten (Flatten) (None, 800) 0
_________________________________________________________________
dense (Dense) (None, 32) 25632
_________________________________________________________________
dense_1 (Dense) (None, 10) 330
=================================================================
Total params: 30,762
Trainable params: 30,762
Non-trainable params: 0
_________________________________________________________________
2. MNIST 딥러닝 네트워크 학습시키기
print("Before Reshape - x_train_norm shape: {}".format(x_train_norm.shape))
print("Before Reshape - x_test_norm shape: {}".format(x_test_norm.shape))
x_train_reshaped=x_train_norm.reshape( -1, 28, 28, 1) # 데이터갯수에 -1을 쓰면 reshape시 자동계산됩니다.
x_test_reshaped=x_test_norm.reshape( -1, 28, 28, 1)
print("After Reshape - x_train_reshaped shape: {}".format(x_train_reshaped.shape))
print("After Reshape - x_test_reshaped shape: {}".format(x_test_reshaped.shape))
Before Reshape - x_train_norm shape: (60000, 28, 28)
Before Reshape - x_test_norm shape: (10000, 28, 28)
After Reshape - x_train_reshaped shape: (60000, 28, 28, 1)
After Reshape - x_test_reshaped shape: (10000, 28, 28, 1)
채널 수는 load_data 했을 때 포함되지 않기 때문에 채널 수를 포함한 후 reshape해줘야한다.
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
model.fit(x_train_reshaped, y_train, epochs=10)