RBF 就是计算两个点之间的相似度。
真正把特征从低维空间映射到高维空间的是你选择的隐层的节点数,隐层的节点数就是高维空间的维数。
如下实现了输入层到隐层之间文随机权重的径向基函数神经网络(RBFNN)
def pairwise_distances(X, Y):
D = -2 * X @ Y.T + np.sum(Y ** 2, axis=1) + np.sum(X ** 2, axis=1)[:, np.newaxis]
D[D < 0] = 0
return D
class RBFNN:
def __init__(self):
self.N_i = None
self.N_o = None
self.N_h = 200
self.sigma = 1
self.beta = 1e-6
def train(self, X, Y):
self.N_i = X.shape[0]
self.N_o = Y.shape[0]
self.W_i = np.random.uniform(-self.sigma,self.sigma, (self.N_h, self.N_i))
# 隐层输出
H = np.exp(-pairwise_distances(self.W_i, X.T))
self.W_o = Y.dot(H.T.dot(np.linalg.inv(H.dot(H.T)+self.beta*np.eye(self.N_h))))
def predict(self, X):
H = np.exp(-pairwise_l2_distances(self.W_i, X.T))
return self.W_o.dot(H)
在洛伦兹系统的动态重建实验上表现很好:
np.random.seed()
model = RBFNN()
n = 1 # 使用 n 个历史点作为输入
num_train = 3000
x_train = np.vstack([select_samples(x,0+i,num_train) for i in range(n)])
y_train = select_samples(x,n,num_train)
model.train(x_train, y_train)
num_test = 5000
test_start = 5000
P = np.empty((3,num_test))
Q = select_samples(x,test_start, num_test)
p = np.vstack([select_samples(x,test_start-n+i,1) for i in range(n)])
for i in range(num_test):
p_next = model.predict(p)
P[:,i] = np.squeeze(p_next)
p = np.vstack([p,p_next])[3:]
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax = fig.add_subplot()
plt.plot(*P, 'r')
plt.plot(*Q, 'g')
plt.figure()
dim = ['x','y','z']
for i in range(3):
plt.subplot(3,1,i+1)
plt.plot(P[i,:].T, label='prediction')
plt.plot(Q[i,:].T, label='true')
plt.ylabel(dim[i])
plt.legend(loc='upper right')