딥러닝 텐서플로우 10개로 분류된 패션이미지 분류 예시, softmax, np.argmax(axis=1), overfitting, callbacks
A Computer Vision Example¶
10개로 분류된 패션 이미지를 분류하는 딥러닝
Start Coding¶
# 버전확인 // 버전이 자주바뀌어 함수문제가 일어날수도 있기때무네
import tensorflow as tf
print(tf.__version__)
2.9.2
Fashion MNIST 데이터는 tf.keras datasets API에 들어있다.
mnist = tf.keras.datasets.fashion_mnist # 텐서플로우 기본제공 데이터
(X_train, y_train),(X_test, y_test) = mnist.load_data() # 트레인먼저 가져오고 테스트를 가져온다 .
# 원래는 storage서버에서 jpg,png등으로 가져온것을 numpy로 변환하는 작업을 해야하지만 제공데이터는 기본으로 되어있다.
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-labels-idx1-ubyte.gz 29515/29515 [==============================] - 0s 0us/step Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-images-idx3-ubyte.gz 26421880/26421880 [==============================] - 2s 0us/step Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/t10k-labels-idx1-ubyte.gz 5148/5148 [==============================] - 0s 0us/step Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/t10k-images-idx3-ubyte.gz 4422102/4422102 [==============================] - 0s 0us/step
트레이닝과 테스트셋 가져온다.
X_train.shape # 갯수가 맨앞으로간다
(60000, 28, 28)
y_train # 첫번째 사진에대한 정답 == 9
# uint8 == 언사인드(양수0~255) 정수 8바이트
array([9, 0, 0, ..., 3, 0, 5], dtype=uint8)
y_train.shape
(60000,)
X_test.shape
(10000, 28, 28)
y_test.shape
(10000,)
이미지는 숫자로 되어있다. 0부터 255까지의 숫자로 되어있다.
X_train[0, :, :] # == X_train[0][:][:] (리스트의문법) 3차원데이터 액세스
array([[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 13, 73, 0, 0, 1, 4, 0, 0, 0, 0, 1, 1, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 36, 136, 127, 62, 54, 0, 0, 0, 1, 3, 4, 0, 0, 3], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 102, 204, 176, 134, 144, 123, 23, 0, 0, 0, 0, 12, 10, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 155, 236, 207, 178, 107, 156, 161, 109, 64, 23, 77, 130, 72, 15], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 69, 207, 223, 218, 216, 216, 163, 127, 121, 122, 146, 141, 88, 172, 66], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 200, 232, 232, 233, 229, 223, 223, 215, 213, 164, 127, 123, 196, 229, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 183, 225, 216, 223, 228, 235, 227, 224, 222, 224, 221, 223, 245, 173, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 193, 228, 218, 213, 198, 180, 212, 210, 211, 213, 223, 220, 243, 202, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 0, 12, 219, 220, 212, 218, 192, 169, 227, 208, 218, 224, 212, 226, 197, 209, 52], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 99, 244, 222, 220, 218, 203, 198, 221, 215, 213, 222, 220, 245, 119, 167, 56], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 55, 236, 228, 230, 228, 240, 232, 213, 218, 223, 234, 217, 217, 209, 92, 0], [ 0, 0, 1, 4, 6, 7, 2, 0, 0, 0, 0, 0, 237, 226, 217, 223, 222, 219, 222, 221, 216, 223, 229, 215, 218, 255, 77, 0], [ 0, 3, 0, 0, 0, 0, 0, 0, 0, 62, 145, 204, 228, 207, 213, 221, 218, 208, 211, 218, 224, 223, 219, 215, 224, 244, 159, 0], [ 0, 0, 0, 0, 18, 44, 82, 107, 189, 228, 220, 222, 217, 226, 200, 205, 211, 230, 224, 234, 176, 188, 250, 248, 233, 238, 215, 0], [ 0, 57, 187, 208, 224, 221, 224, 208, 204, 214, 208, 209, 200, 159, 245, 193, 206, 223, 255, 255, 221, 234, 221, 211, 220, 232, 246, 0], [ 3, 202, 228, 224, 221, 211, 211, 214, 205, 205, 205, 220, 240, 80, 150, 255, 229, 221, 188, 154, 191, 210, 204, 209, 222, 228, 225, 0], [ 98, 233, 198, 210, 222, 229, 229, 234, 249, 220, 194, 215, 217, 241, 65, 73, 106, 117, 168, 219, 221, 215, 217, 223, 223, 224, 229, 29], [ 75, 204, 212, 204, 193, 205, 211, 225, 216, 185, 197, 206, 198, 213, 240, 195, 227, 245, 239, 223, 218, 212, 209, 222, 220, 221, 230, 67], [ 48, 203, 183, 194, 213, 197, 185, 190, 194, 192, 202, 214, 219, 221, 220, 236, 225, 216, 199, 206, 186, 181, 177, 172, 181, 205, 206, 115], [ 0, 122, 219, 193, 179, 171, 183, 196, 204, 210, 213, 207, 211, 210, 200, 196, 194, 191, 195, 191, 198, 192, 176, 156, 167, 177, 210, 92], [ 0, 0, 74, 189, 212, 191, 175, 172, 175, 181, 185, 188, 189, 188, 193, 198, 204, 209, 210, 210, 211, 188, 188, 194, 192, 216, 170, 0], [ 2, 0, 0, 0, 66, 200, 222, 237, 239, 242, 246, 243, 244, 221, 220, 193, 191, 179, 182, 182, 181, 176, 166, 168, 99, 58, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 40, 61, 44, 72, 41, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=uint8)
# 첫번째이미지만 가져온다.
X_train[0]
array([[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 13, 73, 0, 0, 1, 4, 0, 0, 0, 0, 1, 1, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 36, 136, 127, 62, 54, 0, 0, 0, 1, 3, 4, 0, 0, 3], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 102, 204, 176, 134, 144, 123, 23, 0, 0, 0, 0, 12, 10, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 155, 236, 207, 178, 107, 156, 161, 109, 64, 23, 77, 130, 72, 15], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 69, 207, 223, 218, 216, 216, 163, 127, 121, 122, 146, 141, 88, 172, 66], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 200, 232, 232, 233, 229, 223, 223, 215, 213, 164, 127, 123, 196, 229, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 183, 225, 216, 223, 228, 235, 227, 224, 222, 224, 221, 223, 245, 173, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 193, 228, 218, 213, 198, 180, 212, 210, 211, 213, 223, 220, 243, 202, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 0, 12, 219, 220, 212, 218, 192, 169, 227, 208, 218, 224, 212, 226, 197, 209, 52], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 99, 244, 222, 220, 218, 203, 198, 221, 215, 213, 222, 220, 245, 119, 167, 56], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 55, 236, 228, 230, 228, 240, 232, 213, 218, 223, 234, 217, 217, 209, 92, 0], [ 0, 0, 1, 4, 6, 7, 2, 0, 0, 0, 0, 0, 237, 226, 217, 223, 222, 219, 222, 221, 216, 223, 229, 215, 218, 255, 77, 0], [ 0, 3, 0, 0, 0, 0, 0, 0, 0, 62, 145, 204, 228, 207, 213, 221, 218, 208, 211, 218, 224, 223, 219, 215, 224, 244, 159, 0], [ 0, 0, 0, 0, 18, 44, 82, 107, 189, 228, 220, 222, 217, 226, 200, 205, 211, 230, 224, 234, 176, 188, 250, 248, 233, 238, 215, 0], [ 0, 57, 187, 208, 224, 221, 224, 208, 204, 214, 208, 209, 200, 159, 245, 193, 206, 223, 255, 255, 221, 234, 221, 211, 220, 232, 246, 0], [ 3, 202, 228, 224, 221, 211, 211, 214, 205, 205, 205, 220, 240, 80, 150, 255, 229, 221, 188, 154, 191, 210, 204, 209, 222, 228, 225, 0], [ 98, 233, 198, 210, 222, 229, 229, 234, 249, 220, 194, 215, 217, 241, 65, 73, 106, 117, 168, 219, 221, 215, 217, 223, 223, 224, 229, 29], [ 75, 204, 212, 204, 193, 205, 211, 225, 216, 185, 197, 206, 198, 213, 240, 195, 227, 245, 239, 223, 218, 212, 209, 222, 220, 221, 230, 67], [ 48, 203, 183, 194, 213, 197, 185, 190, 194, 192, 202, 214, 219, 221, 220, 236, 225, 216, 199, 206, 186, 181, 177, 172, 181, 205, 206, 115], [ 0, 122, 219, 193, 179, 171, 183, 196, 204, 210, 213, 207, 211, 210, 200, 196, 194, 191, 195, 191, 198, 192, 176, 156, 167, 177, 210, 92], [ 0, 0, 74, 189, 212, 191, 175, 172, 175, 181, 185, 188, 189, 188, 193, 198, 204, 209, 210, 210, 211, 188, 188, 194, 192, 216, 170, 0], [ 2, 0, 0, 0, 66, 200, 222, 237, 239, 242, 246, 243, 244, 221, 220, 193, 191, 179, 182, 182, 181, 176, 166, 168, 99, 58, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 40, 61, 44, 72, 41, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=uint8)
# 사람용으로 표시
import matplotlib.pyplot as plt
plt.imshow( X_train[0] )
plt.show()
plt.imshow( X_train[200], cmap='gray' )
plt.show()
# 정답지 확인 8==가방(사람이 레이블링한것)
y_train[200]
8
학습이 잘 되도록 0과 1사이의 값으로 노말라이징(normalizing) 한다.
# minmaxscaler를 해도되지만 귀찮으니까 넘파이 255.0로 나눠버린다(딥러닝은 무조건 플롯 , 인트는안댐)
X_train = X_train / 255.0
X_test = X_test / 255.0
이미지의 가로 세로를 전부 일렬로 만드는 작업이 flatten 이다.
모델을 만들어 보자.
import tensorflow as tf
from tensorflow import keras
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Flatten
Sequential: SEQUENCE layers 로 모델링
Flatten: 2차원, 3차원을 1차원으로 만드는것
Dense: 뉴런을 레이어에 붙인다.
각 레이어는 activation function 이 필요하다.
Relu 액티베이션 함수 참고 https://docs.google.com/presentation/d/1DCOW7Lum2rnoPU7gxpznimrXV0DOJFc-YkkJt3jZC0U/edit#slide=id.ga8aac09587_0_2
Softmax 여러개의 값 중에서 가장 큰 값을 선택. [0.1, 0.1, 0.05, 0.1, 9.5, 0.1, 0.05, 0.05, 0.05], 여기서 가장 큰 값을 1로 만들고 나머지는 0으로 만들어준다. [0,0,0,0,1,0,0,0,0]
# 1장의 사진 == 2차원을 1차원으로 만드는것 (하나의 행으로 만드는것)
def build_model() :
model = Sequential()
model.add( Flatten() ) # 열과행의 수에 관계없이 알아서 변환해줌
model.add( Dense(128, 'relu'))
model.add( Dense(64, 'relu'))
model.add( Dense(10, 'softmax')) # 2개로 분류할때는 노드1개 엑티베이션=시그모이드, 3개이상일때는 레이블의 갯수만큼
model.compile('adam', 'sparse_categorical_crossentropy', ['accuracy']) # 즉, 여기선10개의 뉴런(노드) 10개도 0과1로 나오게할것,
return model # 엑티베이션=softmax (확률로 나와서 가장큰걸로 결정하는 함수 , 전체의 합은1)
y_train # 레이블인코딩상태
array([9, 0, 0, ..., 3, 0, 5], dtype=uint8)
# 2개로 분류하는 문제에서의 로스 펑션은 binary_crossentropy 를 사용.
# 3개 이상으로 분류하는 문제에서는, 두가지 방법이 있는데,
# y의 값을 확인하여 선택하는 것이다.
# 첫번째 방법은, y값이 레이블 인코딩으로 되어있으면, sparse_categorical_crossentropy
# 두번째 방법은, y값이 원핫인코딩으로 되어있으면, categorical_crossentropy
optimizer and loss function 으로 컴파일 한 후에 model.fit 함수로 학습한다..
model = build_model()
model.fit(X_train, y_train, epochs = 5)
Epoch 1/5 1875/1875 [==============================] - 11s 4ms/step - loss: 0.4956 - accuracy: 0.8227 Epoch 2/5 1875/1875 [==============================] - 7s 4ms/step - loss: 0.3704 - accuracy: 0.8640 Epoch 3/5 1875/1875 [==============================] - 5s 3ms/step - loss: 0.3346 - accuracy: 0.8756 Epoch 4/5 1875/1875 [==============================] - 5s 3ms/step - loss: 0.3114 - accuracy: 0.8844 Epoch 5/5 1875/1875 [==============================] - 5s 3ms/step - loss: 0.2952 - accuracy: 0.8907
<keras.callbacks.History at 0x7fe0c01501f0>
accuracy 가 약 90% 라는 뜻. 5 epochs 라 금방 끝났다.
학습에 사용하지 않는, 테스트 데이터를 통해서, 얼마나 정확도되 나오는지 확인해 본다.
model.evaluate(X_test, y_test)
313/313 [==============================] - 1s 2ms/step - loss: 0.3690 - accuracy: 0.8645
[0.3690395951271057, 0.8644999861717224]
# ANN == 기본적인구조
y_pred = model.predict(X_test)
313/313 [==============================] - 1s 2ms/step
y_pred
array([[6.2642157e-06, 1.2893028e-05, 8.6467444e-06, ..., 5.1825982e-01, 7.6142972e-04, 4.7485906e-01], [9.8711294e-05, 2.6011189e-09, 9.9776161e-01, ..., 1.2294908e-12, 2.8359122e-07, 1.7571462e-10], [2.3507123e-09, 1.0000000e+00, 1.6610641e-10, ..., 4.3737702e-20, 6.1341182e-10, 9.1725611e-16], ..., [3.1925822e-04, 4.2129066e-08, 6.7577137e-05, ..., 6.1767085e-09, 9.9935621e-01, 5.1176413e-10], [6.1121850e-06, 9.9997795e-01, 5.7848951e-07, ..., 4.9597555e-13, 2.4816867e-07, 7.4746270e-10], [1.5104997e-04, 1.2393270e-04, 6.9673464e-04, ..., 2.1131155e-01, 9.3408413e-03, 5.8493303e-04]], dtype=float32)
# 결과가 맞는지 확인
plt.imshow(X_test[0])
plt.show()
y_pred[0] # 9가 아닌이유는, output을 10개로 만들엇기 때문에 10개로 나온것.
array([6.2642157e-06, 1.2893028e-05, 8.6467444e-06, 3.0621634e-06, 1.1318511e-05, 6.0653663e-03, 1.2088867e-05, 5.1825982e-01, 7.6142972e-04, 4.7485906e-01], dtype=float32)
y_pred[0].sum()
1.0
y_pred[0].argmax() # 제일큰값의 인덱스를 찾는함수
7
9.9584609 * 10**-1 # 99.5퍼 확률로 9라고 예측한것
0.9958460900000001
# 컨퓨전 매트릭스를 이용해서, 어떤것을 컴퓨터가 많이 헷갈려 하는지 파악한다.
from sklearn.metrics import confusion_matrix
y_test
array([9, 2, 1, ..., 8, 1, 5], dtype=uint8)
y_pred # 이건 소프트맥스값이기 때문에 아래와같이 변환한다.
array([[6.2642157e-06, 1.2893028e-05, 8.6467444e-06, ..., 5.1825982e-01, 7.6142972e-04, 4.7485906e-01], [9.8711294e-05, 2.6011189e-09, 9.9776161e-01, ..., 1.2294908e-12, 2.8359122e-07, 1.7571462e-10], [2.3507123e-09, 1.0000000e+00, 1.6610641e-10, ..., 4.3737702e-20, 6.1341182e-10, 9.1725611e-16], ..., [3.1925822e-04, 4.2129066e-08, 6.7577137e-05, ..., 6.1767085e-09, 9.9935621e-01, 5.1176413e-10], [6.1121850e-06, 9.9997795e-01, 5.7848951e-07, ..., 4.9597555e-13, 2.4816867e-07, 7.4746270e-10], [1.5104997e-04, 1.2393270e-04, 6.9673464e-04, ..., 2.1131155e-01, 9.3408413e-03, 5.8493303e-04]], dtype=float32)
y_pred = y_pred.argmax(axis=1)
# y_pred.argmax(axis=1) 이것을 풀어보자면 우선 y_pred는 numpy이의 10열 10000개의 데이터이다 (shape을 해보면 알수있음)
# 왜냐하면 []로 이루어진[] ,즉 [[],[]] 의 형태로 이루어져잇기때문
# 여기서 argmax(axis=1) 이라는것은 말로하면 10열의 행별 최대값을 구하라는 말과도 같다.
cm = confusion_matrix(y_test, y_pred)
cm
array([[782, 0, 31, 57, 5, 2, 113, 0, 10, 0], [ 0, 960, 4, 24, 8, 0, 2, 0, 2, 0], [ 11, 0, 816, 20, 128, 0, 25, 0, 0, 0], [ 8, 5, 11, 913, 34, 0, 25, 0, 4, 0], [ 0, 0, 94, 38, 849, 0, 18, 0, 1, 0], [ 0, 0, 0, 1, 0, 909, 0, 47, 2, 41], [ 93, 0, 133, 46, 158, 0, 551, 0, 19, 0], [ 0, 0, 0, 0, 0, 8, 0, 983, 0, 9], [ 4, 0, 3, 5, 3, 2, 3, 7, 973, 0], [ 0, 0, 0, 0, 0, 1, 1, 89, 0, 909]])
from sklearn.metrics import accuracy_score
accuracy_score(y_test,y_pred) # model.evaluate 과 같다.(내부적으로 컨퓨전매트릭스를 구현한것)
0.8645
# 그냥보면 불편하니까 차트로 표현
import seaborn as sb
sb.heatmap(cm, annot=True, fmt='.0f', cmap='RdPu')
plt.show()
# 크리티컬한 데이터는 보완해야함.
Exploration Exercises¶
Exercise 1:¶
테스트 이미지를 예측한 후, 첫번째 이미지에 대해서 예측한 결과를 출력한다.
y_pred
array([7, 2, 1, ..., 8, 1, 5])
y_pred[0]
7
plt.imshow(X_test[0])
plt.show()
예측한 결과가 리스트로 나온다. 리스트는 무엇을 나타내는가 ?¶
It's the probability that this item is each of the 10 classes
# ANN의 아웃풋의 노드(뉴런)수가 10개 이기 때문에,
# softmax 활성화 함수를 통해서, 0~1사이의 10개의 숫자가 나오게 되어있다.(확률)
첫번째 이미지의 실제값을 출력한다.
X_test[0]
array([[0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ], [0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ], [0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ], [0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ], [0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ], [0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ], [0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ], [0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0.01176471, 0.00392157, 0. , 0. , 0.02745098, 0. , 0.14509804, 0. , 0. ], [0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0.00392157, 0.00784314, 0. , 0.10588235, 0.32941176, 0.04313725, 0. , 0. , 0. , 0. , 0. , 0. , 0.46666667, 0. , 0. ], [0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0.00392157, 0. , 0. , 0.34509804, 0.56078431, 0.43137255, 0. , 0. , 0. , 0. , 0.08627451, 0.36470588, 0.41568627, 0. , 0. ], [0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0.01568627, 0. , 0.20784314, 0.50588235, 0.47058824, 0.57647059, 0.68627451, 0.61568627, 0.65098039, 0.52941176, 0.60392157, 0.65882353, 0.54901961, 0. , 0. ], [0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0.00784314, 0. , 0.04313725, 0.5372549 , 0.50980392, 0.50196078, 0.62745098, 0.69019608, 0.62352941, 0.65490196, 0.69803922, 0.58431373, 0.59215686, 0.56470588, 0. , 0. ], [0. , 0. , 0. , 0. , 0. , 0. , 0.00392157, 0. , 0.00784314, 0.00392157, 0. , 0.01176471, 0. , 0. , 0.45098039, 0.44705882, 0.41568627, 0.5372549 , 0.65882353, 0.6 , 0.61176471, 0.64705882, 0.65490196, 0.56078431, 0.61568627, 0.61960784, 0.04313725, 0. ], [0. , 0. , 0. , 0. , 0.00392157, 0. , 0. , 0. , 0. , 0. , 0.01176471, 0. , 0. , 0.34901961, 0.54509804, 0.35294118, 0.36862745, 0.6 , 0.58431373, 0.51372549, 0.59215686, 0.6627451 , 0.6745098 , 0.56078431, 0.62352941, 0.6627451 , 0.18823529, 0. ], [0. , 0. , 0. , 0. , 0. , 0. , 0.00784314, 0.01568627, 0.00392157, 0. , 0. , 0. , 0.38431373, 0.53333333, 0.43137255, 0.42745098, 0.43137255, 0.63529412, 0.52941176, 0.56470588, 0.58431373, 0.62352941, 0.65490196, 0.56470588, 0.61960784, 0.6627451 , 0.46666667, 0. ], [0. , 0. , 0.00784314, 0.00784314, 0.00392157, 0.00784314, 0. , 0. , 0. , 0. , 0.10196078, 0.42352941, 0.45882353, 0.38823529, 0.43529412, 0.45882353, 0.53333333, 0.61176471, 0.5254902 , 0.60392157, 0.60392157, 0.61176471, 0.62745098, 0.55294118, 0.57647059, 0.61176471, 0.69803922, 0. ], [0.01176471, 0. , 0. , 0. , 0. , 0. , 0. , 0.08235294, 0.20784314, 0.36078431, 0.45882353, 0.43529412, 0.40392157, 0.45098039, 0.50588235, 0.5254902 , 0.56078431, 0.60392157, 0.64705882, 0.66666667, 0.60392157, 0.59215686, 0.60392157, 0.56078431, 0.54117647, 0.58823529, 0.64705882, 0.16862745], [0. , 0. , 0.09019608, 0.21176471, 0.25490196, 0.29803922, 0.33333333, 0.4627451 , 0.50196078, 0.48235294, 0.43529412, 0.44313725, 0.4627451 , 0.49803922, 0.49019608, 0.54509804, 0.52156863, 0.53333333, 0.62745098, 0.54901961, 0.60784314, 0.63137255, 0.56470588, 0.60784314, 0.6745098 , 0.63137255, 0.74117647, 0.24313725], [0. , 0.26666667, 0.36862745, 0.35294118, 0.43529412, 0.44705882, 0.43529412, 0.44705882, 0.45098039, 0.49803922, 0.52941176, 0.53333333, 0.56078431, 0.49411765, 0.49803922, 0.59215686, 0.60392157, 0.56078431, 0.58039216, 0.49019608, 0.63529412, 0.63529412, 0.56470588, 0.54117647, 0.6 , 0.63529412, 0.76862745, 0.22745098], [0.2745098 , 0.6627451 , 0.50588235, 0.40784314, 0.38431373, 0.39215686, 0.36862745, 0.38039216, 0.38431373, 0.4 , 0.42352941, 0.41568627, 0.46666667, 0.47058824, 0.50588235, 0.58431373, 0.61176471, 0.65490196, 0.74509804, 0.74509804, 0.76862745, 0.77647059, 0.77647059, 0.73333333, 0.77254902, 0.74117647, 0.72156863, 0.14117647], [0.0627451 , 0.49411765, 0.67058824, 0.7372549 , 0.7372549 , 0.72156863, 0.67058824, 0.6 , 0.52941176, 0.47058824, 0.49411765, 0.49803922, 0.57254902, 0.7254902 , 0.76470588, 0.81960784, 0.81568627, 1. , 0.81960784, 0.69411765, 0.96078431, 0.98823529, 0.98431373, 0.98431373, 0.96862745, 0.8627451 , 0.80784314, 0.19215686], [0. , 0. , 0. , 0.04705882, 0.2627451 , 0.41568627, 0.64313725, 0.7254902 , 0.78039216, 0.82352941, 0.82745098, 0.82352941, 0.81568627, 0.74509804, 0.58823529, 0.32156863, 0.03137255, 0. , 0. , 0. , 0.69803922, 0.81568627, 0.7372549 , 0.68627451, 0.63529412, 0.61960784, 0.59215686, 0.04313725], [0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ], [0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ], [0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ], [0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ], [0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ], [0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ]])
이 예측결과가 앵클부츠인지는, 예측결과로 나온 리스트를 보고 어떻게 알 수 있는가?¶
10번째 값이 가장 크니까, 레이블은 0부터라, 9 이다.
# numpy 의 argmax() 함수를 이용하면, 가장 큰값이 들어있는 곳의 인덱스를 얻을 수 있다.
Exercise 2:¶
히든레이어를 1024개의 뉴런으로 바꿔서 실행해보자
def build_model() :
model = Sequential()
model.add( Flatten() )
model.add( Dense(1024, 'relu'))
model.add( Dense(64, 'relu'))
model.add( Dense(10, 'softmax'))
model.compile('adam', 'sparse_categorical_crossentropy', ['accuracy'])
return model
model = build_model()
model.fit(X_train, y_train, epochs = 5)
Epoch 1/5 1875/1875 [==============================] - 5s 2ms/step - loss: 0.4743 - accuracy: 0.8290 Epoch 2/5 1875/1875 [==============================] - 4s 2ms/step - loss: 0.3594 - accuracy: 0.8678 Epoch 3/5 1875/1875 [==============================] - 4s 2ms/step - loss: 0.3236 - accuracy: 0.8801 Epoch 4/5 1875/1875 [==============================] - 4s 2ms/step - loss: 0.2985 - accuracy: 0.8900 Epoch 5/5 1875/1875 [==============================] - 4s 2ms/step - loss: 0.2796 - accuracy: 0.8953
<keras.callbacks.History at 0x7fe0286fb250>
model.evaluate(X_test,y_test) # 평가 : 위보다 2%정도 성능향상
313/313 [==============================] - 1s 2ms/step - loss: 0.3315 - accuracy: 0.8837
[0.3315395712852478, 0.8837000131607056]
Question 1. 1024 개로 뉴런을 늘리면 어떤 일이 일어나는가?¶
# 위보다 2%정도 성능향상
Exercise 3:¶
Flatten() layer를 지우면 어떻게 되는가?
def build_model() :
model = Sequential()
model.add( Dense(128, 'relu'))
model.add( Dense(64, 'relu'))
model.add( Dense(10, 'softmax'))
model.compile('adam', 'sparse_categorical_crossentropy', ['accuracy'])
return model
model = build_model()
model.fit(X_train,y_train, epochs=5 ) # 2차원이 들어왓기 때문에 에러발생. 말이안된다는것
Epoch 1/5
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-63-f49c2b7e688a> in <module> ----> 1 model.fit(X_train,y_train, epochs=5 ) /usr/local/lib/python3.8/dist-packages/keras/utils/traceback_utils.py in error_handler(*args, **kwargs) 65 except Exception as e: # pylint: disable=broad-except 66 filtered_tb = _process_traceback_frames(e.__traceback__) ---> 67 raise e.with_traceback(filtered_tb) from None 68 finally: 69 del filtered_tb /usr/local/lib/python3.8/dist-packages/keras/engine/training.py in tf__train_function(iterator) 13 try: 14 do_return = True ---> 15 retval_ = ag__.converted_call(ag__.ld(step_function), (ag__.ld(self), ag__.ld(iterator)), None, fscope) 16 except: 17 do_return = False ValueError: in user code: File "/usr/local/lib/python3.8/dist-packages/keras/engine/training.py", line 1051, in train_function * return step_function(self, iterator) File "/usr/local/lib/python3.8/dist-packages/keras/engine/training.py", line 1040, in step_function ** outputs = model.distribute_strategy.run(run_step, args=(data,)) File "/usr/local/lib/python3.8/dist-packages/keras/engine/training.py", line 1030, in run_step ** outputs = model.train_step(data) File "/usr/local/lib/python3.8/dist-packages/keras/engine/training.py", line 890, in train_step loss = self.compute_loss(x, y, y_pred, sample_weight) File "/usr/local/lib/python3.8/dist-packages/keras/engine/training.py", line 948, in compute_loss return self.compiled_loss( File "/usr/local/lib/python3.8/dist-packages/keras/engine/compile_utils.py", line 201, in __call__ loss_value = loss_obj(y_t, y_p, sample_weight=sw) File "/usr/local/lib/python3.8/dist-packages/keras/losses.py", line 139, in __call__ losses = call_fn(y_true, y_pred) File "/usr/local/lib/python3.8/dist-packages/keras/losses.py", line 243, in call ** return ag_fn(y_true, y_pred, **self._fn_kwargs) File "/usr/local/lib/python3.8/dist-packages/keras/losses.py", line 1860, in sparse_categorical_crossentropy return backend.sparse_categorical_crossentropy( File "/usr/local/lib/python3.8/dist-packages/keras/backend.py", line 5238, in sparse_categorical_crossentropy res = tf.nn.sparse_softmax_cross_entropy_with_logits( ValueError: `labels.shape` must equal `logits.shape` except for the last dimension. Received: labels.shape=(32,) and logits.shape=(896, 10)
Exercise 4:¶
마지막 레이어를 10개가 아니라, 5개로 바꾸면 어떻게 되는가?
def build_model() :
model = Sequential()
model.add( Flatten() )
model.add( Dense(128, 'relu'))
model.add( Dense(64, 'relu'))
model.add( Dense(5, 'softmax'))
model.compile('adam', 'sparse_categorical_crossentropy', ['accuracy'])
return model
model =build_model()
model.fit(X_train,y_train, epochs=5 ) # 5~9 의 값이 나온다면 y_test의 값과 비교를 할수없기 때문에 에러발생
Epoch 1/5 1875/1875 [==============================] - 4s 2ms/step - loss: nan - accuracy: 0.1001 Epoch 2/5 1875/1875 [==============================] - 4s 2ms/step - loss: nan - accuracy: 0.1000 Epoch 3/5 1875/1875 [==============================] - 5s 3ms/step - loss: nan - accuracy: 0.1000 Epoch 4/5 1875/1875 [==============================] - 4s 2ms/step - loss: nan - accuracy: 0.1000 Epoch 5/5 1875/1875 [==============================] - 4s 2ms/step - loss: nan - accuracy: 0.1000
<keras.callbacks.History at 0x7fe049cb7610>
def build_model() :
model = Sequential()
model.add( Flatten() )
model.add( Dense(128, 'relu'))
model.add( Dense(64, 'relu'))
model.add( Dense(10, 'softmax'))
model.compile('adam', 'sparse_categorical_crossentropy', ['accuracy'])
return model
model = build_model()
epoch_history = model.fit(X_train,y_train, epochs=30, validation_split = 0.2) # 일부분만 학습시키고 중간시험 (80%기 때문에 48000개는학습 12000개는 시험)
Epoch 1/30 1500/1500 [==============================] - 4s 3ms/step - loss: 0.2174 - accuracy: 0.9190 - val_loss: 0.2308 - val_accuracy: 0.9146 Epoch 2/30 1500/1500 [==============================] - 5s 3ms/step - loss: 0.2106 - accuracy: 0.9203 - val_loss: 0.2606 - val_accuracy: 0.8978 Epoch 3/30 1500/1500 [==============================] - 7s 5ms/step - loss: 0.2041 - accuracy: 0.9221 - val_loss: 0.2371 - val_accuracy: 0.9107 Epoch 4/30 1500/1500 [==============================] - 6s 4ms/step - loss: 0.1987 - accuracy: 0.9244 - val_loss: 0.2331 - val_accuracy: 0.9142 Epoch 5/30 1500/1500 [==============================] - 4s 3ms/step - loss: 0.1894 - accuracy: 0.9280 - val_loss: 0.2561 - val_accuracy: 0.9073 Epoch 6/30 1500/1500 [==============================] - 4s 3ms/step - loss: 0.1835 - accuracy: 0.9307 - val_loss: 0.2428 - val_accuracy: 0.9109 Epoch 7/30 1500/1500 [==============================] - 4s 3ms/step - loss: 0.1829 - accuracy: 0.9315 - val_loss: 0.2556 - val_accuracy: 0.9059 Epoch 8/30 1500/1500 [==============================] - 4s 3ms/step - loss: 0.1752 - accuracy: 0.9335 - val_loss: 0.2353 - val_accuracy: 0.9159 Epoch 9/30 1500/1500 [==============================] - 4s 3ms/step - loss: 0.1698 - accuracy: 0.9353 - val_loss: 0.2632 - val_accuracy: 0.9082 Epoch 10/30 1500/1500 [==============================] - 4s 3ms/step - loss: 0.1643 - accuracy: 0.9384 - val_loss: 0.2499 - val_accuracy: 0.9122 Epoch 11/30 1500/1500 [==============================] - 4s 3ms/step - loss: 0.1606 - accuracy: 0.9391 - val_loss: 0.2523 - val_accuracy: 0.9128 Epoch 12/30 1500/1500 [==============================] - 4s 3ms/step - loss: 0.1565 - accuracy: 0.9412 - val_loss: 0.2662 - val_accuracy: 0.9099 Epoch 13/30 1500/1500 [==============================] - 4s 3ms/step - loss: 0.1531 - accuracy: 0.9408 - val_loss: 0.2803 - val_accuracy: 0.9087 Epoch 14/30 1500/1500 [==============================] - 4s 3ms/step - loss: 0.1478 - accuracy: 0.9439 - val_loss: 0.2714 - val_accuracy: 0.9064 Epoch 15/30 1500/1500 [==============================] - 4s 3ms/step - loss: 0.1467 - accuracy: 0.9447 - val_loss: 0.2904 - val_accuracy: 0.9057 Epoch 16/30 1500/1500 [==============================] - 4s 3ms/step - loss: 0.1400 - accuracy: 0.9467 - val_loss: 0.2858 - val_accuracy: 0.9071 Epoch 17/30 1500/1500 [==============================] - 4s 3ms/step - loss: 0.1369 - accuracy: 0.9485 - val_loss: 0.2971 - val_accuracy: 0.9045 Epoch 18/30 1500/1500 [==============================] - 4s 3ms/step - loss: 0.1343 - accuracy: 0.9496 - val_loss: 0.3031 - val_accuracy: 0.9081 Epoch 19/30 1500/1500 [==============================] - 4s 3ms/step - loss: 0.1299 - accuracy: 0.9511 - val_loss: 0.3267 - val_accuracy: 0.9048 Epoch 20/30 1500/1500 [==============================] - 4s 3ms/step - loss: 0.1286 - accuracy: 0.9514 - val_loss: 0.3583 - val_accuracy: 0.8987 Epoch 21/30 1500/1500 [==============================] - 4s 3ms/step - loss: 0.1249 - accuracy: 0.9519 - val_loss: 0.3172 - val_accuracy: 0.9068 Epoch 22/30 1500/1500 [==============================] - 4s 3ms/step - loss: 0.1202 - accuracy: 0.9543 - val_loss: 0.3193 - val_accuracy: 0.9093 Epoch 23/30 1500/1500 [==============================] - 4s 3ms/step - loss: 0.1209 - accuracy: 0.9535 - val_loss: 0.3467 - val_accuracy: 0.9032 Epoch 24/30 1500/1500 [==============================] - 4s 3ms/step - loss: 0.1162 - accuracy: 0.9556 - val_loss: 0.3555 - val_accuracy: 0.9007 Epoch 25/30 1500/1500 [==============================] - 4s 3ms/step - loss: 0.1174 - accuracy: 0.9558 - val_loss: 0.3517 - val_accuracy: 0.9042 Epoch 26/30 1500/1500 [==============================] - 4s 3ms/step - loss: 0.1138 - accuracy: 0.9575 - val_loss: 0.3477 - val_accuracy: 0.9020 Epoch 27/30 1500/1500 [==============================] - 4s 3ms/step - loss: 0.1118 - accuracy: 0.9570 - val_loss: 0.3639 - val_accuracy: 0.9029 Epoch 28/30 1500/1500 [==============================] - 4s 3ms/step - loss: 0.1072 - accuracy: 0.9590 - val_loss: 0.3413 - val_accuracy: 0.9029 Epoch 29/30 1500/1500 [==============================] - 4s 3ms/step - loss: 0.1049 - accuracy: 0.9596 - val_loss: 0.3607 - val_accuracy: 0.9077 Epoch 30/30 1500/1500 [==============================] - 4s 3ms/step - loss: 0.1057 - accuracy: 0.9604 - val_loss: 0.3640 - val_accuracy: 0.9019
epoch_history.history.keys()
dict_keys(['loss', 'accuracy', 'val_loss', 'val_accuracy'])
plt.plot(epoch_history.history['loss'] ) # 학습로스
plt.plot(epoch_history.history['val_loss'] ) # 시험로스
plt.legend( ['Train Loss', 'Vaildation Loss']) # 그냥보면 헷갈리니까 레전드로본다.
plt.show()
# 밸리데이션 로스가 가장낮을때가 적당한 에포크이다.
# 위의 그래프를 보면 밸리대이션 로스가 점점 커진다
# 오버피팅되었기 때문 : 에포크가 지나쳐서 잘못맞추는것
plt.plot(epoch_history.history['accuracy'] ) # 학습로스
plt.plot(epoch_history.history['val_accuracy'] ) # 시험로스
plt.legend( ['Train accuracy', 'Vaildation accuracy']) # 그냥보면 헷갈리니까 레전드로본다.
plt.show()
# 정확도가 오히려 떨어지고 있다 (이것도 오버피팅의 증거)
30 에포크를 했을때의 결과를 보면 어떠한 문제가 있다. 이러한 문제를 무엇이라고 하는가???
# 오버 피팅 이라고 한다. Over Fitting
# 반대로 에포크가 너무 적으면 언더피팅 이라고 한다. Under Fitting
Exercise 7:¶
accuracy 나 loss 가, 우리가 원하는 특정 값이 되면 자동으로 학습을 멈추가 하고 싶다. 즉, 특정값에 도달하면 학습을 멈추게 할 수 있는 콜백기능을 제공한다. callbacks
# 04 강의에서 본것은, early stopping : 특정횟수동안 성능개선이 없으면 멈춘다였고.
# val_accuracy 가 88% 가 넘으면 멈추도록 하고싶다. (오버피팅,언더피팅을 안하려고)
class myCallback(tf.keras.callbacks.Callback) :
def on_epoch_end(self, epoch, logs= {} ) :
if logs[ 'val_accuracy'] > 0.88 :
print('\n내가 정한 정확도에 도달했으니, 학습을 멈춘다.')
self.model.stop_training = True
my_cb = myCallback()
def build_model() :
model = Sequential()
model.add( Flatten() )
model.add( Dense(128, 'relu'))
model.add( Dense(64, 'relu'))
model.add( Dense(10, 'softmax'))
model.compile('adam', 'sparse_categorical_crossentropy', ['accuracy'])
return model
model = build_model()
epoch_history = model.fit(X_train,y_train, epochs=30, validation_split = 0.2, callbacks = [my_cb] )
Epoch 1/30 1500/1500 [==============================] - 4s 3ms/step - loss: 0.5127 - accuracy: 0.8176 - val_loss: 0.3990 - val_accuracy: 0.8532 Epoch 2/30 1500/1500 [==============================] - 4s 3ms/step - loss: 0.3767 - accuracy: 0.8616 - val_loss: 0.3491 - val_accuracy: 0.8740 Epoch 3/30 1500/1500 [==============================] - 4s 3ms/step - loss: 0.3370 - accuracy: 0.8749 - val_loss: 0.3744 - val_accuracy: 0.8704 Epoch 4/30 1500/1500 [==============================] - 4s 3ms/step - loss: 0.3143 - accuracy: 0.8835 - val_loss: 0.3543 - val_accuracy: 0.8730 Epoch 5/30 1478/1500 [============================>.] - ETA: 0s - loss: 0.2961 - accuracy: 0.8898 내가 정한 정확도에 도달했으니, 학습을 멈춘다. 1500/1500 [==============================] - 4s 3ms/step - loss: 0.2956 - accuracy: 0.8900 - val_loss: 0.3260 - val_accuracy: 0.8833
model.evaluate(X_test, y_test)
313/313 [==============================] - 1s 2ms/step - loss: 0.3549 - accuracy: 0.8764
[0.3549431264400482, 0.8763999938964844]