由于Adience数据集比较复杂,包含了多种不同的模式,比如人脸检测、人脸对齐、年龄估计等,因此本文将只着重讲解如何使用Adience数据集进行年龄估计的CNN网络搭建。

  1. 数据集处理

首先,我们需要把Adience数据集中的图片按照年龄分别放入不同的文件夹中,以便后续训练和测试的时候能够方便地读取数据。

我们可以使用如下代码来实现这个功能:

import os
import shutil

root_dir = 'adience'
train_dir = 'train'
test_dir = 'test'

if not os.path.exists(train_dir):
    os.makedirs(train_dir)
if not os.path.exists(test_dir):
    os.makedirs(test_dir)

for i in range(0, 8):
    age_dir = os.path.join(root_dir, 'aligned', 'fold_0{}'.format(i), 'train')
    for subdir in os.listdir(age_dir):
        subdir_path = os.path.join(age_dir, subdir)
        if os.path.isdir(subdir_path):
            age = int(subdir.split('.')[0])
            if age < 18:
                dst_dir = os.path.join(train_dir, 'child')
            elif age < 30:
                dst_dir = os.path.join(train_dir, 'young')
            elif age < 45:
                dst_dir = os.path.join(train_dir, 'middle_aged')
            else:
                dst_dir = os.path.join(train_dir, 'old')
            if not os.path.exists(dst_dir):
                os.makedirs(dst_dir)
            for filename in os.listdir(subdir_path):
                src_file = os.path.join(subdir_path, filename)
                dst_file = os.path.join(dst_dir, filename)
                shutil.copyfile(src_file, dst_file)

for i in range(0, 8):
    age_dir = os.path.join(root_dir, 'aligned', 'fold_0{}'.format(i), 'test')
    for subdir in os.listdir(age_dir):
        subdir_path = os.path.join(age_dir, subdir)
        if os.path.isdir(subdir_path):
            age = int(subdir.split('.')[0])
            if age < 18:
                dst_dir = os.path.join(test_dir, 'child')
            elif age < 30:
                dst_dir = os.path.join(test_dir, 'young')
            elif age < 45:
                dst_dir = os.path.join(test_dir, 'middle_aged')
            else:
                dst_dir = os.path.join(test_dir, 'old')
            if not os.path.exists(dst_dir):
                os.makedirs(dst_dir)
            for filename in os.listdir(subdir_path):
                src_file = os.path.join(subdir_path, filename)
                dst_file = os.path.join(dst_dir, filename)
                shutil.copyfile(src_file, dst_file)

这段代码会把Adience数据集中的训练集和测试集按照年龄分别放入四个文件夹中:child、young、middle_aged、old。

  1. CNN网络搭建

接下来,我们需要搭建一个CNN网络来实现年龄预测。这里我们使用Keras来实现。

from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout
from keras.optimizers import SGD

model = Sequential()
model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(227, 227, 3)))
model.add(MaxPooling2D((2, 2)))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D((2, 2)))
model.add(Conv2D(128, (3, 3), activation='relu'))
model.add(MaxPooling2D((2, 2)))
model.add(Conv2D(128, (3, 3), activation='relu'))
model.add(MaxPooling2D((2, 2)))
model.add(Flatten())
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(4, activation='softmax'))

sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])

这个CNN网络包含了四个卷积层和两个全连接层。其中,第一个卷积层的输入大小为227x227x3,输出通道数为32;第二个卷积层的输出通道数为64;第三个卷积层的输出通道数为128;第四个卷积层的输出通道数为128。最后的全连接层输出大小为4,对应四个年龄段。

  1. 训练和测试

接下来,我们使用Keras的ImageDataGenerator来读取数据,并进行训练和测试。

from keras.preprocessing.image import ImageDataGenerator

train_datagen = ImageDataGenerator(rescale=1./255, shear_range=0.2, zoom_range=0.2, horizontal_flip=True)
test_datagen = ImageDataGenerator(rescale=1./255)

train_generator = train_datagen.flow_from_directory(train_dir, target_size=(227, 227), batch_size=32, class_mode='categorical')
test_generator = test_datagen.flow_from_directory(test_dir, target_size=(227, 227), batch_size=32, class_mode='categorical')

history = model.fit_generator(train_generator, steps_per_epoch=len(train_generator), epochs=30, validation_data=test_generator, validation_steps=len(test_generator))

这里我们使用了数据增强的方法来增加数据量,以提高模型的鲁棒性。训练过程中,我们使用了30个epoch,并使用验证集进行了模型验证。

  1. 绘制预测准确率曲线

最后,我们可以使用Matplotlib来绘制模型的预测准确率曲线。

import matplotlib.pyplot as plt

plt.plot(history.history['accuracy'])
plt.plot(history.history['val_accuracy'])
plt.title('Model accuracy')
plt.ylabel('Accuracy')
plt.xlabel('Epoch')
plt.legend(['Train', 'Test'], loc='upper left')
plt.show()

这里我们可以看到,模型在训练过程中的准确率逐渐提高,并在测试集上达到了较高的准确率

python中使用adience数据集搭建CNN网络结构分为训练集测试集数据集处理实现年龄预测绘制预测准确率曲线

原文地址: https://www.cveoy.top/t/topic/ePpm 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录