径向基函数是一个取值仅仅依赖于离远点的实值函数,也就是 ϕ ( x ) = ϕ ( ∣ ∣ x ∣ ∣ ) \ \phi(x)=\phi(||x||) ϕ(x)=ϕ(∣∣x∣∣),或者还可以是任意一点c的距离,c点称为中心点,也就是 ϕ ( x − c ) = ϕ ( ∣ ∣ x − c ∣ ∣ ) \ \phi(x-c)=\phi(||x-c||) ϕ(x−c)=ϕ(∣∣x−c∣∣)。任意一点满足 ϕ ( x ) = ϕ ( ∣ ∣ x ∣ ∣ ) \ \phi(x)=\phi(||x||) ϕ(x)=ϕ(∣∣x∣∣)特性的函数都叫做径向基函数,标准的一般使用欧式距离(也叫做欧式径向基函数),尽管其他距离函数也可以,但是最为常用的径向基函数是高斯核函数,形式为 k ( ∣ ∣ x − x c ∣ ∣ ) = e x p ( − ∣ ∣ x − x c ∣ ∣ 2 ) ( 2 ∗ σ ) 2 \ k(||x-x_c||) =\frac {exp(-||x-x_c||^2)}{(2*\sigma)^2} k(∣∣x−xc∣∣)=(2∗σ)2exp(−∣∣x−xc∣∣2),其中 x c \ x_c xc
为和函数中心, σ \ \sigma σ为函数的宽度参数,控制了函数的径向作用范围。
RBF神经网络的拓扑结果是一种三层前向网络:
1. 局部逼近核全局逼近:
SVM等如果使用核函数的技巧的话,不太适应大样本核大的特征数的情况,因此提出了RBF。另外,SVM中的高斯核函数可以看作与每一个输入点的距离,而RBF神经网络对输入点做了一个聚类。RBF神经网络用高斯核函数时,其数据中心C可以是训练样本中的抽样,此时与SVM的高斯核函数是完全等价的,也可以是训练样本集的多个聚类中心,所以他们都是需要选择数据中心的,只不过SVM使用高斯核函数时,这里的数据中心都是训练样本本身而已。
RBF神经网络的kernel核函数:
RBF神经网络是为了解决大部分基于反向传播的多层前馈网络的学习算法必须基于某种非线性优化技术的缺点、计算量大、学习速度慢的问题。RBF通过使用高斯核函数的方法,使得网络由输入到输出的映射是非线性的,而网络输出对可调参数而言却又是线性的。网络的权就是可由线性方程租直接解出,从而大大加速学习速度并避免局部极小问题。
RBF Network
import numpy as np
import matplotlib.pyplot as plt
from RBFN import RBFN
# generating data
x = np.linspace(0, 10, 100)
y = np.sin(x)
# fitting RBF-Network with data
model = RBFN(hidden_shape=10, sigma=1.)
model.fit(x, y)
y_pred = model.predict(x)
# plotting 1D interpolation
plt.plot(x, y, 'b-', label='real')
plt.plot(x, y_pred, 'r-', label='fit')
plt.legend(loc='upper right')
plt.title('Interpolation using a RBFN')
plt.show()
# generating dummy data for interpolation
x, y = np.meshgrid(np.linspace(-5, 5, 20), np.linspace(-5, 5, 20))
z = (np.sin(np.sqrt((x - 2.)**2 + (y - 1)**2)) -
np.sin(np.sqrt((x + 2.)**2 + (y + 4)**2))) / 2.
# fitting RBF-Network with data
features = np.asarray(list(zip(x.flatten(), y.flatten())))
model = RBFN(hidden_shape=70, sigma=1.)
model.fit(features, z.flatten())
predictions = model.predict(features)
# plotting 2D interpolation
figure, (axis_left, axis_right) = plt.subplots(1, 2, figsize=(15, 10), sharey=True)
figure.suptitle('RBF-Network 2D interpolation', fontsize=20)
axis_right.set_title('fit', fontsize=20)
axis_left.set_title('real', fontsize=20)
axis_left.contourf(x, y, z)
right_image = axis_right.contourf(x, y, predictions.reshape(20, 20))
plt.show()
"""
File: RBFN.py
Author: Octavio Arriaga
Email: [email protected]
Github: https://github.com/oarriaga
Description: Minimal implementation of a radial basis function network
"""
import numpy as np
class RBFN(object):
def __init__(self, hidden_shape, sigma=1.0):
""" radial basis function network
# Arguments
input_shape: dimension of the input data
e.g. scalar functions have should have input_dimension = 1
hidden_shape: the number
hidden_shape: number of hidden radial basis functions,
also, number of centers.
"""
self.hidden_shape = hidden_shape
self.sigma = sigma
self.centers = None
self.weights = None
def _kernel_function(self, center, data_point):
return np.exp(-self.sigma*np.linalg.norm(center-data_point)**2)
def _calculate_interpolation_matrix(self, X):
""" Calculates interpolation matrix using a kernel_function
# Arguments
X: Training data
# Input shape
(num_data_samples, input_shape)
# Returns
G: Interpolation matrix
"""
G = np.zeros((len(X), self.hidden_shape))
for data_point_arg, data_point in enumerate(X):
for center_arg, center in enumerate(self.centers):
G[data_point_arg, center_arg] = self._kernel_function(
center, data_point)
return G
def _select_centers(self, X):
random_args = np.random.choice(len(X), self.hidden_shape)
centers = X[random_args]
return centers
def fit(self, X, Y):
""" Fits weights using linear regression
# Arguments
X: training samples
Y: targets
# Input shape
X: (num_data_samples, input_shape)
Y: (num_data_samples, input_shape)
"""
self.centers = self._select_centers(X)
G = self._calculate_interpolation_matrix(X)
self.weights = np.dot(np.linalg.pinv(G), Y)
def predict(self, X):
"""
# Arguments
X: test data
# Input shape
(num_test_samples, input_shape)
"""
G = self._calculate_interpolation_matrix(X)
predictions = np.dot(G, self.weights)
return predictions