[关闭]
@cww97 2017-12-28T18:25:31.000000Z 字数 1956 阅读 857

人脸识别

机器学习


陈伟文 10152510217

一张图片 转换成一个列向量,各个像素点就是列向量中的元素,然后 这些训练的图片集就是A(训练数据集)。b就是testing,一张图片,我们要迭代x,使得让最后b作为测试的图片带入这个方程

算法原理

人脸的稀疏表示是基于光照模型。即一张人脸图像,可以用数据库中同一个人所有的人脸图像的线性组合表示。而对于数据库中其它人的脸,其线性组合的系数理论上为零。由于数据库中一般有很多个不同的人脸的多张图像,如果把数据库中所有的图像的线性组合来表示这张给定的测试人脸,其系数向量是稀疏的。因为除了这张和同一个人的人脸的图像组合系数不为零外,其它的系数都为零。

Src算法

image.png-220.9kB

数据加载

image.png-243.5kB

在这里,我们将每一张图片转换为一个列向量,行数为像素点的个数。一组照片为一系列列向量的集合。然后把 30 组的照片的测试集合都集合在一个矩阵中,用于迭代系数x(每组照片五张用于训练,一张用于测试)。另外,将用于预测的图片 testImg 转换为单独的列向量

  1. N, M = 112, 92
  2. EPS = 0.025
  3. def Normalize(A):
  4. m = A.shape[1] # col
  5. B = np.empty(shape=[N*M, 0])
  6. for i in range(m):
  7. b = A[:, i] / np.linalg.norm(A[:, i], ord=2)
  8. b = np.reshape(b, (N*M, 1))
  9. B = np.concatenate((B, b), axis=1)
  10. return B
  11. def load_data():
  12. testImg = np.array(Image.open('data/feret/1-1.bmp'))
  13. testImg = np.reshape(testImg, (N*M, 1))
  14. testImg = testImg / np.linalg.norm(testImg, ord=2)
  15. #print(testImg)
  16. A = np.empty(shape=[N*M, 0])
  17. for i in np.arange(1, 31):
  18. for j in np.arange(1, 6):
  19. img = np.array(Image.open('data/feret/' + str(i) + '-' + str(j) + '.bmp'))
  20. img = np.reshape(img, (N*M, 1))
  21. A = np.concatenate((A, img), axis=1)
  22. A = Normalize(A)
  23. print(A, 'shape = ', A.shape)
  24. return A, testImg

算法主过程

近端梯度下降法实现,数值计算很重要啊

  1. def proximal_gradient(A, testImg):
  2. L = np.linalg.norm(2*np.dot(A, A.T))**2
  3. lamada = 5
  4. x1 = np.ones((A.shape[1], 1))
  5. cnt = 0
  6. while True:
  7. cnt += 1
  8. x0 = x1
  9. gradient = 2*np.dot(np.dot(A.T, A), x0) - 2*np.dot(A.T, testImg)
  10. z = x0 - gradient / L
  11. e0 = np.linalg.norm(np.dot(A, x0) - testImg, ord=2)**2 + lamada*np.linalg.norm(x0, ord=1)
  12. for i in np.arange(0, x0.shape[0]):
  13. if z[i, 0] > lamada/L:
  14. x1[i, 0] = z[i, 0] - lamada/L
  15. elif z[i, 0] < -lamada/L:
  16. x1[i, 0] = z[i, 0] + lamada/L
  17. else:
  18. x1[i, 0] = 0
  19. e1 = np.linalg.norm(np.dot(A, x1) - testImg, ord=2)**2 + lamada*np.linalg.norm(x1, ord=1)
  20. print('cnt = ', cnt, ', :', e0-e1)
  21. if e0-e1 < EPS: break
  22. return x1

分组测试

  1. def get_group_data(x, i):
  2. new_x = np.zeros((x.shape[1], 1))
  3. for j in np.arange(5*i,i*i+5):
  4. new_x[j, 0] = x[j, 0]
  5. return new_x
  6. def test(A, x, y):
  7. Min = float(np.inf)
  8. idx = -1
  9. for i in range(29):
  10. dis = np.ninalg.norm(y - np.dot(A, get_group_data(x, i)))
  11. if dis < Min:
  12. Min, idx = dis, i
  13. return idx

正确率100%,大概是所有给的数据都是很正的,即人脸都充满整张图,大概如果数据没这么舒服可能就会难很多,明年有个项目想做人脸识别模块,数据预处理果然永远比机器学习算法更重要,灰度化,从照片中抠出一张人脸,再压缩成规定像素,哇哦,这门课叫数字图像处理

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注