from scipy.linalg import norm, pinv
from matplotlib import pyplot as plt
import numpy
class RBF:
def __init__(self, indim, numcenters, outdim):
self.indim = indim
self.outdim = outdim
self.numcenters = numcenters
self.centers = [numpy.random.uniform(-1, 1, indim) for i in range(numcenters)]
self.beta = 8
self.W = numpy.random.random((numcenters, outdim))
def _basisfunc(self, c, d):
assert len(d) == self.indim
return numpy.exp(-self.beta * norm(c - d) ** 2)
def _calcAct(self, X):
# calculate activations of RBFs
G = numpy.zeros((X.shape[0], self.numcenters), float)
for ci, c in enumerate(self.centers):
for xi, x0 in enumerate(X):
G[xi, ci] = self._basisfunc(c, x0)
return G
def train(self, X, Y):
""" X: matrix of dimensions n x indim
y: column vector of dimension n x 1 """
# choose random center vectors from training set
rnd_idx = numpy.random.permutation(X.shape[0])[:self.numcenters]
self.centers = [X[i, :] for i in rnd_idx]
print("center", self.centers)
# calculate activations of RBFs
G = self._calcAct(X)
print(G)
# calculate output weights (pseudoinverse)
self.W = numpy.dot(pinv(G), Y)
def test(self, X):
""" X: matrix of dimensions n x indim """
G = self._calcAct(X)
Y = numpy.dot(G, self.W)
return Y
if __name__ == '__main__':
n = 100
x = numpy.mgrid[-1:1:complex(0, n)].reshape(n, 1)
# set y and add random noise
y = numpy.sin(3 * (x + 0.5) ** 3 - 1)
# y += random.normal(0, 0.1, y.shape)
# rbf regression
rbf = RBF(1, 20, 1)
rbf.train(x, y)
z = rbf.test(x)
# plot original data
plt.figure(figsize=(12, 8))
plt.plot(x, y, 'k-')
# plot learned model
plt.plot(x, z, 'r-', linewidth=2)
# plot rbfs
# plt.plot(rbf.centers, numpy.zeros(rbf.numcenters), 'gs')
# for c in rbf.centers:
# # RF prediction lines
# cx = numpy.arange(c - 0.7, c + 0.7, 0.01)
# cy = [rbf._basisfunc(numpy.array([cx_]), numpy.array([c])) for cx_ in cx]
# plt.plot(cx, cy, '-', color='black', linewidth=0.2)
# plt.xlim(-1.2, 1.2)
plt.show()
径向基(RBF)神经网络python代码实现
最新推荐文章于 2024-10-08 14:37:53 发布