인공지능과 가위바위보!

ai_lim·2022년 1월 4일
0

AI

목록 보기
6/16

1. 데이터 불러오기

학습용 데이터를 만들기위해서 사이트에 들어가
묵,찌,빠를 여러장 찍어서 각각을 zip파일로 저장한다
https://teachablemachine.withgoogle.com/

2.Resize하기

from PIL import Image
import glob

PIL : 이미지 분석 및 처리를 쉽게 할 수 있는 라이브러리
glob: 사용자가 제시한 조건에 맞는 파일명을 리스트형식으로 반환한다.

resize 하는 함수

def resize_images(img_path):
	images=glob.glob(img_path+'/*.jpg') #jpg로 끝나는 파일명을 리스트로 반환
 	print(len(images),'images to be resized')
  
 	#이미지를 28*28로 resize
  	target_size=(28,28)
  	for img in images:
  		old_image=Image.open(img)
   		new_image=old_image.resize(target_size,Image.ANTIALIAS)
      		new_image.save(img,'JPEG')
          

학습용데이터 가위,바위,보 resize하기


s_train_dir_path = os.getenv("HOME") + "/aiffel/rock_scissor_paper/scissor"
resize_images(s_train_dir_path)

r_train_dir_path = os.getenv("HOME") + "/aiffel/rock_scissor_paper/rock"
resize_images(r_train_dir_path)

p_train_dir_path = os.getenv("HOME") + "/aiffel/rock_scissor_paper/paper"
resize_images(p_train_dir_path)

3.데이터 로드하기

데이터로드 함수

import numpy as np
def load_data(img_path,number_of_data):
	img_size=28
	color=3 #1이면 흑백,3이면 컬러
	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
    #가위에 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
        idx+=1
    #바위에 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   
        idx=idx+1  
    #보에 2 라벨링하기     
	for file in glob.iglob(img_path+'/paper/*.jpg'):
        img = np.array(Image.open(file),dtype=np.int32)
        imgs[idx,:,:,:]=img    
        labels[idx]=2   
        idx=idx+1
	
    return imgs,labels

imgs=np.zeros(number_of_dataimg_sizeimg_size*color,dtype=np.int32).reshape(number_of_data,img_size,img_size,color)

  • numpy.zeros(shape, dtype=float, order='C', *, like=None)
    :0으로 초기화된 shape차원의 ndarray배열 객체를 반환한다.
  • numpy.int32:숫자형

for file in glob.iglob(img_path+'/scissor/*.jpg'):
img=np.array(Image.open(file),dtype=np.int32)
imgs[idx,:,:,:]=img
labels[idx]=0
idx+=1

  • 가위 파일들을 하나씩 들고와서 img에 오픈한 파일의 행렬을 만든다
image_dir_path=os.getenv("HOME")+"/aiffel/rock_scissor_paper"
(x_train,y_train)=load_data(image_dir_path,300)
x_train_norm=x_train/255.0 #최대 255로 나눠서 입력을 정규화

4. 딥러닝 네트워크 설계하기

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

model=keras.model.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(3, activation='softmax'))

model.summary()

model.add(keras.layers.Conv2D(16, (3,3), activation='relu', input_shape=(28,28,1)))

  • keras.layers.Conv2D(filters, kernel_size, kernel_initializer='glorot_uniform',input_shape=())
  • relu: 정류된 선형함수, +/-가 반복되는 신호에서 -흐름을 차단하여 기울기 소실문제를 해결함

model.add(keras.layers.MaxPool2D(2,2))

  • 사이즈를 줄일때 2*2 창 내에서 최대값을 가져옴
  • conv 다음 가중치를 줄인다는 목적으로 maxpool 씀

keras.layers.Flatten(): 입력을 1차원으로 변환함

model.add(keras.layers.Dense(3, activation='softmax'))

  • dense:네트워크에서 밀집층을 구현할 때 쓰이는 함수로 마지막 dense에는 가위,바위,보 3개를 분류해야함으로 3이 들어가야한다.
  • softmax는 일반적으로 마지막 활성함수로 많이 사용된다.

5. 딥러닝 네트워크 학습시키기

print(x_train.shape)를 하면 (60000,28,28)로 채널수 정보가 없으므로 수정한다.

x_train_reshaped=x_train_norm.reshape(-1,28,28,3)
#데이터갯수에 -1을 쓰면 자동계산됨/채널수에 3을 쓰면 컬러임

학습모델

model.compile(optimizer='adam',
             loss='sparse_categorical_crossentropy',
             metrics=['accuracy']
             
model.fit(x_train_shaped,y_train,epochs=10)#epochs는 학습횟수
             

optimizer='adam' 보통 이렇게 많이 쓴다고한다
loss='sparse_categorical_crossentropy' :다중분류손실함수
metrics=['accuracy']

6. 테스트하기

테스트할 데이터들을 수집하고 저장한다

테스트용 데이터 만들기(학습용이랑 똑같은 방법)

test_dir_path=os.getenv("HOME")+"/aiffel/rock_scissor_paper/test"

s_test_dir_path=os.getenv("HOME")+"/aiffel/rock_scissor_paper/test/scissor"
resize_images(s_test_dir_path)

r_test_dir_path=os.getenv("HOME")+"/aiffel/rock_scissor_paper/test/rock"
resize_images(r_test_dir_path)

p_test_dir_path=os.getenv("HOME")+"/aiffel/rock_scissor_paper/test/paper"
resize_images(p_test_dir_path)

(x_test,y_test)=load_data(test_dir_path,300)
x_test_norm=x_test/255.0 
x_test_reshaped=x_test_norm.reshape( -1, 28, 28,3)

테스트하기

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))

참고문헌:아이펠

0개의 댓글