A.I
Explolation1 가위바위보 분류하기 본문
1-1.MNIST 숫자 손글씨 Dataset 불러들이기
In [7]:
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.2.0 60000
In [8]:
# index에 0에서 59999 사이 숫자를 지정해 보세요.
index=10000
plt.imshow(x_train[index],cmap=plt.cm.binary)
plt.show()
print( (index+1), '번째 이미지의 숫자는 바로 ', y_train[index], '입니다.')
10001 번째 이미지의 숫자는 바로 3 입니다.
참고: Matplotlib 이란?
파이썬에서 제공하는 시각화(Visualization) 패키지인 Matplotlib은 차트(chart), 플롯(plot) 등 다양한 형태로 데이터를 시각화할 수 있는 강력한 기능을 제공합니다.
1-2.데이터 전처리 하기
In [9]:
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.0 최대값: 1.0
1-3.딥러닝 네트워크 설계하기
In [10]:
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
In [11]:
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 _________________________________________________________________
1-4. 딥러닝 네트워크 학습시키기
print(x_train.shape) 을 해보면,(60000, 28, 28) 로 채널수에 대한 정보가 없습니다. 따라서 (60000, 28, 28, 1) 로 만들어 주어야 합니다
In [12]:
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)
In [13]:
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
model.fit(x_train_reshaped, y_train, epochs=10)
Epoch 1/10 1875/1875 [==============================] - 3s 1ms/step - loss: 0.1962 - accuracy: 0.9405 Epoch 2/10 1875/1875 [==============================] - 3s 1ms/step - loss: 0.0628 - accuracy: 0.9803 Epoch 3/10 1875/1875 [==============================] - 3s 1ms/step - loss: 0.0460 - accuracy: 0.9858 Epoch 4/10 1875/1875 [==============================] - 3s 1ms/step - loss: 0.0353 - accuracy: 0.9888 Epoch 5/10 1875/1875 [==============================] - 3s 1ms/step - loss: 0.0292 - accuracy: 0.9906 Epoch 6/10 1875/1875 [==============================] - 3s 1ms/step - loss: 0.0244 - accuracy: 0.9923 Epoch 7/10 1875/1875 [==============================] - 3s 1ms/step - loss: 0.0196 - accuracy: 0.9937 Epoch 8/10 1875/1875 [==============================] - 3s 1ms/step - loss: 0.0163 - accuracy: 0.9948 Epoch 9/10 1875/1875 [==============================] - 3s 1ms/step - loss: 0.0137 - accuracy: 0.9955 Epoch 10/10 1875/1875 [==============================] - 3s 1ms/step - loss: 0.0120 - accuracy: 0.9958
Out[13]:
<tensorflow.python.keras.callbacks.History at 0x7f3d1c175290>
1-5. 테스트 데이터로 성능을 확인하기
In [14]:
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 - 2s - loss: 0.0407 - accuracy: 0.9892 test_loss: 0.0406544953584671 test_accuracy: 0.9891999959945679
1-6 모델링, 학습, 테스트
In [15]:
#바꿔 볼 수 있는 하이퍼파라미터들
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 [==============================] - 3s 2ms/step - loss: 0.1991 - accuracy: 0.9413 Epoch 2/10 1875/1875 [==============================] - 3s 1ms/step - loss: 0.0645 - accuracy: 0.9803 Epoch 3/10 1875/1875 [==============================] - 3s 1ms/step - loss: 0.0455 - accuracy: 0.9863 Epoch 4/10 1875/1875 [==============================] - 3s 1ms/step - loss: 0.0358 - accuracy: 0.9890 Epoch 5/10 1875/1875 [==============================] - 3s 1ms/step - loss: 0.0293 - accuracy: 0.9909 Epoch 6/10 1875/1875 [==============================] - 3s 2ms/step - loss: 0.0252 - accuracy: 0.9919 Epoch 7/10 1875/1875 [==============================] - 3s 1ms/step - loss: 0.0195 - accuracy: 0.9935 Epoch 8/10 1875/1875 [==============================] - 3s 2ms/step - loss: 0.0172 - accuracy: 0.9942 Epoch 9/10 1875/1875 [==============================] - 3s 2ms/step - loss: 0.0137 - accuracy: 0.9956 Epoch 10/10 1875/1875 [==============================] - 3s 2ms/step - loss: 0.0133 - accuracy: 0.9955 313/313 - 0s - loss: 0.0382 - accuracy: 0.9893 test_loss: 0.03815147280693054 test_accuracy: 0.989300012588501
2-1 가위바위보 이미지 수집후 resize하기
In [17]:
# PIL 라이브러리가 설치되어 있지 않다면 설치
!pip install pillow
from PIL import Image
import os, glob
print("PIL 라이브러리 import 완료!")
Requirement already satisfied: pillow in ./anaconda3/envs/aiffel/lib/python3.7/site-packages (8.0.1) PIL 라이브러리 import 완료!
In [20]:
import os
# 가위 이미지가 저장된 디렉토리 아래의 모든 jpg 파일을 읽어들여서
image_dir_path = os.getenv("HOME") + "/aiffel/rock_scissor_paper/scissor"
print("이미지 디렉토리 경로: ", image_dir_path)
images=glob.glob(image_dir_path + "/*.jpg")
# 파일마다 모두 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("가위 이미지 resize 완료!")
# 바위 이미지가 저장된 디렉토리 아래의 모든 jpg 파일을 읽어들여서
image_dir_path = os.getenv("HOME") + "/aiffel/rock_scissor_paper/rock"
print("이미지 디렉토리 경로: ", image_dir_path)
images=glob.glob(image_dir_path + "/*.jpg")
# 파일마다 모두 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("바위 이미지 resize 완료!")
# 보 이미지가 저장된 디렉토리 아래의 모든 jpg 파일을 읽어들여서
image_dir_path = os.getenv("HOME") + "/aiffel/rock_scissor_paper/paper"
print("이미지 디렉토리 경로: ", image_dir_path)
images=glob.glob(image_dir_path + "/*.jpg")
# 파일마다 모두 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("보 이미지 resize 완료!")
이미지 디렉토리 경로: /home/ssac24/aiffel/rock_scissor_paper/scissor 가위 이미지 resize 완료! 이미지 디렉토리 경로: /home/ssac24/aiffel/rock_scissor_paper/rock 바위 이미지 resize 완료! 이미지 디렉토리 경로: /home/ssac24/aiffel/rock_scissor_paper/paper 보 이미지 resize 완료!
2-2 이미지 라벨링 하기
In [41]:
def load_data(img_path):
# 가위 : 0, 바위 : 1, 보 : 2
number_of_data=3300 # 가위바위보 이미지 개수 총합에 주의하세요.
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.getenv("HOME") + "/aiffel/rock_scissor_paper"
(x_train, y_train)=load_data(image_dir_path)
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)의 이미지 개수는 3300 입니다. x_train shape: (3300, 28, 28, 3) y_train shape: (3300,)
2-3 딥러닝 설계
In [48]:
import tensorflow as tf
from tensorflow import keras
import numpy as np
n_channel_1=32
n_channel_2=64
n_dense=128
n_train_epoch=5
model=keras.models.Sequential()
model.add(keras.layers.Conv2D(n_channel_1, (3,3), activation='relu', input_shape=(28,28,3)))
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.summary()
import matplotlib.pyplot as plt
plt.imshow(x_train[0])
print('라벨: ', y_train[0])
index=50
plt.imshow(x_train[index],cmap=plt.cm.binary)
plt.show()
print( (index+1), '번째 이미지는 바로 ', y_train[index], '입니다.')
Model: "sequential_7" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= conv2d_14 (Conv2D) (None, 26, 26, 32) 896 _________________________________________________________________ max_pooling2d_14 (MaxPooling (None, 13, 13, 32) 0 _________________________________________________________________ conv2d_15 (Conv2D) (None, 11, 11, 64) 18496 _________________________________________________________________ max_pooling2d_15 (MaxPooling (None, 5, 5, 64) 0 _________________________________________________________________ flatten_7 (Flatten) (None, 1600) 0 _________________________________________________________________ dense_14 (Dense) (None, 128) 204928 _________________________________________________________________ dense_15 (Dense) (None, 10) 1290 ================================================================= Total params: 225,610 Trainable params: 225,610 Non-trainable params: 0 _________________________________________________________________ 라벨: 0
51 번째 이미지는 바로 0 입니다.
2-4 딥러닝 네트워크 학습
In [50]:
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
model.fit(x_train, y_train, epochs=10)
Epoch 1/10 104/104 [==============================] - 4s 36ms/step - loss: 4.4448 - accuracy: 0.4770 Epoch 2/10 104/104 [==============================] - 0s 2ms/step - loss: 0.7039 - accuracy: 0.7006 Epoch 3/10 104/104 [==============================] - 0s 2ms/step - loss: 0.4769 - accuracy: 0.8039 Epoch 4/10 104/104 [==============================] - 0s 1ms/step - loss: 0.2724 - accuracy: 0.9006 Epoch 5/10 104/104 [==============================] - 0s 1ms/step - loss: 0.1938 - accuracy: 0.9291 Epoch 6/10 104/104 [==============================] - 0s 1ms/step - loss: 0.1702 - accuracy: 0.9358 Epoch 7/10 104/104 [==============================] - 0s 2ms/step - loss: 0.1095 - accuracy: 0.9606 Epoch 8/10 104/104 [==============================] - 0s 1ms/step - loss: 0.0837 - accuracy: 0.9706 Epoch 9/10 104/104 [==============================] - 0s 2ms/step - loss: 0.0859 - accuracy: 0.9715 Epoch 10/10 104/104 [==============================] - 0s 1ms/step - loss: 0.0792 - accuracy: 0.9712
Out[50]:
<tensorflow.python.keras.callbacks.History at 0x7f3cfc1cbe50>
2-5 테스트셋 만들기
In [51]:
def load_data2(img_path):
# 가위 : 0, 바위 : 1, 보 : 2
number_of_data=300 # 가위바위보 이미지 개수 총합에 주의하세요.
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_test/*.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_test/*.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_test/*.jpg'):
img = np.array(Image.open(file),dtype=np.int32)
imgs[idx,:,:,:]=img # 데이터 영역에 이미지 행렬을 복사
labels[idx]=2 # 보 : 2
idx=idx+1
print("학습데이터(x_test)의 이미지 개수는",idx,"입니다.")
return imgs, labels
image_dir_path = os.getenv("HOME") + "/aiffel/rock_scissor_paper"
(x_test, y_test)=load_data2(image_dir_path)
x_test_norm = x_test/255.0 # 입력은 0~1 사이의 값으로 정규화
print("x_test shape: {}".format(x_test.shape))
print("y_test shape: {}".format(y_test.shape))
학습데이터(x_test)의 이미지 개수는 300 입니다. x_test shape: (300, 28, 28, 3) y_test shape: (300,)
2-6 Accuracy 측정¶
In [52]:
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 - 2s - loss: 1.4619 - accuracy: 0.7033 test_loss: 1.461875319480896 test_accuracy: 0.70333331823349
중점적으로 체크해야할 부분
- 경로가 올바른지
- 사진을 resize했을 경우 새롭게 하는 testset도 resize 까먹지 말것
- 모델링의 경우 식을 맞출 것
- 특징을 더 상세하게 잡기위해 Conv2d값을 올릴수록 세세한 분류가 가능함
'AIFFEL' 카테고리의 다른 글
Exploration5 오디오 음성 데이터 분류 (0) | 2021.01.19 |
---|---|
Exploration4 영화 리뷰 감성 분류 (0) | 2021.01.14 |
Exploration 3 카메라 스티커 인식 (0) | 2021.01.12 |
Explolation2 아이리스 분류하기 (0) | 2021.01.08 |
1일차 인공지능 개발자가 되기위한 첫걸음 (0) | 2021.01.04 |