나른한 코딩 생활

[25일차] ABC 부트캠프 정규화 / YOLO / 얼굴 학습 본문

ABC 부트캠프

[25일차] ABC 부트캠프 정규화 / YOLO / 얼굴 학습

GerHerMo 2024. 7. 28. 18:36

오늘은 크게 3가지의 프로젝트를 해보면서 인공지능 수업의 대단원을 마치도록 하겠다


정규화

# 24.07.26. 금요일
import FinanceDataReader as fdr
import numpy as np
from matplotlib import pyplot as plt

# print(fdr.DataReader(symbol='005930',start='01/01/2016', end= '12/23/2020'))
samsung = fdr.DataReader(symbol='005930',start='01/01/2016', end= None)
print(samsung)
print(samsung.columns)

open_values = samsung[['Open']]
print(open_values)
print(open_values.shape)
print(f'최솟값 : {open_values.min()}') # 최솟값 : 0
print(f'최댓값 : {open_values.max()}') # 최댓값 : 90300
# 학습시키기 너무 어려움 -> 정규화

# 정규화
# MinMaxScalere : 최소, 최대 정규화
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler(feature_range=(0,1)) # 0 ~ 90300 -> (0, 1)
scaled_open_values = scaler.fit_transform(open_values)
print(scaled_open_values)
print(scaled_open_values.shape) # (2107, 1)

## 테스트, 훈련데이터 : 테스트 200개
TEST_SIZE = 200
train_data = scaled_open_values[:-TEST_SIZE]
test_data = scaled_open_values[-TEST_SIZE:]
print(train_data)
print(train_data.shape) # (1907, 1)
print(test_data)
print(test_data.shape) # (200, 1)


## 훈련데이터 생성 : Tensor 3 인 데이터를 넣어줘야 함
def make_feature(open_values, windowing) -> tuple:
    train = list()
    test = list()
    for i in range(len(open_values) - windowing):
        train.append(open_values[i:i+windowing])
        test.append(open_values[i+windowing])
    print(train)
    print(test)
    return (np.array(train), np.array(test))

(X_train, y_train) = make_feature(train_data,windowing=30)
print(f"X_train: {X_train}") # Tensor 가 3인 형태로 출력
print(f"X_train.shape: {X_train.shape}") # X_train.shape: (1877, 30, 1)
print(f"y_train: {y_train}") # Tensor 가 2인 형태로 출력
print(f"y_train.shape: {y_train.shape}") # y_train.shape: (1877, 1)

# LSTM ( RNN 문제를 해결한 모델 ) 만들기
from keras.models import Sequential
from keras.layers import Dense, LSTM, Input
# 버전이 바뀌어서 빨간줄이 나오는듯 하다

model = Sequential([],name="LSTM_MODEL")
model.add(Input(shape=(X_train.shape[1],1), name='INPUT'))
# LSTM units=32 : cell 이 32개 ( 메모리갯수 )
model.add (LSTM(units=32, activation='tanh', return_sequences=True, name='LAYER1'))
model.add(LSTM(units=16, activation='tanh', return_sequences=False, name='LAYER2'))
# return_sequence = False : 시퀀스를 출력으로 보내겠다
model.add(Dense(units=1,name='OUTPUT'))
model.summary()

# 모델학습하기
# model.compile(loss='mse',optimizer='adam')
# model.fit(X_train,y_train,epochs=100, batch_size=16,verbose=2)
# verbose : 출력할때 몇단계로 출력하는지 보여준다 Default 값은 0
# model.save('LSTM_MODEL.keras')
import tensorflow as tf
model2 = tf.keras.models.load_model('LSTM_MODEL.keras')

# 학습예측하기
(X_test, y_test) = make_feature(open_values=test_data,windowing=30)
predictions = model2.predict(X_test)
print(predictions)
print(predictions.shape) # (170, 1)

# 그래프를 그려서 예측이 잘 따라왔는지 확인해보기
plt.figure(figsize=(10,8))
plt.plot(y_test,label='STOCK PRICE', color='blue')
plt.plot(predictions,label='PREDICTIONS', color='red')
plt.legend()
plt.show()

예측값 predictions가 그래프를 잘 따라가는 모습이다


Yolo 모델 사용

import cv2
import numpy as np

# 모델 및 설정
model = 'yolov3.weights' # yolo 모델 사용
config = 'yolov3.cfg'
class_labels = 'coco.names'
confThreshold = 0.5
nmsThreshold = 0.4

# 테스트 이미지들
img_files = ['bicycle.jpg','car.jpg','dog.jpg','kite.jpg','person.jpg','sheep.jpg']

# 모델 읽어오기
net = cv2.dnn.readNet(model, config)

# 클래스들의 이름을 출력해보기
classes = []
with open(file=class_labels, mode='rt') as f: # mode= 'read text type'
    classes = f.read().split('\n')[:-1] # -1 : 마지막 공백 행 하나 제거
print(classes)

# 랜덤하게 컬러를 화면에 보여준다. (텍스트,윈도우)
colors = np.random.uniform(0,255,size=(len(classes),3))

# 출력할 이름들
layers_names = net.getLayerNames()
# output_layers = [ 'yolo_82', 'yolo_94', 'yolo_106' ]
output_layers = [layers_names[i-1] for i in net.getUnconnectedOutLayers()]

for f in img_files:
    img = cv2.imread(f)
    blob = cv2.dnn.blobFromImage(image=img,scalefactor=1/255.,size=(416,416),
                                 swapRB=True,crop=False)
    net.setInput(blob)
    outs = net.forward(output_layers)

    (h,w) = img.shape[:2]
    class_ids = list()
    confidences = [] # 신뢰도
    boxes = [] # 윈도우 박스

    for out in outs:
        for detection in out:
            scores = detection[5:]
            class_id = np.argmax(scores)
            confidence = scores[class_id]
            if confidence > confThreshold:
                # 박스를 그려준다
                cx= int(detection[0]*w)
                cy=int(detection[1]*h)
                bw=int(detection[2]*w)
                bh=int(detection[3]*h)

                sx = int(cx-bw/2)
                sy = int(cy-bh/2)
                boxes.append([sx,sy,bw,bh])
                confidences.append(float(confidence))
                class_ids.append(int(class_id))
    indices = cv2.dnn.NMSBoxes(boxes,confidences,confThreshold,nmsThreshold)

    for i in indices:
        (sx,sy,bw,bh)=boxes[i]
        label = f'{classes[class_ids[i]]} : {confidences[i]:.2}'
        color = colors[class_ids[i]]
        cv2.rectangle(img,(sx,sy,bw,bh),color,2)
        cv2.putText(img,label,(sx,sy-10),cv2.FONT_HERSHEY_SIMPLEX,
                    0.7,color,2,cv2.LINE_AA) # AA : 안티앨리어싱
    (t, _) = net.getPerfProfile()
    label = "Inference time : %2.f ms" % (t*1000.0 / cv2.getTickFrequency())
    # 이미지를 추론하는데 거리는 시간
    cv2.putText(img,label,(10,30),cv2.FONT_HERSHEY_SIMPLEX,
                0.7,(0,0,255),1,cv2.LINE_AA)
    cv2.imshow('IMAGE',img)
    cv2.waitKey(0)
cv2.destroyAllWindows()

예시 이미지 중 하나로서, 학습된 모델들은 잘 가려냄
배경과 혼돈일 올 수 있지만 sheep 개체를 잘 찾아내는 모습


FaceDetector

 

import cv2
import numpy as np

face_images = list() # 얼굴을 저장할 리스트 파일
for i in range(15):
    file = './faces/'+'img{0:02d}.jpg'.format(i+1)
    img = cv2.imread(file)
    img = cv2.resize(img,(64,64))
    img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB) # RGB 로 바꿔주기
    face_images.append(img)

from matplotlib import pyplot as plt
def plot_images(n_row:int, n_col:int, images:list[np.ndarray]) -> None:
    fig = plt.figure()
    (fig,ax) = plt.subplots(nrows=n_row,ncols=n_col,figsize=(n_col,n_row))
    for i in range(n_row):
        for j in range(n_col):
            if n_row <= 1:
                axis = ax[j]
            else:
                axis = ax[i, j]
                axis.get_xaxis().set_visible(False)
                axis.get_yaxis().set_visible(False)
                axis.imshow(images[i*n_col+j])
    return None

plot_images(3,5,face_images)



X = face_images + animal_images
y=[[1,0]]* len(face_images) + [[0,1]] * len(animal_images)

print(np.array(X))
print(np.array(y))

# 수정
X = np.array(X)
y = np.array(y)

# CNN 모델 만들기
import tensorflow as tf
model = tf.keras.models.Sequential([
    tf.keras.layers.Input(shape=(64,64,3)),
    tf.keras.layers.Conv2D(kernel_size=(3,3),filters=32),
    tf.keras.layers.MaxPooling2D((2,2),strides=2),
    tf.keras.layers.Conv2D(kernel_size=(3,3),filters=32),
    tf.keras.layers.MaxPooling2D((2,2),strides=2),
    tf.keras.layers.Conv2D(kernel_size=(3,3),filters=32),
    tf.keras.layers.MaxPooling2D((2,2),strides=2),
    tf.keras.layers.Conv2D(kernel_size=(3,3),filters=32),
    tf.keras.layers.MaxPooling2D((2,2),strides=2), # Conv2D, MaxPooling2D : 4번 반복
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(units=128,activation='relu'),
    tf.keras.layers.Dense(units=16,activation='relu'),
    tf.keras.layers.Dense(units=2,activation='softmax')
],name='FACE_DETECTOR')

model.summary()
# model.compile(optimizer='adam',loss='categorical_crossentropy',
#               metrics=['accuracy'])
# history = model.fit(X,y,epochs=1_000)
# model.save('FACE_CNN.keras')

# 예제파일을 이용해서 이미지 테스트해보기
example_images = list()
for i in range(10):
    file = './examples/'+'img{0:02d}.jpg'.format(i+1)
    img = cv2.imread(file)
    img = cv2.resize(img,(64,64))
    img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB) # RGB 로 바꿔주기
    example_images.append(img)

example_images = np.array(example_images)
plot_images(n_col=5,n_row=2,images=example_images)
plt.show()

model2 = tf.keras.models.load_model('FACE_CNN.keras')
predict_images = model2.predict(example_images)

fig = plt.figure()
fig,ax = plt.subplots(2,5,figsize=(10,4))
for i in range(2):
    for j in range(5):
        axis = ax[i,j]
        axis.get_xaxis().set_visible(False)
        axis.get_yaxis().set_visible(False)
        if predict_images[i*5 + j][0] > 0.5: #  정확도를 높이기 위해서는 해당 값을 변경
            axis.imshow(example_images[i*5 + j])

plt.show()

학습시킬 사람 얼굴 이미지 15장

animal_images = list()
for i in range(15):
    file = './animals/'+'img{0:02d}.jpg'.format(i+1)
    img = cv2.imread(file)
    img = cv2.resize(img,(64,64))
    img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB) # RGB 로 바꿔주기
    animal_images.append(img)

plot_images(3,5,animal_images)

학습시킬 동물 이미지 15장

X = face_images + animal_images
y=[[1,0]]* len(face_images) + [[0,1]] * len(animal_images)

print(np.array(X))
print(np.array(y))

# 수정
X = np.array(X)
y = np.array(y)

# CNN 모델 만들기
import tensorflow as tf
model = tf.keras.models.Sequential([
    tf.keras.layers.Input(shape=(64,64,3)),
    tf.keras.layers.Conv2D(kernel_size=(3,3),filters=32),
    tf.keras.layers.MaxPooling2D((2,2),strides=2),
    tf.keras.layers.Conv2D(kernel_size=(3,3),filters=32),
    tf.keras.layers.MaxPooling2D((2,2),strides=2),
    tf.keras.layers.Conv2D(kernel_size=(3,3),filters=32),
    tf.keras.layers.MaxPooling2D((2,2),strides=2),
    tf.keras.layers.Conv2D(kernel_size=(3,3),filters=32),
    tf.keras.layers.MaxPooling2D((2,2),strides=2), # Conv2D, MaxPooling2D : 4번 반복
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(units=128,activation='relu'),
    tf.keras.layers.Dense(units=16,activation='relu'),
    tf.keras.layers.Dense(units=2,activation='softmax')
],name='FACE_DETECTOR')

model.summary()
# model.compile(optimizer='adam',loss='categorical_crossentropy',
#               metrics=['accuracy'])
# history = model.fit(X,y,epochs=1_000)
# model.save('FACE_CNN.keras')

# 예제파일을 이용해서 이미지 테스트해보기
example_images = list()
for i in range(10):
    file = './examples/'+'img{0:02d}.jpg'.format(i+1)
    img = cv2.imread(file)
    img = cv2.resize(img,(64,64))
    img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB) # RGB 로 바꿔주기
    example_images.append(img)

example_images = np.array(example_images)
plot_images(n_col=5,n_row=2,images=example_images)
plt.show()

model2 = tf.keras.models.load_model('FACE_CNN.keras')
predict_images = model2.predict(example_images)

fig = plt.figure()
fig,ax = plt.subplots(2,5,figsize=(10,4))
for i in range(2):
    for j in range(5):
        axis = ax[i,j]
        axis.get_xaxis().set_visible(False)
        axis.get_yaxis().set_visible(False)
        if predict_images[i*5 + j][0] > 0.5: #  정확도를 높이기 위해서는 해당 값을 변경
            axis.imshow(example_images[i*5 + j])

plt.show()

예시 이미지(Test용) 10장

 

위 이미지들 중 사람이라고 판단되는(학습이 잘 되었다면) 이미지만 출력하도록 한다

중간 개, 불가사리 또한 사람 얼굴로 인식 -> 완벽하진 않다 -> 학습할 데이터가 부족