Windows+Anaconda3+Tensorflow+Opencv3 --人脸识别,年龄,性别,表情识别,头部姿态教程

因为项目上的需要,我需要去训练一个人脸识别的系统,但是机器视觉方向并不是我特别喜欢的方向,所以我特别急功求成,想尽快搭建一个人脸识别系统,其实在git上已经有很多相关论文还有已经训练好的模型,大家如果想去了解这方面的知识,这篇文章并不适合您看。当然,时间是必须去付出的,大家如果喜欢这方面的方向,就好好斟酌一下,神经网络现在应用的很广,推荐Tensorflow框架,实在是太简单方便搭建了。当然不要光只学框架,具体的原理一定要搞清楚,推荐Coursera-Andrew ng-MachineLearing课程,没看过就相当于没学过,这是经典,而且入门简单,好好学,好好吸收,原理就这样。好吧,接下来我就将这10天的工作总结在此吧。

【2019/3/11】鉴于文章关注好像挺多了,过2天我会尝试将代码放到github上,我不知道是否能上传这么大量的图片。

一,材料准备

Anaconda3-4.2.0
这是一个python3.5.2的集成环境,特别好用和方便,方便管理需要用的包。

二,学习教程

Python3
这个学习教程无所谓的,你可以看书,也可以找网站来自学,当然必须先有python3的基础知识了。

Tensorflow
这个我推荐莫烦大牛的基础Tensorflow视频教程,不过这个课程说实在的是过于简单,就是快速的让人了解整个过程,其实面对的还是一些有基础的人,所以一定要看Coursera-Andrew ng-MachineLearing这课程,经典!经典!经典!重要的东西说3遍。当然学习框架的东西最好还是去tensoflow官方(好难打开)去细酌,当然tensorFlow中文社区也行,看自己喜欢,八仙过海,各显神通。

opencv3
这个就没什么好说的了,直接看官方的教程,一点点敲,一点点尝试,这是3.0的教程2.0在某些方面上不一样,我觉得可以直接入3.0。当然个人也极度推荐看毛星云大牛博客,当然自己先需要懂c++,然后去搞懂每个原理就好,更多东西,还是回归官网,官网说的为准

三,环境布置

1.安装anaconda3

我刚刚给的链接是个exe文件,所以这我就不用说了吧,就是傻瓜式的下一步,选择安装就好。

注意:这里可能有人纠结选择什么,我选择的是这个。

安装完成后,一般所有软件都会在这里。


2.安装opencv3

打开开始找到Anaconda Prompt,并以管理员身份运行,其实就是个普通终端罢了。

输入以下命令,然后按下y即可。

conda install -c https://conda.anaconda.org/menpo opencv3

安装完成后我们可以用以下命令试试是否正常使用,没反应就是最好的反应了啊,能正常使用。

python

import cv2

3.安装tensorflow

同样地,打开开始找到Anaconda Prompt,并以管理员身份运行,输入以下命令,这时候使用的Tensorflow1.3.0

#Anaconda安装完成后,打开Anaconda Prompt,输入如下命令,创建Tensorflow虚拟环境。

    conda create -n tensorflow python=3.5

#进入Tensorflow虚拟环境

    activate tensorflow

退出Tensorflow虚拟环境

    deactivate tensorflow

安装Tensorflow

    pip install tensorflow

亲测可用,完成了之后,同样可以输入以下命令来进行测试。

python

import tensorflow

用anaconda3就是这么方便,很多东西都集成好在一个地方,如果想卸载,其实很简单,直接把anaconda3卸载了,什么都脱离了你的环境了。就是这么好用。

四,源代码

ps:下面步骤如果没提示到的文件和数据包,不需要管,我会在每一个文件对应需要下载和安装什么东西,一步一步进行讲述

spyder工具

我们使用的编辑工具叫spyderanaconda3自带工具,在开始输入spyder即可找到。

main.py

首先去opencv官网,下载一个opencv包,将下面的两个文件放入xml文件夹

然后可以运行以下代码,当然要注意我们的----------------------------ps:位置,等等我们将到对应位置之后,遍可打开,将得到你渴望的效果。慢慢来,心急吃不到热豆腐,先试试人脸识别怎么样,这是opencv的demo改写的,就是利用haar_like分类器进行分类有2部判断,先判断是否是人脸,是人脸的话,判断人脸有没眼睛,如果有这个就是人脸。当然相关论文知识我的这篇文章不会详细介绍,大家可以上网去找,我只想用最简单的方式给大家带来效果

代码

# -*- coding: utf-8 -*-
"""
Created on Tue Oct 17 10:14:19 2017

@author: Gavinjou
"""

import cv2
import numpy as np
import datetime
#----------------------------ps:讲到年龄,性别的时候可以打开
#import age_sex as myahesex
#调用自己的表情文档
#----------------------------ps:讲到表情识别的时候可以打开
#import model as mymodel
#调用自己的headpose文档
#----------------------------ps:讲到头部姿态的时候可以打开
#import headpose as myheadpose

#haar人脸识别分类器数据位置
face_cascade_name = "xml/haarcascade_frontalface_alt2.xml"
#眼睛识别,提高准确率
eyes_cascade_name = "xml/haarcascade_eye.xml"
#窗口命名
window_name = "Face detection"
#定义人脸识别分类器
face_cascade = cv2.CascadeClassifier(face_cascade_name)
if face_cascade.empty() :
   raise IOError('Unable to load the face cascade classifier xml file')
#定义眼睛检测分类器
eyes_cascade = cv2.CascadeClassifier(eyes_cascade_name)
if eyes_cascade.empty() :
   raise IOError('Unable to load the eye cascade classifier xml file')
   
#年龄
age_list=['(0, 2)','(4, 6)','(8, 12)','(15, 20)','(25, 32)','(38, 43)','(48, 53)','(60, 100)']
#性别
gender_list=['Male','Female']

#得到性别识别器
#----------------------------ps:讲到年龄,性别的时候可以打开
#age_net=myahesex.get_age_net()
#得到年龄识别器
#----------------------------ps:讲到年龄,性别的时候可以打开
#gender_net = myahesex.get_gender_net()


#人脸识别画框
def detectAndDisplay(frame,scale):
    #算法开始时间
    startTime = datetime.datetime.now()
    #将原图转化为灰度图片
    frame_gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
    #灰度直方图均衡化
    frame_gray = cv2.equalizeHist(frame_gray)
    
    #改变图像大小,使用双线性差值
    rows, cols = frame_gray.shape
    
    #缩小灰度图片加速计算
    smallImage = cv2.resize(frame_gray,(int(round(cols/scale)),round(int(rows/scale))),interpolation=cv2.INTER_CUBIC)
   
    #人脸侦测
    faces = face_cascade.detectMultiScale(smallImage,1.1,2,cv2.CASCADE_SCALE_IMAGE,(30, 30))
    
    
    index=int(1)
    
    for faceRect in faces:
        x,y,w,h = faceRect
        #左上角
        LUpoint = (int(round(x * scale)),int(round(y * scale)))
        #右上角
        RDpoint = (int(round((x+w-1) * scale)),int(round((y+h-1) * scale)))
        
        #人脸映像
        faceROI = frame_gray[int(round(y * scale)):int(round((y+h-1) * scale)), int(round(x * scale)):int(round((x+w-1) * scale))]
        #三维人脸映像
        faceROI2 = frame[int(round(y * scale)):int(round((y+h-1) * scale)), int(round(x * scale)):int(round((x+w-1) * scale))]
        #眼睛识别
        eyes = eyes_cascade.detectMultiScale(faceROI,1.1,2,cv2.CASCADE_SCALE_IMAGE,(30, 30))
        
        if len(eyes) !=2 :
            continue
        
        #得到角度参数
        #----------------------------ps:讲到头部姿态的时候可以打开
        #pitch,yaw,roll= myheadpose.predict_head_pose(faceROI2)
        #print(pitch,yaw,roll)
        #得到性别
        #----------------------------ps:讲到年龄,性别的时候可以打开
        #gender_prediction = gender_net.predict([faceROI2])
        #print(gender_list[gender_prediction[0].argmax()])
        #得到年龄
        #----------------------------ps:讲到年龄,性别的时候可以打开
        #age_prediction = age_net.predict([faceROI2])
        #print(age_list[age_prediction[0].argmax()])
        

        #得到所有表情参数
        #----------------------------ps:讲到表情识别的时候可以打开
        #facemodel=mymodel.predict_emotion(faceROI)
        #得到最大值位置
        #----------------------------ps:讲到表情识别的时候可以打开
        #_positon = np.argmax(facemodel)
        
        
       
        #画正方形
        cv2.rectangle(frame,LUpoint,RDpoint,(0, 0, 255),2,8)
        #标记
        cv2.putText(frame,str(index),LUpoint,cv2.FONT_HERSHEY_SIMPLEX,2.0,(0, 0, 255))
        #----------------------------ps:讲到表情识别的时候可以打开
        #cv2.putText(frame,mymodel.emotion_labels[_positon],LUpoint,cv2.FONT_HERSHEY_SIMPLEX,1.0,(0, 0, 255))
        index+=1
        
        
    
    cv2.imshow(window_name,frame)
    #算法结束时间
    endTime = datetime.datetime.now()
    print (endTime - startTime)
#---detectAndDisplay
    

#main

#初始化窗口
cv2.namedWindow(window_name,cv2.WINDOW_NORMAL)   
capture = cv2.VideoCapture(0)

while(capture.isOpened()):
    ret, frame = capture.read()
    
    #判断是否最后一帧
    if ret:
        detectAndDisplay(frame,2.0)
        
    #按q退出程序
    if cv2.waitKey(30) & 0xFF == ord('q'):
        break

#释放视频
capture.release()
cv2.destroyAllWindows()

效果图

model.py

这是我参考的两篇文章,第一篇是参考代码文章,第二篇是作者的文章,第三篇是安装keras教程,这是训练好的结果,所以可以直接调用,这时我测试部分就不写了,直接使用参考代码文章代码即可测试。

http://blog.csdn.net/sinat_26917383/article/details/72885715
https://github.com/JostineHo/mememoji
http://blog.csdn.net/shenziheng1/article/details/69664920

这时需要将作者github上的文件夹下载,并放置刚刚的目录结构中。利用以下代码即可测试

安装keras
具体请按照这篇文章进行操作

http://blog.csdn.net/shenziheng1/article/details/69664920

代码

# -*- coding: utf-8 -*-
"""
Created on Wed Oct 18 15:36:48 2017

@author: Gavinjou
"""


import cv2
import sys
import json
import time
import numpy as np
from keras.models import model_from_json


root_model="real-time_emotion_analyzer-master"

#动作表情
#愤怒,害怕,开心,伤心,惊喜,平静
emotion_labels = ['angry', 'fear', 'happy', 'sad', 'surprise', 'neutral']

# load json and create model arch
json_file = open(root_model+'/model.json','r')
loaded_model_json = json_file.read()
json_file.close()
print("加载keras模型成功")


model = model_from_json(loaded_model_json)
# load weights into new model
model.load_weights(root_model+'/model.h5')
print("加载权重成功")

#定义预测函数
def predict_emotion(face_image_gray):
    resized_img = cv2.resize(face_image_gray, (48,48), interpolation = cv2.INTER_AREA)
    # cv2.imwrite(str(index)+'.png', resized_img)
    image = resized_img.reshape(1, 1, 48, 48)
    list_of_list = model.predict(image, batch_size=1, verbose=1)
    angry, fear, happy, sad, surprise, neutral = [prob for lst in list_of_list for prob in lst]
    return [angry, fear, happy, sad, surprise, neutral]

#img_gray = cv2.imread('C:/Users/Gavinjou/Desktop/FaceRecognation/real-time_emotion_analyzer-master/meme_faces/happy-fear.png')
#img_gray = cv2.cvtColor(img_gray, cv2.COLOR_BGR2GRAY)
#angry, fear, happy, sad, surprise, neutral = predict_emotion(img_gray)

效果图

这时候还记得我们main.py,有----------------------------ps:标记吗,将----------------------------ps:讲到表情识别的时候可以打开下面的语句全部打开,然后运行main.py

headpose.py

头部姿态识别我是按照这篇文章来进行使用的,这是原版的作者的文章,其实人家写的真够详细了,各种demo都告诉你怎么用了,直接调用就好,人家模型都是训练好的了,直接用就好。

https://github.com/mpatacchiola/deepgaze

这时需要将作者github上的文件夹下载,并放置刚刚的目录结构中。利用以下代码即可测试,记得把文件夹名字改成我这个,不过也无所谓啦,就是个路径问题,当然自己去修改一下代码路径也是没问题的。测试代码我就不讲了,作者的文章上清清楚楚写了demo,自己写一遍测试一下即可。

安装dlib
打开Anaconda Prompt,输入如下命令,安装dlib

conda install -c conda-forge dlib=19.4

注意: 这是我折腾最久的,我不知道你是否能安装上,我是参考了几篇文章都无法装上,然后不知道搜了哪个位置的文章,使用一条命令就把dlib装上了。如果不行的话,我也推荐我之前参考的文章的链接去试试,但我并没有成功,总说什么Unicode不对。然后就放弃了。我用的材料是boost1.57.0,cmake3.8.2,dlib19.4.0

http://blog.csdn.net/insanity666/article/details/72235275
http://www.jianshu.com/p/004c99828af2

代码

# -*- coding: utf-8 -*-
"""
Created on Wed Oct 18 20:10:15 2017

@author: Gavinjou
"""


import tensorflow as tf
from deepgazemaster.deepgaze.head_pose_estimation import CnnHeadPoseEstimator

#图像大小设定
width = 64
height= 64

sess = tf.Session()

my_head_pose_estimator = CnnHeadPoseEstimator(sess)
my_head_pose_estimator.load_pitch_variables("deepgazemaster/etc/tensorflow/head_pose/pitch/cnn_cccdd_30k.tf")
my_head_pose_estimator.load_yaw_variables("deepgazemaster/etc/tensorflow/head_pose/yaw/cnn_cccdd_30k")
my_head_pose_estimator.load_roll_variables("deepgazemaster/etc/tensorflow/head_pose/roll/cnn_cccdd_30k.tf")


#输入的图像大小必须要相等(64>=x,64>=x,3),x代表输入
def predict_head_pose (face_image):
    #resized_img = cv2.resize(face_image, (width,height), interpolation = cv2.INTER_AREA)
    pitch = my_head_pose_estimator.return_pitch(face_image)
    yaw   = my_head_pose_estimator.return_yaw(face_image)
    roll  = my_head_pose_estimator.return_roll(face_image)
    return [pitch,yaw,roll]

效果图

这时候还记得我们main.py,有----------------------------ps:标记吗,将----------------------------ps:讲到头部姿态的时候可以打开下面的语句全部打开,然后运行main.py

这时我多加了一个语句

输出便如下图了


age_sex.py

年龄,性别识别部分我是参照我是参考该第一篇作者的文章,利用的是caffe神经网络框架,不过新的caffe好像还是会出问题,所以我还是会一步步让大家运行我的整份代码,第二篇修改caffe的文章。不用紧张,我们继续一步步来。

https://github.com/GilLevi/AgeGenderDeepLearning
http://blog.csdn.net/gzljss/article/details/45849013

这是需要将作者的整份代码下载下来,放文件根目录下

这时候还没完成呢,还需要作者已经训练好的模型放到这个master文件中。这个文章还是原作者模型的参考文章,有时间还是好好看看。

http://www.openu.ac.il/home/hassner/projects/cnn_agegender/

我下载的是作者最原始的训练好的模型下完完成之后解压,创建一个文件名为cnn_age_gender_models的文件,把解压缩文件全部放进去

安装caffe
网上很少有anaconda3+python3.5的caffe安装,就算有,也是特别麻烦,还有各种编译的烦事,还不一定成功,得谢谢第二篇文章上知乎上朋友的回答,2个回答的朋友已经告诉你怎么把caffe放到anaconda3中调用了,当然如果你不想编译,真得谢天谢地。第一篇文章已经提供了python35的预编译版本,开心吧。接下来我再来一步一步的说该怎么装

https://github.com/BVLC/caffe/tree/windows
https://www.zhihu.com/question/34119328

首先打开第一篇文章下载caffe到我们程序根目录当中

因为代码中并不需要添加到anaconda3环境当中所以我就不需要演示怎么放进环境中了,其实代码已经声明路径添加上去罢了。

修改caffe

参考文章

http://blog.csdn.net/gzljss/article/details/45849013

打开caffe/python/caffe/io.py 第258行,修改成以下代码

 if ms != self.inputs[in_][1:]:
    in_shape = self.inputs[in_][1:]
    m_min, m_max = mean.min(), mean.max()
    normal_mean = (mean - m_min) / (m_max - m_min)
    mean = resize_image(normal_mean.transpose((1,2,0)),in_shape[1:]).transpose((2,0,1)) * (m_max - m_min) + m_min
    #raise ValueError('Mean shape incompatible with input shape.')

打开caffe/python/caffe/classifier.py 第96行,修改成以下代码

代码


import os
import numpy as np
import matplotlib.pyplot as plt

caffe_root = './caffe/' 
import sys
sys.path.insert(0, caffe_root + 'python')
import caffe

plt.rcParams['figure.figsize'] = (10, 10)
plt.rcParams['image.interpolation'] = 'nearest'
plt.rcParams['image.cmap'] = 'gray'

mean_filename='./AgeGenderDeepLearning-master/cnn_age_gender_models/mean.binaryproto'
proto_data = open(mean_filename, "rb").read()
a = caffe.io.caffe_pb2.BlobProto.FromString(proto_data)
mean  = caffe.io.blobproto_to_array(a)[0]
"""
age_net_pretrained='./AgeGenderDeepLearning-master/cnn_age_gender_models/age_net.caffemodel'
age_net_model_file='./AgeGenderDeepLearning-master/cnn_age_gender_models/deploy_age.prototxt'
age_net = caffe.Classifier(age_net_model_file, age_net_pretrained,
                       mean=mean,
                       channel_swap=(2,1,0),
                       raw_scale=255,
                       image_dims=(256, 256))



gender_net_pretrained='./AgeGenderDeepLearning-master/cnn_age_gender_models/gender_net.caffemodel'
gender_net_model_file='./AgeGenderDeepLearning-master/cnn_age_gender_models/deploy_gender.prototxt'
gender_net = caffe.Classifier(gender_net_model_file, gender_net_pretrained,
                       mean=mean,
                       channel_swap=(2,1,0),
                       raw_scale=255,
                       image_dims=(256, 256))
"""

def get_age_net():
    age_net_pretrained='./AgeGenderDeepLearning-master/cnn_age_gender_models/age_net.caffemodel'
    age_net_model_file='./AgeGenderDeepLearning-master/cnn_age_gender_models/deploy_age.prototxt'
    age_net = caffe.Classifier(age_net_model_file, age_net_pretrained,
                       mean=mean,
                       channel_swap=(2,1,0),
                       raw_scale=255,
                       image_dims=(256, 256))
    return age_net

def get_gender_net():
    gender_net_pretrained='./AgeGenderDeepLearning-master/cnn_age_gender_models/gender_net.caffemodel'
    gender_net_model_file='./AgeGenderDeepLearning-master/cnn_age_gender_models/deploy_gender.prototxt'
    gender_net = caffe.Classifier(gender_net_model_file, gender_net_pretrained,
                       mean=mean,
                       channel_swap=(2,1,0),
                       raw_scale=255,
                       image_dims=(256, 256))
    return gender_net

"""
gender_net = get_gender_net()
    
age_list=['(0, 2)','(4, 6)','(8, 12)','(15, 20)','(25, 32)','(38, 43)','(48, 53)','(60, 100)']
gender_list=['Male','Female']


example_image = './AgeGenderDeepLearning-master/cnn_age_gender_models/example_image.jpg'
input_image = caffe.io.load_image(example_image)
print(input_image.shape)
_ = plt.imshow(input_image)


prediction = gender_net.predict([input_image]) 

print ('predicted gender:', gender_list[prediction[0].argmax()])
"""

效果图

这时候还记得我们main.py,有----------------------------ps:标记吗,将#----------------------------ps:讲到年龄,性别的时候可以打开下面的语句全部打开,然后运行main.py

可以看到性别是Female,年龄在(38-43)区间。。 我曹,我是女的,还那么老。。

五,总结

上面都是很基础的东西,只是个乱调用,但是很快就做出模型来,可以满足一下小心脏,当然,如果要自己去研究这东西,这是最好的,我是没什么心思搞这个方向,所以我更想快点能调用来使用。但是这个程序速度跑起来有点慢,如果大家有什么好建议的话,可以留言给我,如果在配置上还出了些什么问题,也可以留言,我基本每天都上一下简书的。

最后还有一份性别,年龄代码。我是参考了这篇文章的代码,可是训练出来的模型很有问题,梯度一直没下降,而且调用的时候也各种出状况,我跑了2天的数据,一点卵用也没,待我好好看看TensorFlow,我再整理一下,先保留着。

http://blog.topspeedsnail.com/archives/10767

import os
import glob
import tensorflow as tf
from tensorflow.contrib.layers import *
from tensorflow.contrib.slim.python.slim.nets.inception_v3 import inception_v3_base
import numpy as np
from random import shuffle
import datetime

#年龄区间
age_table=['(0, 2)','(4, 6)','(8, 12)','(15, 20)','(25, 32)','(38, 43)','(48, 53)','(60, 100)']
#性别
sex_table=['f','m']  # f:女; m:男

# AGE==True 训练年龄模型,False,训练性别模型
AGE = False

if AGE == True:
     #获取长度
     lables_size = len(age_table) # 年龄
else:
     #获取长度
     lables_size = len(sex_table) # 性别

face_set_fold = 'AdienceBenchmarkOfUnfilteredFacesForGenderAndAgeClassification'
#拼接路径
fold_0_data = os.path.join(face_set_fold, 'fold_0_data.txt')
fold_1_data = os.path.join(face_set_fold, 'fold_1_data.txt')
fold_2_data = os.path.join(face_set_fold, 'fold_2_data.txt')
fold_3_data = os.path.join(face_set_fold, 'fold_3_data.txt')
fold_4_data = os.path.join(face_set_fold, 'fold_4_data.txt')

face_image_set = os.path.join(face_set_fold, 'aligned')
#拼接路径
def parse_data(fold_x_data):
     #数据集存储
     data_set = []
     
     with open(fold_x_data, 'r') as f:
          #用于标记第一行,第一行数据全部是名称,全部不读
          line_one = True
          for line in f:
              tmp = []
              #如果是第一行,继续
              if line_one == True:
                  line_one = False
                  continue
              #获取所在文件编号
              tmp.append(line.split('\t')[0])
              #获取对应图片名称
              tmp.append(line.split('\t')[1])
              #获取年龄区间
              tmp.append(line.split('\t')[3])
              #获取性别
              tmp.append(line.split('\t')[4])
               
              #查看对应文件夹是否存在
              file_path = os.path.join(face_image_set, tmp[0])
              #如果存在
              if os.path.exists(file_path):
                    #获取该文件所有图片
                    filenames = glob.glob(file_path + "/*.jpg")
                    #查找图片是否在这批文件中
                    for filename in filenames:
                        if tmp[1] in filename:
                            break
                    #将数据挂载到内存
                    if AGE == True:
                        if tmp[2] in age_table:
                            data_set.append([filename, age_table.index(tmp[2])])
                    else:
                        if tmp[3] in sex_table:
                            data_set.append([filename, sex_table.index(tmp[3])])
     #返回数据集
     return data_set
"""
#------读取数据
startTime = datetime.datetime.now()
#读取所有文件的数据集
data_set_0 = parse_data(fold_0_data)
data_set_1 = parse_data(fold_1_data)
data_set_2 = parse_data(fold_2_data)
data_set_3 = parse_data(fold_3_data)
data_set_4 = parse_data(fold_4_data)

#合并所有数据
data_set = data_set_0 + data_set_1 + data_set_2 + data_set_3 + data_set_4
#打乱数据
shuffle(data_set)

endTime = datetime.datetime.now()
print ("完成读取数据时间:"+str(endTime - startTime))
#------读取数据
"""

# 缩放图像的大小
IMAGE_HEIGHT = 227
IMAGE_WIDTH = 227
# 读取缩放图像
#待放入字符串
jpg_data = tf.placeholder(dtype=tf.string)
#待解码jpg图片
decode_jpg = tf.image.decode_jpeg(jpg_data, channels=3)
#对待读取图片重置size
resize = tf.image.resize_images(decode_jpg, [IMAGE_HEIGHT, IMAGE_WIDTH])
#优化转换
resize = tf.cast(resize, tf.uint8) / 255
#读取图片并重置图片数据
def resize_image(file_name):
     #读取图片
     with tf.gfile.FastGFile(file_name, 'rb') as f:
         image_data = f.read()
     #加载程序
     with tf.Session() as sess:
         image = sess.run(resize, feed_dict={jpg_data: image_data})
     return image

#批量数据处理
pointer = 0
def get_next_batch(data_set, batch_size=128):
     global pointer
     batch_x = []
     batch_y = []
     for i in range(batch_size):
         batch_x.append(resize_image(data_set[pointer][0]))
         batch_y.append(data_set[pointer][1])
         pointer += 1
     return batch_x, batch_y
#分批大小
#batch_size = 128
batch_size = 1
#总个数
#num_batch = len(data_set) // batch_size
num_batch = 1
print("总共的batch数量---"+str(num_batch))
#输入的数据大小
X = tf.placeholder(dtype=tf.float32, shape=[batch_size, IMAGE_HEIGHT, IMAGE_WIDTH, 3])
#输出数据大小
Y = tf.placeholder(dtype=tf.int32, shape=[batch_size])

def conv_net(nlabels, images, pkeep=1.0):
     weights_regularizer = tf.contrib.layers.l2_regularizer(0.0005)
     with tf.variable_scope("conv_net", "conv_net", [images],reuse=True) as scope:
          with tf.contrib.slim.arg_scope([convolution2d, fully_connected], weights_regularizer=weights_regularizer, biases_initializer=tf.constant_initializer(1.), weights_initializer=tf.random_normal_initializer(stddev=0.005), trainable=True):
               with tf.contrib.slim.arg_scope([convolution2d], weights_initializer=tf.random_normal_initializer(stddev=0.01)):
                    conv1 = convolution2d(images, 96, [7,7], [4, 4], padding='VALID', biases_initializer=tf.constant_initializer(0.), scope='conv1')
                    pool1 = max_pool2d(conv1, 3, 2, padding='VALID', scope='pool1')
                    norm1 = tf.nn.local_response_normalization(pool1, 5, alpha=0.0001, beta=0.75, name='norm1')
                    conv2 = convolution2d(norm1, 256, [5, 5], [1, 1], padding='SAME', scope='conv2') 
                    pool2 = max_pool2d(conv2, 3, 2, padding='VALID', scope='pool2')
                    norm2 = tf.nn.local_response_normalization(pool2, 5, alpha=0.0001, beta=0.75, name='norm2')
                    conv3 = convolution2d(norm2, 384, [3, 3], [1, 1], biases_initializer=tf.constant_initializer(0.), padding='SAME', scope='conv3')
                    pool3 = max_pool2d(conv3, 3, 2, padding='VALID', scope='pool3')
                    flat = tf.reshape(pool3, [-1, 384*6*6], name='reshape')
                    full1 = fully_connected(flat, 512, scope='full1')
                    drop1 = tf.nn.dropout(full1, pkeep, name='drop1')
                    full2 = fully_connected(drop1, 512, scope='full2')
                    drop2 = tf.nn.dropout(full2, pkeep, name='drop2')
     with tf.variable_scope('output',reuse=True) as scope:
         weights = tf.Variable(tf.random_normal([512, nlabels], mean=0.0, stddev=0.01), name='weights')
         biases = tf.Variable(tf.constant(0.0, shape=[nlabels], dtype=tf.float32), name='biases')
         output = tf.add(tf.matmul(drop2, weights), biases, name=scope.name)
     return output

"""
def training():
     logits = conv_net(lables_size, X)

     def optimizer(eta, loss_fn):
         global_step = tf.Variable(0, trainable=False)
         optz = lambda lr: tf.train.MomentumOptimizer(lr, 0.9)
         lr_decay_fn = lambda lr,global_step : tf.train.exponential_decay(lr, global_step, 100, 0.97, staircase=True)
         return tf.contrib.layers.optimize_loss(loss_fn, global_step, eta, optz, clip_gradients=4., learning_rate_decay_fn=lr_decay_fn)

     def loss(logits, labels):
         cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits = logits, labels = labels)
         cross_entropy_mean = tf.reduce_mean(cross_entropy)
         regularization_losses = tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES)
         total_loss = cross_entropy_mean + 0.01 * sum(regularization_losses)
         loss_averages = tf.train.ExponentialMovingAverage(0.9)
         loss_averages_op = loss_averages.apply([cross_entropy_mean] + [total_loss])
         with tf.control_dependencies([loss_averages_op]):
                total_loss = tf.identity(total_loss)
         return total_loss
    # loss
     total_loss = loss(logits, Y)
    # optimizer
     train_op = optimizer(0.001, total_loss)

     saver = tf.train.Saver(tf.global_variables())
     with tf.Session() as sess:
          sess.run(tf.global_variables_initializer())
          
          global pointer
          epoch = 0
          while True:
               print("start-----"+str(epoch))
               pointer = 0
               for batch in range(num_batch):
                   startTime = datetime.datetime.now()
                   batch_x, batch_y = get_next_batch(data_set, batch_size)
                   _, loss_value = sess.run([train_op, total_loss], feed_dict={X:batch_x, Y:batch_y})
                   print(epoch, batch, loss_value)
                   endTime = datetime.datetime.now()
                   print ("一次batch时间训练:"+str(endTime - startTime))
               saver.save(sess, './age.ckpt' if AGE == True else './sex.ckpt')
               epoch += 1
               print("end-----"+str(epoch))
training()

"""
# 检测性别和年龄
# 把batch_size改为1
def detect_age_or_sex(image_path):
    logits = conv_net(lables_size, X)
    saver = tf.train.Saver()

    with tf.Session() as sess:
        saver.restore(sess, './age.ckpt' if AGE == True else './sex.ckpt')
        
        softmax_output = tf.nn.softmax(logits)
        res = sess.run(softmax_output, feed_dict={X:[resize_image(image_path)]})
        res = np.argmax(res)

        if AGE == True:
            return age_table[res]
        else:
            return sex_table[res]

print(detect_age_or_sex("1.jpg"))
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,911评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,014评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 142,129评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,283评论 1 264
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,159评论 4 357
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,161评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,565评论 3 382
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,251评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,531评论 1 292
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,619评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,383评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,255评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,624评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,916评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,199评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,553评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,756评论 2 335

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,081评论 25 707
  • 今天追了一部新剧《四重奏》,看了之后感觉心潮起伏,可能正是因为这个特殊时期,所以因为那个特殊比喻——蚂蚁和蟋蟀,所...
    第三区间八小时阅读 295评论 0 1
  • 为了回答公众号里朋友的问题,我特意拟一篇文章,因为我觉得这个问题稍微有点儿棘手,三言两语是解释不了的。但其实,要是...
    说你是只兔子阅读 493评论 0 4
  • 多年了,你是否有进步。 是否仍然感性多于理性,敏感依旧。 我努力奔跑,也还会无意间被一片掉落的树叶割伤,依然体无完...
    月上逆光阅读 356评论 0 0
  • 智多牛阅读 137评论 0 0