使用TensorFlow2.0集成的keras实现CNN人脸识别

本文在python环境下通过TensorFlow2.0集成的keras进行人脸识别。相对于之前通过TensorFlow自己实现cnn会方便很多。

数据准备

筛选数据来自sklearn的datasets的fetch_olivetti_faces,只有400张,在cnn训练时,占用时间少,方便测试。

from sklearn import datasets

faces = datasets.fetch_olivetti_faces()

通过faces.images就是人脸对应的图像数组,我们先来看下shape:

print(faces.images.shape)
(400, 64, 64)

一共是400张64X64的图片。
我们通过matplotlib来显示出这些图片到一张图中:

from matplotlib import pyplot as plt

i = 0
plt.figure(figsize=(20, 20))
for img in faces.images:
    #总共400张图,把图像分割成20X20
    plt.subplot(20, 20, i+1)
    plt.imshow(img, cmap="gray")
    #关闭x,y轴显示
    plt.xticks([])
    plt.yticks([])
    plt.xlabel(faces.target[i])
    i = i + 1

plt.show()

看到对应的图片:
人脸以及对应的代号
从图中可以看到,每个人有10个头像,对应的人脸标签是从0-39,一共40种人脸。

了解了数据后,我们准备好特征数据和对应标签

#人脸数据
X = faces.images
#人脸对应的标签
y = faces.target
print(X[0])
print(y[0])
[[0.30991736 0.3677686  0.41735536 ... 0.37190083 0.3305785  0.30578512]
 [0.3429752  0.40495867 0.43801653 ... 0.37190083 0.338843   0.3140496 ]
 [0.3429752  0.41735536 0.45041323 ... 0.38016528 0.338843   0.29752067]
 ...
 [0.21487603 0.20661157 0.2231405  ... 0.15289256 0.16528925 0.17355372]
 [0.20247933 0.2107438  0.2107438  ... 0.14876033 0.16115703 0.16528925]
 [0.20247933 0.20661157 0.20247933 ... 0.15289256 0.16115703 0.1570248 ]]
0

每个images对应的是已经归一化的像素数据
每个target对应人脸的标签

数据预处理

首先要reshape一下数据格式,由原本的[一次的训练数量,长,宽],变为[一次的训练数量,长,宽,通道数], 通道数实际上就是深度,我们本次样本是黑白图,所以深度只有1, 如果是RGB彩色照片,通道数就是3,这个通道数也可以自己设计。

X = X.reshape(400, 64, 64, 1)

随机分割30%的数据做测试验证的数据

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)

构建模型

import  tensorflow.keras as keras

model = keras.Sequential()
# 第一层卷积,卷积的数量为128,卷积的高和宽是3x3,激活函数使用relu
model.add(keras.layers.Conv2D(128, kernel_size=3, activation='relu', input_shape=(64, 64, 1)))
# 第二层卷积
model.add(keras.layers.Conv2D(64, kernel_size=3, activation='relu'))
#把多维数组压缩成一维,里面的操作可以简单理解为reshape,方便后面Dense使用
model.add(keras.layers.Flatten())
#对应cnn的全链接层,可以简单理解为把上面的小图汇集起来,进行分类
model.add(keras.layers.Dense(40, activation='softmax'))


model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])
              

训练

训练比较简单,通过fit就会开始训练,我这里定义的是5次

model.fit(X_train, y_train, epochs=5)

训练大概要个1分钟,期间会自动打印出训练信息,最后一轮次输出的训练结果:

Epoch 5/5

 32/280 [==>...........................] - ETA: 2s - loss: 0.1754 - accuracy: 1.0000
 64/280 [=====>........................] - ETA: 2s - loss: 0.1746 - accuracy: 0.9844
 96/280 [=========>....................] - ETA: 2s - loss: 0.1948 - accuracy: 0.9688
128/280 [============>.................] - ETA: 1s - loss: 0.2082 - accuracy: 0.9609
160/280 [================>.............] - ETA: 1s - loss: 0.1858 - accuracy: 0.9625
192/280 [===================>..........] - ETA: 1s - loss: 0.1946 - accuracy: 0.9531
224/280 [=======================>......] - ETA: 0s - loss: 0.1739 - accuracy: 0.9598
256/280 [==========================>...] - ETA: 0s - loss: 0.1582 - accuracy: 0.9648
280/280 [==============================] - 3s 12ms/sample - loss: 0.1528 - accuracy: 0.9679

通过打印的结果可以看到,accuracy的评分可以达到0.9679,已经是比较高的评分了。损失值也很低。当然这里还是有优化的空间的, 我们可以自己尝试。

验证

先进行预测,发现这里的方法和sklearn很相似。

y_predict = model.predict(X_test)

预测后,然后和测试标签进行比对:

print(y_test[0], np.argmax(y_predict[0]))
18 18

预测准确~

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值