day 11 rock paper scissors AI

12 minute read

rock paper scissors AI

This lesson, I will try to create a simple AI that categorizes images.

Generally, developing deep learning technologies follow the below process.

  1. preparing the data

  2. deep learning network archetecture

  3. learning

  4. test

Data preparation

MNIST calling handwritten number dataset

The Sequential API in tf.keras is the standard API for TensorFlow, and we will be using it to build a handwritten number interpreter.

Provided by Google, TensorFlow is one fothe biggest open source manchine learning libraries.

I will be using TensorFlow 2.4.1.

import tensorflow as tf
from tensorflow import keras

import numpy as np
import matplotlib.pyplot as plt

print(tf.__version__)   # Tensorflow의 버전을 출력

mnist = keras.datasets.mnist

# MNIST 데이터를 로드. 다운로드하지 않았다면 다운로드까지 자동으로 진행됩니다. 
(x_train, y_train), (x_test, y_test) = mnist.load_data()   

print(len(x_train))  # x_train 배열의 크기를 출력
2.5.0
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz
11493376/11490434 [==============================] - 2s 0us/step
60000

The above reads the MNIST database for handwritten numbers. MNIST dataset is an opensourse dataset provided by professor Yann Lecun.

plt.imshow(x_train[1],cmap=plt.cm.binary)
plt.show()
print(y_train[1])

output_3_0

0
# index에 0에서 59999 사이 숫자를 지정해 보세요.
index=10000     
plt.imshow(x_train[index],cmap=plt.cm.binary)
plt.show()
print( (index+1), '번째 이미지의 숫자는 바로 ',  y_train[index], '입니다.')

output_4_0

10001 번째 이미지의 숫자는 바로  3 입니다.

x_train holds the handwritten numbers while the y_train holds the actual numbers

training data and test data

image

print(x_train.shape)
print(x_test.shape)
(60000, 28, 28)

This means that there are 60,000 28X28 images in the training set.

And 10,000 28X28 images in the test set

We can use the test set to check if we the training set is being learned properly to avoid overfitting or to finish learning.

Data preprocessing

When training an AI, it is good practice to normalize the data between value 0~1. MNIST data pixel range is 0~255 so we divide all the data by 255.0.

print('최소값:',np.min(x_train), ' 최대값:',np.max(x_train))
x_train_norm, x_test_norm = x_train / 255.0, x_test / 255.0
print('최소값:',np.min(x_train_norm), ' 최대값:',np.max(x_train_norm))
최소값: 0  최대값: 255
최소값: 0.0  최대값: 1.0

Sequential Model

Sequential API lacks freedom in development but can easily create simpe deep learning models

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

image

  • The first parameter in Conv2D is the count of image attriubutes. We used 16 for the first and 32 for the second.

  • The first parameter in Dense layer is the count of neurons in the model. The more the neurons, the more complicated the model wil be.

  • The last dense layer would need a neuron count input of the count of the class being used. For number interpreter, it would be 10, while alphabet interpreter would be 52.

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
_________________________________________________________________

Training the network

We will be training the deep learning network.epochs = 10 means we are training the entire 60,000 data 10 times.

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)

We can see that the accuracy is increased each time the training is repeated.

model.compile(optimizer='adam',
             loss='sparse_categorical_crossentropy',
             metrics=['accuracy'])

model.fit(x_train_reshaped, y_train, epochs=10)
Epoch 1/10
1875/1875 [==============================] - 16s 8ms/step - loss: 0.2052 - accuracy: 0.9375
Epoch 2/10
1875/1875 [==============================] - 15s 8ms/step - loss: 0.0662 - accuracy: 0.9793
Epoch 3/10
1875/1875 [==============================] - 15s 8ms/step - loss: 0.0473 - accuracy: 0.9851
Epoch 4/10
1875/1875 [==============================] - 16s 8ms/step - loss: 0.0379 - accuracy: 0.9882
Epoch 5/10
1875/1875 [==============================] - 17s 9ms/step - loss: 0.0305 - accuracy: 0.9903
Epoch 6/10
1875/1875 [==============================] - 16s 8ms/step - loss: 0.0258 - accuracy: 0.9919
Epoch 7/10
1875/1875 [==============================] - 16s 8ms/step - loss: 0.0223 - accuracy: 0.9929
Epoch 8/10
1875/1875 [==============================] - 15s 8ms/step - loss: 0.0186 - accuracy: 0.9936
Epoch 9/10
1875/1875 [==============================] - 15s 8ms/step - loss: 0.0165 - accuracy: 0.9944
Epoch 10/10
1875/1875 [==============================] - 15s 8ms/step - loss: 0.0134 - accuracy: 0.9958





<tensorflow.python.keras.callbacks.History at 0x209d587bf40>

Testing the model

Now we have trained the model, we can use the test dataset to test the model’s accuracy.

We thought we would get 99.58 like we did at epoch = 10. However, we got 99.0 as a return. This is probably due to the test data set being slight different than the training set.

test_loss, test_accuracy = model.evaluate(x_test_reshaped,y_test, verbose=2)
print("test_loss: {} ".format(test_loss))
print("test_accuracy: {}".format(test_accuracy))
313/313 - 1s - loss: 0.0337 - accuracy: 0.9905
test_loss: 0.03374210745096207 
test_accuracy: 0.9904999732971191

We can check to see if any data has been wrongfully predicted by using model.predict() instead of model.evaluate()

predicted_result = model.predict(x_test_reshaped)  # model이 추론한 확률값. 
predicted_labels = np.argmax(predicted_result, axis=1)

idx=0  #1번째 x_test를 살펴보자. 
print('model.predict() 결과 : ', predicted_result[idx])
print('model이 추론한 가장 가능성이 높은 결과 : ', predicted_labels[idx])
print('실제 데이터의 라벨 : ', y_test[idx])
model.predict() 결과 :  [1.0836570e-11 2.3412986e-12 1.6144620e-08 7.0978801e-09 2.8864579e-11
 1.5477299e-10 1.4353321e-16 1.0000000e+00 4.6068139e-11 7.0869732e-10]
model이 추론한 가장 가능성이 높은 결과 :  7
실제 데이터의 라벨 :  7

From the result, we can see that the 7 is closest to probability of 1.00. and that 7 is the number image that was given.

plt.imshow(x_test[idx],cmap=plt.cm.binary)
plt.show()

output_24_0

We can also check if there are cases where the number is different thatn the actualimage.

import random
wrong_predict_list=[]
for i, _ in enumerate(predicted_labels):
    # i번째 test_labels과 y_test이 다른 경우만 모아 봅시다. 
    if predicted_labels[i] != y_test[i]:
        wrong_predict_list.append(i)

# wrong_predict_list 에서 랜덤하게 5개만 뽑아봅시다.
samples = random.choices(population=wrong_predict_list, k=5)

for n in samples:
    print("예측확률분포: " + str(predicted_result[n]))
    print("라벨: " + str(y_test[n]) + ", 예측결과: " + str(predicted_labels[n]))
    plt.imshow(x_test[n], cmap=plt.cm.binary)
    plt.show()
예측확률분포: [2.0359074e-07 3.3595033e-09 4.4263084e-06 2.6430980e-09 9.1997719e-01
 7.2176810e-08 2.1493831e-07 1.4528151e-03 1.0258805e-03 7.7539213e-02]
라벨: 9, 예측결과: 4

output_26_1

예측확률분포: [6.1953899e-02 8.3907469e-07 1.5398560e-01 6.2571180e-06 2.1130256e-01
 1.7999881e-05 5.5529898e-01 2.0181865e-06 5.7964656e-04 1.6852170e-02]
라벨: 9, 예측결과: 6

output_26_3

예측확률분포: [8.2259599e-10 1.9643799e-08 1.0912075e-01 6.3180656e-04 3.5885941e-10
 6.2729305e-10 3.6877209e-14 8.8909811e-01 1.1492207e-03 9.8078409e-08]
라벨: 2, 예측결과: 7

output_26_5

예측확률분포: [1.2156348e-08 5.1902880e-08 6.5793887e-07 1.6131591e-05 1.2996738e-06
 1.4296992e-07 5.3622693e-09 1.2289144e-05 1.0808504e-03 9.9888855e-01]
라벨: 8, 예측결과: 9

output_26_7

예측확률분포: [5.7679647e-12 3.9962678e-08 1.4873635e-12 1.0595202e-07 3.8946368e-02
 5.5609997e-09 2.0662406e-12 1.1481816e-05 1.7612513e-07 9.6104181e-01]
라벨: 4, 예측결과: 9

output_26_9

From the images where the model returned an inaccurate result, we can see that the model has low level of certainty.

Improving the network

Here, we will try to improve the network to get the accuracy up to 99 %.

We can change the hyper parameter.

  • increase count of Conv2D

  • change the Dense layer neuron count

  • change the repeats in epoch

# 바꿔 볼 수 있는 하이퍼파라미터들
n_channel_1=16
n_channel_2=32
n_dense=32
n_train_epoch=10

model=keras.models.Sequential()
model.add(keras.layers.Conv2D(n_channel_1, (3,3), activation='relu', input_shape=(28,28,1)))
model.add(keras.layers.MaxPool2D(2,2))
model.add(keras.layers.Conv2D(n_channel_2, (3,3), activation='relu'))
model.add(keras.layers.MaxPooling2D((2,2)))
model.add(keras.layers.Flatten())
model.add(keras.layers.Dense(n_dense, activation='relu'))
model.add(keras.layers.Dense(10, activation='softmax'))

model.summary()
model.compile(optimizer='adam',
             loss='sparse_categorical_crossentropy',
             metrics=['accuracy'])

# 모델 훈련
model.fit(x_train_reshaped, y_train, epochs=n_train_epoch)

# 모델 시험
test_loss, test_accuracy = model.evaluate(x_test_reshaped, y_test, verbose=2)
print("test_loss: {} ".format(test_loss))
print("test_accuracy: {}".format(test_accuracy))
Model: "sequential_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_2 (Conv2D)            (None, 26, 26, 16)        160       
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 13, 13, 16)        0         
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 11, 11, 32)        4640      
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, 5, 5, 32)          0         
_________________________________________________________________
flatten_1 (Flatten)          (None, 800)               0         
_________________________________________________________________
dense_2 (Dense)              (None, 32)                25632     
_________________________________________________________________
dense_3 (Dense)              (None, 10)                330       
=================================================================
Total params: 30,762
Trainable params: 30,762
Non-trainable params: 0
_________________________________________________________________
Epoch 1/10
1875/1875 [==============================] - 15s 8ms/step - loss: 0.1854 - accuracy: 0.9437
Epoch 2/10
1875/1875 [==============================] - 14s 8ms/step - loss: 0.0659 - accuracy: 0.9796
Epoch 3/10
1875/1875 [==============================] - 15s 8ms/step - loss: 0.0484 - accuracy: 0.9851
Epoch 4/10
1875/1875 [==============================] - 15s 8ms/step - loss: 0.0375 - accuracy: 0.9884
Epoch 5/10
1875/1875 [==============================] - 15s 8ms/step - loss: 0.0308 - accuracy: 0.9904
Epoch 6/10
1875/1875 [==============================] - 15s 8ms/step - loss: 0.0249 - accuracy: 0.9920
Epoch 7/10
1875/1875 [==============================] - 15s 8ms/step - loss: 0.0222 - accuracy: 0.9931
Epoch 8/10
1875/1875 [==============================] - 15s 8ms/step - loss: 0.0179 - accuracy: 0.9947
Epoch 9/10
1875/1875 [==============================] - 15s 8ms/step - loss: 0.0152 - accuracy: 0.9954
Epoch 10/10
1875/1875 [==============================] - 15s 8ms/step - loss: 0.0125 - accuracy: 0.9959
313/313 - 1s - loss: 0.0341 - accuracy: 0.9892
test_loss: 0.034050457179546356 
test_accuracy: 0.9891999959945679

Mini Project: rock paper scissors AI

I will try to create a rock paper scissors classifier.

We have to create images for training and testing here.

https://teachablemachine.withgoogle.com/

from PIL import Image
import os, glob

print("PIL 라이브러리 import 완료!")
PIL 라이브러리 import 완료!
import os

def resize_images(img_path):
    images=glob.glob(img_path + "/*.jpg")  
    
    print(len(images), " images to be resized.")

    # 파일마다 모두 28x28 사이즈로 바꾸어 저장합니다.
    target_size=(28,28)
    for img in images:
        old_img=Image.open(img)
        new_img=old_img.resize(target_size,Image.ANTIALIAS)
        new_img.save(img, "JPEG")
    
    print(len(images), " images resized.")


# 가위 이미지가 저장된 디렉토리 아래의 모든 jpg 파일을 읽어들여서
image_dir_path = os.path.abspath(os.getcwd()) + "/aiffel/data_preprocess/rock_scissor_paper/scissor"
print(image_dir_path)
resize_images(image_dir_path)

print("가위 이미지 resize 완료!")
C:\workspace1\aiffel_LMS/aiffel/data_preprocess/rock_scissor_paper/scissor
994  images to be resized.
994  images resized.
가위 이미지 resize 완료!
#  바위 이미지가 저장된 디렉토리 아래의 모든 jpg 파일을 읽어들여서
image_dir_path = os.path.abspath(os.getcwd()) + "/aiffel/data_preprocess/rock_scissor_paper/rock"
print(image_dir_path)
resize_images(image_dir_path)

print("rock resize 완료!")
C:\workspace1\aiffel_LMS/aiffel/data_preprocess/rock_scissor_paper/rock
1105  images to be resized.
1105  images resized.
rock resize 완료!
# paper 이미지가 저장된 디렉토리 아래의 모든 jpg 파일을 읽어들여서
image_dir_path = os.path.abspath(os.getcwd()) + "/aiffel/data_preprocess/rock_scissor_paper/paper"
print(image_dir_path)
resize_images(image_dir_path)

print("paper 이미지 resize 완료!")
C:\workspace1\aiffel_LMS/aiffel/data_preprocess/rock_scissor_paper/paper
1108  images to be resized.
1108  images resized.
paper 이미지 resize 완료!
import numpy as np

def load_data(img_path, number_of_data=300):  # 가위바위보 이미지 개수 총합에 주의하세요.
    # 가위 : 0, 바위 : 1, 보 : 2
    img_size=28
    color=3
    #이미지 데이터와 라벨(가위 : 0, 바위 : 1, 보 : 2) 데이터를 담을 행렬(matrix) 영역을 생성합니다.
    imgs=np.zeros(number_of_data*img_size*img_size*color,dtype=np.int32).reshape(number_of_data,img_size,img_size,color)
    labels=np.zeros(number_of_data,dtype=np.int32)

    idx=0
    for file in glob.iglob(img_path+'/scissor/*.jpg'):
        img = np.array(Image.open(file),dtype=np.int32)
        imgs[idx,:,:,:]=img    # 데이터 영역에 이미지 행렬을 복사
        labels[idx]=0   # 가위 : 0
        idx=idx+1

    for file in glob.iglob(img_path+'/rock/*.jpg'):
        img = np.array(Image.open(file),dtype=np.int32)
        imgs[idx,:,:,:]=img    # 데이터 영역에 이미지 행렬을 복사
        labels[idx]=1   # 바위 : 1
        idx=idx+1  
    
    for file in glob.iglob(img_path+'/paper/*.jpg'):
        img = np.array(Image.open(file),dtype=np.int32)
        imgs[idx,:,:,:]=img    # 데이터 영역에 이미지 행렬을 복사
        labels[idx]=2   # 보 : 2
        idx=idx+1
        
    print("학습데이터(x_train)의 이미지 개수는", idx,"입니다.")
    return imgs, labels

image_dir_path = os.path.abspath(os.getcwd()) + "/aiffel/data_preprocess/rock_scissor_paper"
(x_train, y_train)=load_data(image_dir_path,3207)




x_train_norm = x_train/255.0   # 입력은 0~1 사이의 값으로 정규화

print("x_train shape: {}".format(x_train.shape))
print("y_train shape: {}".format(y_train.shape))
학습데이터(x_train)의 이미지 개수는 3207 입니다.
x_train shape: (3207, 28, 28, 3)
y_train shape: (3207,)
import matplotlib.pyplot as plt
plt.imshow(x_train[0])
print('라벨: ', y_train[0])
라벨:  0

output_38_1

import tensorflow as tf
from tensorflow import keras
import numpy as np


# model을 직접 만들어 보세요.
# Hint! model의 입력/출력부에 특히 유의해 주세요. 가위바위보 데이터셋은 MNIST 데이터셋과 어떤 점이 달라졌나요?
model=keras.models.Sequential()
model.add(keras.layers.Conv2D(16, (3,3), activation='relu', input_shape=(28,28,3)))
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(3, activation='softmax'))

print('Model에 추가된 Layer 개수: ', len(model.layers))

model.summary()
Model에 추가된 Layer 개수:  7
Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d (Conv2D)              (None, 26, 26, 16)        448       
_________________________________________________________________
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, 3)                 99        
=================================================================
Total params: 30,819
Trainable params: 30,819
Non-trainable params: 0
_________________________________________________________________
# model을 학습시키는 코드를 직접 작성해 보세요.
# Hint! model.compile()과 model.fit()을 사용해 봅시다.
# [[YOUR CODE]]

model.compile(optimizer='adam',
             loss='sparse_categorical_crossentropy',
             metrics=['accuracy'])

model.fit(x_train, y_train, epochs=10)
Epoch 1/10
101/101 [==============================] - 1s 9ms/step - loss: 3.5071 - accuracy: 0.4602
Epoch 2/10
101/101 [==============================] - 1s 9ms/step - loss: 0.8311 - accuracy: 0.6109
Epoch 3/10
101/101 [==============================] - 1s 9ms/step - loss: 0.6757 - accuracy: 0.6978
Epoch 4/10
101/101 [==============================] - 1s 9ms/step - loss: 0.5651 - accuracy: 0.7702
Epoch 5/10
101/101 [==============================] - 1s 10ms/step - loss: 0.5310 - accuracy: 0.7764
Epoch 6/10
101/101 [==============================] - 1s 9ms/step - loss: 0.4129 - accuracy: 0.8407
Epoch 7/10
101/101 [==============================] - 1s 9ms/step - loss: 0.3619 - accuracy: 0.8597
Epoch 8/10
101/101 [==============================] - 1s 9ms/step - loss: 0.3300 - accuracy: 0.8750
Epoch 9/10
101/101 [==============================] - 1s 9ms/step - loss: 0.2678 - accuracy: 0.9030
Epoch 10/10
101/101 [==============================] - 1s 9ms/step - loss: 0.1986 - accuracy: 0.9264





<tensorflow.python.keras.callbacks.History at 0x1dd1549f8e0>
# 가위 이미지가 저장된 디렉토리 아래의 모든 jpg 파일을 읽어들여서
image_dir_path = os.path.abspath(os.getcwd()) + "/aiffel/data_preprocess/rock_scissor_paper/test/scissor"
print(image_dir_path)
resize_images(image_dir_path)

print("가위 이미지 resize 완료!")
C:\workspace1\aiffel_LMS/aiffel/data_preprocess/rock_scissor_paper/test/scissor
100  images to be resized.
100  images resized.
가위 이미지 resize 완료!
#  바위 이미지가 저장된 디렉토리 아래의 모든 jpg 파일을 읽어들여서
image_dir_path = os.path.abspath(os.getcwd()) + "/aiffel/data_preprocess/rock_scissor_paper/test/rock"
print(image_dir_path)
resize_images(image_dir_path)

print("rock resize 완료!")
C:\workspace1\aiffel_LMS/aiffel/data_preprocess/rock_scissor_paper/test/rock
100  images to be resized.
100  images resized.
rock resize 완료!
# paper 이미지가 저장된 디렉토리 아래의 모든 jpg 파일을 읽어들여서
image_dir_path = os.path.abspath(os.getcwd()) + "/aiffel/data_preprocess/rock_scissor_paper/test/paper"
print(image_dir_path)
resize_images(image_dir_path)

print("paper 이미지 resize 완료!")
C:\workspace1\aiffel_LMS/aiffel/data_preprocess/rock_scissor_paper/test/paper
100  images to be resized.
100  images resized.
paper 이미지 resize 완료!
image_dir_path = os.path.abspath(os.getcwd()) + "/aiffel/data_preprocess/rock_scissor_paper/test"
(x_test, y_test)=load_data(image_dir_path,300)

print("x_test shape: {}".format(x_test.shape))
print("y_test shape: {}".format(y_test.shape))
학습데이터(x_train)의 이미지 개수는 300 입니다.
x_test shape: (300, 28, 28, 3)
y_test shape: (300,)
# model을 학습시키는 코드를 직접 작성해 보세요.
# Hint! model.evaluate()을 사용해 봅시다.
# [[YOUR CODE]]

test_loss, test_accuracy = model.evaluate(x_test,y_test, verbose=2)
print("test_loss: {} ".format(test_loss))
print("test_accuracy: {}".format(test_accuracy))
10/10 - 0s - loss: 3.6065 - accuracy: 0.3233
test_loss: 3.6064822673797607 
test_accuracy: 0.3233333230018616

The test accuracy was severely lower than the train accuracy…

Instead of using a different sample data, we will split the original sample into test and training batch for improvements in accuracy in spite of possibilities of overfitting

image_dir_path = os.path.abspath(os.getcwd()) + "/aiffel/data_preprocess/rock_scissor_paper"
(x_train1, y_train1)=load_data(image_dir_path,3207)

# model을 직접 만들어 보세요.
# Hint! model의 입력/출력부에 특히 유의해 주세요. 가위바위보 데이터셋은 MNIST 데이터셋과 어떤 점이 달라졌나요?
model=keras.models.Sequential()
model.add(keras.layers.Conv2D(16, (3,3), activation='relu', input_shape=(28,28,3)))
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(3, activation='softmax'))

print('Model에 추가된 Layer 개수: ', len(model.layers))

model.summary()
학습데이터(x_train)의 이미지 개수는 3207 입니다.
Model에 추가된 Layer 개수:  7
Model: "sequential_5"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_10 (Conv2D)           (None, 26, 26, 16)        448       
_________________________________________________________________
max_pooling2d_10 (MaxPooling (None, 13, 13, 16)        0         
_________________________________________________________________
conv2d_11 (Conv2D)           (None, 11, 11, 32)        4640      
_________________________________________________________________
max_pooling2d_11 (MaxPooling (None, 5, 5, 32)          0         
_________________________________________________________________
flatten_5 (Flatten)          (None, 800)               0         
_________________________________________________________________
dense_10 (Dense)             (None, 32)                25632     
_________________________________________________________________
dense_11 (Dense)             (None, 3)                 99        
=================================================================
Total params: 30,819
Trainable params: 30,819
Non-trainable params: 0
_________________________________________________________________
import numpy as np
from sklearn.model_selection import train_test_split

x_train, x_test = train_test_split(x_train1, test_size=0.2, random_state=10)
y_train, y_test = train_test_split(y_train1, test_size=0.2, random_state=10)
print("x_train shape: {}".format(x_train.shape))
print("y_train shape: {}".format(y_train.shape))
print("x_test shape: {}".format(x_test.shape))
print("y_test shape: {}".format(y_test.shape))
x_train shape: (2565, 28, 28, 3)
y_train shape: (2565,)
x_test shape: (642, 28, 28, 3)
y_test shape: (642,)
plt.imshow(x_test[500])
print('라벨: ', y_test[500])
라벨:  1

output_50_1

# model을 학습시키는 코드를 직접 작성해 보세요.
# Hint! model.compile()과 model.fit()을 사용해 봅시다.
# [[YOUR CODE]]

model.compile(optimizer='adam',
             loss='sparse_categorical_crossentropy',
             metrics=['accuracy'])

model.fit(x_train, y_train, epochs=10)
Epoch 1/10
81/81 [==============================] - 1s 10ms/step - loss: 5.2412 - accuracy: 0.4160
Epoch 2/10
81/81 [==============================] - 1s 10ms/step - loss: 0.9380 - accuracy: 0.4908
Epoch 3/10
81/81 [==============================] - 1s 10ms/step - loss: 0.8454 - accuracy: 0.5591
Epoch 4/10
81/81 [==============================] - 1s 9ms/step - loss: 0.7381 - accuracy: 0.6402
Epoch 5/10
81/81 [==============================] - 1s 9ms/step - loss: 0.6679 - accuracy: 0.6760
Epoch 6/10
81/81 [==============================] - 1s 9ms/step - loss: 0.6226 - accuracy: 0.7193
Epoch 7/10
81/81 [==============================] - 1s 9ms/step - loss: 0.5236 - accuracy: 0.7731
Epoch 8/10
81/81 [==============================] - 1s 9ms/step - loss: 0.4197 - accuracy: 0.8327
Epoch 9/10
81/81 [==============================] - 1s 9ms/step - loss: 0.3660 - accuracy: 0.8612
Epoch 10/10
81/81 [==============================] - 1s 9ms/step - loss: 0.4241 - accuracy: 0.8234





<tensorflow.python.keras.callbacks.History at 0x1dd09180130>
plt.imshow(x_test[0])
print('라벨: ', y_test[0])
라벨:  1

output_52_1

test_loss, test_accuracy = model.evaluate(x_test,y_test, verbose=2)
print("test_loss: {} ".format(test_loss))
print("test_accuracy: {}".format(test_accuracy))
21/21 - 0s - loss: 0.4301 - accuracy: 0.7991
test_loss: 0.4301043748855591 
test_accuracy: 0.7990654110908508

This way, we can raise the test accuracy

Leave a comment