從本機圖片建立模型的簡單範例
以下為從classify資料夾內載入圖片並建構分類模組的範例。圖片資料夾的結構如下:
其中daisy、dandelion、roses、sunflowers、tulips為標籤名稱,在各個資料夾內為圖片
然後使用 image_dataset_from_directory
函數載入圖片,需要傳遞以下參數:
- directory:包含圖片的目錄。
- labels:標籤的名稱。預設情況下,每個圖片所在的子目錄將被當作標籤。
- class_names:標籤的名稱列表。
- label_mode:標籤的格式。可以是 ‘int’(預設值)、’binary’ 或 ‘categorical’。
- batch_size: 用於指定每個批次中包含的圖片數量。
在載入圖片時,tf.keras.utils.image_dataset_from_directory 函數會使用 RGB 色彩空間。
tf.keras.utils.image_dataset_from_directory
函數中的 seed 參數用於設置隨機數生成器的種子。
如果指定了 seed 參數,則在載入資料集時,將使用指定的種子初始化隨機數生成器,這樣可以保證每次載入資料集的順序都是一致的。
# TensorFlow and tf.keras import tensorflow as tf import pathlib # Helper libraries import numpy as np import matplotlib.pyplot as plt from keras.callbacks import Callback print(tf.__version__) batch_size = 32 img_height = 150 img_width = 150 data_dir = pathlib.Path('flower_photos') # 從資料集中取出訓練資料,需要將 subset 參數設置為 'training'。 train_ds = tf.keras.utils.image_dataset_from_directory( data_dir, validation_split=0.2, subset="training", seed=123, image_size=(img_height, img_width), batch_size=batch_size) # 同時設定了 subset 參數和 validation_split 參數,則會從資料集中取出指定的子集作為驗證集。 val_ds = tf.keras.utils.image_dataset_from_directory( data_dir, validation_split=0.2, subset="validation", seed=123, image_size=(img_height, img_width), batch_size=batch_size) class_names = train_ds.class_names print(class_names) image_batch, label_batch = next(iter(train_ds)) num_classes = len(class_names) model = tf.keras.Sequential([ # 對輸入的張量進行縮放。將輸入的張量除以 255,這將會將輸入的值縮放到 0 到 1 之間。 tf.keras.layers.Rescaling(1./255), tf.keras.layers.Conv2D(32, 3, activation='relu'), tf.keras.layers.MaxPooling2D(), tf.keras.layers.Conv2D(32, 3, activation='relu'), tf.keras.layers.MaxPooling2D(), tf.keras.layers.Conv2D(32, 3, activation='relu'), tf.keras.layers.MaxPooling2D(), tf.keras.layers.Flatten(), tf.keras.layers.Dense(128, activation='relu'), tf.keras.layers.Dense(num_classes) ]) model.compile( optimizer='adam', loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), metrics=['accuracy']) model.fit( train_ds, validation_data=val_ds, epochs=3 ) model.save('model.h5')
然後按下complier之後,會有下面的樣建模的資訊
因為我們在model.compile
的metrics選擇了accuracy,因此評估模型的評估方式會以accuracy作為標準
將資料集分割為訓練集和測試集
上面的程式碼我們呼叫了兩次image_dataset_from_directory
來分別載入訓練集和測試集
但也可以只載入一次,然後再將資料集分割為訓練集和測試集
範例程式如下
import tensorflow as tf # 建立圖片資料集 dataset = tf.keras.utils.image_dataset_from_directory( 'image_directory', labels='inferred', class_names=None, label_mode='int' ) # 計算資料集的大小 dataset_size = tf.data.experimental.cardinality(dataset).numpy() # 計算訓練集和測試集的大小 test_size = int(0.2 * dataset_size) train_size = dataset_size - test_size # 將資料集分割為訓練集和測試集 train_dataset = dataset.take(train_size) test_dataset = dataset.skip(train_size)
用 Keras 載入模型並預測答案
以下為一個簡單範例,使用keras.preprocessing.image.load_img所載入的圖片預設格式為 RGB 圖片
import numpy as np import tensorflow as tf from tensorflow import keras import os import re import pathlib # 載入模型 rank_model = keras.models.load_model('model.h5') # 讓模型輸出的機率值分布在0-1之間 probability_rank_model = tf.keras.Sequential([rank_model, tf.keras.layers.Softmax()]) class_names = ['daisy','dandelion','roses','sunflowers','tulips'] img = keras.preprocessing.image.load_img('./test.jpg', target_size=(150, 150)) if img is None: continue x = keras.preprocessing.image.img_to_array(img) x = np.expand_dims(x, axis=0) pred = probability_rank_model.predict(x)[0] print(path) top_inds = pred.argsort()[::-1][:5] if pred[top_inds[0]] > 0.8: print('result is: ' + class_names[top_inds[0]]) # 印出機率分布 for data in top_inds: print(' {:.3f} {}'.format(pred[data], class_names[data]))
上面是使用keras.preprocessing.image.load_img
來載入圖片
我們也可以使用OpenCV來載入圖片使用
# 使用 OpenCV 讀取圖片 image = cv2.imread('image.jpg') # 將圖片轉換為 RGB 格式 image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) image = PIL.Image.fromarray(image) x = keras.preprocessing.image.img_to_array(image) probability_rank_model.predict(x.tolist())
如何關掉預測時吐出的log
在使用 predict 方法進行預測時,Keras 模型可能會輸出一些訓練過程中的訊息,如果你想要避免輸出這些訊息,則可以在建立模型時設置 verbose 參數。
例如,如果你想要在預測時停止輸出訓練過程中的訊息,則可以在建立模型時使用以下代碼:
# 預測 predictions = model.predict(x_test, verbose=0)
這樣,在進行預測時就不會再輸出任何訓練過程中的訊息了。