深度学习在年龄检测问题中的应用

深度学习技术已经在多个领域展现出其强大的能力,从手机的面部识别到自动驾驶汽车,深度学习的应用无处不在。本文将带了解如何将深度学习应用于一个有趣的问题——年龄检测。

为什么参与实践问题(深度学习)?

如果最近学习或阅读了关于深度学习的内容,并希望将新技能付诸实践,那么实践问题是一个理想的起点。这些实践问题提供了从零开始解决问题的经验,而且不会过于竞争。以下是应该选择一些实践问题的几个理由:

建立基础知识:总是建议,应该始终从建立正确的基础开始(考虑问题陈述和探索数据集),并大量实践。仍然看到有人在没有思考问题和理解数据的情况下就开始编码。这种方法实际上并没有探索问题和数据,因为直接关注于利用算法。

同行学习(论坛/博客):在实践问题中,参与者会在论坛或通过博客分享他们的方法,并总是愿意讨论新的方法。由于这不是一个有奖竞赛,人们不会保留意见。

实践:这些实践问题就像在处理现实生活问题之前的练习。应该首先在这里评估表现,并努力做得更好。在这段时间里,主要目标应该是充分利用工具、算法和数据集。

测试知识:这是一个尝试学到的东西的好地方,这将对非常有益。结果并不那么重要,因为这是一个实践问题。

问题是什么?

参与黑客马拉松的第一步是理解问题。在本文中,将关注一个最近发布的实践问题:印度演员的年龄检测。可以在黑客马拉松页面上查看问题陈述,但会在这里简要提及。

任务是从他或她的面部特征预测一个人的年龄。为了简单起见,问题已经被转换为一个多类问题,类别为年轻、中年和老年。

乍一看似乎很容易,对吧?但如果查看数据,即使对人类来说也很难!让自己检查一下!以下是数据中的一些随机示例。

中年:

老年:

年轻:

但能否猜出这些?显然,这两个都是中年演员!

要解决这些问题,需要有一个系统化的方法。将在下一节中看到这一点。

让解决问题!

现在知道了问题,让开始吧。假设已经安装了numpy、scipy、pandas、scikit-learn和keras。如果没有,请安装它们。上述文章应该可以帮助。

首先,让下载数据并将其加载到jupyter笔记本中!如果还没有被介绍;这里是实践问题的链接()。

在构建模型之前,敦促解决这个简单的练习:能编写一个脚本来随机加载一个图像到jupyter笔记本并打印它吗?(PS:不要看下面的答案!)。请在中发布代码。

以下是对这个练习的方法;像往常一样,首先导入了所有必要的模块:

% pylab inline import os import random import pandas as pd from scipy.misc import imread

然后加载了csv文件,这样可以更容易地定位文件:

root_dir = os.path.abspath('.') data_dir = '/mnt/hdd/datasets/misc' train = pd.read_csv(os.path.join(data_dir, 'train.csv')) test = pd.read_csv(os.path.join(data_dir, 'test.csv'))

然后编写了一个脚本来随机选择一个图像并打印它:

i = random.choice(train.index) img_name = train.ID[i] img = imread(os.path.join(data_dir, 'Train', img_name)) print('Age: ', train.Class[i]) imshow(img)

这就是得到的结果:

Age: YOUNG

这个练习的目的是可以随机查看数据集,并检查在构建模型时可能面临的一些问题。以下是对可能面临的一些问题的假设:

形状变化:一张图像的形状是(66, 46),而其他图像是(102, 87)。

多个视角:有各种视角的面孔!以下是一些示例:

图像质量:一些图像被发现过于像素化。这是一个示例。

亮度和对比度的差异:检查下面的图像;它们是否让觉得解决问题变得更容易了?

目前,让只关注一个问题,即如何处理形状的变化?可以通过简单地调整图像大小来做到这一点。让加载所有图像并将它们调整为一个单一的numpy数组。

from scipy.misc import imresize temp = [] for img_name in train.ID: img_path = os.path.join(data_dir, 'Train', img_name) img = imread(img_path) img = imresize(img, (32, 32)) img = img.astype('float32') # 这将在后期帮助 temp.append(img) train_x = np.stack(temp)

对于测试图像也类似:

temp = [] for img_name in test.ID: img_path = os.path.join(data_dir, 'Test', img_name) img = imread(img_path) img = imresize(img, (32, 32)) temp.append(img.astype('float32')) test_x = np.stack(temp)

还可以做的一件事是可以帮助构建更好的模型,即可以归一化图像。归一化图像将使训练更快。

train_x = train_x / 255. test_x = test_x / 255.

现在让看看目标变量。还有一个练习给;能说出数据中类别的分布吗?能说这是一个高度不平衡的问题吗?

train.Class.value_counts(normalize=True)

基于数据的分布,可以创建一个简单的提交。看到大多数演员都是中年的。所以可以认为测试数据集中的所有演员都是中年的!

test['Class'] = 'MIDDLE' test.to_csv('sub01.csv', index=False)

上传这个文件到提交页面,看看结果!

让解决问题!第2部分:构建更好的模型

在创建一些实质性的东西之前,让将目标变量调整为形状。将把目标转换为虚拟列,这样模型就更容易消化了。以下是将如何做到这一点。

import keras from sklearn.preprocessing import LabelEncoder lb = LabelEncoder() train_y = lb.fit_transform(train.Class) train_y = keras.utils.np_utils.to_categorical(train_y)

现在来到了主要部分,构建模型!由于问题与图像处理相关,使用神经网络来解决问题是更明智的。也将为此问题构建一个简单的前馈神经网络。

首先,应该指定将在网络中使用的所有参数:

input_num_units = (32, 32, 3) hidden_num_units = 500 output_num_units = 3 epochs = 5 batch_size = 128

然后将导入必要的keras模块:

from keras.models import Sequential from keras.layers import Dense, Flatten, InputLayer

之后,将定义网络:

model = Sequential([ InputLayer(input_shape=input_num_units), Flatten(), Dense(units=hidden_num_units, activation='relu'), Dense(units=output_num_units, activation='softmax'), ])

让看看模型是什么样子;让打印它

model.summary()

现在让编译网络,让它训练一段时间

model.compile(optimizer='sgd', loss='categorical_crossentropy', metrics=['accuracy']) model.fit(train_x, train_y, batch_size=batch_size, epochs=epochs, verbose=1)

看起来它正在训练!但还没有验证它。如果希望确保模型在它训练的数据和新的测试数据上都表现良好,验证是必要的。

让稍微调整一下代码来进行交叉验证。

model.fit(train_x, train_y, batch_size=batch_size, epochs=epochs, verbose=1, validation_split=0.2)

模型似乎对第一个模型表现良好。让提交结果。

pred = model.predict_classes(test_x) pred = lb.inverse_transform(pred) test['Class'] = pred test.to_csv('sub02.csv', index=False)

这是另一个简单的练习给;打印图像以及训练的模型的预测。最好在训练数据集上这样做,这样就可以检查预测和实际目标。

以下是对练习的看法:

i = random.choice(train.index) img_name = train.ID[i] img = imread(os.path.join(data_dir, 'Train', img_name)).astype('float32') imshow(imresize(img, (128, 128))) pred = model.predict_classes(train_x) print('Original:', train.Class[i], 'Predicted:', lb.inverse_transform(pred[i]))

原始:MIDDLE 预测:MIDDLE

已经建立了一个简单的基准解决方案。还能做什么?以下是可以建议的一些建议:

一个更好的神经网络模型可以给很大的提升。可以尝试使用卷积神经网络,它更适合图像相关问题。这里有一个简单的CNN供参考。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485