python rbf神经网络_RBF神经网络是什么?
RBF是啥?
RBF全稱Radial Basis Function,中文名稱“徑向基函數(shù)”,辣么RBF神經(jīng)網(wǎng)絡(luò)就是徑向基函數(shù)神經(jīng)網(wǎng)絡(luò)了。
是不是想到了一種核函數(shù)就叫RBF?沒錯(cuò),就是這貨:
衡量某個(gè)點(diǎn)到中心的距離
RBF神經(jīng)網(wǎng)絡(luò)是啥?
說白了就是以RBF作為激活函數(shù)的神經(jīng)網(wǎng)絡(luò),不過與傳統(tǒng)的BP神經(jīng)網(wǎng)絡(luò)在前向傳播有所區(qū)別:拓?fù)浣Y(jié)構(gòu):如何計(jì)算各單元值:
隱單元計(jì)算方法如下
輸出層的計(jì)算不用說了,和傳統(tǒng)方法一樣,WZ即可。如何更新參數(shù)(包含中心向量C,寬度向量D,權(quán)重W)
把大概流程走一波:
① 初始化權(quán)重
,網(wǎng)上很多方法,什么fan-in,fan-out, 或者caffe里面的一堆方法
②初始化中心
意義:使較弱的輸入信息在較小的中心附近產(chǎn)生較強(qiáng)的響應(yīng),這樣可以不失一般性。
③初始化寬度向量
意義:使每個(gè)隱含層神經(jīng)元更容易實(shí)現(xiàn)對局部信息的感受能力,有利于提高RBF神經(jīng)網(wǎng)絡(luò)的局部響應(yīng)能力。《模式識別與智能計(jì)算》里面沒有平方,但是有平方更加合理。
計(jì)算隱單元輸出值:計(jì)算輸出層值
損失
梯度下降,更新參數(shù)
————————————————————————————————————
總結(jié):所以發(fā)現(xiàn)其實(shí)就是在計(jì)算隱層單元的時(shí)候用了RBF激活函數(shù),這個(gè)RBF涉及中心和寬度兩個(gè)參數(shù),其它的和BP區(qū)別不是特別大。
意義?應(yīng)該就是中心和寬度存在的意義吧,RBF函數(shù)的存在使得網(wǎng)絡(luò)結(jié)構(gòu)具有局部響應(yīng)的特性。
具體可移步個(gè)人博客看看,而且matlab中有例子可以跑一波看看,有興趣還能研究一波源碼:人工神經(jīng)網(wǎng)絡(luò)--徑向基函數(shù)(RBF)神經(jīng)網(wǎng)絡(luò) - 風(fēng)翼冰舟的博客 - CSDN博客?blog.csdn.net基于RBF簡單的matlab手寫識別 - 風(fēng)翼冰舟的博客 - CSDN博客?blog.csdn.net
————————————————————————————————————
更新日志:2020-11-2
好像蠻多人看的,我找了一份`keras`代碼實(shí)現(xiàn)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
構(gòu)建`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_
構(gòu)建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()))
---------- 更新日志-------------
感覺按照理論來講,上面的代碼寬度向量好像沒有加進(jìn)來的樣子,我自己改了一下:
def call(self, x):
C = K.expand_dims(self.centers)
XC = K.transpose(K.transpose(x)-C)
D = K.expand_dims(K.sqrt(K.mean(XC**2,axis=0)),0)
H = XC/D
return K.exp(-self.betas * K.sum(H**2, axis=1))
構(gòu)建測試數(shù)據(jù):
歸一化函數(shù):
def maxminnorm(array):
maxcols=array.max(axis=0)
mincols=array.min(axis=0)
data_shape = array.shape
data_rows = data_shape[0]
data_cols = data_shape[1]
t=np.empty((data_rows,data_cols))
for i in range(data_cols):
t[:,i]=(array[:,i]-mincols[i])/(maxcols[i]-mincols[i])
return t
訓(xùn)練集:
## create dataset
# reference https://zhuanlan.zhihu.com/p/36982945
def test_data1(sample_number = 1000):
#隨機(jī)從高斯分布中生成兩個(gè)數(shù)據(jù)集
mean0=[2,7]
cov=np.mat([[1,0],[0,2]])
data1=np.random.multivariate_normal(mean0,cov,sample_number)
mean1=[8,3]
cov=np.mat([[1,0],[0,2]])
data2=np.random.multivariate_normal(mean1,cov,sample_number)
y1 = np.zeros((sample_number,1))#第一類,標(biāo)簽為0
y2 = np.ones((sample_number,1))#第二類類,標(biāo)簽為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 = 3000
train_data,train_label = test_data2(samples_num)
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')
測試集
## create dataset
# reference https://zhuanlan.zhihu.com/p/36982945
def test_data2(sample_number = 1000):
#隨機(jī)均勻分布中生成數(shù)據(jù)
all_data = np.random.rand(sample_number*2,2)
data1 = all_data[all_data[...,0]>all_data[...,1]]
data2 = all_data[all_data[...,0]<=all_data[...,1]]
y1 = np.zeros((sample_number,1))#第一類,標(biāo)簽為0
y2 = np.ones((sample_number,1))#第二類類,標(biāo)簽為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
創(chuàng)建模型并訓(xùn)練
model = Sequential()
rbflayer = RBFLayer(10,
initializer=InitCentersKMeans(train_data),
betas=2.0,
input_shape=(2,))
model.add(rbflayer)
model.add(Dense(1,activation='sigmoid'))
model.compile(loss=binary_crossentropy,optimizer=Adam(),metrics=['accuracy'])
model.fit(train_data,train_label,epochs=1000)
測試模型:
# x1 = np.linspace(-2,12,1000)
# x2 = np.linspace(-2,12,1000)
# test_x = np.vstack((x1,x2)).T
test_x,_ = test_data1()
test_x = maxminnorm(test_x)
test_y = model.predict(test_x)
plt.figure(figsize=(16,16))
# 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',marker='x')
plt.scatter(train_data[np.argwhere(train_label==1),0],train_data[np.argwhere(train_label==1),1],s=5,c='g',marker='x')
#plot the test data
plt.scatter(test_x[np.argwhere(test_y<0.5),0],test_x[np.argwhere(test_y<0.5),1],s=20,c='b',marker='o')
plt.scatter(test_x[np.argwhere(test_y>=0.5),0],test_x[np.argwhere(test_y>=0.5),1],s=20,c='g',marker='o')
結(jié)果圖:
圖中小點(diǎn)是訓(xùn)練集,大圓點(diǎn)是測試集,對應(yīng)顏色為類別。
有興趣可以關(guān)注公眾號哦,csdn和公眾號都有這個(gè)理論,同時(shí)挖個(gè)坑
意思是這個(gè)RBF還能用來做頂點(diǎn)修正;這個(gè)是骨骼動畫的一篇文章《Phase-Functioned Neural Networks for Character Control 》里面描述的,作用是從地形圖里面取一塊地形,然后把人放上去,但是由于腳可能踩不到地面上,所以用RBF把地形校正上來,以后有時(shí)間研究一波。
總結(jié)
以上是生活随笔為你收集整理的python rbf神经网络_RBF神经网络是什么?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 架构之数据架构
- 下一篇: 基于边缘的主动轮廓模型——从零到一用py