论文:
AgeNet: Deeply Learned Regressor and Classifier for Robust Apparent Age Estimation
ICCV2015
论文提出了一种基于人脸的年龄识别网络AgeNet。该网络同时基于分类和回归对年龄进行预测,然后将2个分支的特征进行融合,得到更好的预测结果。并且在ChaLearn 2015 Apparent Age Competition 取得了最好的结果。
主要贡献:
-
提出了端到端的年龄识别方案AgeNet,并且了融合了回归和分类2个模。训练过程中,分别基于年龄数值进行回归,基于年龄的高斯分布作为label进行分类。
-
为了减少小数据上的过拟合,使用了迁移学习的策略。
-
取得了ICCV2015 Looking at People Challenge - Track 1 Apparent Age Estimation 第一名的成绩
整体网络结构:
使用的主干网络结构为GoogLeNet ,
网络结构的修改包括,去掉多余的2个loss层。在每一个Relu操作之前,增加BN操作,去除所有的dropout。
Label制作:
年龄的训练标签,可以使用下面3种方式表示。
(1)1-dimension real-value encoding,就是使用具体的一维数值表示
(2)0/1 encoding,使用one-hot形式表示
(3)Label distribution encoding,基于分布表示,
j表示按照时间顺序的年龄,比如0到85,
y表示标签,
σ 表示label的标准差,
最终标签分布如下,
Loss函数:
训练流程:
首先使用CASIA-WebFace 进行人脸识别训练。然后使用CACD ,Morph-II ,WebFaceAge 进行真实年龄的微调。
最后使
用Morph-II 进
行表面年龄的微调。
人脸预处理:
(1)Face Detection 人脸检测
(2)Facial Landmark Localization 人脸关键点定位,包括左眼中心,右眼中心,鼻子尖,嘴巴左角,嘴巴右角。
(3)Face Normalization 人脸标准化,论文采用了基于外部(Exterior )和内部(Interior )的2种人脸标准化方法。
基于Exterior 的方法,既包括了外部的信息,也包括了全面的纹理信息。
基于organs 的方法,仅仅包括了内部的人脸五官。
2种方法都将人脸归一化到256*256大小。
集成学习:
(1)模型集成Model Ensemble ,将分类和回归进行集成。
(2)人脸模板集成Face Template Ensemble,采用不同的人脸标准化方法,不同的crop大小。
实验结果:
# 检测人脸并绘制人脸bounding box
def getFaceBox(net, frame, conf_threshold=0.7):
frameOpencvDnn = frame.copy()
frameHeight = frameOpencvDnn.shape[0] # 高就是矩阵有多少行
frameWidth = frameOpencvDnn.shape[1] # 宽就是矩阵有多少列
blob .
提出了一种应用于跨
年龄
人脸
识别
的联合学习方法,该方法由深度卷积神经网络构建而成,能在特征学习的
同时学习到最优的测度函数,从而避免不合适的固定阈值所带来的匹配错误. 针对有限的内存、过拟合和计算复杂
性高的问题,在模型训练过程中采用了多种新颖和有效的训练策略.
基于MTCNN+SSR网络实现人脸(关键点)检测及
年龄
预测实验内容实验环境MTCNN简介及实现流程MTCNN简介三种网络模型网络模型结构图MTCNN实现调用MTCNN类库构建MTCNN模型实现SSR简介及实现流程SSRNET解读SSRNET实现流程参考资料
1、通过MTCNN网络将图片中人脸所在区域及其人脸的关键点部位检测出来。
2、通过SSR网络实现对人脸进行
年龄
判断。
Notebook编译器 + Python3.6.9 (当然你也可以选择其他编译器)
TensorFlow-1.14
好的,我们可以使用PyTorch库来实现人脸
年龄
识别
。首先需要准备数据集,可以使用一些公开的人脸数据集,如IMDB-WIKI或UTKFace。这里以IMDB-WIKI数据集为例。
1. 数据集准备
首先下载IMDB-WIKI数据集,可以从以下链接中下载:
https://data.vision.ee.ethz.ch/cvl/rrothe/imdb-wiki/static/imdb_crop.tar
https://data.vision.ee.ethz.ch/cvl/rrothe/imdb-wiki/static/wiki_crop.tar
将下载好的数据集解压到指定目录中,然后使用OpenCV库读取图片并进行预处理。
2. 模型搭建
我们可以使用CNN网络来构建人脸
年龄
识别
模型。这里我们使用ResNet网络作为基础网络,并在其后面添加全连接层进行分类。具体代码如下:
```python
import torch.nn as nn
import torchvision.models as models
class
AgeNet
(nn.Module):
def __init__(self, num_classes):
super(
AgeNet
, self).__init__()
self.resnet = models.resnet18(pretrained=True)
self.fc = nn.Linear(1000, num_classes)
def forward(self, x):
x = self.resnet(x)
x = self.fc(x)
return x
3. 模型训练
我们可以使用PyTorch的DataLoader和Dataset来加载数据集,然后使用交叉熵损失函数和随机梯度下降优化器进行训练。具体代码如下:
```python
import torch.optim as optim
from torch.utils.data import DataLoader
from torchvision.transforms import transforms
# 数据预处理
train_transform = transforms.Compose([
transforms.Resize((224, 224)),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
test_transform = transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
# 加载数据集
train_dataset = AgeDataset(train_data, train_labels, transform=train_transform)
test_dataset = AgeDataset(test_data, test_labels, transform=test_transform)
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=64, shuffle=False)
# 模型训练
model =
AgeNet
(num_classes=101).to(device)
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)
for epoch in range(10):
running_loss = 0.0
for i, data in enumerate(train_loader, 0):
inputs, labels = data[0].to(device), data[1].to(device)
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
if i % 100 == 99:
print('[%d, %5d] loss: %.3f' %
(epoch + 1, i + 1, running_loss / 100))
running_loss = 0.0
4. 模型预测
使用训练好的模型对新的人脸图片进行预测,具体代码如下:
```python
import torch.nn.functional as F
# 模型预测
def predict_age(image):
image = test_transform(image).unsqueeze(0)
output = model(image.to(device))
pred = F.softmax(output, dim=1)
pred = torch.argmax(pred).item()
return pred