RBF(Radial-Basis Function)网路之一:多元插值法

1 插值:在离散数学的基础上补插连续函数,使得这条连续曲线通过全部给定的离散数据点。(来自百度百科)插值除了给定的离散数据点外,连续曲线的其他点都属于“插入”进来的,所以称插值。

在多维空间的插值法定义为:

给定N个不同的点集x\epsilon R^{m_{0}}|i=1,2,...N和一组相对应的N个实数集合d\epsilon R^{1}|i=1,2,...N,找到一个函数满足如下的条件:

F(x_{i})=d_{i}                                                                                                                                  (1)     插值和拟合的区别:

(1)共同点:两者都是寻求函数曲线(曲线)

(2)不同点:插值要求曲线(或曲面)过全部的离散数据点,而拟合是寻求全局最接近的结果,即要求拟合函数和数据点的最小二乘意义最小。

2插值的常用方法

(1)牛顿法

(2)逐次线性插值

(3)拉格朗日插值法

(4)等距节点插值

(5)Herminte法

(6)分段低次插值

(7)样条插值

本篇主要介绍的rbf插值法

3 rbf插值法

rbf插值法是由Powell 于1985年提出。其基本思想不是直接使用原数据点进行插值,而是使用每个点与中心点的距离,距离一般是欧几里得距离,也就是每个点离中心点的径向距离如下表示:

||\mathbf{x}-\mathbf{x}_{i}||)

其中已知的插值节点\mathbf{x}_{i}是中心点,\mathbf{x}_{i}\epsilon R^{m_{0}}|i=1,2,...N\mathbf{x}\epsilon R^{m_{0}}是等待插值的节点,m_{0}是插值节点的维度 。而RBF插值的基函数具有如下形式:

\varphi (||\mathbf{x}-\mathbf{x}_{i}||)| i=1,2,...,N,

此函数称为径向基函数,通常是非线性的,此函数常用的形式见下文。而RBF的插值函数有如下形式:

F(\mathbf{x})=\sum_{i=1}^{N}w_{i}\varphi (||\mathbf{x}-\mathbf{x}_{i}||)

其中w_{i}是插值矩阵。由于F(x_{i})=d_{i}我们可以得到如下变换式:

\begin{bmatrix} \varphi _{11} & \varphi _{12} &... & \varphi _{1N}\\ \varphi _{21}& \varphi _{22} &... &\varphi _{2N} \\ ... & ... & ... & ...\\ \varphi _{N1}& \varphi _{N2} &... &\varphi _{NN} \end{bmatrix}\begin{bmatrix} w_{1}\\ w_{2}\\ ...\\ w_{N} \end{bmatrix}= \begin{bmatrix} d_{1}\\ d_{2}\\ ...\\ d_{N} \end{bmatrix}

其中记\varphi _{i,j}=\varphi (||\mathbf{x}_{i}-\mathbf{x}_{j}||)|i,j=1,2,...N

便于表示,我们有如下记号:

\mathbf{w}=\left [ w_{1} ,w_{1} ,... ,w_{1N} \right ]^{T}

\mathbf{d}=\left [ d_{1} ,d_{1} ,... ,d_{1N} \right ]^{T}

\mathbf{\phi }=\left \{ \varphi _{i,j}\right \}_{i=1}^{N} (左边是粗体),

其中\mathbf{d,w }均是N行1列的向量,称\mathbf{d}为要求的结果向量,称\mathbf{w}为线性权重向量,而\phi称为插值矩阵,它是N行N列,且是对称矩阵

由此,上述公式可简化为:

\mathbf{\phi }\mathbf{w}=\mathbf{d}

如果插值矩阵\phi是非奇异的,则其逆矩阵\phi ^{-1}存在,此时可求得线性权重向量

\mathbf{w}=\phi ^{-1}\mathbf{d}

插值向量是不是非奇异的,可以由Micchelli理论来解释。

Micchelli定理:

\mathbf{x}_{i}\epsilon R^{m_{0}}|i=1,2,...N是实数域R^{m_{0}}里互不相同的节点,则其插值矩阵\mathbf{\phi }=\left \{ \varphi _{i,j}\right \}_{i=1}^{N}是非奇异的。

满足Micchelli定理的径向基函数\varphi有如下:

(1)多二次函数

\varphi(r)=(r^{2}+c^{2})^{1/2},c>0,r\epsilon R

(2)逆多二次函数

\varphi(r)=\frac{1}{(r^{2}+c^{2})^{1/2}} ,c>0,r\epsilon R

(3)高斯函数

\varphi(r)=exp(-\frac{r^{2}}{2\sigma ^{2}}) ,\sigma >0,r\epsilon R

对于上述三种函数,如果插值节点是互不相同的,无论输入样本数N是多少,也无论输入样本的维度m_{0}是多少,它的插值矩阵\phi总是非奇异的。注意:此方法介绍的插值法是完全内插法,要求插值曲线过每一个插值节点。对于逆多二次函数和高斯函数,当r\rightarrow \infty时,\varphi(r)\rightarrow 0,插值矩阵是正定的,这两种函数被称为本地化函数,而多二次函数则r\rightarrow \infty时,\varphi(r)\rightarrow \infty,被称为非本地化函数,插值矩阵具有N-1个负的特征值和1个正的特征值,而且它还不是正定的

插值节点的计算公式如下:

4实现

(1)使用RBF进行一维插值

#rbf插值
import numpy as np
import matplotlib.pyplot as plt

def gen_data(x1,x2):
    y_sample = np.sin(np.pi*x1/2)+np.cos(np.pi*x1/2)
    y_all = np.sin(np.pi*x2/2)+np.cos(np.pi*x2/2)
    return y_sample, y_all

def kernel_interpolation(y_sample,x1,sig):
    gaussian_kernel = lambda x,c,h: np.exp(-(x-c)**2/(2*(h**2)))#使用高斯核函数
    num = len(y_sample)
    w = np.zeros(num)
    int_matrix = np.asmatrix(np.zeros((num,num)))#计算插值矩阵
    for i in range(num):
        int_matrix[i,:] = gaussian_kernel(x1,x1[i],sig)  
    w = int_matrix.I * np.asmatrix(y_sample).T  #计算权重矩阵    
    return w

def kernel_interpolation_rec(w,x1,x2,sig):#根据权重矩阵,进行插值
    gkernel = lambda x,xc,h: np.exp(-(x-xc)**2/(2*(h**2)))
    num = len(x2)
    y_rec = np.zeros(num)
    for i in range(num):
        for k in range(len(w)):
            y_rec[i] = y_rec[i] + w[k]*gkernel(x2[i],x1[k],sig)
    return y_rec

if __name__ == '__main__':
    snum = 20   # 插值节点数量
    ratio = 20  # 总数据点数量:snum*ratio
    sig = 1		# 核函数宽度
    xs = -8
    xe = 8
    x1 = np.linspace(xs,xe,snum)
    x2 = np.linspace(xs,xe,(snum-1)*ratio+1)
    y_sample, y_all = gen_data(x1,x2)
    plt.figure(1)
    plt.rcParams['font.sans-serif']=['SimHei'] #显示中文标签
    plt.rcParams['axes.unicode_minus']=False   #这两行需要手动设置
    w = kernel_interpolation(y_sample,x1,sig)   
    y_rec = kernel_interpolation_rec(w,x1,x2,sig)
    plt.plot(x2,y_rec,'k')
    plt.plot(x2,y_all,'r:')        
    plt.ylabel('y')
    plt.xlabel('x')
    for i in range(len(x1)):        
        plt.plot(x1[i],y_sample[i],'go',markerfacecolor='none')        
        
    plt.legend(labels=['插值曲线','原函数曲线','插值节点'],loc='lower left')
    plt.title('kernel interpolation:$y=sin(\pi x/2)+cos(\pi x/2)$')       
    plt.show()
    MSE = np.linalg.norm(y_all-y_rec, ord=2)**2/len(y_all)

MSE误差为0.00013145540771572465

(2)使用RBF进行二维插值

#rbf二维插值
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
#定义二维函数
def gen_data(x1,x2):
    y=20+x1**2-10*np.cos(2*np.pi*x1)+x2**2-10*np.cos(2*np.pi*x2) #插值函数
    return y
def kernel_interpolation(y_sample,x1,x2,sig):
    gaussian_kernel = lambda x1,x2,y1,y2,h:np.exp((-(x1-x2)**2-(y1-y2)**2)/(2*(h**2)))#计算二维空间欧式距离
    num = len(y_sample)
    w = np.zeros(num)
    int_matrix = np.asmatrix(np.zeros((num,num))) #插值矩阵
    for i in range(num):
        int_matrix[i,:] = gaussian_kernel(x1,x1[i],x2,x2[i],sig)  
    w = int_matrix.I * np.asmatrix(y_sample).T    #权重矩阵  
    return w

def kernel_interpolation_rec(w,x1,x2,y1,y2,sig):#进行插值
    gkernel = lambda x1,y1,x2,y2,h: np.exp((-(x1-y1)**2-(x2-y2)**2)/(2*(h**2)))
    num = len(y1)
    y_rec = np.zeros(num)
    for i in range(num):
        for k in range(len(w)):
            y_rec[i] = y_rec[i] + w[k]*gkernel(y1[i],x1[k],y2[i],x2[k],sig)
    return y_rec
if __name__ == '__main__':
    snum = 20  # 插值节点数量
    ratio = 20  # 总数据点数量:snum*ratio
    sig = 1		# 核函数宽度
    xs = -8
    xe = 8
    x1 = np.linspace(xs,xe,snum)
    x2=x1
    y1 = np.linspace(xs,xe,(snum-1)*ratio+1)
    y2=y1
    y_sample = gen_data(x1,x2)
    y_all=gen_data(y1,y2)
    w = kernel_interpolation(y_sample,x1,x2,sig) 
    y_rec = kernel_interpolation_rec(w,x1,x2,y1,y2,sig)
    MSE = np.linalg.norm(y_all-y_rec, ord=2)**2/len(y_all)
    print(MSE)

参考资料:

1 Nerual networks and Learning Machines Third Edition ,.神经网络与机器学习 Simon Haykin第三版,第五章。

2 基于径向基函数(RBF)的函数插值.https://blog.csdn.net/xfijun/article/details/105670892

3 数值分析 第五版 李庆扬、王能超、易大义编

  • 6
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值