In [1]:
import matplotlib.pyplot as plt
%matplotlib inline

In [2]:
import os
import sys

CURRENT_DIR = os.path.abspath(os.path.dirname(__name__))
LIBRARY_DIR = os.path.join(CURRENT_DIR, '..', '..')

def saveas(name):
    image_name = '{}.png'.format(name)
    image_path = os.path.join(LIBRARY_DIR, 'site', '2018', '03', '26', 'images', image_name)
    plt.savefig(image_path, facecolor='#f8fafb', bbox_inches='tight')

In [3]:
import numpy as np

def draw_circle(alpha=1.0):
    ax = plt.gca()
    circle = plt.Circle((0, 0), 1, color='#1f77b4', alpha=alpha)
    ax.add_artist(circle)

plt.figure(figsize=(5, 5))
draw_circle()

plt.xlim(-1.2, 1.2)
plt.ylim(-1.2, 1.2);



In [4]:
import copy
from neupy import algorithms

def draw_edge(node_1, node_2, alpha=1.):
    weights = np.concatenate([node_1.weight, node_2.weight])
    return plt.plot(*weights.T, color='black', zorder=500, alpha=alpha)

def draw_graph(graph, alpha=1.):
    for node_1, node_2 in graph.edges:
        draw_edge(node_1, node_2, alpha)
        
    weights = np.concatenate([node.weight for node in graph.nodes])
    plt.scatter(*weights.T, color='#2ca02c', zorder=1000, s=160, alpha=alpha)

node_positions = [
    np.array([-0.4, 0.0]),
    np.array([-0.3, 0.3]),
    np.array([-0.7, 0.2]),
    np.array([-0.2, 0.0]),
    np.array([0.1, 0.6]),
    np.array([0.0, 0.3]),
]
graph = algorithms.NeuralGasGraph()

nodes = []
for node_position in node_positions:
    node = algorithms.NeuronNode(node_position.reshape(1, -1))
    graph.add_node(node)
    nodes.append(node)
    
graph.add_edge(nodes[0], nodes[1])
graph.add_edge(nodes[1], nodes[2])
graph.add_edge(nodes[1], nodes[3])

graph.add_edge(nodes[0], nodes[2])
graph.add_edge(nodes[0], nodes[3])
graph.add_edge(nodes[1], nodes[4])

graph.add_edge(nodes[5], nodes[4])
graph.add_edge(nodes[5], nodes[1])
graph.add_edge(nodes[2], nodes[4])

draw_graph(graph)

original_graph = copy.deepcopy(graph)



In [5]:
random_point = np.array([0.5, -0.5])

def draw_base():
    plt.figure(figsize=(5, 5))
    plt.scatter(random_point[0], random_point[1], color='#d62728', s=160, zorder=1000)
    draw_circle(alpha=0.3)

    plt.xlim(-1.2, 1.2)
    plt.ylim(-1.2, 1.2)
    
draw_base()
saveas('gng-sampled-point')



In [6]:
draw_base()
draw_graph(graph)
saveas('gng-sampled-point-with-graph')



In [7]:
draw_base()

closest_node, second_closest_node = nodes[3], nodes[5]
graph.add_edge(closest_node, second_closest_node)
draw_graph(graph, alpha=1.0)

line, = draw_edge(closest_node, second_closest_node)
plt.scatter(*closest_node.weight.T, color='#1f77b4', zorder=2000, s=160)
plt.scatter(*second_closest_node.weight.T, color='#1f77b4', zorder=2000, s=160)
plt.setp(line, linewidth=4., color='black')

saveas('gng-added-edge')



In [8]:
gng = algorithms.GrowingNeuralGas(
    n_inputs=2,
    
    step=0.5,
    neighbour_step=0.2,
)

gng.graph = graph
gng.train(random_point.reshape(1, -1), epochs=1)

In [9]:
draw_base()
draw_graph(original_graph, alpha=0.2)
draw_graph(graph, alpha=1.0)
saveas('gng-updated')



In [10]:
draw_base()

graph.remove_edge(nodes[2], nodes[4])
draw_graph(graph, alpha=1.0)

saveas('gng-edge-removed')



In [11]:
draw_base()

new_node = algorithms.NeuronNode(0.5 * (nodes[0].weight + nodes[2].weight) )
graph.add_node(new_node)

plt.scatter(*new_node.weight.T, color='#1f77b4', zorder=2000, s=160)
draw_graph(graph, alpha=1.0)

saveas('gng-new-neuron-added')