最近deep learning的研究和话题开始又火了起来。然而我却还逗留在RBF神经网络的阶段。真是屌丝得不能再屌丝。对SVM也照旧一知半解,呆板进修最多也就是个入门级别,看来离成为一名数据科学家和数据事情者的阶梯还很远。
这一周时间在研究神经网络,虽然内容是很低级的。所以这篇日志较量适合入门者。我写下它也权当是进修进程的记录。写了点R代码,也共享出来。这篇日记不涉及任何数学公式。
RBF在我看来,本质上就长短参数回归模子(拜见Element of statistical learning的11章)。依据Cover的理论,它先将数据非线性映射到一个更高维度的空间中,然后再在高维空间用线性模子来做回归可能分类。从而获得一个较好的结果。
Vapnik曾经说过,一个好的理论是更为实用的。Cover的理论浮现了这一点。Cover理论是说,数据在高维空间更倾向于线性可分的,可能更倾向于用线性模子来拟合。从这个理论出发,成长出来了一系列模子。都取得了不错的结果。
RBF神经网络,是首先操作RBF,即径向基函数,来首先将数据映射到一个更高的空间。关于RBF,可以参看我的念书条记。之后的在高维空间上的线性模子,是较量容易实现的。这里就不多说了。
基于上面的描写,RBF神经网络的进修进程包括了两步,第一步要进修RBF的参数。一般来说选择Gaussian函数作为RBF,则其参数包罗两个,位置参数和刻度参数,即center和width。最简朴的要领是用kmeans聚类,进修出center,而用每个聚类中的方差来作为width的预计。
进修完RBF的参数之后,我们需要进修高维空间中线性模子的系数,该系数,可以利用根基的最小二乘要领,可是很大概碰见矩阵求逆很贫苦的环境。因此,往往是用递归最小二乘RLS,给出个中需要求逆的矩阵的一个递归形式,使得计较上较量利便。
关于RBF神经网络更多的内容,请参看神经网络与呆板进修一书。

闲话不多说了,下面直接上代码。代码用R语言写成,个中包括3个函数,simData用来生成模仿的数据,用以RBF网络的练习和检测。Euc_dist用以计较两个向量的欧式间隔。mysign则给出某个值的标记。练习RBF的算法即为上述的,更为基本和简朴的Kmeans和RLS。

simData=function(radius,width,distance,sample_size)
{
   aa1=runif(sample_size/2)
   aa2=runif(sample_size/2)
   rad=(radius-width/2)+width*aa1
   theta=pi*aa2
   x=rad*cos(theta)
   y=rad*sin(theta)
   label=1*rep(1,length(x))

   x1=rad*cos(-theta)+rad
   y1=rad*sin(-theta)-distance
   label1=-1*rep(1,length(x1))

   n_row=length(x)+length(x1)
   data=matrix(rep(0,3*n_row),nrow=n_row,ncol=3)
   data[,1]=c(x,x1)
   data[,2]=c(y,y1)
   data[,3]=c(label,label1)
   
   data
   
}
dataSim=simData(radius=10,width=6,distance=-6,sample_size=3000)
plot(dataSim[,1],dataSim[,2],col=ifelse(dataSim[,3]==1,"red","green"),xlab="x",ylab="y")

RBF神经网络极简介绍及其算法R语言实现


Euc_dist=function(a,b)
{
  sqrt(sum((a-b)^2))
}

mysign=function(d)
{
  1*(d>=0)+(-1)*(d<0)
}


#############算法主体部门######################################
  num_input=dim(dataSim)[2]-1 #输入练习样本为矩阵
  num_hidden_node=6 #隐层结点数
  num_out=1 #输出层结点数
  data_train=dataSim
  num_train=dim(data_train)[1]

  ########初始化
  c_threshold=1e-3
  c_delta=Inf
  w=matrix(rep(0,num_hidden_node*num_out),nrow=num_hidden_node,ncol=num_out) #权重矩阵
  
  sig=0.01
  P=matrix(rep(0,6^2),nrow=6) #RLS算法中的R^-1
  for(i in 1:6)
  {P[i,i]=1*sig^(-1)}
  
  c=simData(radius=10,width=6,distance=-6,sample_size=num_hidden_node) #RBF中心的初值
  c=c[,-3]
  iter_train_min=10 #练习次数
  epochs=50 #轮次
  w_threshold=1e-8
  mse_threshold=1e-6
  w_delta=Inf
  n=1
  m=1
  eta=1 #进修速率
  err=0 #错误检测计数器
  
  pos_vector=rep(1,num_train) #位置向量,用以标志属于某个聚类的样本的位置
  mse=vector()
  ee=vector()
  
  ################Kmeans算法
  while(c_delta>c_threshold && n<=num_train)
  {
    
    x=data_train[n,-3]
    y=data_train[n,3]
    eu_dist=vector()
    for(i in 1:num_hidden_node)
      {
         eu_dist[i]=Euc_dist(x,c[i,])
      }
    eu_min_value=min(eu_dist)
    eu_min_pos=order(eu_dist)[1]
    c[eu_min_pos,]=c[eu_min_pos,]+eta*(x-c[eu_min_pos,])
    pos_vector[n]=eu_min_pos
    n=n+1
  }
   ############计较每个聚类中的方差
  tem_vec=vector()
  sigma=vector()
  for(i in 1:num_hidden_node)
  {
    tem_vec=(pos_vector==i)
    dist_temp=0
    for(j in 1:num_train)
    {
      if(tem_vec[j]==TRUE)
        dist_temp=Euc_dist(c[i,],data_train[j,-3])+dist_temp
    }
    sigma[i]=dist_temp/sum(tem_vec)
  }
  g=matrix(rep(0,num_hidden_node),nrow=num_hidden_node)
  #####################练习输出层权重
  for(epoch in 1:epochs)
  {
    random_seq=sample(seq(1:num_train),replace=FALSE)
    data_randomized_tr=data_train[random_seq,]
    for(m in 1:num_train)
    {
      
      x=data_randomized_tr[m,-3]
      d=data_randomized_tr[m,3]
      
      for(i in 1:num_hidden_node)
        g[i,]=exp(-t(x-c[i,])%*%(x-c[i,])/(2*sigma[i]^2))
      #########RLS算法
      pai=P%*%g
      kk=pai/(1+t(g)%*%pai)[1,1]
      e=d-mysign(t(w)%*%g)
      w_delta=t(kk*e[1,1])
      ee[m]=d-mysign(t(w)%*%g)
      w=w+t(w_delta)
      P=P-kk%*%t(g)%*%P
    }
  mse[epoch]=mean(ee^2)
    if(mse[epoch]<mse_threshold) break
  }
  
print(w)
print(c)

##########################RBF网络检讨##############################
o=vector()
gg=matrix(rep(0,num_hidden_node),nrow=num_hidden_node)
data_test=simData(radius=10,width=6,distance=-6,sample_size=2000)
num_test=dim(data_test)[1]
for(i in 1:num_test)
{
  xx=data_test[i,-3]
  for(j in 1:num_hidden_node)
    {gg[j,]=exp(-t(xx-c[j,])%*%(xx-c[j,])/(2*sigma[j]^2))
    o[i]=t(w)%*%gg}
  if(abs(mysign(o[i])-data_test[i,3])>1e-6)
       err=err+1
}
err/num_test

 最后获得的结果还行,3000个练习样本,2000个检测样本,最终分类错误率在8%以内。虽然,由于随机数,假如你在本身呆板上跑上述代码,得到的功效应该与我的差异。

其他教程

2017-12-04


最近deep learning的研究和话题开始又火了起来。然而我却还逗留在RBF神经网络的阶段。真是屌丝得不能再屌丝。对SVM也照旧一知半解,呆板进修最多也就是个入门级别,看来离成为一名数