深度学习实战-使用Kera预测人物年龄
来源:互联网 发布:琉璃神社app备用域名 编辑:程序博客网 时间:2024/05/22 21:44
问题描述
我们的任务是从一个人的面部特征来预测他的年龄(用“Young”“Middle ”“Old”表示),我们训练的数据集大约有19906多张照片及其每张图片对应的年龄(全是阿三的头像。。。),测试集有6636张图片,首先我们加载数据集,然后我们通过深度学习框架Keras建立、编译、训练模型,预测出6636张人物头像对应的年龄
引入所需要模块
import osimport randomimport pandas as pdimport numpy as npfrom PIL import Image
加载数据集
root_dir=os.path.abspath('E:/data/age')train=pd.read_csv(os.path.join(root_dir,'train.csv'))test=pd.read_csv(os.path.join(root_dir,'test.csv'))print(train.head())print(test.head())
ID Class0 377.jpg MIDDLE1 17814.jpg YOUNG2 21283.jpg MIDDLE3 16496.jpg YOUNG4 4487.jpg MIDDLE ID0 25321.jpg1 989.jpg2 19277.jpg3 13093.jpg4 5367.jpg
随机读取一张图片试下(☺)
i=random.choice(train.index)img_name=train.ID[i]print(img_name)img=Image.open(os.path.join(root_dir,'Train',img_name))img.show()print(train.Class[i])
20188.jpgMIDDLE
难点
我们随机打开几张图片之后,可以发现图片之间的差别比较大。大家感受下:
质量好的图片:
- Middle:
- Young:
- Old:
- Middle:
质量差的:
- Middle:
- Middle:
下面是我们需要面临的问题:
- 图片的尺寸差别:有的图片的尺寸是66x46,而另一张图片尺寸为102x87
- 人物面貌角度不同:
- 侧脸:
- 正脸:
- 侧脸:
图片质量不一(直接上图):
亮度和对比度的差异
现在,我们只专注下图片尺寸处理,将每一张图片尺寸重置为32x32
格式化图片尺寸和将图片转换成numpy数组
temp=[]for img_name in train.ID: img_path=os.path.join(root_dir,'Train',img_name) img=Image.open(img_path) img=img.resize((32,32)) array=np.array(img) temp.append(array.astype('float32'))train_x=np.stack(temp)print(train_x.shape)print(train_x.ndim)
(19906, 32, 32, 3)4
temp=[]for img_name in test.ID: img_path=os.path.join(root_dir,'Test',img_name) img=Image.open(img_path) img=img.resize((32,32)) array=np.array(img) temp.append(array.astype('float32'))test_x=np.stack(temp)print(test_x.shape)
(6636, 32, 32, 3)
另外我们再归一化图像,这样会使模型训练的更快
train_x = train_x / 255.test_x = test_x / 255.
我们看下图片年龄大致分布
train.Class.value_counts(normalize=True)
MIDDLE 0.542751YOUNG 0.336883OLD 0.120366Name: Class, dtype: float64
test['Class'] = 'MIDDLE'test.to_csv('sub01.csv', index=False)
将目标变量处理虚拟列,能够使模型更容易接受识别它
import kerasfrom sklearn.preprocessing import LabelEncoderlb=LabelEncoder()train_y=lb.fit_transform(train.Class)print(train_y)train_y=keras.utils.np_utils.to_categorical(train_y)print(train_y)print(train_y.shape)
[0 2 0 ..., 0 0 0][[ 1. 0. 0.] [ 0. 0. 1.] [ 1. 0. 0.] ..., [ 1. 0. 0.] [ 1. 0. 0.] [ 1. 0. 0.]](19906, 3)
创建模型
#构建神经网络input_num_units=(32,32,3)hidden_num_units=500output_num_units=3epochs=5batch_size=128
from keras.models import Sequentialfrom keras.layers import Dense,Flatten,InputLayermodel=Sequential({ InputLayer(input_shape=input_num_units), Flatten(), Dense(units=hidden_num_units,activation='relu'), Dense(input_shape=(32,32,3),units=output_num_units,activation='softmax')})model.summary()
_________________________________________________________________Layer (type) Output Shape Param # =================================================================input_23 (InputLayer) (None, 32, 32, 3) 0 _________________________________________________________________flatten_23 (Flatten) (None, 3072) 0 _________________________________________________________________dense_45 (Dense) (None, 500) 1536500 _________________________________________________________________dense_46 (Dense) (None, 3) 1503 =================================================================Total params: 1,538,003Trainable params: 1,538,003Non-trainable params: 0_________________________________________________________________
编译模型
# model.compile(optimizer='sgd',loss='categorical_crossentropy',metrics=['accuracy'])model.compile(optimizer='sgd',loss='categorical_crossentropy', metrics=['accuracy'])model.fit(train_x,train_y,batch_size=batch_size,epochs=epochs,verbose=1)
Epoch 1/519906/19906 [==============================] - 4s - loss: 0.8878 - acc: 0.5809 Epoch 2/519906/19906 [==============================] - 4s - loss: 0.8420 - acc: 0.6077 Epoch 3/519906/19906 [==============================] - 4s - loss: 0.8210 - acc: 0.6214 Epoch 4/519906/19906 [==============================] - 4s - loss: 0.8149 - acc: 0.6194 Epoch 5/519906/19906 [==============================] - 4s - loss: 0.8042 - acc: 0.6305 <keras.callbacks.History at 0x1d3803e6278>
model.fit(train_x, train_y, batch_size=batch_size,epochs=epochs,verbose=1, validation_split=0.2)
Train on 15924 samples, validate on 3982 samplesEpoch 1/515924/15924 [==============================] - 3s - loss: 0.7970 - acc: 0.6375 - val_loss: 0.7854 - val_acc: 0.6396Epoch 2/515924/15924 [==============================] - 3s - loss: 0.7919 - acc: 0.6378 - val_loss: 0.7767 - val_acc: 0.6519Epoch 3/515924/15924 [==============================] - 3s - loss: 0.7870 - acc: 0.6404 - val_loss: 0.7754 - val_acc: 0.6534Epoch 4/515924/15924 [==============================] - 3s - loss: 0.7806 - acc: 0.6439 - val_loss: 0.7715 - val_acc: 0.6524Epoch 5/515924/15924 [==============================] - 3s - loss: 0.7755 - acc: 0.6519 - val_loss: 0.7970 - val_acc: 0.6346<keras.callbacks.History at 0x1d3800a4eb8>
优化
我们使用最基本的模型来处理这个年龄预测结果,并且最终的预测结果为0.6375。接下来,从以下角度尝试优化:
- 使用更好的神经网络模型
- 增加训练次数
- 将图片进行灰度处理(因为对于本问题而言,图片颜色不是一个特别重要的特征。)
optimize1 使用卷积神经网络
添加卷积层之后,预测准确率有所上涨,从6.3到6.7;最开始epochs轮数是5,训练轮数增加到10,此时准确率为6.87;然后将训练轮数增加到20,结果没有发生变化。
Conv2D层
keras.layers.convolutional.Conv2D(filters, kernel_size, strides=(1, 1), padding='valid', data_format=None, dilation_rate=(1, 1), activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None)
- filters:输出的维度
- strides:卷积的步长
更多关于Conv2D的介绍请看Keras文档Conv2D层
#参数初始化filters=10filtersize=(5,5)epochs =10batchsize=128input_shape=(32,32,3)
from keras.models import Sequentialmodel = Sequential()model.add(keras.layers.InputLayer(input_shape=input_shape))model.add(keras.layers.convolutional.Conv2D(filters, filtersize, strides=(1, 1), padding='valid', data_format="channels_last", activation='relu'))model.add(keras.layers.MaxPooling2D(pool_size=(2, 2)))model.add(keras.layers.Flatten())model.add(keras.layers.Dense(units=3, input_dim=50,activation='softmax'))model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])model.fit(train_x, train_y, epochs=epochs, batch_size=batchsize,validation_split=0.3)model.summary()
Train on 13934 samples, validate on 5972 samplesEpoch 1/1013934/13934 [==============================] - 9s - loss: 0.8986 - acc: 0.5884 - val_loss: 0.8352 - val_acc: 0.6271Epoch 2/1013934/13934 [==============================] - 9s - loss: 0.8141 - acc: 0.6281 - val_loss: 0.7886 - val_acc: 0.6474Epoch 3/1013934/13934 [==============================] - 9s - loss: 0.7788 - acc: 0.6504 - val_loss: 0.7706 - val_acc: 0.6551Epoch 4/1013934/13934 [==============================] - 9s - loss: 0.7638 - acc: 0.6577 - val_loss: 0.7559 - val_acc: 0.6626Epoch 5/1013934/13934 [==============================] - 9s - loss: 0.7484 - acc: 0.6679 - val_loss: 0.7457 - val_acc: 0.6710Epoch 6/1013934/13934 [==============================] - 9s - loss: 0.7346 - acc: 0.6723 - val_loss: 0.7490 - val_acc: 0.6780Epoch 7/1013934/13934 [==============================] - 9s - loss: 0.7217 - acc: 0.6804 - val_loss: 0.7298 - val_acc: 0.6795Epoch 8/1013934/13934 [==============================] - 9s - loss: 0.7162 - acc: 0.6826 - val_loss: 0.7248 - val_acc: 0.6792Epoch 9/1013934/13934 [==============================] - 9s - loss: 0.7082 - acc: 0.6892 - val_loss: 0.7202 - val_acc: 0.6890Epoch 10/1013934/13934 [==============================] - 9s - loss: 0.7001 - acc: 0.6940 - val_loss: 0.7226 - val_acc: 0.6885_________________________________________________________________Layer (type) Output Shape Param # =================================================================input_6 (InputLayer) (None, 32, 32, 3) 0 _________________________________________________________________conv2d_6 (Conv2D) (None, 28, 28, 10) 760 _________________________________________________________________max_pooling2d_6 (MaxPooling2 (None, 14, 14, 10) 0 _________________________________________________________________flatten_6 (Flatten) (None, 1960) 0 _________________________________________________________________dense_6 (Dense) (None, 3) 5883 =================================================================Total params: 6,643Trainable params: 6,643Non-trainable params: 0_________________________________________________________________
optimize2 增加神经网络的层数
我们在模型中多添加几层并且提高卷几层的输出维度,这次结果得到显著提升:0.750904
#参数初始化filters1=50filters2=100filters3=100filtersize=(5,5)epochs =10batchsize=128input_shape=(32,32,3)
from keras.models import Sequentialmodel = Sequential()model.add(keras.layers.InputLayer(input_shape=input_shape))model.add(keras.layers.convolutional.Conv2D(filters1, filtersize, strides=(1, 1), padding='valid', data_format="channels_last", activation='relu'))model.add(keras.layers.MaxPooling2D(pool_size=(2, 2)))model.add(keras.layers.convolutional.Conv2D(filters2, filtersize, strides=(1, 1), padding='valid', data_format="channels_last", activation='relu'))model.add(keras.layers.MaxPooling2D(pool_size=(2, 2)))model.add(keras.layers.convolutional.Conv2D(filters3, filtersize, strides=(1, 1), padding='valid', data_format="channels_last", activation='relu'))model.add(keras.layers.Flatten())model.add(keras.layers.Dense(units=3, input_dim=50,activation='softmax'))model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])model.fit(train_x, train_y, epochs=epochs, batch_size=batchsize,validation_split=0.3)model.summary()
Train on 13934 samples, validate on 5972 samplesEpoch 1/1013934/13934 [==============================] - 44s - loss: 0.8613 - acc: 0.5985 - val_loss: 0.7778 - val_acc: 0.6586Epoch 2/1013934/13934 [==============================] - 44s - loss: 0.7493 - acc: 0.6697 - val_loss: 0.7545 - val_acc: 0.6808Epoch 3/1013934/13934 [==============================] - 43s - loss: 0.7079 - acc: 0.6877 - val_loss: 0.7150 - val_acc: 0.6947Epoch 4/1013934/13934 [==============================] - 43s - loss: 0.6694 - acc: 0.7061 - val_loss: 0.6496 - val_acc: 0.7261Epoch 5/1013934/13934 [==============================] - 43s - loss: 0.6274 - acc: 0.7295 - val_loss: 0.6683 - val_acc: 0.7125Epoch 6/1013934/13934 [==============================] - 43s - loss: 0.5950 - acc: 0.7462 - val_loss: 0.6194 - val_acc: 0.7400Epoch 7/1013934/13934 [==============================] - 43s - loss: 0.5562 - acc: 0.7655 - val_loss: 0.5981 - val_acc: 0.7465Epoch 8/1013934/13934 [==============================] - 43s - loss: 0.5165 - acc: 0.7852 - val_loss: 0.6458 - val_acc: 0.7354Epoch 9/1013934/13934 [==============================] - 46s - loss: 0.4826 - acc: 0.7986 - val_loss: 0.6206 - val_acc: 0.7467Epoch 10/1013934/13934 [==============================] - 45s - loss: 0.4530 - acc: 0.8130 - val_loss: 0.5984 - val_acc: 0.7569_________________________________________________________________Layer (type) Output Shape Param # =================================================================input_15 (InputLayer) (None, 32, 32, 3) 0 _________________________________________________________________conv2d_31 (Conv2D) (None, 28, 28, 50) 3800 _________________________________________________________________max_pooling2d_23 (MaxPooling (None, 14, 14, 50) 0 _________________________________________________________________conv2d_32 (Conv2D) (None, 10, 10, 100) 125100 _________________________________________________________________max_pooling2d_24 (MaxPooling (None, 5, 5, 100) 0 _________________________________________________________________conv2d_33 (Conv2D) (None, 1, 1, 100) 250100 _________________________________________________________________flatten_15 (Flatten) (None, 100) 0 _________________________________________________________________dense_7 (Dense) (None, 3) 303 =================================================================Total params: 379,303Trainable params: 379,303Non-trainable params: 0_________________________________________________________________
输出结果
pred=model.predict_classes(test_x)pred=lb.inverse_transform(pred)print(pred)test['Class']=predtest.to_csv('sub02.csv',index=False)
6636/6636 [==============================] - 7s ['MIDDLE' 'YOUNG' 'MIDDLE' ..., 'MIDDLE' 'MIDDLE' 'YOUNG']
i = random.choice(train.index)img_name = train.ID[i]img=Image.open(os.path.join(root_dir,'Train',img_name))img.show()pred = model.predict_classes(train_x)print('Original:', train.Class[i], 'Predicted:', lb.inverse_transform(pred[i]))
19872/19906 [============================>.] - ETA: 0sOriginal: MIDDLE Predicted: MIDDLE
结果
还可以优化,继续探讨
- 深度学习实战-使用Kera预测人物年龄
- Python3《机器学习实战》学习笔记(十一):线性回归基础篇之预测鲍鱼年龄
- 《机器学习实战》学习笔记(十一):线性回归基础篇之预测鲍鱼年龄
- 使用caffe实现性别年龄预测
- [机器学习实战]使用 scikit-learn 预测用户流失
- 深度学习利器:TensorFlow使用实战分享
- tensorflow19《TensorFlow实战Google深度学习框架》笔记-08-04 预测正弦函数 code
- tensorflow70 《深度学习原理与TensorFlow实战》05 RNN能说会道 01 正弦序列预测
- 深度学习RNN实现股票预测实战(附数据、代码)
- 深度学习语音预测口型
- 性别、年龄预测
- 性别、年龄预测
- 实战深度学习
- 《机器学习实战》学习笔记:绘制树形图&使用决策树预测隐形眼镜类型
- 深度学习笔记-客流预测模型-20170627
- python深度学习之销量预测
- R语言h2o深度学习回归预测
- 深度学习-BP曲线拟合(预测)
- Go Reflect
- Vue实现百度下拉提示搜索
- Swift调用OC第三方框架
- Laravel-博客实战+踩坑
- 安装es_bug
- 深度学习实战-使用Kera预测人物年龄
- 好东西
- 通过递归的矩阵向量空间预测组合语义
- Apache2.4.9本地访问正常但是在局域网或外网IP拒绝访问
- 卡特兰数
- 初学Linux--编辑环境2(调试、库)
- leetcode 198. House Robber
- 创建一个Mule应用程序
- PHP小知识