精华内容
下载资源
问答
  • 径向基(RBF)神经网络python实现

    千次阅读 2019-10-02 00:02:47
    18 return exp(- metrics(mu, x)**2 / (2 * sigma**2 )) 19 20 21 def multiQuadric (x, mu, sigma): 22 return pow(metrics(mu,x)**2 + sigma**2, 0.5 ) 23 24 25 def ...

     

      1 from numpy import array, append, vstack, transpose, reshape, \
      2                   dot, true_divide, mean, exp, sqrt, log, \
      3                   loadtxt, savetxt, zeros, frombuffer
      4 from numpy.linalg import norm, lstsq
      5 from multiprocessing import Process, Array
      6 from random import sample
      7 from time import time
      8 from sys import stdout
      9 from ctypes import c_double
     10 from h5py import File
     11 
     12 
     13 def metrics(a, b): 
     14     return norm(a - b)
     15 
     16 
     17 def gaussian (x, mu, sigma): 
     18     return exp(- metrics(mu, x)**2 / (2 * sigma**2))
     19 
     20 
     21 def multiQuadric (x, mu, sigma):
     22     return pow(metrics(mu,x)**2 + sigma**2, 0.5)
     23 
     24 
     25 def invMultiQuadric (x, mu, sigma):
     26     return pow(metrics(mu,x)**2 + sigma**2, -0.5)
     27 
     28 
     29 def plateSpine (x,mu):
     30     r = metrics(mu,x)
     31     return (r**2) * log(r)
     32 
     33 
     34 class Rbf:
     35     def __init__(self, prefix = 'rbf', workers = 4, extra_neurons = 0, from_files = None):
     36         self.prefix = prefix
     37         self.workers = workers
     38         self.extra_neurons = extra_neurons
     39 
     40         # Import partial model
     41         if from_files is not None:            
     42             w_handle = self.w_handle = File(from_files['w'], 'r')
     43             mu_handle = self.mu_handle = File(from_files['mu'], 'r')
     44             sigma_handle = self.sigma_handle = File(from_files['sigma'], 'r')
     45             
     46             self.w = w_handle['w']
     47             self.mu = mu_handle['mu']
     48             self.sigmas = sigma_handle['sigmas']
     49             
     50             self.neurons = self.sigmas.shape[0]
     51 
     52     def _calculate_error(self, y):
     53         self.error = mean(abs(self.os - y))
     54         self.relative_error = true_divide(self.error, mean(y))
     55 
     56     def _generate_mu(self, x):
     57         n = self.n
     58         extra_neurons = self.extra_neurons
     59 
     60         # TODO: Make reusable
     61         mu_clusters = loadtxt('clusters100.txt', delimiter='\t')
     62 
     63         mu_indices = sample(range(n), extra_neurons)
     64         mu_new = x[mu_indices, :]
     65         mu = vstack((mu_clusters, mu_new))
     66 
     67         return mu
     68 
     69     def _calculate_sigmas(self):
     70         neurons = self.neurons
     71         mu = self.mu
     72 
     73         sigmas = zeros((neurons, ))
     74         for i in xrange(neurons):
     75             dists = [0 for _ in xrange(neurons)]
     76             for j in xrange(neurons):
     77                 if i != j:
     78                     dists[j] = metrics(mu[i], mu[j])
     79             sigmas[i] = mean(dists)* 2
     80                       # max(dists) / sqrt(neurons * 2))
     81         return sigmas
     82 
     83     def _calculate_phi(self, x):
     84         C = self.workers
     85         neurons = self.neurons
     86         mu = self.mu
     87         sigmas = self.sigmas
     88         phi = self.phi = None
     89         n = self.n
     90 
     91 
     92         def heavy_lifting(c, phi):
     93             s = jobs[c][1] - jobs[c][0]
     94             for k, i in enumerate(xrange(jobs[c][0], jobs[c][1])):
     95                 for j in xrange(neurons):
     96                     # phi[i, j] = metrics(x[i,:], mu[j])**3)
     97                     # phi[i, j] = plateSpine(x[i,:], mu[j]))
     98                     # phi[i, j] = invMultiQuadric(x[i,:], mu[j], sigmas[j]))
     99                     phi[i, j] = multiQuadric(x[i,:], mu[j], sigmas[j])
    100                     # phi[i, j] = gaussian(x[i,:], mu[j], sigmas[j]))
    101                 if k % 1000 == 0:
    102                     percent = true_divide(k, s)*100
    103                     print(c, ': {:2.2f}%'.format(percent))
    104             print(c, ': Done')
    105         
    106         # distributing the work between 4 workers
    107         shared_array = Array(c_double, n * neurons)
    108         phi = frombuffer(shared_array.get_obj())
    109         phi = phi.reshape((n, neurons))
    110 
    111         jobs = []
    112         workers = []
    113 
    114         p = n / C
    115         m = n % C
    116         for c in range(C):
    117             jobs.append((c*p, (c+1)*p + (m if c == C-1 else 0)))
    118             worker = Process(target = heavy_lifting, args = (c, phi))
    119             workers.append(worker)
    120             worker.start()
    121 
    122         for worker in workers:
    123             worker.join()
    124 
    125         return phi
    126 
    127     def _do_algebra(self, y):
    128         phi = self.phi
    129 
    130         w = lstsq(phi, y)[0]
    131         os = dot(w, transpose(phi))
    132         return w, os
    133         # Saving to HDF5
    134         os_h5 = os_handle.create_dataset('os', data = os)
    135 
    136     def train(self, x, y):
    137         self.n = x.shape[0]
    138 
    139         ## Initialize HDF5 caches
    140         prefix = self.prefix
    141         postfix = str(self.n) + '-' + str(self.extra_neurons) + '.hdf5'
    142         name_template = prefix + '-{}-' + postfix
    143         phi_handle = self.phi_handle = File(name_template.format('phi'), 'w')
    144         os_handle = self.w_handle = File(name_template.format('os'), 'w')
    145         w_handle = self.w_handle = File(name_template.format('w'), 'w')
    146         mu_handle = self.mu_handle = File(name_template.format('mu'), 'w')
    147         sigma_handle = self.sigma_handle = File(name_template.format('sigma'), 'w')
    148 
    149         ## Mu generation
    150         mu = self.mu = self._generate_mu(x)
    151         self.neurons = mu.shape[0]
    152         print('({} neurons)'.format(self.neurons))
    153         # Save to HDF5
    154         mu_h5 = mu_handle.create_dataset('mu', data = mu)
    155 
    156         ## Sigma calculation
    157         print('Calculating Sigma...')
    158         sigmas = self.sigmas = self._calculate_sigmas()
    159         # Save to HDF5
    160         sigmas_h5 = sigma_handle.create_dataset('sigmas', data = sigmas)
    161         print('Done')
    162 
    163         ## Phi calculation
    164         print('Calculating Phi...')
    165         phi = self.phi = self._calculate_phi(x)
    166         print('Done')
    167         # Saving to HDF5
    168         print('Serializing...')
    169         phi_h5 = phi_handle.create_dataset('phi', data = phi)
    170         del phi
    171         self.phi = phi_h5
    172         print('Done')
    173 
    174         ## Algebra
    175         print('Doing final algebra...')
    176         w, os = self.w, _ = self._do_algebra(y)
    177         # Saving to HDF5
    178         w_h5 = w_handle.create_dataset('w', data = w)
    179         os_h5 = os_handle.create_dataset('os', data = os)
    180 
    181         ## Calculate error
    182         self._calculate_error(y)
    183         print('Done')
    184 
    185     def predict(self, test_data):
    186         mu = self.mu = self.mu.value
    187         sigmas = self.sigmas = self.sigmas.value
    188         w = self.w = self.w.value
    189 
    190         print('Calculating phi for test data...')
    191         phi = self._calculate_phi(test_data)
    192         os = dot(w, transpose(phi))
    193         savetxt('iok3834.txt', os, delimiter='\n')
    194         return os
    195 
    196     @property
    197     def summary(self):
    198         return '\n'.join( \
    199             ['-----------------',
    200             'Training set size: {}'.format(self.n),
    201             'Hidden layer size: {}'.format(self.neurons),
    202             '-----------------',
    203             'Absolute error   : {:02.2f}'.format(self.error),
    204             'Relative error   : {:02.2f}%'.format(self.relative_error * 100)])
    205 
    206 
    207 def predict(test_data):
    208     mu = File('rbf-mu-212243-2400.hdf5', 'r')['mu'].value
    209     sigmas = File('rbf-sigma-212243-2400.hdf5', 'r')['sigmas'].value
    210     w = File('rbf-w-212243-2400.hdf5', 'r')['w'].value
    211 
    212     n = test_data.shape[0]  
    213     neur = mu.shape[0]  
    214     
    215     mu = transpose(mu)
    216     mu.reshape((n, neur))   
    217 
    218     phi = zeros((n, neur)) 
    219     for i in range(n):
    220         for j in range(neur):
    221             phi[i, j] = multiQuadric(test_data[i,:], mu[j], sigmas[j])
    222 
    223     os = dot(w, transpose(phi))
    224     savetxt('iok3834.txt', os, delimiter='\n')
    225     return os

     

    转载于:https://www.cnblogs.com/hhh5460/p/4319654.html

    展开全文
  • 核函数&径向基核函数 (Radial Basis Function)--RBF

    万次阅读 多人点赞 2016-05-26 21:47:44
    http://zhidao.baidu.com/question/16706714.html )。  由于计算的是内积,我们可以想到IR中的余弦相似度,如果x和z向量夹角越小,那么核函数值越大,反之,越小。 因此,核函数值是 和 的相似度。 ...

    1.核函数


    1.1核函数的由来

    -----------还记得为何要选用核函数么?-----------

    对于这个问题,在Jasper's Java Jacal博客《SVM入门(七)为何需要核函数》中做了很详细的阐述,另外博主对于SVM德入门学习也是做了很详细的阐述,有兴趣的可以去学习,写得相当好,特意转载了过来,留念一下。

    如果提供的样本线性不可分,结果很简单,线性分类器的求解程序会无限循环,永远也解不出来。这必然使得它的适用范围大大缩小,而它的很多优点我们实在不原意放弃,怎么办呢?是否有某种方法,让线性不可分的数据变得线性可分呢?

    例子是下面这张图:


    我们把横轴上端点a和b之间红色部分里的所有点定为正类,两边的黑色部分里的点定为负类。试问能找到一个线性函数把两类正确分开么?不能,因为二维空间里的线性函数就是指直线,显然找不到符合条件的直线。

    但我们可以找到一条曲线,例如下面这一条:



    显然通过点在这条曲线的上方还是下方就可以判断点所属的类别(你在横轴上随便找一点,算算这一点的函数值,会发现负类的点函数值一定比0大,而正类的一定比0小)。这条曲线就是我们熟知的二次曲线,它的函数表达式可以写为:


    问题只是它不是一个线性函数,但是,下面要注意看了,新建一个向量y和a:


    这样g(x)就可以转化为f(y)=<a,y>,你可以把y和a分别回带一下,看看等不等于原来的g(x)。用内积的形式写你可能看不太清楚,实际上f(y)的形式就是:

    g(x)=f(y)=ay

    在任意维度的空间中,这种形式的函数都是一个线性函数(只不过其中的a和y都是多维向量罢了),因为自变量y的次数不大于1。


    看出妙在哪了么?原来在二维空间中一个线性不可分的问题,映射到四维空间后,变成了线性可分的!因此这也形成了我们最初想解决线性不可分问题的基本思路——向高维空间转化,使其变得线性可分。


    而转化最关键的部分就在于找到x到y的映射方法。遗憾的是,如何找到这个映射,没有系统性的方法(也就是说,纯靠猜和凑)。具体到我们的文本分类问题,文本被表示为上千维的向量,即使维数已经如此之高,也常常是线性不可分的,还要向更高的空间转化。其中的难度可想而知。

    小Tips:为什么说f(y)=ay是四维空间里的函数?

    大家可能一时没看明白。回想一下我们二维空间里的函数定义
    g(x)=ax+b
    变量x是一维的,为什么说它是二维空间里的函数呢?因为还有一个变量我们没写出来,它的完整形式其实是
    y=g(x)=ax+b

    y=ax+b
    看看,有几个变量?两个,二维。
    再看看
    f(y)=ay
    里面的y是三维的变量,再加上f(y)成为四维的了。


    用一个具体文本分类的例子来看看这种向高维空间映射从而分类的方法如何运作,想象一下,我们文本分类问题的原始空间是1000维的(即每个要被分类的文档被表示为一个1000维的向量),在这个维度上问题是线性不可分的。现在我们有一个2000维空间里的线性函数

    f(x)=<w,x>+b

    注意向量的右上角有个 ’哦。它能够将原问题变得可分。式中的 w和x都是2000维的向量,只不过w是定值,而x是变量(好吧,严格说来这个函数是2001维的,哈哈),现在我们的输入呢,是一个1000维的向量x,分类的过程是先把x变换为2000维的向量x,然后求这个变换后的向量x与向量w的内积,再把这个内积的值和b相加,就得到了结果,看结果大于阈值还是小于阈值就得到了分类结果。

    你发现了什么?我们其实只关心那个高维空间里内积的值,那个值算出来了,分类结果就算出来了。而从理论上说, x是经由x变换来的,因此广义上可以把它叫做x的函数(有一个x,就确定了一个x,对吧,确定不出第二个),而w是常量,它是一个低维空间里的常量w经过变换得到的,所以给了一个w 和x的值,就有一个确定的f(x)值与其对应。这让我们幻想,是否能有这样一种函数K(w,x),他接受低维空间的输入值,却能算出高维空间的内积值<w,x>?


    如果有这样的函数,那么当给了一个低维空间的输入x以后,

    g(x)=K(w,x)+b

    f(x)=<w,x>+b

    这两个函数的计算结果就完全一样,我们也就用不着费力找那个映射关系,直接拿低维的输入往g(x)里面代就可以了(再次提醒,这回的g(x)就不是线性函数啦,因为你不能保证K(w,x)这个表达式里的x次数不高于1哦)。

    万幸的是,这样的K(w,x)确实存在(发现凡是我们人类能解决的问题,大都是巧得不能再巧,特殊得不能再特殊的问题,总是恰好有些能投机取巧的地方才能解决,由此感到人类的渺小),它被称作核函数(核,kernel),而且还不止一个,事实上,只要是满足了Mercer条件的函数(后面会具体写出),都可以作为核函数。核函数的基本作用就是接受两个低维空间里的向量,能够计算出经过某个变换后在高维空间里的向量内积值。几个比较常用的核函数,俄,教课书里都列过,我就不敲了(懒!)。

    回想我们上节说的求一个线性分类器,它的形式应该是:


    现在这个就是高维空间里的线性函数(为了区别低维和高维空间里的函数和向量,我改了函数的名字,并且给w和x都加上了 ’),我们就可以用一个低维空间里的函数(再一次的,这个低维空间里的函数就不再是线性的啦)来代替,


    又发现什么了?f(x’) 和g(x)里的α,y,b全都是一样一样的!这就是说,尽管给的问题是线性不可分的,但是我们就硬当它是线性问题来求解,只不过求解过程中,凡是要求内积 的时候就用你选定的核函数来算。这样求出来的α再和你选定的核函数一组合,就得到分类器啦!


    明白了以上这些,会自然的问接下来两个问题:

    1. 既然有很多的核函数,针对具体问题该怎么选择?

    2. 如果使用核函数向高维空间映射后,问题仍然是线性不可分的,那怎么办?


    第一个问题现在就可以回答你:对核函数的选择,现在还缺乏指导原则!各种实验的观察结果(不光是文本分类)的确表明,某些问题用某些核函数效果很 好,用另一些就很差,但是一般来讲,径向基核函数是不会出太大偏差的一种,首选。(我做文本分类系统的时候,使用径向基核函数,没有参数调优的情况下,绝 大部分类别的准确和召回都在85%以上,可见。虽然libSVM的作者林智仁认为文本分类用线性核函数效果更佳,待考证)

    对第二个问题的解决则引出了我们下一节的主题:松弛变量。

    ==================

    2.核函数的定义及计算复杂度

    将核函数形式化定义,如果原始特征内积是,映射后为,那么定义核函数(Kernel)为:


    到这里,我们可以得出结论,我们计算SVM的分类问题的时候,只需先计算,然后计算即可,然而这种计算方式是非常低效的。比如最初的特征是n维的,我们将其映射到n^2维,然后再计算,这样需要的时间。那么我们能不能想办法减少计算时间呢? 
    先看一个例子,假设x和z都是n维的,

    展开后,得

    这个时候发现我们可以只计算原始特征x和z内积的平方(时间复杂度是O(n)),就等价与计算映射后特征的内积。也就是说我们不需要花时间了。
    更一般地,核函数对应的映射后特征维度为。(求解方法参见 http://zhidao.baidu.com/question/16706714.html )。 
    由于计算的是内积,我们可以想到IR中的余弦相似度,如果x和z向量夹角越小,那么核函数值越大,反之,越小。
    因此,核函数值是的相似度。

    2.径向基函数——Radial Basis Function(RBF)

    所谓径向基函数 (Radial Basis Function 简称 RBF), 就是某种沿径向对称的标量函数。 通常定义为空间中任一点x到某
    一中心xc之间欧氏距离的单调函数 ,可记作 k(||x-xc||), 其作用往往是局部的 , 即当x远离xc时函数取值很小。

    最常用的径向基函数是高斯核函数 ,形式为 k(||x-xc||)=exp{- ||x-xc||^2/(2*σ)^2) } 其中x_c为核函数中心,σ为函数的宽度参数 , 控制了函数的径向作用范围。如果x和x_c很相近那么核函数值为1,如果x和x_c相差很大那么核函数值约等于0。由于这个函数类似于高斯分布,因此称为高斯核函数,也叫做径向基函数(Radial Basis Function 简称RBF)。它能够把原始特征映射到无穷维。


    那么核函数值约等于0。由于这个函数类似于高斯分布,因此称为高斯核函数,也叫做径向基函数(Radial Basis

    Function 简称RBF)。它能够把原始特征映射到无穷维。

    既然高斯核函数能够比较x和z的相似度,并映射到0到1,回想logistic回归,sigmoid函数可以,因此还有sigmoid核

    函数等等。

    ==================

    核函数有很多种,如线性核、多项式核、Sigmoid 核和 RBF(Radial Basis function)核。本文选定 RBF 核为 SVM 的核函数(RBF 核K(x, y) = exp(-γ || x -y ||的平方),γ > 0)。因为RBF 核可以将样本映射到一个更高维的空间,可以处理当类标签(Class Labels)和特征之间的关系是非线性时的样例。Keerthi 等[25]证明了一个有惩罚参数C 的线性核同有参数(C,γ )(其中C 为惩罚因子,γ 为核参数)的 RBF 核具有相同的性能。对某些参数,Sigmoid核同 RBF 核具有相似的性能[26]。另外,RBF 核与多项式核相比具有参数少的优点。因为参数的个数直接影响到模型选择的复杂性。非常重要的一点是0< Kij ≤1与多项式核相反,核值可能趋向无限(γxi xj + r >1)或者0 < γxi xj + r <1,跨度非常大。而且,必须注意的是Sigmoid 核在某些参数下是不正确的(例如,没有两个向量的内积)。

    用交叉验证找到最好的参数 C 和γ 。使用 RBF 核时,要考虑两个参数 C 和γ 。因为参数的选择并没有一定的先验知识,必须做某种类型的模型选择(参数搜索)。目的是确定好的(C,γ)使得分类器能正确的预测未知数据(即测试集数 据),有较高的分类精确率。值得注意的是得到高的训练正确率即是分类器预测类标签已知的训练数据的正确率)不能保证在测试集上具有高的预测精度。因此,通 常采用交叉验证方法提高预测精度。k 折交叉验证(k-fold cross validation)

    =========================

    下面有张图说明在低维线性不可分时,映射到高维后就可分了,使用高斯核函数。



    来自Eric Xing的slides

    注意,使用核函数后,怎么分类新来的样本呢?线性的时候我们使用SVM学习出w和b,新来样本x的话,我们使用来判断,如果值大于等于1,那么是正类,小于等于是负类。在两者之间,认为无法确定。如果使用了核函数后,就变成了,是否先要找到,然后再预测?答案肯定不是了,找很麻烦,回想我们之前说过的


    只需将clip_image057[4]替换成,然后值的判断同上。


    建议首选RBF核函数进行高维投影,因为:

    1. 能够实现非线性映射;( 线性核函数可以证明是他的一个特例;SIGMOID核函数在某些参数上近似RBF的功能。)
    2. 参数的数量影响模型的复杂程度,多项式核函数参数较多。
    3. the RBF kernel has less numerical difficulties.

    3. 核函数有效性判定

    问题:给定一个函数K,我们能否使用K来替代计算,也就说,是否能够找出一个,使得对于所有的x和z,都有
    比如给出了,是否能够认为K是一个有效的核函数。
    下面来解决这个问题,给定m个训练样本,每一个对应一个特征向量。那么,我们可以将任意两个带入K中,计算得到。i可以从1到m,j可以从1到m,这样可以计算出m*m的核函数矩阵(Kernel Matrix)。为了方便,我们将核函数矩阵和都使用K来表示。

    如果假设K是有效地核函数,那么根据核函数定义

    可见,矩阵K应该是个对称阵。让我们得出一个更强的结论,首先使用符号来表示映射函数的第k维属性值。那么对于任意向量z,得

    最后一步和前面计算时类似。从这个公式我们可以看出,如果K是个有效的核函数(即等价),那么,在训练集上得到的核函数矩阵K应该是半正定的(K>=0).

    这样我们得到一个核函数的必要条件

    K是有效的核函数 ==> 核函数矩阵K是对称半正定的。

    可幸的是,这个条件也是充分的,由Mercer定理来表达。 

    Mercer定理:

    如果函数K是上的映射(也就是从两个n维向量映射到实数域)。那么如果K是一个有效核函数(也称为Mercer核函数),那么当且仅当对于训练样例,其相应的核函数矩阵是对称半正定的。


    Mercer定理表明为了证明K是有效的核函数,那么我们不用去寻找,而只需要在训练集上求出各个,然后判断矩阵K是否是半正定(使用左上角主子式大于等于零等方法)即可。

    许多其他的教科书在Mercer定理证明过程中使用了L^2范数和再生希尔伯特空间等概念,但在特征是n维的情况下,这里给出的证明是等价的。

    =========================

    参考自:

    1、互动百科

    2、Jasper's Java Jacal--《SVM入门(七)为何需要核函数》

    3、博文:径向基核函数 (Radial Basis Function)--RBF | 丕子 +http://www.zhizhihu.com/html/y2010/2103.html

    4、支撑向量机(三)核函数:http://www.cnblogs.com/jerrylead/archive/2011/03/18/1988406.html

    转载请注明:Pual-Huang+地址





    展开全文
  • 1.核函数 1.1核函数的由来 -----------还记得为何要选用核函数么?----------- 对于这个问题,在Jasper's Java Jacal博客《SVM入门(七)为何需要...http://www.cnblogs.com/jerrylead/archive/2011/03/18/1988406.html

    1.核函数


    1.1核函数的由来

    -----------还记得为何要选用核函数么?-----------

    对于这个问题,在Jasper's Java Jacal博客《SVM入门(七)为何需要核函数》中做了很详细的阐述,另外博主对于SVM德入门学习也是做了很详细的阐述,有兴趣的可以去学习,写得相当好,特意转载了过来,留念一下。

    如果提供的样本线性不可分,结果很简单,线性分类器的求解程序会无限循环,永远也解不出来。这必然使得它的适用范围大大缩小,而它的很多优点我们实在不原意放弃,怎么办呢?是否有某种方法,让线性不可分的数据变得线性可分呢?

    例子是下面这张图:


    我们把横轴上端点a和b之间红色部分里的所有点定为正类,两边的黑色部分里的点定为负类。试问能找到一个线性函数把两类正确分开么?不能,因为二维空间里的线性函数就是指直线,显然找不到符合条件的直线。

    但我们可以找到一条曲线,例如下面这一条:



    显然通过点在这条曲线的上方还是下方就可以判断点所属的类别(你在横轴上随便找一点,算算这一点的函数值,会发现负类的点函数值一定比0大,而正类的一定比0小)。这条曲线就是我们熟知的二次曲线,它的函数表达式可以写为:


    问题只是它不是一个线性函数,但是,下面要注意看了,新建一个向量y和a:


    这样g(x)就可以转化为f(y)=<a,y>,你可以把y和a分别回带一下,看看等不等于原来的g(x)。用内积的形式写你可能看不太清楚,实际上f(y)的形式就是:

    g(x)=f(y)=ay

    在任意维度的空间中,这种形式的函数都是一个线性函数(只不过其中的a和y都是多维向量罢了),因为自变量y的次数不大于1。


    看出妙在哪了么?原来在二维空间中一个线性不可分的问题,映射到四维空间后,变成了线性可分的!因此这也形成了我们最初想解决线性不可分问题的基本思路——向高维空间转化,使其变得线性可分。


    而转化最关键的部分就在于找到x到y的映射方法。遗憾的是,如何找到这个映射,没有系统性的方法(也就是说,纯靠猜和凑)。具体到我们的文本分类问题,文本被表示为上千维的向量,即使维数已经如此之高,也常常是线性不可分的,还要向更高的空间转化。其中的难度可想而知。

    小Tips:为什么说f(y)=ay是四维空间里的函数?

    大家可能一时没看明白。回想一下我们二维空间里的函数定义
    g(x)=ax+b
    变量x是一维的,为什么说它是二维空间里的函数呢?因为还有一个变量我们没写出来,它的完整形式其实是
    y=g(x)=ax+b

    y=ax+b
    看看,有几个变量?两个,二维。
    再看看
    f(y)=ay
    里面的y是三维的变量,再加上f(y)成为四维的了。


    用一个具体文本分类的例子来看看这种向高维空间映射从而分类的方法如何运作,想象一下,我们文本分类问题的原始空间是1000维的(即每个要被分类的文档被表示为一个1000维的向量),在这个维度上问题是线性不可分的。现在我们有一个2000维空间里的线性函数

    f(x)=<w,x>+b

    注意向量的右上角有个 ’哦。它能够将原问题变得可分。式中的 w和x都是2000维的向量,只不过w是定值,而x是变量(好吧,严格说来这个函数是2001维的,哈哈),现在我们的输入呢,是一个1000维的向量x,分类的过程是先把x变换为2000维的向量x,然后求这个变换后的向量x与向量w的内积,再把这个内积的值和b相加,就得到了结果,看结果大于阈值还是小于阈值就得到了分类结果。

    你发现了什么?我们其实只关心那个高维空间里内积的值,那个值算出来了,分类结果就算出来了。而从理论上说, x是经由x变换来的,因此广义上可以把它叫做x的函数(有一个x,就确定了一个x,对吧,确定不出第二个),而w是常量,它是一个低维空间里的常量w经过变换得到的,所以给了一个w 和x的值,就有一个确定的f(x)值与其对应。这让我们幻想,是否能有这样一种函数K(w,x),他接受低维空间的输入值,却能算出高维空间的内积值<w,x>?


    如果有这样的函数,那么当给了一个低维空间的输入x以后,

    g(x)=K(w,x)+b

    f(x)=<w,x>+b

    这两个函数的计算结果就完全一样,我们也就用不着费力找那个映射关系,直接拿低维的输入往g(x)里面代就可以了(再次提醒,这回的g(x)就不是线性函数啦,因为你不能保证K(w,x)这个表达式里的x次数不高于1哦)。

    万幸的是,这样的K(w,x)确实存在(发现凡是我们人类能解决的问题,大都是巧得不能再巧,特殊得不能再特殊的问题,总是恰好有些能投机取巧的地方才能解决,由此感到人类的渺小),它被称作核函数(核,kernel),而且还不止一个,事实上,只要是满足了Mercer条件的函数(后面会具体写出),都可以作为核函数。核函数的基本作用就是接受两个低维空间里的向量,能够计算出经过某个变换后在高维空间里的向量内积值。几个比较常用的核函数,俄,教课书里都列过,我就不敲了(懒!)。

    回想我们上节说的求一个线性分类器,它的形式应该是:


    现在这个就是高维空间里的线性函数(为了区别低维和高维空间里的函数和向量,我改了函数的名字,并且给w和x都加上了 ’),我们就可以用一个低维空间里的函数(再一次的,这个低维空间里的函数就不再是线性的啦)来代替,


    又发现什么了?f(x’) 和g(x)里的α,y,b全都是一样一样的!这就是说,尽管给的问题是线性不可分的,但是我们就硬当它是线性问题来求解,只不过求解过程中,凡是要求内积 的时候就用你选定的核函数来算。这样求出来的α再和你选定的核函数一组合,就得到分类器啦!


    明白了以上这些,会自然的问接下来两个问题:

    1. 既然有很多的核函数,针对具体问题该怎么选择?

    2. 如果使用核函数向高维空间映射后,问题仍然是线性不可分的,那怎么办?


    第一个问题现在就可以回答你:对核函数的选择,现在还缺乏指导原则!各种实验的观察结果(不光是文本分类)的确表明,某些问题用某些核函数效果很 好,用另一些就很差,但是一般来讲,径向基核函数是不会出太大偏差的一种,首选。(我做文本分类系统的时候,使用径向基核函数,没有参数调优的情况下,绝 大部分类别的准确和召回都在85%以上,可见。虽然libSVM的作者林智仁认为文本分类用线性核函数效果更佳,待考证)

    对第二个问题的解决则引出了我们下一节的主题:松弛变量。

    ==================

    2.核函数的定义及计算复杂度

    将核函数形式化定义,如果原始特征内积是,映射后为,那么定义核函数(Kernel)为:


    到这里,我们可以得出结论,我们计算SVM的分类问题的时候,只需先计算,然后计算即可,然而这种计算方式是非常低效的。比如最初的特征是n维的,我们将其映射到n^2维,然后再计算,这样需要的时间。那么我们能不能想办法减少计算时间呢? 
    先看一个例子,假设x和z都是n维的,

    展开后,得

    这个时候发现我们可以只计算原始特征x和z内积的平方(时间复杂度是O(n)),就等价与计算映射后特征的内积。也就是说我们不需要花时间了。
    更一般地,核函数对应的映射后特征维度为。(求解方法参见 http://zhidao.baidu.com/question/16706714.html )。 
    由于计算的是内积,我们可以想到IR中的余弦相似度,如果x和z向量夹角越小,那么核函数值越大,反之,越小。
    因此,核函数值是的相似度。

    2.径向基函数——Radial Basis Function(RBF)

    所谓径向基函数 (Radial Basis Function 简称 RBF), 就是某种沿径向对称的标量函数。 通常定义为空间中任一点x到某
    一中心xc之间欧氏距离的单调函数 ,可记作 k(||x-xc||), 其作用往往是局部的 , 即当x远离xc时函数取值很小。

    最常用的径向基函数是高斯核函数 ,形式为 k(||x-xc||)=exp{- ||x-xc||^2/(2*σ)^2) } 其中x_c为核函数中心,σ为函数的宽度参数 , 控制了函数的径向作用范围。如果x和x_c很相近那么核函数值为1,如果x和x_c相差很大那么核函数值约等于0。由于这个函数类似于高斯分布,因此称为高斯核函数,也叫做径向基函数(Radial Basis Function 简称RBF)。它能够把原始特征映射到无穷维。


    那么核函数值约等于0。由于这个函数类似于高斯分布,因此称为高斯核函数,也叫做径向基函数(Radial Basis

    Function 简称RBF)。它能够把原始特征映射到无穷维。

    既然高斯核函数能够比较x和z的相似度,并映射到0到1,回想logistic回归,sigmoid函数可以,因此还有sigmoid核

    函数等等。

    ==================

    核函数有很多种,如线性核、多项式核、Sigmoid 核和 RBF(Radial Basis function)核。本文选定 RBF 核为 SVM 的核函数(RBF 核K(x, y) = exp(-γ || x -y ||的平方),γ > 0)。因为RBF 核可以将样本映射到一个更高维的空间,可以处理当类标签(Class Labels)和特征之间的关系是非线性时的样例。Keerthi 等[25]证明了一个有惩罚参数C 的线性核同有参数(C,γ )(其中C 为惩罚因子,γ 为核参数)的 RBF 核具有相同的性能。对某些参数,Sigmoid核同 RBF 核具有相似的性能[26]。另外,RBF 核与多项式核相比具有参数少的优点。因为参数的个数直接影响到模型选择的复杂性。非常重要的一点是0< Kij ≤1与多项式核相反,核值可能趋向无限(γxi xj + r >1)或者0 < γxi xj + r <1,跨度非常大。而且,必须注意的是Sigmoid 核在某些参数下是不正确的(例如,没有两个向量的内积)。

    用交叉验证找到最好的参数 C 和γ 。使用 RBF 核时,要考虑两个参数 C 和γ 。因为参数的选择并没有一定的先验知识,必须做某种类型的模型选择(参数搜索)。目的是确定好的(C,γ)使得分类器能正确的预测未知数据(即测试集数 据),有较高的分类精确率。值得注意的是得到高的训练正确率即是分类器预测类标签已知的训练数据的正确率)不能保证在测试集上具有高的预测精度。因此,通 常采用交叉验证方法提高预测精度。k 折交叉验证(k-fold cross validation)

    =========================

    下面有张图说明在低维线性不可分时,映射到高维后就可分了,使用高斯核函数。



    来自Eric Xing的slides

    注意,使用核函数后,怎么分类新来的样本呢?线性的时候我们使用SVM学习出w和b,新来样本x的话,我们使用来判断,如果值大于等于1,那么是正类,小于等于是负类。在两者之间,认为无法确定。如果使用了核函数后,就变成了,是否先要找到,然后再预测?答案肯定不是了,找很麻烦,回想我们之前说过的


    只需将clip_image057[4]替换成,然后值的判断同上。


    建议首选RBF核函数进行高维投影,因为:

    1. 能够实现非线性映射;( 线性核函数可以证明是他的一个特例;SIGMOID核函数在某些参数上近似RBF的功能。)
    2. 参数的数量影响模型的复杂程度,多项式核函数参数较多。
    3. the RBF kernel has less numerical difficulties.

    3. 核函数有效性判定

    问题:给定一个函数K,我们能否使用K来替代计算,也就说,是否能够找出一个,使得对于所有的x和z,都有
    比如给出了,是否能够认为K是一个有效的核函数。
    下面来解决这个问题,给定m个训练样本,每一个对应一个特征向量。那么,我们可以将任意两个带入K中,计算得到。i可以从1到m,j可以从1到m,这样可以计算出m*m的核函数矩阵(Kernel Matrix)。为了方便,我们将核函数矩阵和都使用K来表示。

    如果假设K是有效地核函数,那么根据核函数定义

    可见,矩阵K应该是个对称阵。让我们得出一个更强的结论,首先使用符号来表示映射函数的第k维属性值。那么对于任意向量z,得

    最后一步和前面计算时类似。从这个公式我们可以看出,如果K是个有效的核函数(即等价),那么,在训练集上得到的核函数矩阵K应该是半正定的(K>=0).

    这样我们得到一个核函数的必要条件

    K是有效的核函数 ==> 核函数矩阵K是对称半正定的。

    可幸的是,这个条件也是充分的,由Mercer定理来表达。 

    Mercer定理:

    如果函数K是上的映射(也就是从两个n维向量映射到实数域)。那么如果K是一个有效核函数(也称为Mercer核函数),那么当且仅当对于训练样例,其相应的核函数矩阵是对称半正定的。


    Mercer定理表明为了证明K是有效的核函数,那么我们不用去寻找,而只需要在训练集上求出各个,然后判断矩阵K是否是半正定(使用左上角主子式大于等于零等方法)即可。

    许多其他的教科书在Mercer定理证明过程中使用了L^2范数和再生希尔伯特空间等概念,但在特征是n维的情况下,这里给出的证明是等价的。

    =========================

    参考自:

    1、互动百科

    2、Jasper's Java Jacal--《SVM入门(七)为何需要核函数》

    3、博文:径向基核函数 (Radial Basis Function)--RBF | 丕子 +http://www.zhizhihu.com/html/y2010/2103.html

    4、支撑向量机(三)核函数:http://www.cnblogs.com/jerrylead/archive/2011/03/18/1988406.html

    展开全文
  • 径向基网络(RBF network)之... 18:17 2377人阅读 评论(1) 收藏 举报 神经网络机器学习RBF 径向基网络(RBF network)之BP监督训练 zouxy09@qq.com http://blog.csdn.net/zouxy09    之前看了流行学习
     

    径向基网络(RBF network)之BP监督训练

    分类: 机器学习 神经网络 C/C++编程   2377人阅读  评论(1)  收藏  举报

    径向基网络(RBF network)之BP监督训练

    zouxy09@qq.com

    http://blog.csdn.net/zouxy09

     

           之前看了流行学习的时候,感觉它很神奇,可以将一个4096维的人脸图像降到3维。然后又看到了可以用径向基网络来将这3维的图像重构到4096维。看到效果的时候,我和小伙伴们都惊呆了(呵呵,原谅我的孤陋寡闻)。见下图,第1和3行是原图像,维度是64x64=4096维,第2和第4行是将4096维的原图像用流行学习算法降到3维后,再用RBF网络重构回来的图像(代码是参考一篇论文写的)。虽然在重构领域,这效果不一定是好的,但对于无知的我,其中的奥妙勾引了我,使我忍不住又去瞻仰了一番。


           推荐大家先看看这个博主的这篇博文:

    http://www.cnblogs.com/zhangchaoyang/articles/2591663.html

     

    一、径向基函数

           在说径向基网络之前,先聊下径向基函数(Radical Basis Function,RBF)。径向基函数(Radical Basis Function,RBF)方法是Powell在1985年提出的。所谓径向基函数,其实就是某种沿径向对称的标量函数。通常定义为空间中任一点x到某一中心c之间欧氏距离的单调函数,可记作k(||x-c||),其作用往往是局部的,即当x远离c时函数取值很小。例如高斯径向基函数:


           当年径向基函数的诞生主要是为了解决多变量插值的问题。可以看下面的图。具体的话是先在每个样本上面放一个基函数,图中每个蓝色的点是一个样本,然后中间那个图中绿色虚线对应的,就表示的是每个训练样本对应一个高斯函数(高斯函数中心就是样本点)。然后假设真实的拟合这些训练数据的曲线是蓝色的那根(最右边的图),如果我们有一个新的数据x1,我们想知道它对应的f(x1)是多少,也就是a点的纵坐标是多少。那么由图可以看到,a点的纵坐标等于b点的纵坐标加上c点的纵坐标。而b的纵坐标是第一个样本点的高斯函数的值乘以一个大点权值得到的,c的纵坐标是第二个样本点的高斯函数的值乘以另一个小点的权值得到。而其他样本点的权值全是0,因为我们要插值的点x1在第一和第二个样本点之间,远离其他的样本点,那么插值影响最大的就是离得近的点,离的远的就没什么贡献了。所以x1点的函数值由附近的b和c两个点就可以确定了。拓展到任意的新的x,这些红色的高斯函数乘以一个权值后再在对应的x地方加起来,就可以完美的拟合真实的函数曲线了。

     

    二、径向基网络

           到了1988年, Moody和 Darken提出了一种神经网络结构,即RBF神经网络,属于前向神经网络类型,它能够以任意精度逼近任意连续函数,特别适合于解决分类问题。

           RBF网络的结构与多层前向网络类似,它是一种三层前向网络。输入层由信号源结点组成;第二层为隐含层,隐单元数视所描述问题的需要而定,隐单元的变换函数是RBF径向基函数,它是对中心点径向对称且衰减的非负非线性函数;第三层为输出层,它对输入模式的作用作出响应。从输人空间到隐含层空间的变换是非线性的,而从隐含层空间到输出层空间变换是线性的。

           RBF网络的基本思想是:用RBF作为隐单元的“基”构成隐含层空间,这样就可将输入矢量直接(即不需要通过权连接)映射到隐空间。根据Cover定理,低维空间不可分的数据到了高维空间会更有可能变得可分。换句话来说,RBF网络的隐层的功能就是将低维空间的输入通过非线性函数映射到一个高维空间。然后再在这个高维空间进行曲线的拟合。它等价于在一个隐含的高维空间寻找一个能最佳拟合训练数据的表面。这点与普通的多层感知机MLP是不同的。

           当RBF的中心点确定以后,这种映射关系也就确定了。而隐含层空间到输出空间的映射是线性的,即网络的输出是隐单元输出的线性加权和,此处的权即为网络可调参数。由此可见,从总体上看,网络由输人到输出的映射是非线性的,而网络输出对可调参数而言却又是线性的。这样网络的权就可由线性方程组直接解出,从而大大加快学习速度并避免局部极小问题。

           从另一个方面也可以这样理解,多层感知器(包括BP神经网络)的隐节点基函数采用线性函数,激活函数则采用Sigmoid函数或硬极限函数。而RBF网络的隐节点的基函数采用距离函数(如欧氏距离),并使用径向基函数(如Gaussian函数)作为激活函数。径向基函数关于n维空间的一个中心点具有径向对称性,而且神经元的输入离该中心点越远,神经元的激活程度就越低。隐节点的这一特性常被称为“局部特性”。

     

    三、RBF网络的设计与求解

           RBF的设计主要包括两个方面,一个是结构设计,也就是说隐藏层含有几个节点合适。另一个就是参数设计,也就是对网络各参数进行求解。由上面的输入到输出的网络映射函数公式可以看到,网络的参数主要包括三种:径向基函数的中心、方差和隐含层到输出层的权值。到目前为止,出现了很多求解这三种参数的方法,主要可以分为以下两大类:

    1、方法一:

           通过非监督方法得到径向基函数的中心和方差,通过监督方法(最小均方误差)得到隐含层到输出层的权值。具体如下:

    (1)在训练样本集中随机选择h个样本作为h个径向基函数的中心。更好的方法是通过聚类,例如K-means聚类得到h个聚类中心,将这些聚类中心当成径向基函数的h个中心。

    (2)RBF神经网络的基函数为高斯函数时,方差可由下式求解:

           式中cmax 为所选取中心之间的最大距离,h是隐层节点的个数。扩展常数这么计算是为了避免径向基函数太尖或太平。

    (3)隐含层至输出层之间神经元的连接权值可以用最小均方误差LMS直接计算得到,计算公式如下:(计算伪逆)(d是我们期待的输出值)

     

    2、方法二:

             采用监督学习算法对网络所有的参数(径向基函数的中心、方差和隐含层到输出层的权值)进行训练。主要是对代价函数(均方误差)进行梯度下降,然后修正每个参数。具体如下:

    (1)随机初始化径向基函数的中心、方差和隐含层到输出层的权值。当然了,也可以选用方法一中的(1)来初始化径向基函数的中心。

    (2)通过梯度下降来对网络中的三种参数都进行监督训练优化。代价函数是网络输出和期望输出的均方误差:

    然后每次迭代,在误差梯度的负方向已一定的学习率调整参数。

     

    四、代码实现:

    1、第一种方法

           第一种方法在zhangchaoyang的博客上面有C++的实现,只是上面针对的是标量的数据(输入和输出都是一维的)。而在Matlab中也提供了第一种方法的改进版(呵呵,个人觉得,大家可以在Matlab中运行open newrb查看下源代码)。

           Matlab提供的一个函数是newrb()。它有个技能就是可以自动增加网络的隐层神经元数目直到均方差满足我们要求的精度或者神经元数数目达到最大(也就是我们提供的样本数目,当神经元数目和我们的样本数目一致时,rbf网络此时的均方误差为0)为止。它使用方法也能简单:

    rbf = newrb(train_x, train_y);

    output = rbf(test_x);

          直接把训练样本给它就可以得到一个rbf网络了。然后我们把输入给它就可以得到网络的输出了。

     

    2、第二种方法

           第二种方法在zhangchaoyang的博客上面也有C++的实现,只是上面针对的还是标量的数据(输入和输出都是一维的)。但我是做图像的,网络需要接受高维的输入,而且在Matlab中,向量的运算要比for训练的运算要快很多。所以我就自己写了个可以接受向量输入和向量输出的通过BP算法监督训练的版本。BP算法可以参考这里:BackpropagationAlgorithm ,主要是计算每层每个节点的残差就可以了。另外,我的代码是可以通过梯度检查的,但在某些训练集上面,代价函数值却会随着迭代次数上升,这就很奇怪了,然后降低了学习率还是一样。但在某些简单点的训练集上面还是可以工作的,虽然训练误差也挺大的(没有完全拟合训练样本)。所以大家如果发现代码里面有错误的部分,还望大家告知下。

           主要代码见下面:

    learnRBF.m

    [cpp]  view plain copy
    1. %// This is a RBF network trained by BP algorithm    
    2. %// Author : zouxy    
    3. %// Date   : 2013-10-28    
    4. %// HomePage : http://blog.csdn.net/zouxy09    
    5. %// Email  : zouxy09@qq.com    
    6.   
    7. close all; clear; clc;  
    8.   
    9. %%% ************************************************  
    10. %%% ************ step 0: load data ****************  
    11. display('step 0: load data...');  
    12. % train_x = [1 2 3 4 5 6 7 8]; % each sample arranged as a column of train_x  
    13. % train_y = 2 * train_x;  
    14. train_x = rand(5, 10);  
    15. train_y = 2 * train_x;  
    16. test_x = train_x;  
    17. test_y = train_y;  
    18.   
    19. %% from matlab  
    20. % rbf = newrb(train_x, train_y);  
    21. % output = rbf(test_x);  
    22.   
    23.   
    24. %%% ************************************************  
    25. %%% ******** step 1: initialize parameters ********   
    26. display('step 1: initialize parameters...');  
    27. numSamples = size(train_x, 2);  
    28. rbf.inputSize = size(train_x, 1);  
    29. rbf.hiddenSize = numSamples;        % num of Radial Basis function  
    30. rbf.outputSize = size(train_y, 1);  
    31. rbf.alpha = 0.1;  % learning rate (should not be large!)  
    32.   
    33. %% centre of RBF  
    34. for i = 1 : rbf.hiddenSize  
    35.     % randomly pick up some samples to initialize centres of RBF  
    36.     index = randi([1, numSamples]);   
    37.     rbf.center(:, i) =  train_x(:, index);  
    38. end  
    39.   
    40. %% delta of RBF  
    41. rbf.delta = rand(1, rbf.hiddenSize);  
    42.   
    43. %% weight of RBF  
    44. r = 1.0; % random number between [-r, r]  
    45. rbf.weight = rand(rbf.outputSize, rbf.hiddenSize) * 2 * r - r;  
    46.   
    47.   
    48. %%% ************************************************  
    49. %%% ************ step 2: start training ************  
    50. display('step 2: start training...');  
    51. maxIter = 400;  
    52. preCost = 0;  
    53. for i = 1 : maxIter  
    54.     fprintf(1, 'Iteration %d ,', i);  
    55.     rbf = trainRBF(rbf, train_x, train_y);  
    56.     fprintf(1, 'the cost is %d \n', rbf.cost);  
    57.       
    58.     curCost = rbf.cost;  
    59.     if abs(curCost - preCost) < 1e-8  
    60.         disp('Reached iteration termination condition and Termination now!');  
    61.         break;  
    62.     end  
    63.     preCost = curCost;  
    64. end  
    65.   
    66.   
    67. %%% ************************************************  
    68. %%% ************ step 3: start testing ************   
    69. display('step 3: start testing...');  
    70. Green = zeros(rbf.hiddenSize, 1);  
    71. for i = 1 : size(test_x, 2)  
    72.     for j = 1 : rbf.hiddenSize  
    73.         Green(j, 1) = green(test_x(:, i), rbf.center(:, j), rbf.delta(j));  
    74.     end   
    75.     output(:, i) = rbf.weight * Green;  
    76. end  
    77. disp(test_y);  
    78. disp(output);  

    trainRBF.m

    [cpp]  view plain copy
    1. function [rbf] = trainRBF(rbf, train_x, train_y)  
    2.     %%% step 1: calculate gradient  
    3.     numSamples = size(train_x, 2);  
    4.     Green = zeros(rbf.hiddenSize, 1);  
    5.     output = zeros(rbf.outputSize, 1);  
    6.     delta_weight = zeros(rbf.outputSize, rbf.hiddenSize);  
    7.     delta_center = zeros(rbf.inputSize, rbf.hiddenSize);  
    8.     delta_delta =  zeros(1, rbf.hiddenSize);  
    9.     rbf.cost = 0;  
    10.     for i = 1 : numSamples  
    11.         %% Feed forward  
    12.         for j = 1 : rbf.hiddenSize  
    13.             Green(j, 1) = green(train_x(:, i), rbf.center(:, j), rbf.delta(j));  
    14.         end   
    15.         output = rbf.weight * Green;      
    16.           
    17.         %% Back propagation  
    18.         delta3 = -(train_y(:, i) - output);  
    19.         rbf.cost = rbf.cost + sum(delta3.^2);  
    20.         delta_weight = delta_weight + delta3 * Green';  
    21.         delta2 = rbf.weight' * delta3 .* Green;  
    22.         for j = 1 : rbf.hiddenSize  
    23.             delta_center(:, j) = delta_center(:, j) + delta2(j) .* (train_x(:, i) - rbf.center(:, j)) ./ rbf.delta(j)^2;  
    24.             delta_delta(j) = delta_delta(j)+ delta2(j) * sum((train_x(:, i) - rbf.center(:, j)).^2) ./ rbf.delta(j)^3;  
    25.         end  
    26.     end  
    27.   
    28.     %%% step 2: update parameters  
    29.     rbf.cost = 0.5 * rbf.cost ./ numSamples;  
    30.     rbf.weight = rbf.weight - rbf.alpha .* delta_weight ./ numSamples;  
    31.     rbf.center = rbf.center - rbf.alpha .* delta_center ./ numSamples;  
    32.     rbf.delta = rbf.delta - rbf.alpha .* delta_delta ./ numSamples;  
    33. end  

    green.m

    [plain]  view plain copy
    1. function greenValue = green(x, c, delta)  
    2.     greenValue = exp(-1.0 * sum((x - c).^2) / (2 * delta^2));  
    3. end  

    五、代码测试

          首先,我测试了一维的输入,需要拟合的函数很简单,就是y=2x。

    train_x = [1 2 3 4 5 6 7 8];

    train_y = 2 * train_x;

         所以期待的输出就是:

    2    4     6     8   10    12    14   16

         我代码训练迭代200次后的网络输出是:

    2.0042   4.0239    5.9250    8.0214  10.0692   11.9351   14.0179  15.9958

          Matlab的newrb的输出是:

    2.0000   4.0000    6.0000    8.0000  10.0000   12.0000   14.0000  16.0000

          可以看到,Matlab的是完美拟合啊。我的那个还是均方误差还是挺大的。

          然后,我测试了高维的输入,训练样本是通过Matlab的rand(5, 10)来得到的,它生成的是5行10列[0 1]之间的随机数。也就是说我们的样本是10个,每个样本的维度是5维。我们测试的也是很简单的函数y=2x。结果如下:

     

          关于这个结果,我也不说什么了。期待大家发现代码里面错误的地方,然后告知下,非常感谢。

    展开全文
  • 文件名称: bpm下载 收藏√ [5 4 3 2 1]开发工具: matlab文件大小: 219 KB上传时间: 2013-06-18下载次数: 10提 供 者: 那笑龙详细说明:Matlab环境下基于期望传播算法的贝叶斯分类器工具箱-Matlab environment based ...
  • 文件名称: test3下载 收藏√ [5 4 3 2 1]开发工具: matlab文件大小: 8262 KB上传时间: 2016-01-09下载次数: 111提 供 者: 刘彧详细说明:利用matlab实现hog特征提取与SVM分类方法 用来识别人车与背景-Using matlab ...
  • For information about the NeuroMem® digital neuromorphic technology, refer to the General Vision web site at www.general-vision,com and in particular the NeuroMem Technology Reference Guide....
  • 周学习笔记(2021.7.12-2021.7.18) 文章目录周学习笔记(2021.7.12-2021.7.18)7.121. typedef2. python 列表3. pandas 操作4. python 其他5. malloc() & new()6. 二叉搜索树7.131. Colab2. github 访问慢可以...
  • 转载自:http://www.cnblogs.com/kshenf/archive/2012/02/07/2342034.html 牛人主页(主页有很多论文代码) Serge Belongie at UC San Diego Antonio Torralba at MIT Alexei Ffros at CMU Ce Liu at ...
  • 图像处理-机器学习-SLAM基础知识...sina.com 1.适用于机器学习的矩阵求导推导技巧 1.矩阵求导术(上)-- 非常好 https://zhuanlan.zhihu.com/p/24709748 2.矩阵求导术(下)-- 非常好 ht...
  • Hadoop3.2.0使用详解

    2019-04-23 07:34:55
    [INFO] Apache Hadoop HDFS-RBF ............................. SUCCESS [ 3.071 s] [INFO] Apache Hadoop HDFS Project ......................... SUCCESS [ 0.035 s] [INFO] Apache Hadoop YARN ...................
  • 1.是否规定团队角色 看板:简单来讲包括需求列表、事项列表等, 并不规定团队中的角色。 Scrum板:规定三种角色—— 产品负责人、Scrum Master、开发团队。在Scrum板中,团队角色及职责能够很清楚地展现,例如产品...
  • BeautifulSoup抓取门户网站上的链接

    万次阅读 2014-12-16 18:25:00
    使用BeautifulSoup抓取门户网站上的所有跳转链接 from bs4 import BeautifulSoup ...request = urllib2.Request('http://www.163.com') response = urllib2.urlopen(request) html_doc = response.read() so...
  • python中神经网络包

    2020-12-05 13:33:59
    {"moduleinfo":{"card_count":[{"count_phone":...","link1":"https://developer.aliyun.com/group/?spm=a2c6h.12883283.1377930.25.7287201c9RKTCi&groupType=other","link":"https://developer.aliyun.com/","icon":...
  • [INFO] Apache Hadoop HDFS-RBF ............................. SUCCESS [01:26 min] [INFO] Apache Hadoop HDFS Project ......................... SUCCESS [ 1.059 s] [INFO] Apache Hadoop YARN ..................
  • 正文 ------------恢复内容开始------------ 第2关-条件判断与条件嵌套 一、条件判断 条件判断:计算机沟通的逻辑——条件判断 作用:明确地让计算机知道:在什么条件下,该去做什么。 范例:《复仇者联盟3:无限宝石...
  • 18 , 105 , 2.95 , 3.32 , .22 , 2.38 , 5.75 , 1.25 , 3.17 , 1510 1 , 14.12 , 1.48 , 2.32 , 16.8 , 95 , 2.2 , 2.43 , .26 , 1.57 , 5 , 1.17 , 2.82 , 1280 1 , 13.75 , 1.73 , 2.41 , 16 , 89 , 2.6 , ...
  • ZDnet.com 的 Ed Burnette 称 EmEditor 为 “全球最快的文本编辑器”。 (见全文) 日本人气网站窓の杜 (Mado-no-mori) 评价,“无需 Excel。最强 CSV 编辑器”。(见译文) Riccardo Tani,一位网络防御经理,推荐...
  • 用protobuf进行C#与Java通信

    千次阅读 2016-08-05 15:20:48
    关于alert()和里面的内容和下面的部分文字还是显示不出来你给我的发的文件就在就没问题...《 http://baobao.baidu.com/article/b03dd0e126a45e27389b516752abcb36.html 》 嫡氛稼mlZZ烈80F鸦hG性锤轿脱肚瓤 《 http...
  • 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 ...
  • ML——支持向量机

    2019-04-17 17:21:41
    文章PDF格式下载地址:https://pan.baidu.com/s/1eQrgiOU 也可参考《统计学习方法》——支持向量机 代码实现 项目案例: 手写数字识别的优化(有核函数) 详见:《机器学习实战》 from numpy import * import ...
  • 晾词骋蔷虑找《http://baobao.baidu.com/question/e68c03283d5525e2723642ed939b2c91?3y582=2018/09/18》 冶慰仙篮览中《http://baobao.baidu.com/question/32b77a398aa96dc1281d5b1327919da4?qfaq3=2018/09/18》 ...
  • 关于图片操作记录

    千次阅读 2017-09-22 18:57:00
    1. 在img标签的src属性中可以是图片路径,也可以是base64位编码的图片格式 base64图片格式: var images = [{"format":"jpg", "data":"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/4QBaRXhpZgAATU0...
  • https://github.com/scikit-learn/scikit-learn/blob/7b136e9/sklearn/cluster/spectral.py#L275 算法及原理: Graph特征提取方法:谱聚类(Spectral Clustering)详解 目录 一、输入参数 1.1 聚类组数 ...
  • 默认MiniGUI.cfg

    2018-09-29 15:45:04
    cursor18=g_nodrop.cur cursor19=h_point.cur cursor20=h_select.cur cursor21=ho_split.cur cursor22=ve_split.cur [resinfo] respath=/usr/local/share/minigui/res/ [classic] # Note that max number defined in...
  • https://www.cnblogs.com/huty/p/8517691.html 参考:http://www.xuehuile.com/thesis/9a81f680054441ad907934b07b465c8e.html,本文做了相关修改。 1 人脸识别技术概述 近年来,随着计算机技术的迅速发展...
  • 'rbf', 'poly')): clf = svm.SVC(kernel=kernel, gamma= 10) clf.fit(X_train, y_train) plt.figure(fig_num) plt.clf() plt.scatter(X[:, 0], X[:, 1], c=y, zorder= 10, cmap=plt.cm.Paired) # Circle...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,215
精华内容 886
关键字:

rbf18.com

友情链接: subsolv.zip