【ディープラーニング入門事例2】畳み込みニューラルネットワークとKerasをベースにした顔認識モデルの構築

記事ディレクトリ

1. ツールと環境

2.ディープラーニング環境の構築

3. 畳み込みニューラルネットワークに基づく顔認識モデルの構築とテスト

1. コアコード

ステップ 1: データ ラベル 0 と 1 にそれぞれ対応する、自分と他人の顔の特徴データを収集します。

 ステップ 2: 顔の特徴を認識するモデルをトレーニングし、モデルを .h5 形式のファイルとして保存します。

 ステップ 3: .h5 ファイル形式で顔認識モデルを読み取り、カメラによって記録された顔画像を認識します

2. 認識の基本原則

3. 実行とテスト

ステップ 1: 自分自身と他の人の顔の特徴データを収集します (コンピューターのカメラをオンにする必要があることに注意してください。オンにしないとエラーが報告されます)。

ステップ 2: 顔データ モデルのトレーニングを 10 ラウンド実行する

ステップ 3: 顔認識と比較テスト

4. 分析とまとめ

参考記事


1. ツールと環境

  • Pycharm 2022.1.4
  • conda バージョン: 4.5.4
  • Python バージョン: 3.6.5.final.0
  • プラットフォーム: win-64

2.ディープラーニング環境の構築

詳細については、私が書いたこの記事の後半を参照してくださいので、ここでは詳しく説明しません

【ディープラーニング入門事例1】Kerasによる手書きデジタル画像認識icon-default.png?t=N4P3https://blog.csdn.net/qq_52487066/article/details/131048466?spm=1001.2014.3001.5501環境構築、以下をダウンロードする必要がありますツールキットを使用して、Anaconda プロンプトで次のコマンドを順番に実行します。

conda install py-opencv -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install dlib==19.7.0 -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install face_recognition -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install Pillow -i https://pypi.tuna.tsinghua.edu.cn/simple

ツールキットのダウンロードとインポートが完了しました。次はプロジェクトの構築と操作です。


3. 畳み込みニューラルネットワークに基づく顔認識モデルの構築とテスト

1. コアコード

ステップ 1:データ ラベル 0 と 1にそれぞれ対応する、自分と他人の顔の特徴データを収集します。

get_my_face.py

import cv2
import dlib
import os
import random

output_dir = './my_crop_faces'
size = 160
if not os.path.exists(output_dir):
    os.makedirs(output_dir)

# 改变图片的亮度与对比度
def relight(img, light=1, bias=0):
    w = img.shape[1]
    h = img.shape[0]
    #image = []
    for i in range(0,w):
        for j in range(0,h):
            for c in range(3):
                tmp = int(img[j,i,c]*light + bias)
                if tmp > 255:
                    tmp = 255
                elif tmp < 0:
                    tmp = 0
                img[j,i,c] = tmp
    return img

#使用dlib自带的frontal_face_detector作为我们的特征提取器
detector = dlib.get_frontal_face_detector()
# 打开摄像头 参数为输入流,可以为摄像头或视频文件
camera = cv2.VideoCapture(0)

index = 0
while True:
    if (index <= 1000):
        print('Being processed picture %s' % index)
        # 从摄像头读取照片
        success, img = camera.read()
        # 转为灰度图片
        gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        # 使用detector进行人脸检测
        dets = detector(gray_img, 1)

        for i, d in enumerate(dets):
            x1 = d.top() if d.top() > 0 else 0
            y1 = d.bottom() if d.bottom() > 0 else 0
            x2 = d.left() if d.left() > 0 else 0
            y2 = d.right() if d.right() > 0 else 0

            face = img[x1:y1,x2:y2]
            # 调整图片的对比度与亮度, 对比度与亮度值都取随机数,这样能增加样本的多样性
            face = relight(face, random.uniform(0.5, 1.5), random.randint(-50, 50))
            face = cv2.resize(face, (size,size))
            cv2.imshow('image', face)
            cv2.imwrite(output_dir+'/'+str(index)+'.jpg', face)
            index += 1
        key = cv2.waitKey(30) & 0xff
        if key == 27:
            break
    else:
        print('Finished!')
        break

 ステップ 2: 顔の特徴を認識するモデルをトレーニングし、モデルを.h5 形式のファイルとして保存します。

モデル_トレイン.py

#-*- coding: utf-8 -*-
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Convolution2D, MaxPooling2D
from keras.optimizers import SGD
from keras.utils import np_utils
import os
import cv2
import numpy as np
from sklearn.model_selection import train_test_split
import random

def get_files(input_dir):
    file_list = []
    for (path, dirnames, filenames) in os.walk(input_dir):
        # print(path) #输出对应顶层文件夹
        # print(dirnames)#在当前文件夹下的文件夹
        # print(filenames)#在当前文件夹下的文件夹
        for filename in filenames:
            if filename.endswith('.jpg') or filename.endswith('.bmp'):
                # print(filename)
                full_path = os.path.join(path, filename)
                # print(full_path)
                file_list.append(full_path)
    return file_list

#设置hujianhua文件夹的对应标签为0
def getPaddingSize(img):
    h, w, _ = img.shape
    top, bottom, left, right = (0,0,0,0)
    longest = max(h, w)

    if w < longest:
        tmp = longest - w
        # //表示整除符号
        left = tmp // 2
        right = tmp - left
    elif h < longest:
        tmp = longest - h
        top = tmp // 2
        bottom = tmp - top
    else:
        pass
    return top, bottom, left, right

def read_img_label(file_list, label):
    size = 64
    imgs = []
    labs = []
    #01
    num = 0
    for filename in file_list:
        # print(filename)
        img = cv2.imread(filename)
        # print(img.shape)
        top, bottom, left, right = getPaddingSize(img)
        # 将图片放大, 扩充图片边缘部分
        img = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT, value=[0, 0, 0])
        img = cv2.resize(img, (size, size))
        imgs.append(img)
        labs.append(label)
        num = num + 1

    # print(len(imgs))
    # print(len(labs))
    return imgs, labs


def read_dataset():
    input_dir = "./data_collection/my_crop_faces"


    all_imgs_list = []
    all_label_list = []
    my_file_list = get_files(input_dir)
    # 0->[0,1] 1->[1,0]
    label = 0 #[0, 1]
    my_imgs_list, my_labs_list = read_img_label(my_file_list, label)

    input_dir = "./data_collection/others_img_crop"

    others_file_list = get_files(input_dir)
    label = 1 #[1, 0] #->0
    others_imgs_list, others_labs_list = read_img_label(others_file_list, label)

    for img in my_imgs_list:
        all_imgs_list.append(img)
    for img in others_imgs_list:
        all_imgs_list.append(img)

    for label in my_labs_list:
        all_label_list.append(label)
    for label in others_labs_list:
        all_label_list.append(label)

    imgs_array = np.array(all_imgs_list)
    # print(imgs_array.shape)

    labs_array = np.array(all_label_list)
    # print(labs_array.shape)

    return imgs_array,labs_array


#加载数据集并按照交叉验证的原则划分数据集并进行相关预处理工作
def load_data(img_rows = 64, img_cols = 64,
         img_channels = 3, nb_classes = 2):
    #加载数据集到内存
    images, labels = read_dataset()
    print(images.shape)
    print(labels.shape)

    train_images, valid_images, train_labels, valid_labels = train_test_split(images, labels, test_size = 0.3, random_state = random.randint(0, 100))
    _, test_images, _, test_labels = train_test_split(images, labels, test_size = 0.5, random_state = random.randint(0, 100))

    train_images = train_images.reshape(train_images.shape[0], img_rows, img_cols, img_channels)
    valid_images = valid_images.reshape(valid_images.shape[0], img_rows, img_cols, img_channels)
    test_images = test_images.reshape(test_images.shape[0], img_rows, img_cols, img_channels)
    input_shape = (img_rows, img_cols, img_channels)

    #输出训练集、验证集、测试集的数量
    print(train_images.shape[0], 'train samples')
    print(valid_images.shape[0], 'valid samples')
    print(test_images.shape[0], 'test samples')

    #我们的模型使用categorical_crossentropy作为损失函数,因此需要根据类别数量nb_classes将
    #类别标签进行one-hot编码使其向量化,在这里我们的类别只有两种,经过转化后标签数据变为二维
    train_labels = np_utils.to_categorical(train_labels, nb_classes)
    valid_labels = np_utils.to_categorical(valid_labels, nb_classes)
    test_labels = np_utils.to_categorical(test_labels, nb_classes)
    print(train_labels.shape)
    print(valid_labels.shape)
    print(test_labels.shape)
    #像素数据浮点化以便归一化
    train_images = train_images.astype('float32')
    valid_images = valid_images.astype('float32')
    test_images = test_images.astype('float32')

    #将其归一化,图像的各像素值归一化到0~1区间
    train_images /= 255
    valid_images /= 255
    test_images /= 255

    return train_images, train_labels, valid_images, valid_labels, test_images, test_labels

#建立模型
def build_model(nb_classes = 2):
    #构建一个空的网络模型,它是一个线性堆叠模型,各神经网络层会被顺序添加,专业名称为序贯模型或线性堆叠模型
    model = Sequential()

    #以下代码将顺序添加CNN网络需要的各层,一个add就是一个网络层
    model.add(Convolution2D(32, 3, 3, border_mode='same',
                                 input_shape =  (64, 64, 3)))    #1 2维卷积层
    model.add(Activation('relu'))                                  #2 激活函数层

    model.add(Convolution2D(32, 3, 3))                             #3 2维卷积层
    model.add(Activation('relu'))                                  #4 激活函数层

    model.add(MaxPooling2D(pool_size=(2, 2)))                      #5 池化层
    model.add(Dropout(0.25))                                       #6 Dropout层

    model.add(Convolution2D(64, 3, 3, border_mode='same'))         #7  2维卷积层
    model.add(Activation('relu'))                                  #8  激活函数层

    model.add(Convolution2D(64, 3, 3))                             #9  2维卷积层
    model.add(Activation('relu'))                                  #10 激活函数层

    model.add(MaxPooling2D(pool_size=(2, 2)))                      #11 池化层
    model.add(Dropout(0.25))                                       #12 Dropout层

    model.add(Flatten())                                           #13 Flatten层
    model.add(Dense(512))                                          #14 Dense层,又被称作全连接层
    model.add(Activation('relu'))                                  #15 激活函数层
    model.add(Dropout(0.5))                                        #16 Dropout层
    model.add(Dense(nb_classes))                                   #17 Dense层
    model.add(Activation('softmax'))                               #18 分类层,输出最终结果
    #输出模型概况
    print(model.summary())
    return model

model = build_model()

sgd = SGD(lr=0.01, decay=1e-6,
          momentum=0.9, nesterov=True)  # 采用SGD+momentum的优化器进行训练,首先生成一个优化器对象
model.compile(loss='categorical_crossentropy',
                   optimizer=sgd,
                   metrics=['accuracy'])  # 完成实际的模型配置工作

train_images, train_labels, valid_images, valid_labels, test_images, test_labels = load_data()

batch_size = 20
nb_epoch = 10
train_history = model.fit(train_images,
               train_labels,
               batch_size=batch_size,
               nb_epoch=nb_epoch,
               validation_data=(valid_images, valid_labels),
               shuffle=True)

scores = model.evaluate(test_images, test_labels)
print('accuracy=', scores[1])
prediction = model.predict_classes(test_images)
# print(prediction)
model.save('./me.face.model.h5')

 ステップ 3: .h5 ファイル形式で顔認識モデルを読み取り、カメラによって記録された顔画像を認識します

video_predict.py

import cv2
import dlib
from keras.models import load_model
import sys

size = 64

# 使用dlib自带的frontal_face_detector作为我们的特征提取器
detector = dlib.get_frontal_face_detector()

cam = cv2.VideoCapture(0)

model = load_model('./me.face.model.h5')

while True:
    _, img = cam.read()
    gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    dets = detector(gray_image, 1)
    for i, d in enumerate(dets):
        x1 = d.top() if d.top() > 0 else 0
        y1 = d.bottom() if d.bottom() > 0 else 0
        x2 = d.left() if d.left() > 0 else 0
        y2 = d.right() if d.right() > 0 else 0
        face = img[x1:y1, x2:y2]
        # 调整图片的尺寸
        face = cv2.resize(face, (size, size))
        shape_img = (face.reshape(1, size, size, 3)).astype('float32') / 255

        prediction = model.predict_classes(shape_img)
        print(prediction[0])
        name = "unknown"
        if prediction[0] == 0:
            print("识别出本人")
            name = "Aricl."
        else:
            print("不是本人")
            name = "unknown"
        cv2.rectangle(img, (x2, x1), (y2, y1), (255, 0, 0), 3)
        font = cv2.FONT_HERSHEY_SIMPLEX
        cv2.putText(img, name, (x2, x1), font, 0.8, (255, 255, 255), 1)

    cv2.imshow('image', img)
    key = cv2.waitKey(30) & 0xff
    if key == 27:
        sys.exit(0)

2. 認識の基本原則

        コアの 1 つは、画像処理用のオープンソース コンピューター ビジョン ライブラリである OpenCV (オープン ソース コンピューター ビジョン ライブラリ)を使用することです。

        コンピュータビジョンに関するオープンソースのAPI関数ライブラリのセットです。これは、(1) 科学研究であっても商用アプリケーションであっても、開発に使用できること、(2) すべての API 関数のソース コードが公開されており、内部実装のプログラム ステップを確認できること、(3) を意味します。 OpenCV のソース コードを変更して、必要な特定の API 関数をコンパイルおよび生成できます。ただし、ライブラリとして提供されるのは、一般的に使用され、古典的で人気のあるアルゴリズムの API のみです。

        一般的なコンピュータ ビジョン アルゴリズムには、通常、次の手順が含まれます。

  1. データ収集
  2. 前処理
  3. 特徴抽出
  4. 機能の選択
  5. 分類器の設計とトレーニング
  6. 分類

これら 6 つの部分について、OpenCV は開発者が呼び出すための API を提供します。

        2 番目のコアは、Keras を使用して畳み込みニューラル ネットワークを構築することです。

        Keras は、人工知能の入門フレームワークとしては比較的優れています。これは、デフォルトのフレームワークとして TensorFlow に追加された高度なPython ニューラル ネットワーク フレームワークであり、TensorFlow にさらに高度な API を提供します。

        TensorFlow をプログラミングの世界で Java または C++ と比較する場合、Keras はプログラミングの世界における Python であり、 TensorFlow の高レベル パッケージとして、TensorFlow と組み合わせて使用​​してモデルを迅速に構築できます。

        そして Keras は TensorFlow によって正式にサポートされています。マシン上に利用可能な GPU がある場合、コードは並列コンピューティングのために自動的に GPU を呼び出します。これは非常に強力です。

3. 実行とテスト

ステップ 1: 自分自身と他の人の顔の特徴データを収集します (コンピューターのカメラをオンにする必要があることに注意してください。オンにしないとエラーが報告されます)。

 

ステップ 2: 顔データ モデルのトレーニングを 10 ラウンド実行する

ステップ 3: 顔認識と比較テスト

上の写真は私(ブロガー Aricl.)、下の写真は私のルームメイト(顔不明)です。顔認識の精度は依然として良好であることがわかります。


4. 分析とまとめ

        今回は、畳み込みニューラルネットワークとKerasをベースに顔認識モデルを構築し、実装の基本原理は、 PythonのOpenCVライブラリを参照し、その中の顔分類器を呼び出し、コンピュータのカメラを呼び出して単一フレームを読み取るというものです。ループ内のデータ。リアルタイムの顔検出を実行し、顔をフレームに収め、情報をマークします。

        まずは顔データを収集します 本人とその他の顔特徴データが合計1,000件収集されました 収集完了後、データモデルの学習が行われます 合計10回の学習が行われます、6,000 ラウンド以上のトレーニングを行っており、優れたモデルは.h5 形式のファイルとして保存されます次に、カメラを呼び出して各フレームの顔写真を読み取り、画像をグレースケール化し、顔を検出して対応する領域をフレームに収めます。顔認識と比較のために .h5 顔認識モデル ファイルを読み取り、上記の情報を個人情報または不明としてマークします。

        また、収集する際には、収集する人物と環境に一定の要件があり、カメラで顔がはっきりと見えるように光が明るく、顔がカメラの方向を向いている必要があり、収集された顔の特徴がよくわかるようにする必要があります。データはより正確であり、認識効果はより優れています。

        今回は顔認証の予備的な紹介であり、私は顔認証について学びたいと強い興味を持っていますが、ブロガーは大学院入学試験を準備しているため、予備的な理解しか得られません。今後も関連技術の学習と研究を続けていきますこの分野で機会があれば、ぜひ!

参考記事

Python+Keras+opencv で顔認識を実現icon-default.png?t=N4P3https://blog.csdn.net/gf19960103/article/details/91038858?ops_request_misc=&request_id=&biz_id=102&utm_term=%E4%BD%BF%E7%94%A8Keras%E6% 9E %84%E5%BB%BA%E4%BA%BA%E8%84%B8%E8%AF%86%E5%88%AB%E6%A8%A1%E5%9E%8B&utm_medium=distribute.pc_search_result. none -task-blog-2~all~sobaiduweb~default-3-91038858.nonecase&spm=1018.2226.3001.4187顔検出と認識 Python 実装シリーズ (5) - keras ライブラリを使用して顔認識モデルをトレーニングするicon-default.png?t=N4P3https://blog.csdn.net/weixin_44491431/article/details/113839543?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522168601107216800185824691%2522%252C %2522scm%2 522%253A%252220140713.130102334..%2522%257D&request_id =168601107216800185824691&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-1-113839543-null-null.142^v88^control_2,239^v2^insert_chatgpt &utm_term= %E4%BD%BF % E7%94%A8Keras%E6%9E%84%E5%BB%BA%E4%BA%BA%E8%84%B8%E8%AF%86%E5%88%AB%E6%A8%A1%E5 % 9E%8B&spm=1018.2226.3001.4187 Keras を使用して顔の検出と認識を行う方法を教えますicon-default.png?t=N4P3https://blog.csdn.net/m0_55479420/article/details/115268470?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522168601107216800185824691%2522%252C%2522scm%252 2%253A%252220140713.130102334..%2522%257D&request_id =168601107216800185824691&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-2-115268470-null-null.142^v88^control_2,239^v2^insert_chatgpt&utm_term= %E4%BD%BF% E7%94%A8Keras%E6%9E%84%E5%BB%BA%E4%BA%BA%E8%84%B8%E8%AF%86%E5%88%AB%E6%A8%A1%E5% 9E%8B&spm=1018.2226.3001.4187

おすすめ

転載: blog.csdn.net/qq_52487066/article/details/131060004