인공지능

tensor flow hub 사용하기.

쿠와와 2020. 12. 20. 16:38
# Day_33_02_tfhub.py
import tensorflow as tf
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import PIL.Image as Image
import tensorflow_hub as hub
from tensorflow.keras.preprocessing.image import ImageDataGenerator


# 오늘의 핵심 -> 안되는 컴터는 껏다 켜기 -> 접근 권한? 때문일 수도 있음
# mobilenet_v2      사용 방법
def get_image_classifier():
    url = 'https://tfhub.dev/google/tf2-preview/mobilenet_v2/classification/4'

    model = tf.keras.Sequential()
    model.add(tf.keras.layers.Input(shape=[224, 224, 3]))
    model.add(hub.KerasLayer(url))
    model.summary()

    labels_path = tf.keras.utils.get_file(
        'ImageNetLabels_get.txt', url, cache_dir='.', cache_subdir='data'
    )

    labels = open(labels_path).read().splitlines()
    # labels = open(labels_path).read().split()       # -> label에 공백이 들어간 것을 나눠버림 ( 두단어로된 label나눔 )
    # labels = open(labels_path).read().split('\n')     # 에러 마지막에 빈칸이 생김
    # labels = open(labels_path).readlines()        # 개행 문자 포함 불편
    # labels = [w.strip() for w in labels]        # 양쪽 공백을 없애주는 strip 함수
    # print(labels)           # ['background', 'tench', 'goldfish', ...]

    return model, np.array(labels)


def classify_image():
    img_url = 'https://storage.googleapis.com/download.tensorflow.org/example_images/grace_hopper.jpg'
    img_path = tf.keras.utils.get_file('grace_hopper.jpg', img_url)
    print(img_path)     # C:\Users\82103\.keras\datasets\grace_hopper.jpg

    # 이미지를 open해서 resize 했음
    img_hopper = Image.open(img_path).resize([224, 224])
    # print(img_hopper)       # <PIL.Image.Image image mode=RGB size=224x224 at 0x7F983C17BC50>

    # plt.imshow(img_hopper)
    # plt.show()

    array_hopper = np.array(img_hopper)
    print(array_hopper.shape)   # (224, 224, 3)

    plt.subplot(1, 2, 1)
    plt.title('original')
    plt.imshow(array_hopper)

    print(np.min(array_hopper), np.max(array_hopper))       # 0 255

    # minmax scaling
    scaled_hopper = array_hopper / 255      # (0~1 사이의 숫자로) RGB 결과는 동일함
    # scaled_hopper = array_hopper / 510          # 어둡게 그려짐   RGB 0~0.5로 낮아져서 어두워지는 것
    # scaled_hopper = array_hopper / 127          # 밝게 그려짐 왜? ->1을 넘어서고 어떤 건 넘지 않음 흰색에 가까워짐

    model, labels = get_image_classifier()

    # 기법 데이터
    # CNN  이미지 1장 (3차원) -> 여러개 4차원
    # RNN  시계열 1개 (2차원) -> 여러개 3차원
    # 그래서 밑에 4차원으로 바꿔야함
    # preds = model.predict([array_hopper]) # error -> list에 오브젝트가 하나 들어간 걸로 나타냄
    # preds = model.predict(array_hopper[np.newaxis]) -> 이거 또는 아래 코드 써야함
    preds = model.predict(array_hopper.reshape(1, 224, 224, 3))
    print(preds.shape)      # (1, 1001)
    preds_arg = np.argmax(preds[0])
    print(preds_arg, labels[preds_arg])            # 722   pillow   -> 엉뚱한 결과

    preds = model.predict(scaled_hopper.reshape(1, 224, 224, 3))    #
    preds_arg = np.argmax(preds[0])
    print(preds_arg, labels[preds_arg])            # 653 military uniform -> 올바른 결과

    plt.subplot(1, 2, 2)
    plt.title('scaled: {}'.format(labels[preds_arg]))
    plt.imshow(scaled_hopper)
    plt.show()


# 정확도를 구하지 않는 이유?? generator을 사용해서 32개를 예측하는 프로그램 구성
def classify_image_by_generator():
    img_url = 'https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz'
    img_path = tf.keras.utils.get_file('flower_photos', img_url, untar=True)    # 압축 풀기 까지
    print(img_path)         # C:\Users\82103\.keras\datasets\flower_photos

    # 이미지 증강은 의미가 없음 그냥 데이터 32개를 예측만 할거임
    data_gen = ImageDataGenerator(rescale=1 / 255)

    batch_size = 32
    # 3가지 방법 -> (x,y), pandas, 폴더에 있는것
    # 우리 폴더 안에 있는 25000개의 데이터를 무제한으로 가져옴 -> 조심해야함
    data_flow = data_gen.flow_from_directory(
        img_path,               # 여기서 사진 가져옴
        batch_size=batch_size,  # 한번에 32개 가져올 것임
        target_size=(224, 224),  # resize 기능을 제공해줌
        class_mode='sparse',  # "categorical"(ont_hot), "binary", "sparse"(단순),
    )

    # for take in data_flow:
    #     print(type(take), len(take))        # <class 'tuple'> 2

    # for xx, yy in data_flow:            # 이미지 32개 , 어떤 레이블인지 알려주는 것
    #     print(xx.shape, yy.shape)        # (32, 224, 224, 3) (32,)

    # 이미지, label
    xx, yy = data_flow.next()       # 1번째 데이터 갯수는 32개

    model, labels = get_image_classifier()
    # list 배열이라서 에러 생김
    labels = np.array(labels)

    preds = model.predict(xx)
    print(preds.shape)              # (32, 1001)

    preds_arg = np.argmax(preds, axis=1)
    print(preds_arg)            # [490 305 717 986 310 ...]
    print(labels[preds_arg])    # ['chainlink fence' 'leaf beetle' 'picket fence' 'daisy'...]
    print(yy[:5])               # [0. 2. 1. 1. 3.]
    # 이결과를 보니 y의 값으로 결과를 예측할 수 없다. -> 정확도를 계산할 수 없음

    # 예측결과를 한줄에 8개씩 4줄 피겨 1개에 그려보자.
    # 예측에 사용한 이미지 출력 + 예측한 레이블 출력
    for i, (img, pred) in enumerate(zip(xx, preds_arg)):
        print(i, img.shape, pred)
        plt.subplot(4, 8, i+1)
        plt.title(labels[pred])
        plt.axis('off')
        plt.imshow(img)     # -> 대부분 꽃 그림이 나옴 데이지를 학습했으니깐

    plt.show()


# classify_image()
classify_image_by_generator()