keras-人脸分类

# -*- coding: utf-8 -*-
"""
Created on 2019/5/21 14:37
@Author: Johnson
@Email:593956670@qq.com
@File: face_reco01.py
"""
import os
import cv2
import numpy as np
from sklearn.model_selection import  train_test_split
from keras.utils import to_categorical
from tensorflow.contrib.keras.api.keras.preprocessing.image import ImageDataGenerator,img_to_array
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation, Flatten
from keras.layers.advanced_activations import PReLU
from keras.layers.convolutional import Conv2D, MaxPooling2D,ZeroPadding2D,Convolution2D
from keras.preprocessing.image import load_img, img_to_array
from keras.optimizers import  SGD
import numpy as np
import cv2
from keras.callbacks import *
import keras



path_name = ""
image_size = 128

def read_path(path_name): #搜索并读取对应路径下的图片,将其和其标签添加到数组 images和 lables中
    numbers = []
    images = []
    labels = []
    k = -1
    for dir_item in os.listdir(path_name):
        k = k + 1
        numbers.append(str(dir_item))
        # 从初始路径开始叠加,合并成可识别的操作路径
        full_path = os.path.abspath(os.path.join(path_name, dir_item))
        for image_item in os.listdir(full_path):
            if image_item.endswith('.png'):
                image_path = os.path.abspath(os.path.join(full_path, image_item))
                image = cv2.imread(image_path)
                images.append(image)
                labels.append(k)
        return images, labels, numbers
def load_dataset(path_name): # 从指定路径读取训练数据
    images, labels, numbers = read_path(path_name)
   # 将输入的所有图片转成四维数组,尺寸为(图片数量*IMAGE_SIZE*IMAGE_SIZE*3)
    images = np.array(images)
    return images, labels
def match_number(path_name): # 得到序号对应的学号
    images, labels, numbers = read_path(path_name)
    return numbers



class facetrain():
    def __init__(self):
        self.path_name = path_name

    def dataload(self,img_rows=image_size,img_cols = image_size,img_channels=3,nb_classes=60):
        #加载数据集到内存
        images,labels = load_dataset(self.path_name)
        #将数据集分别为训练集 验证集和测试集 划分比例为test_size
        train_images,valid_images,train_labels,valid_labels = train_test_split(images,labels,test_size=0.2,random_state=0)
        _, test_images, _, test_labels = train_test_split(images, labels, test_size=0.4,random_state = 0)
        #tensorflow的维度顺序为行数 列数 通道数
        #根据keras库要求的维度顺序重组训练数据集
        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)
        self.input_shape = (img_rows,img_cols,img_channels)
        #使用categorical_crossentropy作为损失函数
        #根据累呗数量nb_classes将类别标签进行one-hot编码使其向量化
        train_labels = to_categorical(train_labels,nb_classes)
        valid_labels = to_categorical(valid_labels,nb_classes)
        test_labels = to_categorical(test_labels,nb_classes)
        #将数据浮点化方便归一化
        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

    def build_model(self,dataset,nb_classes=60):
        # 构建一个空的线性堆叠模型(序贯模型),各神经网络层会被顺序添加
        self.model = Sequential()
          # 以下代码将顺序添加CNN网络需要的各层,一个add就是一个网络层
        self.model.add(Convolution2D(32, 3, 3, border_mode='same',input_shape = dataset.input_shape))# 1 2维卷积层
        self.model.add(Activation('relu'))# 2 激活函数层
        self.model.add(Convolution2D(32, 3, 3)) # 3 2维卷积层
        self.model.add(Activation('relu'))  # 4 激活函数层
        self.model.add(MaxPooling2D(pool_size=(2, 2))) # 5 池化层
        self.model.add(Dropout(0.25))# 6 Dropout层
        self.model.add(Convolution2D(64, 3, 3, border_mode='same')) # 7  2维卷积层
        self.model.add(Activation('relu')) # 8  激活函数层
        self.model.add(Convolution2D(64, 3, 3)) # 9  2维卷积层
        self.model.add(Activation('relu')) # 10 激活函数层
        self.model.add(MaxPooling2D(pool_size=(2, 2)))  # 11 池化层
        self.model.add(Dropout(0.25))  # 12 Dropout层
        self.model.add(Flatten()) # 13 Flatten层
        self.model.add(Dense(512))# 14 Dense层,又被称作全连接层
        self.model.add(Activation('relu')) # 15 激活函数层
        self.model.add(Dropout(0.5)) # 16 Dropout层
        self.model.add(Dense(nb_classes))  # 17 Dense层
        self.model.add(Activation('softmax'))  # 18 分类层,输出最终结果
        self.model.summary() # 输出模型概况

    def train(self,dataset,batch_size=20,nb_epoch=20): #训练模型
        #采用SGD+momentum的优化器进行训练,首先生成一个优化器对象
        sgd = SGD(lr=0.01,decay=1e-6,momentum=0.9,nesterov=True)
        #完成实际的模型配置工作
        self.model.compile(loss="categorical",optimizer=sgd,metrics=["accuracy"])
        #使用实时数据提升,从训练数据中利用旋转,翻转 加噪声等方法创造新的训练数据
        datagen = ImageDataGenerator(
                rotation_range = 20,# 数据提升时图片随机转动的角度(范围为0~180)
                width_shift_range = 0.2,# 数据提升时图片水平偏移的幅度
                height_shift_range = 0.2, # 数据提升时图片垂直偏移的幅度
                horizontal_flip = True) # 进行随机水平翻转
        # 计算整个训练样本集的数量以用于特征值归一化、ZCA白化等处理
        datagen.fit(dataset.train_images)
        # 利用生成器开始训练模型
        self.model.fit_generator(datagen.flow(dataset.train_images, dataset.train_labels, batch_size=batch_size),
                                        samples_per_epoch=dataset.train_images.shape[0], nb_epoch=nb_epoch,validation_data = (dataset.valid_images, dataset.valid_labels))
        MODEL_PATH = './model/facerec_model.h5'


        def save_model(self, file_path=MODEL_PATH): # 存储模型
            self.model.save(file_path)

        def load_model(self, file_path=MODEL_PATH): # 加载模型
            self.model = load_model(file_path)

        def evaluate(self, dataset): # 模型评估
            score = self.model.evaluate(dataset.test_images, dataset.test_labels, verbose=1)
            print("%s: %.2f%%" % (self.model.metrics_names[1], score[1] * 100))


    def face_recognize(self,image): #识别人脸
        if K.image_dim_ordering()=="tf" and image.shape!=(1,image_size,image_size,3):
            image = cv2.resize(image,(image_size,image_size))#尺寸必须与训练集保持一直
            image = image.reshape((1,image_size,image_size,3))
        image = image.astpe("float32")
        image/=255
        result = self.model.predict_proba(image) #给出输入属于各个类别的概率
        result = self.model.predict_classes(image) #类别
        return result[0] #




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值