import
math
from
tqdm.notebook
import
tqdm
import
matplotlib.pyplot as plt
import
numpy as np
data_
=
np.random.uniform(
-
1
,
1
, (
1500
,
2
))
x, y
=
10
,
10
sigma
=
1.
learning_rate
=
0.5
epochs
=
50000
decay_parameter
=
epochs
/
2
activation_map
=
np.zeros((x, y))
weights
=
2
*
(np.random.ranf((x, y, data_.shape[
1
]))
-
0.5
)
neighbour_x
=
np.arange(x)
neighbour_y
=
np.arange(y)
def
decay_learning_rate_sigma(iteration):
learning_rate_
=
learning_rate
/
(
1
+
iteration
/
decay_parameter)
sigma_
=
sigma
/
(
1
+
iteration
/
decay_parameter)
return
learning_rate_, sigma_
def
get_winner_neuron(x):
s
=
np.subtract(x, weights)
it
=
np.nditer(activation_map, flags
=
[
'multi_index'
])
while
not
it.finished:
activation_map[it.multi_index]
=
np.linalg.norm(s[it.multi_index])
it.iternext()
return
np.unravel_index(activation_map.argmin(), activation_map.shape)
def
update_weights(win_neuron, inputx, iteration):
learning_rate_, sigma_
=
decay_learning_rate_sigma(iteration)
d
=
2
*
np.pi
*
(sigma_
*
*
2
)
ax
=
np.exp(
-
1
*
np.square(neighbour_x
-
win_neuron[
0
])
/
d)
ay
=
np.exp(
-
1
*
np.square(neighbour_y
-
win_neuron[
1
])
/
d)
neighborhood
=
np.outer(ax, ay)
it
=
np.nditer(neighborhood, flags
=
[
'multi_index'
])
while
not
it.finished:
weights[it.multi_index]
+
=
learning_rate_
*
neighborhood[it.multi_index]
*
(inputx
-
weights[it.multi_index])
it.iternext()
for
epoch
in
tqdm(
range
(
1
, epochs
+
1
)):
np.random.shuffle(data_)
idx
=
np.random.randint(
0
, data_.shape[
0
])
win_neuron
=
get_winner_neuron(data_[idx])
update_weights(win_neuron, data_[idx], epoch)
if
epoch
=
=
1
or
epoch
=
=
100
=
=
0
or
epoch
=
=
1000
or
epoch
=
=
10000
or
epoch
=
=
50000
:
plot_x
=
[]
plot_y
=
[]
for
i
in
range
(weights.shape[
0
]):
for
j
in
range
(weights.shape[
1
]):
plot_x.append(weights[i][j][
0
])
plot_y.append(weights[i][j][
1
])
plt.title(
'After '
+
str
(epoch)
+
' iterations'
)
plt.scatter(plot_x, plot_y, c
=
'r'
)
plt.show()
plt.close()