▩ 설현과 수지 인식 신경망 만들기 수업 노트 전체
잘 선별한 수지 사진 100장과 설현 사진 100장을 하나의 폴더에 모아져 있어야합니다.
수지사진은 1.jpg ~ 100.jpg 로 번호가 붙어있어야하고
설현사진은 101.jpg ~ 200.jpg 로 변호가 붙어있어야 합니다.
**<코랩에서 진행>**
#0. 구글드라이브 마운트
from google.colab import drive
drive.mount('/content/drive')
# Mounted at /content/drive
#0. 수지 사진 100장, 설현 사진 100장을 구글 드라이브에 /content/drive/MyDrive/pretty 폴더에 올리세요 ~~
<https://cafe.daum.net/oracleoracle/SmRD/381>
- zip 파일 상태로
- 데이터 : 잘 선별한 상태
- 다른 사람과 같이 있는 사진 x -> 혼자 있는 사진
- 이상한, 엉뚱한 사진 x
#1. train200 이라는 폴더를 코렙에 생성하시오
/content/drive/MyDrive/pretty 폴더 밑에 생성
#2. 코렙에 올린 사진 압축파일의 압축을 풉니다.
!unzip -uq /content/drive/MyDrive/pretty/image_all.zip -d /content/drive/MyDrive/pretty/train200
#3. train_resize 라는 폴더를 만듭니다.
!mkdir /content/drive/MyDrive/pretty/train_resize
- 리눅스 명령어
#4. 32x32 로 사진들을 전부 resize 합니다.
# 훈련 이미지를 resize 합니다.
import cv2
import os
import numpy as np
path = "/content/drive/MyDrive/pretty/train200" # 원본위치
file_list = os.listdir(path) # 파일이름 불러오는 부분
for k in file_list: # 리스트안에 있는 파일들을 하나씩 빼내는 코드
img = cv2.imread(path + '/' + k) # 이미지 데이터를 행렬로 숫자로 변환합니다.
resize_img = cv2.resize(img, (32 , 32), interpolation=cv2.INTER_CUBIC)
cv2.imwrite( '/content/drive/MyDrive/pretty/train_resize/' + k, resize_img)
# train_resize 에 resize 된 이미지들이 몇개가 있는지 확인합니다.
!ls /content/drive/MyDrive/pretty/train_resize | wc -l
# 200
#5. 정답 csv 파일을 생성합니다.
# 수지를 0번으로하고 설현을 1번으로 하겠습니다.
path='/content/drive/MyDrive/pretty/train_label.csv'
file = open( path, 'w' )
# 숫자 0을 100개 , 숫자 1을 100개 씁니다.
for i in range( 1, 101 ):
file.write( str(0) + '\\n' )
for i in range( 101, 201 ):
file.write( str(1) + '\\n' )
file.close()
#6. 지난번에 만들었던 image_load 함수와 label_load 함수를 생성하시오 !
<https://cafe.daum.net/oracleoracle/SmRD/387> <--- 전체 코드, 게시글 387번
train_images='/content/drive/MyDrive/pretty/train_resize'
import os
import re
import cv2
def image_load(path):
#1. 사진 파일명에서 숫자부분만 취합니다.
file_list = os.listdir(path) # path 디렉토리에 파일명들을 불러옵니다.
file_name = []
for i in file_list:
a = int( re.sub('[^0-9]', '', i ) ) # i 가 숫자가 아니라면 null 로 변경해라
file_name.append(a)
file_name.sort()
#2. 디렉토리와 숫자 파일명을 이어 붙입니다.
file_res = [ ]
for j in file_name:
file_res.append( path + '/' + str(j) + '.jpg') # 전체 경로 + 파일명을 생성
#3. 위에서만든 디렉토리와 파일명을 가지고 사진을 숫자로 변경합니다.
image= [ ]
for k in file_res:
img = cv2.imread(k) # 이미지를 숫자로 변경합니다.
image.append(img)
return np.array(image)
print ( image_load(train_images) )
from tensorflow.keras.utils import to_categorical
import csv
import numpy as np
train_label = '/content/drive/MyDrive/pretty/train_label.csv'
def label_load(path):
file = open(path)
labeldata = csv.reader(file)
labellist = [ ]
for i in labeldata:
labellist.append(i)
label = np.array( labellist ) # 넘파이 배열로 변환
label = label.astype(int) # 숫자로 변환
label = to_categorical(label) # [ 1, 0] 또는 [0, 1] 로 one hot encoding 합니다.
return label
print ( label_load(train_label) )
#7. 수지와 설현 사진을 분류하는 신경망을 학습 시키시오 !
# 1. 필요한 패키지 가져오는 코드
import tensorflow as tf # 텐써 플로우 2.0
from tensorflow.keras.datasets.mnist import load_data # 텐써플로우에 내장되어있는
# mnist 데이터를 가져온다.
from tensorflow.keras.models import Sequential # 모델을 구성하기 위한 모듈
from tensorflow.keras.layers import Dense, Conv2D, MaxPooling2D, Flatten ,BatchNormalization,Dropout # CNN, 완전 연결계층을 구성하기 위한 모듈
from tensorflow.keras.utils import to_categorical # one encoding 하는 모듈
tf.random.set_seed(777)
# 데이터를 가져오는 코드
train_images='/content/drive/MyDrive/pretty/train_resize'
train_label = '/content/drive/MyDrive/pretty/train_label.csv'
x_train = image_load( train_images)
y_train = label_load(train_label)
# 2. 정규화를 진행합니다.
x_train = x_train / 255.0
print(x_train.shape) # (4000, 32, 32, 3)
# 3. 모델을 구성합니다. 3층 신경망으로 구성
model = Sequential()
model.add(Conv2D(100, kernel_size=(5,5), input_shape=(32,32,3), padding='same', activation='relu') )
model.add(MaxPooling2D(pool_size=(2,2), padding='same') ) # 이미지를 선명하게 해주는 층
model.add(BatchNormalization())
model.add(Dropout(0.2))
model.add(Flatten() ) # 완전연결계층에 들어갈수 있도록 이미지(피쳐맵들)를 1차원으로 변경합니다.
model.add(Dense(50, activation = 'relu')) # 1층
model.add(BatchNormalization())
model.add(Dropout(0.2))
model.add(Dense(50, activation = 'relu') ) # 2층 은닉층
model.add(BatchNormalization())
model.add(Dropout(0.2))
model.add(Dense( 2, activation = 'softmax')) # 3층 출력층
# 5. 모델을 설정합니다. ( 경사하강법, 오차함수를 정의해줍니다. )
model.compile(optimizer='Adam',
loss = 'categorical_crossentropy',
metrics=['acc']) # 학습과정에서 정확도를 보려고
#6. 모델을 훈련시킵니다.
history = model.fit(x_train, y_train,
epochs = 200, # 30에폭
batch_size = 10 )
# 7.모델을 평가합니다. (오차, 정확도가 출력됩니다.)
#model.evaluate(x_test, y_test)
model.save('/content/drive/MyDrive/pretty/suji_model.keras')
# Epoch 200/200
# 20/20 ━━━━━━━━━━━━━━━━━━━━ 1s 57ms/step - acc: 1.0000 - loss: 0.0031
▩ 신경망 활용 화면 개발 <로컬 주피터 노트북>
예제1. 신경망 모델을 내리는 코드
model.save('/content/drive/MyDrive/pretty/suji_model.keras')
<https://cafe.daum.net/oracleoracle/SmRD/404> <--- 전체 코드
예제4. 코렙에서 여러분들이 생성한 모델을 로컬 컴퓨터로 다운로드 받아
c 드라이브 밑에 data 폴더 밑에 둡니다.
예제5. 로컬 주피터 노트북에서 다운 받은 모델을 불러옵니다.
from tensorflow.keras.models import load_model # 만들어진 모델을 불러오는 함수
new_model = load_model('c:\\\\data\\\\suji_model.keras')
new_model # built=True
예제6. 사진 한장을 모델에 넣고 잘 예측하는지 확인합니다.
<https://cafe.daum.net/oracleoracle/SmRD/399>
#0. 신경망에 넣어서 맞추고 싶은 사진을 선택합니다.
file_path='C:\\\\image_all\\\\1.jpg'
#※ 주의사항 : 경로에 한글이 포함되어 있으면 안됩니다.
#1. 필요한 패키지를 불러옵니다.
import tensorflow as tf
import cv2
# 설명: cv2 가 없다고 나오면 다음과 같이 설치합니다.
#!pip install opencv-python
#2. 이미지를 숫자로 변환합니다.
img = cv2.imread(file_path) # 이미지를 숫자로 변환하는 코드
img
#3. 32 x 32 로 reshape 합니다.
import matplotlib.pyplot as plt
resize_img = cv2.resize( img, (32, 32), interpolation = cv2.INTER_CUBIC)
# 설명: 어제 만들었던 신경망이 학습한 사진들이 32x32 로 학습 했기 때문에
# 예측할 사진도 32x32로 resize 해줘야합니다.
# 4. 학습 시킨 모델 불러오는 코드
from tensorflow.keras.models import load_model
new_model = load_model('c:\\\\data10\\\\suji_model.h5')
#5. 리사이즈한 사진을 4차원으로 변경하고 정규화 작업을 수행
x4 = tf.reshape(resize_img,(1,32,32,3))
x4 = x4/255 # 정규화
#6. 모델에 이미지 넣고 예측을 합니다.
results = new_model.predict(x4)
a= np.argmax(results) # [0.6, 0.4] ---> 0, [ 0.2, 0.8 ] ---> 1
print(a)
#7. 0번이면 '수지', 1번이면 '설현' 으로 매칭해줍니다.
target_dict = {
0: '수지',
1: '설현'
}
print( target_dict[a] )
#8. 시각화 합니다.
import cv2
import matplotlib.pyplot as plt
# 이미지 파일을 읽어옵니다.
image = cv2.imread(file_path)
# 이미지를 BGR에서 RGB로 변환합니다.
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# 이미지를 시각화합니다.
plt.imshow(image)
plt.axis('off') # 축과 눈금 숨기기
plt.show()
예제7. 화면 개발을 위한 패키지들을 임폴트해서 오류가 나는지 확인합니다.
<https://cafe.daum.net/oracleoracle/SmRD/400>
# 게임화면 또는 특정 목적의 사용자 인터페이스를 구현 할 수 있는 tkinter 모듈을 임폴트 받습니다.
import tkinter as tk
from tkinter import filedialog
from tkinter import *
import numpy as np
# 이미지 데이터 전처리하는 모듈과 텐써 플로우 케라스 load_model 모듈을 임폴트 합니다.
from PIL import ImageTk, Image
import numpy as np
from keras.models import load_model
import cv2
# 화면을 띄웁니다.
top=tk.Tk() # tkinter 의 Tk 클래스를 이용해서 top 이라는 객체를 만듭니다.
top.geometry('800x600') # 사용자 화면 가로 세로 사이즈를 지정합니다.
top.title('수지와 설현 분류 Classification') # 맨 위에 막대에 제목을 적어줍니다.
top.configure(background='#CDCDCD') # 맨위에 막대에 색깔을 회색으로 지정합니다.
label=Label(top,background='#CDCDCD', font=('arial',15,'bold'))
sign_image = Label(top)
def classify(file_path):
#1. 필요한 패키지를 불러옵니다.
import tensorflow as tf
import cv2
#2. 이미지가 있는 위치를 지정합니다.
img = cv2.imread(file_path) # 이미지를 숫자로 변환하는 코드
#img = cv2.bitwise_not(img)
#3. 28x 28 로 reshape 합니다.
import matplotlib.pyplot as plt
resize_img = cv2.resize( img, (32, 32), interpolation = cv2.INTER_CUBIC)
#4. 다음 코드를 이용해서 흑백으로 변경합니다.
import numpy as np
#x2 =tf.image.rgb_to_grayscale(resize_img)
# 5. 학습 시킨 모델 불러오는 코드
from tensorflow.keras.models import load_model
new_model = load_model('c:\\\\data100\\\\suji_model.h5')
x4 = tf.reshape(resize_img,(1,32,32,3)) # 컬러 사진을 인식할 수 있게 사이즈 설정
x4 = x4/255 # 정규화
results = new_model.predict(x4)
a= np.argmax(results)
#7. 9번의 상품이 뭔지 확인하기
target_dict = {
0: '수지',
1: '설현'
}
sign = target_dict[a]
label.configure(foreground='#011638', text=sign)
def show_classify_button(file_path): # 분류하는 버튼을 구현하는 함수
classify_b=Button(top,text="Classify Image",
command=lambda: classify(file_path), padx=10,pady=5)
classify_b.configure(background='#364156', foreground='white',font=('arial',10,'bold'))
classify_b.place(relx=0.79,rely=0.46)
def upload_image(): # 이미지를 업로드하는 버튼을 구현하는 함수
try:
file_path=filedialog.askopenfilename()
uploaded=Image.open(file_path)
uploaded.thumbnail(((top.winfo_width()/2.25),(top.winfo_height()/2.25)))
im=ImageTk.PhotoImage(uploaded)
sign_image.configure(image=im)
sign_image.image=im
label.configure(text='')
show_classify_button(file_path)
except:
pass
# 위에서 만든 함수들을 가지고 실행하는 코드들
upload=Button(top,text="Upload an image",command=upload_image,padx=10,pady=5)
upload.configure(background='#364156', foreground='white',font=('arial',10,'bold'))
upload.pack(side=BOTTOM,pady=50)
sign_image.pack(side=BOTTOM,expand=True)
label.pack(side=BOTTOM,expand=True)
heading = Label(top, text="수지와 설현 분류",pady=20, font=('arial',20,'bold'))
heading.configure(background='#CDCDCD',foreground='#364156')
heading.pack()
top.mainloop()