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

2023-10-09 17:32

本文主要是介绍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 pltdef 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_alldef 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 wdef 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_recif __name__ == '__main__':snum = 20   # 插值节点数量ratio = 20  # 总数据点数量:snum*ratiosig = 1		# 核函数宽度xs = -8xe = 8x1 = 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 wdef 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*ratiosig = 1		# 核函数宽度xs = -8xe = 8x1 = np.linspace(xs,xe,snum)x2=x1y1 = np.linspace(xs,xe,(snum-1)*ratio+1)y2=y1y_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 数值分析 第五版 李庆扬、王能超、易大义编

这篇关于RBF(Radial-Basis Function)网路之一:多元插值法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/174452

相关文章

AutoGen Function Call 函数调用解析(一)

目录 一、AutoGen Function Call 1.1 register_for_llm 注册调用 1.2 register_for_execution 注册执行 1.3 三种注册方法 1.3.1 函数定义和注册分开 1.3.2 定义函数时注册 1.3.3  register_function 函数注册 二、实例 本文主要对 AutoGen Function Call

(function() {})();只执行一次

测试例子: var xx = (function() {     (function() { alert(9) })(); alert(10)     return "yyyy";  })(); 调用: alert(xx); 在调用的时候,你会发现只弹出"yyyy"信息,并不见弹出"10"的信息!这也就是说,这个匿名函数只在立即调用的时候执行一次,这时它已经赋予了给xx变量,也就是只是

js私有作用域(function(){})(); 模仿块级作用域

摘自:http://outofmemory.cn/wr/?u=http%3A%2F%2Fwww.phpvar.com%2Farchives%2F3033.html js没有块级作用域,简单的例子: for(var i=0;i<10;i++){alert(i);}alert(i); for循环后的i,在其它语言像c、java中,会在for结束后被销毁,但js在后续的操作中仍然能访

rtklib.h : RTKLIB constants, types and function prototypes 解释

在 RTKLIB 中,rtklib.h 是一个头文件,包含了与 RTKLIB 相关的常量、类型和函数原型。以下是该头文件的一些常见内容和翻译说明: 1. 常量 (Constants) rtklib.h 中定义的常量通常包括: 系统常量: 例如,GPS、GLONASS、GALILEO 等系统的常量定义。 时间常量: 如一年、一天的秒数等。 精度常量: 如距离、速度的精度标准。 2. 类型

【AI大模型应用开发】2.1 Function Calling连接外部世界 - 入门与实战(1)

Function Calling是大模型连接外部世界的通道,目前出现的插件(Plugins )、OpenAI的Actions、各个大模型平台中出现的tools工具集,其实都是Function Calling的范畴。时下大火的OpenAI的GPTs,原理就是使用了Function Calling,例如联网检索、code interpreter。 本文带大家了解下Function calling,看

Vite + Vue3 +Vant4出现Toast is not a function

今天写前端的时候出现了这个问题搞了我一会 搜集原因: 1:是vant版本的问题,Toast()的方法是vant3版本的写法,而我用的是vant4,vant4中的写法改成了showToast()方法,改正过来 import {showToast} from "vant";  发现还是报错,说是找不到对应的样式文件 2:Vant 从 4.0 版本开始不再支持 babel-plugin-i

Ollama Qwen2 支持 Function Calling

默认 Ollama 中的 Qwen2 模型不支持 Function Calling,使用默认 Qwen2,Ollama 会报错。本文将根据官方模板对 ChatTemplate 进行改进,使得Qwen2 支持 Tools,支持函数调用。 Ollama 会检查对话模板中是否存在 Tools,如果不存在就会报错,下面的代码是 Ollama 解析模板的代码。 Ollama 3.1 是支持 Tools

android kotlin复习 Anonymous function 匿名函数

1、还是先上个图,新建kt: 2、代码: package com.jstonesoft.myapplication.testfun main(){val count = "helloworld".count()println(count);println("------------------------")var count2 = "helloworld".count(){it ==

Maximum likelihood function maximizes what thing?

最大似然函数(Maximum Likelihood Function)最大化的是数据在给定参数下出现的概率。具体来说,它最大化的是似然函数(Likelihood Function),即给定参数 ( \theta ) 下观测数据的概率。在统计学中,似然函数 ( L(\theta) ) 通常定义为所有独立观测数据点概率的乘积,对于参数 ( \theta ) 的函数。 对于一组独立同分布的观测数据

前段百科---JS中形如(function(window, undefined) {})(window)写法的理解

在Web开发过程中,往往会看到有人这样编写JS脚本: (function(window, undefined) {//do something})(window);可能有人会问: 卧槽,这是什么鬼? OK,且听我慢慢道来: 首先,(function(window, undefined) {})(window)可以简化看成这样()();而()()就是一个匿名函数自执行的写法.