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