我假设你已经安装了numpy,scipy,pandas,scikit-learn和keras 。如果没有,请安装它们。以上文章可以帮助你。
第一件事 让我们下载数据并将其加载到我们的jupyter笔记本中!这里是实践问题的链接https://datahack.analyticsvidhya.com/contest/practice-problem-age-detection/。
在建立模型之前,我希望你解决这个简单的练习:
你可以写一个脚本,随机地将图像加载到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))
imshow(img)
print(‘Age: ‘, train.Class[i])
这是我得到的:Age:YOUNG

上述实践的练习的动机是让你能随机的访问到数据集,并且帮助发现你在建立模型时可能遇到的问题。
这里有几个我从上述实践中分析到的可能在建立模型时要面对的问题的假设。
1.形状变化:一个图像是(66,46),而另一个图像是(102,87)。
2.多个方向:我们的图像可能是多个方向的,这里有些例子:
侧面图

正视图

3.图像质量:一些图像的质量可以太差了点,例如下面这张:

4.亮度和对比度差异:检查下面的图像, 他们似乎是故意来捣乱的,但是,这种现象在实际生活中确实存在。
现在,让我们先关注一个问题,即如何处理形状的变化?

我们可以通过简单地调整图像大小来做到这一点。让我们加载所有的图像,并将它们调整为单个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') # this will help us in later stage
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)
MIDDLE 0.542751
YOUNG 0.336883
OLD 0.120366
Name: Class, dtype: float64
在分拣数据的基础上,我们可以创建一个简单的提交。我们看到大多数演员都是中年人。所以我们可以说我们测试数据集中的所有演员都是中年了!
在提交页面上上传这个文件,看看结果!
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]))
Original: MIDDLE Predicted: MIDDLE

下一步是什么?
我们已经建立了一个具有简单模型的基准解决方案。我们还能做些什么?
这里是我的一些建议:
-
一个好的神经网络模型可以帮你取得更大的进步。你可以尝试使用更适合图像相关问题的卷积神经网络。这是一个简单的CNN供你参考
希望这个简单的年龄检测实践问题能够帮助到你!
本文由北邮@爱可可-爱生活老师推荐,阿里云云栖社区组织翻译。
文章原标题《Hands on with Deep Learning -Solution for Age Detection Practice Problem》,
作者:Faizan Shaikh,数据科学爱好者,深度学习的新秀 译者:袁虎 审阅:
文章为简译,更为详细的内容,请查看原文
项目地址