#!/usr/bin/env python # coding: utf-8 # In[2]: import sys; sys.version # In[3]: from keras.datasets import mnist # In[4]: # images는 손글씨 숫자 이미지, labvel은 이미지의 번호 (train_images, train_labels), (test_images, test_labels) = mnist.load_data() # ### MNIST 데이터 # In[5]: # train: 훈련시킹 이미지들 6만개 print('train_images type: {} / len: {}'.format(type(train_images), len(train_images))) print('train_labels type: {} / len: {}'.format(type(train_labels), len(train_labels))) # In[6]: # train_label : 평가 테스트용 이미지들 1만개 print('test_images type: {} / len: {}'.format(type(test_images), len(test_images))) print('test_labels type: {} / len: {}'.format(type(test_labels), len(test_labels))) # In[7]: # 차원 확인:shape # (60000, 28, 28) -> 28x28 배열이 6만개 있다는 의미 print(train_images.shape, test_images.shape) # - image 파일은 28x28의 배열로 이루어져 있으며 요소는 01부터 255까지 명암값으로 이루어짐. # - 이런 이미지 파일이 6만개가 있음 # # # # # # # ### Matplotlib: 배열을 이미지로 출력 # In[8]: import matplotlib.pyplot as plt # In[9]: plt.figure(figsize=(3,3)) plt.imshow(train_images[0]) plt.show() # ### 신경망 모델을 keras로 만들기 # In[10]: from keras import models, layers network = models.Sequential() network.add(layers.Dense(512, activation='relu', input_shape=(28*28,))) network.add(layers.Dense(10, activation='softmax', input_shape=(512,))) network.compile( optimizer = 'adam', loss = 'categorical_crossentropy', metrics = ['accuracy'], ) # ### 데이터 정규화 # In[11]: train_X = train_images.reshape(60000, -1) train_X = train_X.astype('float')/ 255 test_X = test_images.reshape(10000, -1) test_X = test_X.astype('float')/ 255 # **Reshapes** : make output to a certain shape. # - 0~255까지 있는 명암값을 255로 나누어 0~1까지의 수로 변환 # In[12]: from keras.utils import to_categorical train_Y = to_categorical(train_labels) test_Y = to_categorical(test_labels) # In[13]: train_Y[0] # 5 # **One-Hot Encoding** : A vector that 1 in only one demension, 0 in the remaing demesion. # - 3일 경우 [0,0,0,1,0,0,0,0,0,0,0,0] 으로 변환. # - 결과적으로 tran_X는 [60000,10] 실수 배열이 된다. # # ### 머신러닝 훈련 과정 # In[14]: network.fit(train_X, train_Y, epochs=5, batch_size=128) # ### 테스트셋을 사용해서 평가 # In[15]: test_loss, test_acc = network.evaluate(test_X, test_Y) # In[16]: print('Accuracy : {:.3f}'.format(test_acc)) # ### 로스 데이터 # In[17]: # test_pred: 1만개의 test_X의 예측한 값 test_pred = network.predict_classes(test_X) import numpy as np # correctly_predicted : 1만개의 예측된 값을 라벨값과 비교하여 참, 거짓 여부를 판단. correctly_predicted = np.equal(test_pred, test_labels) # In[18]: len(test_pred), test_pred # In[19]: len(correctly_predicted), correctly_predicted # In[20]: # wong_predictions : 거짓(라벨값과 다름)으로 판단한 숫자들의 인덱스 wong_predictions = np.where(correctly_predicted == False)[0]; wong_predictions # In[1]: fig = plt.figure() # In[129]: for i in range(3): wong_prediction = wong_predictions[i] # wong_prediction : wong_predictions에서 추출한 하나의 인덱스 번호 plt.figure(figsize=(3,3)) # 처음에 정의한 평가용 1만개의 이미지에 잘 못 인식한 숫자의 인덱스를 적용 plt.imshow(test_images[wong_prediction]) # plt.title('Predicted: {}'.format(test_pred[wong_prediction]), fontsize=30) plt.title('Predicted: {} / Label: {}'.format( test_pred[wong_prediction], test_labels[wong_prediction] ), fontsize=20) plt.show() # ### 신경망 추가 # In[137]: network_deep = models.Sequential() network_deep.add(layers.Dense(units=512, activation='relu', input_shape=(28*28,))) network_deep.add(layers.Dense(units=256, activation='relu')) network_deep.add(layers.Dense(units=256, activation='relu')) network_deep.add(layers.Dense(units=10, activation='softmax')) network_deep.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) # In[138]: network_deep.fit(train_X, train_Y, epochs=5, batch_size=128) # In[139]: _ , acc_deep = network_deep.evaluate(test_X, test_Y) print('Accuracy of network_deep : {:.3f}'.format(acc_deep)) # ### 클래스화 # In[159]: from keras.models import Sequential from keras.layers import Dense class DNN(Sequential): def __init__(self, input_size, output_size, *num_hidden_nodes): super().__init__() num_nodes = (*num_hidden_nodes, output_size) print(num_nodes) for idx, num_node in enumerate(num_nodes): activation = 'relu' if idx == 0: self.add(Dense(num_node, activation = activation, input_shape=(input_size,))) else: if idx == len(num_nodes) - 1: activation = 'softmax' self.add(Dense(output_size, activation=activation)) self.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) # In[160]: model = DNN(train_X.shape[1], train_Y.shape[1], 512) # In[161]: train_X[0].shape, train_Y[0].shape # In[163]: model.fit(train_X, train_Y, epochs=5, batch_size=128) # In[175]: test_loss, test_acc = model.evaluate(test_X, test_Y) print('Loss:{} / Acc:{}'.format(test_loss, test_acc)) # In[184]: # precidt : ML로 예측한 값. precidt = model.predict_classes(test_X) # In[177]: import numpy as np comapare_precidt = np.equal(test_precidt, test_labels) # 예측값과 라벨값과 비교 array_false = np.where(comapare_precidt == False)[0] # 비교해서 다른 것을 array_false에 추가. len(array_false), array_false # In[211]: # 잘못 인식한 숫자중 하나를 추출해서 이미지화 for i in range(20,30): index = array_false[i] select = precidt[index] label = test_labels[index] plt.imshow(test_images[index]) plt.title('index: {}, Predict: {}, Label: {}'.format(index, select, label), fontsize=15) plt.show()