-
Notifications
You must be signed in to change notification settings - Fork 1
/
kanervacoding.py
80 lines (67 loc) · 2.28 KB
/
kanervacoding.py
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
70
71
72
73
74
75
76
77
78
79
80
#!/usr/bin/env python
from __future__ import print_function
import numpy as np
class kanervacoder:
def __init__(self, dims, ptypes, n_active, limits, dist=lambda x1, x2: np.max(np.abs(x1 - x2), axis=1), seed=None):
np.random.seed(seed)
self._n_pts = ptypes
self._k = n_active
self._lims = np.array(limits)
self._ranges = self._lims[:, 1] - self._lims[:, 0]
self._pts = np.random.random([self._n_pts, dims])
self._dist = dist
@property
def n_ptypes(self):
return self._n_pts
def __getitem__(self, x):
xs = (x - self._lims[:, 0]) / self._ranges
return np.argpartition(self._dist(self._pts, xs), self._k)[:self._k]
def example():
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import time
# kanerva coder dimensions, limits, prototypes, number of active features
dims = 2
lims = [(0, 2.0 * np.pi)] * 2
ptypes = 512
n_active = 10
# create kanerva coder
K = kanervacoder(dims, ptypes, n_active, lims)
# learning params
w = np.zeros(K.n_ptypes)
alpha = 0.1 / n_active
# target function with gaussian noise
def target_ftn(x, y, noise=True):
return np.sin(x) + np.cos(y) + noise * np.random.randn() * 0.1
# randomly sample target function until convergence
timer = time.time()
batch_size = 100
for iters in range(100):
mse = 0.0
for b in range(batch_size):
xi = lims[0][0] + np.random.random() * (lims[0][1] - lims[0][0])
yi = lims[1][0] + np.random.random() * (lims[1][1] - lims[1][0])
zi = target_ftn(xi, yi)
phi = K[xi, yi]
w[phi] += alpha * (zi - w[phi].sum())
mse += (w[phi].sum() - zi) ** 2
mse /= batch_size
print('samples:', (iters + 1) * batch_size, 'batch_mse:', mse)
print('elapsed time:', time.time() - timer)
# get learned function
print('mapping function...')
res = 200
x = np.arange(lims[0][0], lims[0][1], (lims[0][1] - lims[0][0]) / res)
y = np.arange(lims[1][0], lims[1][1], (lims[1][1] - lims[1][0]) / res)
z = np.zeros([len(y), len(x)])
for i in range(len(x)):
for j in range(len(y)):
z[i, j] = w[K[x[i], y[j]]].sum()
# plot
fig = plt.figure()
ax = fig.gca(projection='3d')
X, Y = np.meshgrid(x, y)
surf = ax.plot_surface(X, Y, z, cmap=plt.get_cmap('hot'))
plt.show()
if __name__ == '__main__':
example()