Image Classification with Python

Peerayut Mongpaek
4 min readAug 10, 2020

--

Image Classification

คือการจำแนกประเภทของรูปภาพ โดยสิ่งที่ต้องมีคือข้อมูล โดยการป้อนข้อมูลเหล่านี่ให้กับคอมพิวเตอร์ของเราเอง โดยมีกระบวนการทำงานแบบ Convolutional Neural Network (CNN)
ในการทำงาน Image Classification ครั้งนี่เราจะใช้รูปผลไม้ 4 ประเภทในการจำแนก ได้แก่ แอปเปิ้ล,มะม่วง,กล้วย,องุ่น

ในการทำงาน Image Classification ครั้งนี่ จะมีผลไม้ทั้งหมด 10 ประเภท ได้แก่

แอปเปิ้ลแดง กล้วย ส้ม มะม่วง มะนาว มะเดื่อ ลิ้นจี่ มะละกอ ลูกแพร์ สละ

ผลไม้ต่างๆ

โดยในแต่ละ ผลไม้ จะมีรูป ทั้งหมด 100 รูปภาพ

ตัวอย่างผลไม้

ทำ Dataset เสร็จแล้ว จะเป็นการเขียนโค้ดแล้วโดยเราจะใช้ Jupyter notebook

!nvidia-smi -L
จะเห็นว่า GPU ของเรา

Config ให้ Tensorflow ใช้งาน GPU ด้วยคำสั่งดังต่อไปนี้

import tensorflow as tf
config = tf.compat.v1.ConfigProto()
config.gpu_options.allow_growth = True
sess = tf.compat.v1.Session(config=config)
print( 'Tensorflow Version:', tf.__version__)
print("GPU Available::", tf.config.list_physical_devices('GPU'))
เรามี physical GPU

Import Libary ต่างๆ ที่จำเป็นเข้ามา

import tensorflow as tf
import PIL
from tensorflow.keras import layers
import matplotlib.pyplot as plt
import numpy as np
import pickle as p
import plotly
from tensorflow.keras.models import load_model
from tensorflow.keras.models import model_from_json
import plotly.graph_objs as go
from tensorflow import keras
from tensorflow.keras.models import Sequential
Libary ต่างๆ

เตรียมชุดของข้อมูล

import pathlib
datadir = "D:/dataSet/training" #path ของ dataset
data = pathlib.Path(datadir)
image_count = len(list(data.glob('*/*.jpg'))) #ขนาดของ dataset
print("จำนวนรูปภาพที่มี .jpg : ",image_count)
batch_size = 15
img_height = 150
img_width = 150

Batch_size เป็นการกำหนดขนาดของแต่ละการอ่านข้อมูลครับ

img_height ความสูงของรูปภาพแต่ละรูป

img_width ความกว้างของรูปภาพแต่ละรูป

train = tf.keras.preprocessing.image_dataset_from_directory(
data,
validation_split=0.2, #sแบ่งข้อมูล เพื่อ training 80% และ validate 20%
subset="training",
seed=123,
image_size=(img_height, img_width),
batch_size=batch_size)
val = tf.keras.preprocessing.image_dataset_from_directory(
data,
validation_split=0.2,
subset="validation",
seed=123,
image_size=(img_height, img_width),
batch_size=batch_size)

train คือ Dataset ที่จะนำมา Train นั่นเอง ซึ่งจะเห็น validation_split = 0.2 หมายความว่าเราจะแบ่ง Dataset มาเพื่อ Train 80% และแบ่ง 20% ไปใช้ในการ Validate

ต่อมาเราจะมาดูว่า Dataset

class_names = train_ds.class_names
print(class_names)
ผลไม้ทั้ง 10

ให้แสดงผลรูปภาพ

import matplotlib.pyplot as plt
plt.figure(figsize=(16, 16))
for images, labels in train.take(1):
for i in range(9):
ax = plt.subplot(3, 3, i + 1)
plt.imshow(images[i].numpy().astype("uint8"))
plt.title(class_names[labels[i]])
plt.axis("off")
รูปที่แสดง

เช็คข้อมูลของ Dataset

for image_batch, labels_batch in train:  
print(image_batch.shape)
print(labels_batch.shape)
break
เช็คข้อมูลของ Dataset

เราจะทำการนำรูปภาพทั้งหมดมา Normalization

normalization_layer = layers.experimental.preprocessing.Rescaling(1./255) 
normalized_ds = train.map(lambda x, y: (normalization_layer(x), y))
image_batch, labels_batch = next(iter(normalized_ds))
first_image = image_batch[0]
print(np.min(first_image), np.max(first_image))

Model

num_classes = 10
epochs=100
model = Sequential([
layers.experimental.preprocessing.Rescaling(1./255, input_shape=(img_height, img_width, 3)),
layers.Conv2D(16, 3, padding='same', activation='relu'),
layers.MaxPooling2D(),
layers.Conv2D(32, 3, padding='same', activation='relu'),
layers.MaxPooling2D(),
layers.Conv2D(64, 3, padding='same', activation='relu'),
layers.MaxPooling2D(),
layers.Flatten(),
layers.Dense(128, activation='relu'),
layers.Dense(num_classes)
])

epochs คือ จำนวนครั้งที่เราจะ Train

num_class จำนวน class (ผลไม้ทั้ง10)

model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
model.summary()
CNN

เป็นการบอกว่าให้โชว์ accuracy หรือค่าความแม่นยำ

his = model.fit(
train,
validation_data=val,
epochs=epochs
)
Train เป็นจำนวน epochs

Save Model

with open('history_model', 'wb') as file:
p.dump(his.history, file)

filepath='model1.h5'
model.save(filepath)
filepath_model = 'model1.json'
filepath_weights = 'weights_model.h5'
model_json = model.to_json()
with open(filepath_model, "w") as json_file:
json_file.write(model_json)

model.save_weights('weights_model.h5')
print("Saved model to disk")

Load Model

with open('history_model', 'rb') as file:
his = p.load(file)

h1 = go.Scatter(y=his['loss'],
mode="lines", line=dict(
width=2,
color='blue'),
name="loss"
)
h2 = go.Scatter(y=his['val_loss'],
mode="lines", line=dict(
width=2,
color='red'),
name="val_loss"
)

data = [h1,h2]
layout1 = go.Layout(title='Loss',
xaxis=dict(title='epochs'),
yaxis=dict(title=''))
fig1 = go.Figure(data, layout=layout1)
plotly.offline.iplot(fig1, filename="testMNIST")
predict_model = load_model(filepath)
predict_model.summary()
with open(filepath_model, 'r') as f:
loaded_model_json = f.read()
predict_model = model_from_json(loaded_model_json)
predict_model.load_weights(filepath_weights)
print("Loaded model from disk")

Prediction

mport requests
from IPython.display import Image
from io import BytesIO
test_path = ('D:/w2.jpg')
img = keras.preprocessing.image.load_img(
test_path, target_size=(img_height, img_width)
)
img_array = keras.preprocessing.image.img_to_array(img)
img_array = tf.expand_dims(img_array, 0) # Create a batch
predictions = predict_model.predict(img_array)
score = tf.nn.softmax(predictions[0])
print("Lychee",score[0],"Pear",score[1],"apple",score[2],"banana",score[3],"fig",score[4],"lemon",score[5],"mango",score[6],"orange",score[7],"papaya",score[8],"waive",score[9])
display(Image(filename=test_path,width=180, height=180))
if score[0]==np.max(score) :
fruit = "Lychee"
elif score[1]==np.max(score) :
fruit = "Pear"
elif score[2]==np.max(score) :
fruit = "apple"
elif score[3]==np.max(score) :
fruit = "banana"
elif score[4]==np.max(score) :
fruit = "fig"
elif score[5]==np.max(score) :
fruit = "lemon"
elif score[6]==np.max(score) :
fruit = "mango"
elif score[7]==np.max(score) :
fruit = "orange"
elif score[8]==np.max(score) :
fruit = "papaya"
elif score[9]==np.max(score) :
fruit = "waive"
print(
"AI {} ด้วยความมั่นใจ {:.2f}%."
.format(fruit, 100 * np.max(score))
)

--

--

No responses yet