RBF是啥?
RBF全称Radial Basis Function,中文名称“径向基函数”,辣么RBF神经网络就是径向基函数神经网络了。
是不是想到了一种核函数就叫RBF?没错,就是这货:
衡量某个点到中心的距离
RBF神经网络是啥?
说白了就是以RBF作为激活函数的神经网络,不过与传统的BP神经网络在前向传播有所区别:拓扑结构:如何计算各单元值:
隐单元计算方法如下
输出层的计算不用说了,和传统方法一样,WZ即可。如何更新参数(包含中心向量C,宽度向量D,权重W)
把大概流程走一波:
① 初始化权重
,网上很多方法,什么fan-in,fan-out, 或者caffe里面的一堆方法
②初始化中心
意义:使较弱的输入信息在较小的中心附近产生较强的响应,这样可以不失一般性。
③初始化宽度向量
意义:使每个隐含层神经元更容易实现对局部信息的感受能力,有利于提高RBF神经网络的局部响应能力。
计算隐单元输出值:计算输出层值
损失
梯度下降,更新参数
————————————————————————————————————
总结:所以发现其实就是在计算隐层单元的时候用了RBF激活函数,这个RBF涉及中心和宽度两个参数,其它的和BP区别不是特别大。
意义?应该就是中心和宽度存在的意义吧,RBF函数的存在使得网络结构具有局部响应的特性。
具体可移步个人博客看看,而且matlab中有例子可以跑一波看看,有兴趣还能研究一波源码:人工神经网络--径向基函数(RBF)神经网络 - 风翼冰舟的博客 - CSDN博客blog.csdn.net基于RBF简单的matlab手写识别 - 风翼冰舟的博客 - CSDN博客blog.csdn.net
————————————————————————————————————
更新日志:2020-11-2
好像蛮多人看的,我找了一份`keras`代码实现RBF层,并且测试了一波,源代码戳这里,我的测试可以直接看下面:
引入包
from keras.initializers import Initializer
from sklearn.cluster import KMeans
from keras import backend as K
from keras.engine.topology import Layer
from keras.initializers import RandomUniform, Initializer, Constant
import numpy as np
from keras.models import Sequential
from keras.layers import Dense
from keras.losses import binary_crossentropy
from keras.optimizers import Adam
构建`kmeans`层:
# kmeans layer
class InitCentersKMeans(Initializer):
""" Initializer for initialization of centers of RBF network
by clustering the given data set.
# Arguments
X: matrix, dataset
"""
def __init__(self, X, max_iter=100):
self.X = X
self.max_iter = max_iter
def __call__(self, shape, dtype=None):
assert shape[1] == self.X.shape[1]
n_centers = shape[0]
km = KMeans(n_clusters=n_centers, max_iter=self.max_iter, verbose=0)
km.fit(self.X)
return km.cluster_centers_
构建RBF层:
## RBF layer
class RBFLayer(Layer):
def __init__(self, output_dim, initializer=None, betas=1.0, **kwargs):
self.output_dim = output_dim
self.init_betas = betas
if not initializer:
self.initializer = RandomUniform(0.0, 1.0)
else:
self.initializer = initializer
super(RBFLayer, self).__init__(**kwargs)
def build(self, input_shape):
self.centers = self.add_weight(name='centers',
shape=(self.output_dim, input_shape[1]),
initializer=self.initializer,
trainable=True)
self.betas = self.add_weight(name='betas',
shape=(self.output_dim,),
initializer=Constant(
value=self.init_betas),
trainable=True)
super(RBFLayer, self).build(input_shape)
def call(self, x):
C = K.expand_dims(self.centers)
H = K.transpose(C-K.transpose(x))
return K.exp(-self.betas * K.sum(H**2, axis=1))
def compute_output_shape(self, input_shape):
return (input_shape[0], self.output_dim)
def get_config(self):
# have to define get_config to be able to use model_from_json
config = {
'output_dim': self.output_dim
}
base_config = super(RBFLayer, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
构建测试数据:
## create dataset
# reference https://zhuanlan.zhihu.com/p/36982945
def test_data(sample_number = 1000):
#随机从高斯分布中生成两个数据集
mean0=[2,3]
cov=np.mat([[1,0],[0,2]])
data1=np.random.multivariate_normal(mean0,cov,sample_number)
mean1=[7,8]
cov=np.mat([[1,0],[0,2]])
data2=np.random.multivariate_normal(mean1,cov,sample_number)
y1 = np.zeros((sample_number,1))#第一类,标签为0
y2 = np.ones((sample_number,1))#第二类类,标签为1
train_data = np.vstack((data1,data2))
train_label = np.vstack((y1,y2))
shuffle_idx = np.arange(sample_number*2)
np.random.shuffle(shuffle_idx)
train_data = train_data[shuffle_idx]
train_label = train_label[shuffle_idx]
return train_data,train_label
samples_num = 1000
train_data,train_label = test_data(samples_num)
创建模型并训练
model = Sequential()
rbflayer = RBFLayer(10,
initializer=InitCentersKMeans(train_data),
betas=2.0,
input_shape=(2,))
model.add(rbflayer)
model.add(Dense(1))
model.compile(loss=binary_crossentropy,optimizer=Adam(),metrics=['accuracy'])
model.fit(train_data,train_label,epochs=1000)
测试模型:
import matplotlib.pyplot as plt
x1 = np.linspace(-2,12,1000)
x2 = np.linspace(-2,12,1000)
test_x = np.vstack((x1,x2)).T
test_y = model.predict(test_x)
# plot the train data
plt.scatter(train_data[np.argwhere(train_label==0),0],train_data[np.argwhere(train_label==0),1],s=5,c='b')
plt.scatter(train_data[np.argwhere(train_label==1),0],train_data[np.argwhere(train_label==1),1],s=5,c='g')
#plot line
plt.scatter(test_x[np.argwhere(test_y<0.5),0],test_x[np.argwhere(test_y<0.5),1],s=2,c='b')
plt.scatter(test_x[np.argwhere(test_y>=0.5),0],test_x[np.argwhere(test_y>=0.5),1],s=2,c='g')
结果图:
图例点都是训练集,线是测试集
有兴趣可以关注公众号哦,csdn和公众号都有这个理论,同时挖个坑
意思是这个RBF还能用来做顶点修正;这个是骨骼动画的一篇文章《Phase-Functioned Neural Networks for Character Control 》里面描述的,作用是从地形图里面取一块地形,然后把人放上去,但是由于脚可能踩不到地面上,所以用RBF把地形校正上来,以后有时间研究一波。