我们的任务是从一个人的面部特征来预测他的年龄(用“Young”“Middle ”“Old”表示),我们训练的数据集大约有19906多张照片及其每张图片对应的年龄(全是阿三的头像。。。),测试集有6636张图片,首先我们加载数据集,然后我们通过深度学习框架Keras建立、编译、训练模型,预测出6636张人物头像对应的年龄
我们随机打开几张图片之后,可以发现图片之间的差别比较大。大家感受下:
质量好的图片:
Middle: **Middle** Young: **Young** Old: **Old**质量差的:
Middle: **Middle**下面是我们需要面临的问题:
图片的尺寸差别:有的图片的尺寸是66x46,而另一张图片尺寸为102x87人物面貌角度不同: 侧脸: 正脸:图片质量不一(直接上图):
插图亮度和对比度的差异
亮度 对比度现在,我们只专注下图片尺寸处理,将每一张图片尺寸重置为32x32
另外我们再归一化图像,这样会使模型训练的更快
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)将目标变量处理虚拟列,能够使模型更容易接受识别它
import keras from sklearn.preprocessing import LabelEncoder lb=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)我们使用最基本的模型来处理这个年龄预测结果,并且最终的预测结果为0.6375。接下来,从以下角度尝试优化:
使用更好的神经网络模型增加训练次数将图片进行灰度处理(因为对于本问题而言,图片颜色不是一个特别重要的特征。)添加卷积层之后,预测准确率有所上涨,从6.3到6.7;最开始epochs轮数是5,训练轮数增加到10,此时准确率为6.87;然后将训练轮数增加到20,结果没有发生变化。
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=10 filtersize=(5,5) epochs =10 batchsize=128 input_shape=(32,32,3) from keras.models import Sequential model = 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 samples Epoch 1/10 13934/13934 [==============================] - 9s - loss: 0.8986 - acc: 0.5884 - val_loss: 0.8352 - val_acc: 0.6271 Epoch 2/10 13934/13934 [==============================] - 9s - loss: 0.8141 - acc: 0.6281 - val_loss: 0.7886 - val_acc: 0.6474 Epoch 3/10 13934/13934 [==============================] - 9s - loss: 0.7788 - acc: 0.6504 - val_loss: 0.7706 - val_acc: 0.6551 Epoch 4/10 13934/13934 [==============================] - 9s - loss: 0.7638 - acc: 0.6577 - val_loss: 0.7559 - val_acc: 0.6626 Epoch 5/10 13934/13934 [==============================] - 9s - loss: 0.7484 - acc: 0.6679 - val_loss: 0.7457 - val_acc: 0.6710 Epoch 6/10 13934/13934 [==============================] - 9s - loss: 0.7346 - acc: 0.6723 - val_loss: 0.7490 - val_acc: 0.6780 Epoch 7/10 13934/13934 [==============================] - 9s - loss: 0.7217 - acc: 0.6804 - val_loss: 0.7298 - val_acc: 0.6795 Epoch 8/10 13934/13934 [==============================] - 9s - loss: 0.7162 - acc: 0.6826 - val_loss: 0.7248 - val_acc: 0.6792 Epoch 9/10 13934/13934 [==============================] - 9s - loss: 0.7082 - acc: 0.6892 - val_loss: 0.7202 - val_acc: 0.6890 Epoch 10/10 13934/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,643 Trainable params: 6,643 Non-trainable params: 0 _________________________________________________________________我们在模型中多添加几层并且提高卷几层的输出维度,这次结果得到显著提升:0.750904
#参数初始化 filters1=50 filters2=100 filters3=100 filtersize=(5,5) epochs =10 batchsize=128 input_shape=(32,32,3) from keras.models import Sequential model = 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 samples Epoch 1/10 13934/13934 [==============================] - 44s - loss: 0.8613 - acc: 0.5985 - val_loss: 0.7778 - val_acc: 0.6586 Epoch 2/10 13934/13934 [==============================] - 44s - loss: 0.7493 - acc: 0.6697 - val_loss: 0.7545 - val_acc: 0.6808 Epoch 3/10 13934/13934 [==============================] - 43s - loss: 0.7079 - acc: 0.6877 - val_loss: 0.7150 - val_acc: 0.6947 Epoch 4/10 13934/13934 [==============================] - 43s - loss: 0.6694 - acc: 0.7061 - val_loss: 0.6496 - val_acc: 0.7261 Epoch 5/10 13934/13934 [==============================] - 43s - loss: 0.6274 - acc: 0.7295 - val_loss: 0.6683 - val_acc: 0.7125 Epoch 6/10 13934/13934 [==============================] - 43s - loss: 0.5950 - acc: 0.7462 - val_loss: 0.6194 - val_acc: 0.7400 Epoch 7/10 13934/13934 [==============================] - 43s - loss: 0.5562 - acc: 0.7655 - val_loss: 0.5981 - val_acc: 0.7465 Epoch 8/10 13934/13934 [==============================] - 43s - loss: 0.5165 - acc: 0.7852 - val_loss: 0.6458 - val_acc: 0.7354 Epoch 9/10 13934/13934 [==============================] - 46s - loss: 0.4826 - acc: 0.7986 - val_loss: 0.6206 - val_acc: 0.7467 Epoch 10/10 13934/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,303 Trainable params: 379,303 Non-trainable params: 0 _________________________________________________________________还可以优化,继续探讨