Age and gender estimation based on Convolutional Neural Network and TensorFlow

本文主要是介绍Age and gender estimation based on Convolutional Neural Network and TensorFlow,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

训练数据处理

imdb数据提取

gender: 0 for female and 1 for male, NaN if unknown

age: 年龄分为101类,分别为从0到100岁.

将训练数据转换为tfrecords格式,命令为,

python convert_to_records_multiCPU.py --imdb --nworks 8 --imdb_db /home/research/data/hjimce/classifyData/age_gender/imdb_crop/imdb.mat --base_path /home/research/data/hjimce/classifyData/age_gender/

lmdb.mat文件包括,

data = {"file_name": full_path, "gender": gender, "age": age, "score": face_score,"second_score": second_face_score}

数据中含有较多的噪声,因此在加载.mat文件,并获得数据词典后,对图像进行筛选,即可以设置face_score,second_face_score需要满足特定的条件,

if face_score[index] < 1:continue
# if (~np.isnan(second_face_score[index])) and second_face_score[index] > 0.0:
#     continue
if ~(0 <= ages[index] <= 100):continueif np.isnan(genders[index]):continue

提取人脸图像

数据处理包括,对输入图像检测人脸框,并对人脸采用仿射变换进行对齐,

# load the input image, resize it, and convert it to grayscale
image = cv2.imread(os.path.join(image_base_dir, str(file_name[index][0])), cv2.IMREAD_COLOR)
# image = imutils.resize(image, width=256)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
rects = detector(gray, 2)
if len(rects) != 1:continue
else:image_raw = fa.align(image, gray, rects[0])image_raw = image_raw.tostring()

最后将age,gender,对齐后的人脸数据,图像名,保存,

# image_raw = images[index].tostring()
example = tf.train.Example(features=tf.train.Features(feature={# 'height': _int64_feature(rows),# 'width': _int64_feature(cols),# 'depth': _int64_feature(depth),'age': _int64_feature(int(ages[index])),'gender': _int64_feature(int(genders[index])),'image_raw': _bytes_feature(image_raw),'file_name': _bytes_feature(str(file_name[index][0]))}))
writer.write(example.SerializeToString())

人脸对齐算法为

from imutils.face_utils import FaceAligner

对于人脸,我们可以指定调整的眼睛位置,人脸大小,

class FaceAligner:def __init__(self, predictor, desiredLeftEye=(0.35, 0.35),desiredFaceWidth=256, desiredFaceHeight=None):# store the facial landmark predictor, desired output left# eye position, and desired output face width + heightself.predictor = predictorself.desiredLeftEye = desiredLeftEyeself.desiredFaceWidth = desiredFaceWidthself.desiredFaceHeight = desiredFaceHeight# if the desired face height is None, set it to be the# desired face width (normal behavior)if self.desiredFaceHeight is None:self.desiredFaceHeight = self.desiredFaceWidth

之后计算放射变换参数,并对人脸框进行放射变换,

def align(self, image, gray, rect):# convert the landmark (x, y)-coordinates to a NumPy arrayshape = self.predictor(gray, rect)shape = shape_to_np(shape)# extract the left and right eye (x, y)-coordinates(lStart, lEnd) = FACIAL_LANDMARKS_IDXS["left_eye"](rStart, rEnd) = FACIAL_LANDMARKS_IDXS["right_eye"]leftEyePts = shape[lStart:lEnd]rightEyePts = shape[rStart:rEnd]# compute the center of mass for each eyeleftEyeCenter = leftEyePts.mean(axis=0).astype("int")rightEyeCenter = rightEyePts.mean(axis=0).astype("int")# compute the angle between the eye centroidsdY = rightEyeCenter[1] - leftEyeCenter[1]dX = rightEyeCenter[0] - leftEyeCenter[0]angle = np.degrees(np.arctan2(dY, dX)) - 180# compute the desired right eye x-coordinate based on the# desired x-coordinate of the left eyedesiredRightEyeX = 1.0 - self.desiredLeftEye[0]# determine the scale of the new resulting image by taking# the ratio of the distance between eyes in the *current*# image to the ratio of distance between eyes in the# *desired* imagedist = np.sqrt((dX ** 2) + (dY ** 2))desiredDist = (desiredRightEyeX - self.desiredLeftEye[0])desiredDist *= self.desiredFaceWidthscale = desiredDist / dist# compute center (x, y)-coordinates (i.e., the median point)# between the two eyes in the input imageeyesCenter = ((leftEyeCenter[0] + rightEyeCenter[0]) // 2,(leftEyeCenter[1] + rightEyeCenter[1]) // 2)# grab the rotation matrix for rotating and scaling the faceM = cv2.getRotationMatrix2D(eyesCenter, angle, scale)# update the translation component of the matrixtX = self.desiredFaceWidth * 0.5tY = self.desiredFaceHeight * self.desiredLeftEye[1]M[0, 2] += (tX - eyesCenter[0])M[1, 2] += (tY - eyesCenter[1])# apply the affine transformation(w, h) = (self.desiredFaceWidth, self.desiredFaceHeight)output = cv2.warpAffine(image, M, (w, h),flags=cv2.INTER_CUBIC)# return the aligned facereturn output

处理后的数据放在/home/research/data/hjimce/classifyData/age_gender/下.

模型结构分析

模型结构为inception v1,

输入大小为 160×160×3

首先为6个卷积层,

# 149 x 149 x 32
net = slim.conv2d(inputs, 32, 3, stride=2, padding='VALID',scope='Conv2d_1a_3x3')
end_points['Conv2d_1a_3x3'] = net
# 147 x 147 x 32
net = slim.conv2d(net, 32, 3, padding='VALID',scope='Conv2d_2a_3x3')
end_points['Conv2d_2a_3x3'] = net
# 147 x 147 x 64
net = slim.conv2d(net, 64, 3, scope='Conv2d_2b_3x3')
end_points['Conv2d_2b_3x3'] = net
# 73 x 73 x 64
net = slim.max_pool2d(net, 3, stride=2, padding='VALID',scope='MaxPool_3a_3x3')
end_points['MaxPool_3a_3x3'] = net
# 73 x 73 x 80
net = slim.conv2d(net, 80, 1, padding='VALID',scope='Conv2d_3b_1x1')
end_points['Conv2d_3b_1x1'] = net
# 71 x 71 x 192
net = slim.conv2d(net, 192, 3, padding='VALID',scope='Conv2d_4a_3x3')
end_points['Conv2d_4a_3x3'] = net
# 35 x 35 x 256
net = slim.conv2d(net, 256, 3, stride=2, padding='VALID',scope='Conv2d_4b_3x3')
end_points['Conv2d_4b_3x3'] = net

之后是5层block35,

# Inception-Resnet-A
def block35(net, scale=1.0, activation_fn=tf.nn.relu, scope=None, reuse=None):"""Builds the 35x35 resnet block."""with tf.variable_scope(scope, 'Block35', [net], reuse=reuse):with tf.variable_scope('Branch_0'):tower_conv = slim.conv2d(net, 32, 1, scope='Conv2d_1x1')with tf.variable_scope('Branch_1'):tower_conv1_0 = slim.conv2d(net, 32, 1, scope='Conv2d_0a_1x1')tower_conv1_1 = slim.conv2d(tower_conv1_0, 32, 3, scope='Conv2d_0b_3x3')with tf.variable_scope('Branch_2'):tower_conv2_0 = slim.conv2d(net, 32, 1, scope='Conv2d_0a_1x1')tower_conv2_1 = slim.conv2d(tower_conv2_0, 32, 3, scope='Conv2d_0b_3x3')tower_conv2_2 = slim.conv2d(tower_conv2_1, 32, 3, scope='Conv2d_0c_3x3')mixed = tf.concat([tower_conv, tower_conv1_1, tower_conv2_2], 3)up = slim.conv2d(mixed, net.get_shape()[3], 1, normalizer_fn=None,activation_fn=None, scope='Conv2d_1x1')net += scale * upif activation_fn:net = activation_fn(net)return net

reuduction A,

def reduction_a(net, k, l, m, n):with tf.variable_scope('Branch_0'):tower_conv = slim.conv2d(net, n, 3, stride=2, padding='VALID',scope='Conv2d_1a_3x3')with tf.variable_scope('Branch_1'):tower_conv1_0 = slim.conv2d(net, k, 1, scope='Conv2d_0a_1x1')tower_conv1_1 = slim.conv2d(tower_conv1_0, l, 3,scope='Conv2d_0b_3x3')tower_conv1_2 = slim.conv2d(tower_conv1_1, m, 3,stride=2, padding='VALID',scope='Conv2d_1a_3x3')with tf.variable_scope('Branch_2'):tower_pool = slim.max_pool2d(net, 3, stride=2, padding='VALID',scope='MaxPool_1a_3x3')net = tf.concat([tower_conv, tower_conv1_2, tower_pool], 3)return net

10 层 Inception-Resnet-B,8x8x896

net = slim.repeat(net, 10, block17, scale=0.10)end_points[‘Mixed_6b’] = net

def block17(net, scale=1.0, activation_fn=tf.nn.relu, scope=None, reuse=None):"""Builds the 17x17 resnet block."""with tf.variable_scope(scope, 'Block17', [net], reuse=reuse):with tf.variable_scope('Branch_0'):tower_conv = slim.conv2d(net, 128, 1, scope='Conv2d_1x1')with tf.variable_scope('Branch_1'):tower_conv1_0 = slim.conv2d(net, 128, 1, scope='Conv2d_0a_1x1')tower_conv1_1 = slim.conv2d(tower_conv1_0, 128, [1, 7],scope='Conv2d_0b_1x7')tower_conv1_2 = slim.conv2d(tower_conv1_1, 128, [7, 1],scope='Conv2d_0c_7x1')mixed = tf.concat([tower_conv, tower_conv1_2], 3)up = slim.conv2d(mixed, net.get_shape()[3], 1, normalizer_fn=None,activation_fn=None, scope='Conv2d_1x1')net += scale * upif activation_fn:net = activation_fn(net)return net

reuduction B,

def reduction_b(net):with tf.variable_scope('Branch_0'):tower_conv = slim.conv2d(net, 256, 1, scope='Conv2d_0a_1x1')tower_conv_1 = slim.conv2d(tower_conv, 384, 3, stride=2,padding='VALID', scope='Conv2d_1a_3x3')with tf.variable_scope('Branch_1'):tower_conv1 = slim.conv2d(net, 256, 1, scope='Conv2d_0a_1x1')tower_conv1_1 = slim.conv2d(tower_conv1, 256, 3, stride=2,padding='VALID', scope='Conv2d_1a_3x3')with tf.variable_scope('Branch_2'):tower_conv2 = slim.conv2d(net, 256, 1, scope='Conv2d_0a_1x1')tower_conv2_1 = slim.conv2d(tower_conv2, 256, 3,scope='Conv2d_0b_3x3')tower_conv2_2 = slim.conv2d(tower_conv2_1, 256, 3, stride=2,padding='VALID', scope='Conv2d_1a_3x3')with tf.variable_scope('Branch_3'):tower_pool = slim.max_pool2d(net, 3, stride=2, padding='VALID',scope='MaxPool_1a_3x3')net = tf.concat([tower_conv_1, tower_conv1_1,tower_conv2_2, tower_pool], 3)return net

5层 Inception-Resnet-C,3x3x1792

net = slim.repeat(net, 5, block8, scale=0.20)
# Inception-Resnet-C
def block8(net, scale=1.0, activation_fn=tf.nn.relu, scope=None, reuse=None):"""Builds the 8x8 resnet block."""with tf.variable_scope(scope, 'Block8', [net], reuse=reuse):with tf.variable_scope('Branch_0'):tower_conv = slim.conv2d(net, 192, 1, scope='Conv2d_1x1')with tf.variable_scope('Branch_1'):tower_conv1_0 = slim.conv2d(net, 192, 1, scope='Conv2d_0a_1x1')tower_conv1_1 = slim.conv2d(tower_conv1_0, 192, [1, 3],scope='Conv2d_0b_1x3')tower_conv1_2 = slim.conv2d(tower_conv1_1, 192, [3, 1],scope='Conv2d_0c_3x1')mixed = tf.concat([tower_conv, tower_conv1_2], 3)up = slim.conv2d(mixed, net.get_shape()[3], 1, normalizer_fn=None,activation_fn=None, scope='Conv2d_1x1')net += scale * upif activation_fn:net = activation_fn(net)return net

一层 Inception-Resnet-C,3x3x1792

net = block8(net, activation_fn=None)

训练

CUDA_VISIBLE_DEVICES=0 python train.py –images /home/research/data/hjimce/classifyData/age_gender/train –lr 1e-3 –weight_decay 1e-5 –epoch 6 –batch_size 128 –keep_prob 0.8 –cuda

测试

单张图像预测

下载模型放在models/下,

CUDA_VISIBLE_DEVICES=0 python eval.py –I “./demo/demo.jpg” –M “./models/” –font_scale 1 –thickness 1

运行结果,

这里写图片描述

这里写图片描述

测试多张图像精度

CUDA_VISIBLE_DEVICES=0 python test.py –images /home/research/data/hjimce/classifyData/age_gender/test

a.测试给定的模型精度,

Age_MAE:7.21,Gender_Acc:80.32%,Loss:4.37

b.测试自己训练模型精度,

Age_MAE:7.55,Gender_Acc:79.24%,Loss:4.33

修改模型就够,模型大小为24M,测试精度,

Age_MAE:7.57,Gender_Acc:78.85%,Loss:4.29

这篇关于Age and gender estimation based on Convolutional Neural Network and TensorFlow的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1079393

相关文章

基于CTPN(tensorflow)+CRNN(pytorch)+CTC的不定长文本检测和识别

转发来源:https://swift.ctolib.com/ooooverflow-chinese-ocr.html chinese-ocr 基于CTPN(tensorflow)+CRNN(pytorch)+CTC的不定长文本检测和识别 环境部署 sh setup.sh 使用环境: python 3.6 + tensorflow 1.10 +pytorch 0.4.1 注:CPU环境

【图像识别系统】昆虫识别Python+卷积神经网络算法+人工智能+深度学习+机器学习+TensorFlow+ResNet50

一、介绍 昆虫识别系统,使用Python作为主要开发语言。通过TensorFlow搭建ResNet50卷积神经网络算法(CNN)模型。通过对10种常见的昆虫图片数据集(‘蜜蜂’, ‘甲虫’, ‘蝴蝶’, ‘蝉’, ‘蜻蜓’, ‘蚱蜢’, ‘蛾’, ‘蝎子’, ‘蜗牛’, ‘蜘蛛’)进行训练,得到一个识别精度较高的H5格式模型文件,然后使用Django搭建Web网页端可视化操作界面,实现用户上传一

【论文精读】分类扩散模型:重振密度比估计(Revitalizing Density Ratio Estimation)

文章目录 一、文章概览(一)问题的提出(二)文章工作 二、理论背景(一)密度比估计DRE(二)去噪扩散模型 三、方法(一)推导分类和去噪之间的关系(二)组合训练方法(三)一步精确的似然计算 四、实验(一)使用两种损失对于实现最佳分类器的重要性(二)去噪结果、图像质量和负对数似然 论文:Classification Diffusion Models: Revitalizing

▶《强化学习的数学原理》(2024春)_西湖大学赵世钰 Ch5 蒙特卡洛方法【model-based ——> model-free】

PPT 截取必要信息。 课程网站做习题。总体 MOOC 过一遍 1、视频 + 学堂在线 习题 2、 过 电子书 是否遗漏 【下载:本章 PDF GitHub 页面链接 】 【第二轮 才整理的,忘光了。。。又看了一遍视频】 3、 过 MOOC 习题 看 PDF 迷迷糊糊, 恍恍惚惚。 学堂在线 课程页面链接 中国大学MOOC 课程页面链接 B 站 视频链接 PPT和书籍下载网址: 【Gi

越复杂的CoT越有效吗?Complexity-Based Prompting for Multi-step Reasoning

Complexity-Based Prompting for Multi-step Reasoning 论文:https://openreview.net/pdf?id=yf1icZHC-l9 Github:https://github.com/FranxYao/chain-of-thought-hub 发表位置:ICLR 2023 Complexity-Based Prompting for

05 TensorFlow 2.0:CNN总结及实战

浮云爱蹉跎 流光怕寂寞 填残篇脉络 续断章因果 问今生旅途几时交错 前尘灯火 隔世传说                                                                                                                                 《流光卷》 卷积层 发现特征轮廓,实现特征提

04 TensorFlow 2.0:高阶OP之meshgrid

谁诀别相思成疾莫问天涯 也莫问归期 怎奈何无人了解 情断之时 冷暖自知                                                                                                                                 《莫问归期》 内容覆盖: stackmeshgrid im

03 TensorFlow 2.0:TOPK Accuracy实战

这江山风雨 岁月山河 刀光剑影 美了多少世间传说 且看他口若悬河 衣上有风尘 却原来是一位江湖说书人                                                                                                                                 《说书人》 在分类问题中会遇到TO

02 TensorFlow 2.0:前向传播之张量实战

你是前世未止的心跳 你是来生胸前的记号 未见分晓 怎么把你忘掉                                                                                                                                 《千年》 内容覆盖: convert to tensorreshape

海洋生物识别系统+图像识别+Python+人工智能课设+深度学习+卷积神经网络算法+TensorFlow

一、介绍 海洋生物识别系统。以Python作为主要编程语言,通过TensorFlow搭建ResNet50卷积神经网络算法,通过对22种常见的海洋生物(‘蛤蜊’, ‘珊瑚’, ‘螃蟹’, ‘海豚’, ‘鳗鱼’, ‘水母’, ‘龙虾’, ‘海蛞蝓’, ‘章鱼’, ‘水獭’, ‘企鹅’, ‘河豚’, ‘魔鬼鱼’, ‘海胆’, ‘海马’, ‘海豹’, ‘鲨鱼’, ‘虾’, ‘鱿鱼’, ‘海星’, ‘海龟