基於Python實現的口罩佩戴檢測

專注的阿熊發表於2022-06-24

import warnings

# 忽視警告

warnings.filterwarnings('ignore')

import os

import matplotlib

import cv2 as cv

import numpy as np

import matplotlib.pyplot as plt

from tensorflow.keras.callbacks import ModelCheckpoint, ReduceLROnPlateau, EarlyStopping

from tensorflow.keras.applications.imagenet_utils import preprocess_input

from tensorflow.keras import backend as K

from tensorflow.keras.optimizers import Adam

K.image_data_format() == 'channels_last'

from keras_py.utils import get_random_data

from keras_py.face_rec import mask_rec

from keras_py.face_rec import face_rec

from keras_py.mobileNet import MobileNet

from tensorflow.keras.preprocessing.image import ImageDataGenerator

# 資料集路徑

basic_path = "./datasets/5f680a696ec9b83bb0037081-momodel/data/"

def letterbox_image(image, size):  # 調整圖片尺寸,返回經過調整的照片

     new_image = cv.resize(image, size, interpolation=cv.INTER_AREA)

     return new_image

read_img = cv.imread("test1.jpg")

print(" 調整前圖片的尺寸 :", read_img.shape)

read_img = letterbox_image(image=read_img, size=(50, 50))

print(" 調整前圖片的尺寸 :", read_img.shape)

def processing_data(data_path, height, width, batch_size=32, test_split=0.1):  # 資料處理, batch_size 預設大小為 32

     train_data = ImageDataGenerator(

             # 對圖片的每個畫素值均乘上這個放縮因子,把畫素值放縮到 0 1 之間有利於模型的收斂

             rescale=1. / 255,  

             # 浮點數,剪下強度(逆時針方向的剪下變換角度)

             shear_range=0.1,  

             # 隨機縮放的幅度,若為浮點數,則相當於 [lower,upper] = [1 - zoom_range, 1+zoom_range]

             zoom_range=0.1,

             # 浮點數,圖片寬度的某個比例,資料提升時圖片水平偏移的幅度

             width_shift_range=0.1,

             # 浮點數,圖片高度的某個比例,資料提升時圖片豎直偏移的幅度

             height_shift_range=0.1,

             # 布林值,進行隨機水平翻轉

             horizontal_flip=True,

             # 布林值,進行隨機豎直翻轉

             vertical_flip=True,

             # 0 1 之間浮動。用作驗證集的訓練資料的比例

             validation_split=test_split  

     )

     # 接下來生成測試集,可以參考訓練集的寫法

     test_data = ImageDataGenerator(

             rescale=1. / 255,

             validation_split=test_split)

     train_generator = train_data.flow_from_directory(

             # 提供的路徑下面需要有子目錄

             data_path,

             # 整數元組 (height, width) ,預設: (256, 256) 。 所有的影像將被調整到的尺寸。

             target_size=(height, width),

             # 一批資料的大小

             batch_size=batch_size,

             # "categorical", "binary", "sparse", "input" None 之一。

             # 預設: "categorical", 返回 one-hot 編碼標籤。

             class_mode='categorical',

             # 資料子集 ("training" "validation")

             subset='training',

             seed=0)

     test_generator = test_data.flow_from_directory(

             data_path,

             target_size=(height, width),

             batch_size=batch_size,

             class_mode='categorical',

             subset='validation',

             seed=0)

     return train_generator, test_generator

# 資料路徑

data_path = basic_path + 'image'

# 影像資料的行數和列數

height, width = 160, 160

# 獲取訓練資料和驗證資料集

train_generator, test_generator = processing_data(data_path, height, width)

# 透過屬性 class_indices 可獲得資料夾名與類的序號的對應字典。

labels = train_generator.class_indices

print(labels)

# 轉換為類的序號與資料夾名對應的字典

labels = 外匯跟單gendan5.comdict((v, k) for k, v in labels.items())

print(labels)

pnet_path = "./datasets/5f680a696ec9b83bb0037081-momodel/data/keras_model_data/pnet.h5"

rnet_path = "./datasets/5f680a696ec9b83bb0037081-momodel/data/keras_model_data/rnet.h5"

>

# 載入 MobileNet 的預訓練模型權重

weights_path = basic_path + 'keras_model_data/mobilenet_1_0_224_tf_no_top.h5'

# 影像資料的行數和列數

height, width = 160, 160

model = MobileNet(input_shape=[height,width,3],classes=2)

model.load_weights(weights_path,by_name=True)

print(' 載入完成 ...')

def save_model(model, checkpoint_save_path, model_dir):  # 儲存模型

     if os.path.exists(checkpoint_save_path):

         print(" 模型載入中 ")

         model.load_weights(checkpoint_save_path)

         print(" 模型載入完畢 ")

     checkpoint_period = ModelCheckpoint(

         # 模型儲存路徑

         model_dir + 'ep{epoch:03d}-loss{loss:.3f}-val_loss{val_loss:.3f}.h5',

         # 檢測的指標

         monitor='val_acc',

         # auto ’,‘ min ’,‘ max ’中選擇

         mode='max',

         # 是否只儲存模型權重

         save_weights_only=False,

         # 是否只儲存最優的模型

         save_best_only=True,

         # 檢測的輪數是每隔 2

         period=2

     )

     return checkpoint_period

checkpoint_save_path = "./results/last_one88.h5"

model_dir = "./results/"

checkpoint_period = save_model(model, checkpoint_save_path, model_dir)

# 學習率下降的方式, acc 三次不下降就下降學習率繼續訓練

reduce_lr = ReduceLROnPlateau(

                         monitor='accuracy',  # 檢測的指標

                         factor=0.5,     # acc 不下降時將學習率下調的比例

                         patience=3,     # 檢測輪數是每隔三輪

                         verbose=2       # 資訊展示模式

                     )

early_stopping = EarlyStopping(

                             monitor='val_accuracy',  # 檢測的指標

                             min_delta=0.0001,         # 增大或減小的閾值

                             patience=3,         # 檢測的輪數頻率

                             verbose=1            # 資訊展示的模式

                         )

# 一次的訓練集大小

batch_size = 64

# 圖片資料路徑

data_path = basic_path + 'image'

# 圖片處理

train_generator, test_generator = processing_data(data_path, height=160, width=160, batch_size=batch_size, test_split=0.1)

# 編譯模型

model.compile(loss='binary_crossentropy',  # 二分類損失函式   

               optimizer=Adam(lr=0.001),   # 最佳化器

               metrics=['accuracy'])        # 最佳化目標

# 訓練模型

history = model.fit(train_generator,    

                     epochs=20, # epochs: 整數,資料的迭代總輪數。

                     # 一個 epoch 包含的步數 , 通常應該等於你的資料集的樣本數量除以批次大小。

                     steps_per_epoch=637 // batch_size,

                     validation_data=test_generator,

                     validation_steps=70 // batch_size,

                     initial_epoch=0, # 整數。開始訓練的輪次(有助於恢復之前的訓練)。

                     callbacks=[checkpoint_period, reduce_lr])

# 儲存模型

model.save_weights(model_dir + 'temp.h5')

plt.plot(history.history['loss'],label = 'train_loss')

plt.plot(history.history['val_loss'],'r',label = 'val_loss')

plt.legend()

plt.show()

plt.plot(history.history['accuracy'],label = 'acc')

plt.plot(history.history['val_accuracy'],'r',label = 'val_acc')

plt.legend()

plt.show()


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69946337/viewspace-2902701/,如需轉載,請註明出處,否則將追究法律責任。

相關文章