Study/class note

딥러닝 / GoogleLeNet(인셉션), ResNet50 + 사용자 인터페이스

chanzae 2022. 5. 1. 15:40

다른 cnn모델은 한번에 한종류의 필터(5x5)만 사용. 그런데 구글에서 만든 인셉션은 1x1, 3x3, 5x5필터의 크기가 다른 세가지 필터를 병렬로 사용.

이렇게 되면 한가지 필터만 사용하는 것보다 물체의 특징을 잡아내기가 더 좋은 장점이 있다는 아이디어를 가지고 구현을 한 신경망.

사과 이미지의 경우 하나의 화면에 사과 한 개가 크게 다 차지한 경우도 있고 사과 여러개가 하나의 이미지에 있는 경우가 있는데 이럴 경우에 필터의 사이즈를 한가지로 하지 않고 다양하게 하게 되면 사과가 하나가 있든 여러개가 있든 사과 이미지의 특징을 필터 사이즈 한개보다는 더 잘 잡아내게 됩니다.

 

ㅇVGG 이외에 다른 유명한 신경망 설계도 가져오는 방법

1. 구글에서 만든 인셉션 - p.272

from tensorflow.keras.applications import *

xception = Xception(weights = None, input_shape = (32,32,3), include_top = False)

 

2. Resnet 신경망 - p.272

: 신경망이 깊어질 때 생길 수 있는 문제점인 기울기 소실문제를 해결한 신경망

from tensorflow.keras.applications import *
resnet50 = ResNet50(weights = 'imagenet', input_shape = (32,32,3), include_top = False)

 

3. mobilenet : 가벼우면서도 성능이 아주 좋은 신경망

from tensorflow.keras.applications import *
model = MobileNet(weights = 'imagenet', input_shape = (32,32,3), include_top = False)

 

문제206. 구글에서 만든 resnet50신경망으로 cifar10데이터를 학습 시키시오.

# resnet50을 사용해서 학습 시키기 실험
# 필요한 패키지 임폴트 받기
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPool2D, Dense, Flatten, BatchNormalization, Activation, Dropout
from tensorflow.keras.optimizers import Adam

from tensorflow.keras.applications import * 

#2. cifar10 데이터를 준비합니다.
# 데이터 준비하기
from tensorflow.keras.datasets import cifar10
import numpy as np

(x_train, y_train), (x_test, y_test) = cifar10.load_data()

# 데이터를 표준화 합니다. 
# 평균과 표준편차는 채널별로 구해줍니다. 

x_mean = np.mean(x_train, axis = (0, 1, 2))  # 평균값을 구합니다.
x_std = np.std(x_train, axis = (0, 1, 2))  # 표준편차를 구합니다. 

x_train = (x_train - x_mean) / x_std  # 훈련 데이터를 표준화 합니다.
x_test = (x_test - x_mean) / x_std # 테스트 데이터를 표준화 합니다. 

# 밑바닥 부터 시작하는 딥러닝 책에서는 min/max 정규화를 사용했었습니다. 
# 여기서는 표준화를 하고 있는데 vgg 라고 해서 꼭 표준화를 하는건 아닙니다. 
# min/max 정규화를 해도 됩니다. 

#3. 훈련 데이터를 검정 데이터로 나눕니다.
from sklearn.model_selection import train_test_split

x_train, x_val, y_train, y_val = train_test_split(x_train, y_train, test_size = 0.1, random_state = 777)

# 훈련 데이터의 일부를 떼서 테스트 데이터(검정 데이터)로 사용하면서 훈련 시킵니다.  
#4. resnet50 신경망을 가져옵니다.
# imagenet을 학습한 모델을 불러옵니다.
res_model = ResNet50(weights = 'imagenet', input_shape = (32, 32, 3), include_top = False)  # include_top = False 완전연결계층 알아서 분류 하겠음
res_model.summary()
#7.resnet50 신경망에 완전 연결계층을 붙입니다. 
model = Sequential()

# resnet50을 사용합니다.
model.add(res_model)

# 분류기를 직접 정의합니다.
model.add(Flatten())
model.add(Dense(256))
model.add(BatchNormalization())
model.add(Dropout(0.4))
model.add(Activation('relu'))
model.add(Dense(10, activation = 'softmax'))
#8. 모델을 설정합니다.
model.compile(optimizer = Adam(1e-4),  # 러닝레이트를 0.0001 로 지정하면서 Adam 을 쓰겠다고 합니다. 
             loss = 'sparse_categorical_crossentropy',
             metrics = ['acc'])

model.summary()

 

ㅇ 사진 한 장 넣고 예측하기

비행기(0), 자동차(1), 새(2), 고양이(3), 사슴(4), 개(5), 개구리(6), 말(7), 배(8), 트럭(9) 

# 사진한장 잘 맞추는지 확인하기 
import tensorflow as  tf
import cv2
from keras.models import load_model
from PIL import ImageTk,Image
import numpy as np

img_path = 'c:\\deep\\horse.jpg'
model = load_model('c:\\deep\\cifar10_model2.h5')

img = cv2.imread(img_path)  #이미지를 숫자로 변환
print(img.shape)

resize_img = cv2.resize(img, (32,32), interpolation = cv2.INTER_CUBIC)

image = np.expand_dims(resize_img, axis = 0)
image = np.array(image)
image = image / 255
results = model.predict(image, batch_size = 1)
a = np.argmax(results)
print(a)  #7  정답!
cifar_dict ={ 0:'비행기',
                 1: '자동차',
                 2: '새',
                 3: '고양이',
                 4: '사슴',
                 5: '개',
                 6: '개구리',
                 7: '말',
                 8: '배',
                 9: '트럭' } 

a = np.argmax(results)
print('신경망이 ' + cifar_dict[a] + '로 예측하였습니다.')

 

 

문제207. 사진 한장을 더 예측해보시오.

# 사진한장 잘 맞추는지 확인하기 
import tensorflow as  tf
import cv2
from keras.models import load_model
from PIL import ImageTk,Image
import numpy as np

img_path = 'c:\\deep\\deer.jpg'
model = load_model('c:\\deep\\cifar10_model2.h5')

img = cv2.imread(img_path)  #이미지를 숫자로 변환
print(img.shape)

resize_img = cv2.resize(img, (32,32), interpolation = cv2.INTER_CUBIC)

image = np.expand_dims(resize_img, axis = 0)
image = np.array(image)
image = image / 255
results = model.predict(image, batch_size = 1)
a = np.argmax(results)
print(a)
cifar_dict ={ 0:'비행기',
                 1: '자동차',
                 2: '새',
                 3: '고양이',
                 4: '사슴',
                 5: '개',
                 6: '개구리',
                 7: '말',
                 8: '배',
                 9: '트럭' } 

a = np.argmax(results)
print('신경망이 ' + cifar_dict[a] + '로 예측하였습니다.')
#신경망이 사슴로 예측하였습니다.

 

 

문제208. 모델을 쉽게 사용할 수 있도록 사용자 인터페이스를 생성하시오.

import tkinter as tk
from tkinter import filedialog
from tkinter import *
from PIL import ImageTk, Image
import numpy  as  np
from keras.models import load_model
import cv2

# 모델을 불러옵니다.

model = load_model('c:\\deep\\cifar10_model2.h5')

# 화면을 띄웁니다.

top=tk.Tk()
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):
    global label_packed
    #image = Image.open(file_path)
    #image = image.resize((32,32))
    image = cv2.imread(file_path) 
    resize_img = cv2.resize(image, (32 , 32), interpolation=cv2.INTER_CUBIC)
    image = numpy.expand_dims(resize_img, axis=0)
    image = numpy.array(image)
    image = image/255
    results = model.predict(image,batch_size=1)
    a = np.argmax(results)
    
    cifar_dict ={ 0:'비행기',
                   1: '자동차',
                   2: '새',
                   3: '고양이',
                   4: '사슴',
                   5: '개',
                   6: '개구리',
                   7: '말',
                   8: '배',
                   9: '트럭' } 
    
    sign = cifar_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="cifar10 데이터 분류 신경망",pady=20, font=('arial',20,'bold'))
heading.configure(background='#CDCDCD',foreground='#364156')
heading.pack()
top.mainloop()

 

반응형