SDM(supervised descent method)算法

最近在研究人脸特征点检测,之前没接触过,有些论文虽然能看懂,但是细节的部分可能之前的论文都有提到过,就没有再提。所以找了一篇稍微早一点的文章开始学习起来。
MATLAB版本的代码基本上都看懂了,不过作者可能之前做过ASM,代码中有一些方法没有使用,或者使用了比较复杂的算法,其实只使用了其中一小部分结果,看起来有点难。准备找时间自己实现一下,看了代码应该不算难(又立flag了,督促自己不要偷懒)。这里先简单的实现SDM算法,不做人脸应用的代码。
简单的说SDM算法是牛顿法的一种改进,牛顿法在求解梯度的时候需要用到Hessian矩阵的逆以及Jacobian矩阵,在高维度的情况下这个计算量较大,而且有些情况下Hessian矩阵是不可逆的。这篇论文通过监督学习来学习Hessian矩阵的逆以及Jacobian矩阵的乘积,这样就可以省去复杂的计算过程。

下面代码是SDM实现的例子,完成对曲线的拟合。拟合过程中会打印误差值。R保存了要学习的参数。steps是蒙特卡洛采样的参数,采样点间隔越小,拟合效果越好。
代码简单的说就是在训练过程中已知dx,dy,然后可以通过最小二乘训练R,然后在Test过程中,已知dy可以通过R求解x的最优解。论文中提到了训练参数R和b,应该可以合到一起,这里只有参数R。

#coding:utf-8

import numpy as np
import math
import matplotlib.pyplot as plt

#采样间距
steps = [0.25,0.025,0.0025,0.00025]

y = np.mat(np.arange(-1,1,0.001))
x = np.mat(np.arcsin(y))


for i in range(len(steps)):
    #train
    R = []  #要学习的参数
    n = 10  #迭代次数,一般要多次迭代才能达到较好的效果,减小n会看到误差增大
    y0 = np.mat(np.arange(-1,1,steps[i]))
    x0 = np.mat(np.arcsin(y0))
    x_start = np.mat([0] * x0.shape[1])
    for j in range(n):
        dx = x0 - x_start
        dy = y0 - np.sin(x_start)
        #岭回归
        r_tmp = (dy*dy.T+np.eye(1)*0.001).I*(dy*dx.T)
        x_start = x_start + r_tmp*dy
        R.append(r_tmp)
        print np.linalg.norm(dx)    #求误差,所有元素平方和开根
    print '--------------------'
    #test
    y_pred = y
    x_pred = np.mat([0]*x.shape[1])
    for j in range(n):
        dy = y - np.sin(x_pred)
        x_pred = x_pred + R[j]*dy
        #  += 上面一句之前用了这个,一直有问题,有点坑,对于变量python是可以这么写的,矩阵不可以吧

    plt.plot(np.asarray(x)[0], np.asarray(y)[0], 'r')
    plt.plot(np.asarray(x_pred)[0], np.asarray(y_pred)[0], 'b')
    plt.show()

下面是拟合的效果图,红色为真实曲线,蓝色为训练得到的曲线。
这里写图片描述

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值