Final assignment
Name: Srisha Reddy Eleti
main.py
– Sample 1,000 points in two disks (radius 0.5) centered at (1,1) and (3,1).
– Initialize 100 Kohonen weights in [2,3]×[0.5,1.5].
– Train for STEPS=1000 with linear decay of learning rate and neighborhood.
– Snapshot at steps={0,100,1000} and plot all three in one figure.
"""
import numpy as np
import matplotlib.pyplot as plt
def sample_disk(center, radius, count):
"""Return `count` points uniformly sampled in a disk."""
u_vals = np.random.rand(count)
angles = 2 * np.pi * np.random.rand(count)
radii = radius * np.sqrt(u_vals)
xs = center[0] + radii * np.cos(angles)
ys = center[1] + radii * np.sin(angles)
return np.vstack([xs, ys]).T
def initialize_weights(num_neurons):
"""Initialize `num_neurons` weight vectors in [2,3]×[0.5,1.5]."""
weights = np.empty((num_neurons, 2))
weights[:, 0] = np.random.uniform(2.0, 3.0, size=num_neurons) # w₁ ∈ [2,3]
weights[:, 1] = np.random.uniform(0.5, 1.5, size=num_neurons) # w₂ ∈ [0.5,1.5]
return weights
def learning_rate(step, initial=2.0, total=1000):
"""Linearly decaying learning rate."""
return initial * (1 - step / total)
def neighborhood_radius(step, max_radius=3, total=1000):
"""Linearly decaying neighborhood radius (integer)."""
return int(np.floor(max_radius * (1 - step / total)))
def train_kohonen(data, num_neurons=100, total_steps=1000):
"""Train a 1‑D Kohonen map and return weight snapshots."""
weights = initialize_weights(num_neurons)
snapshots = {}
for step in range(total_steps + 1):
sample = data[np.random.randint(len(data))]
winner_idx = np.argmin(np.linalg.norm(weights - sample, axis=1))
radius_val = neighborhood_radius(step)
alpha = learning_rate(step)
idx_min = max(0, winner_idx - radius_val)
idx_max = min(num_neurons, winner_idx + radius_val + 1)
for idx in range(idx_min, idx_max):
weights[idx] += alpha * (sample - weights[idx])
if step in (0, 100, 1000):
snapshots[step] = weights.copy()
return snapshots
def plot_snapshots(data, snapshots, connect_thresh=1.0):
"""Plot inputs (blue), neurons (red), and local links for each snapshot."""
steps = sorted(snapshots.keys()) # [0, 100, 1000]
fig, axes = plt.subplots(1, 3, figsize=(15, 5), sharex=True, sharey=True)
for ax, step in zip(axes, steps):
w_snapshot = snapshots[step]
ax.scatter(data[:, 0], data[:, 1], s=5, c='blue', alpha=0.3)
ax.scatter(w_snapshot[:, 0], w_snapshot[:, 1], s=30, c='red')
for i in range(len(w_snapshot) - 1):
if np.linalg.norm(w_snapshot[i] - w_snapshot[i+1]) <= connect_thresh:
ax.plot(
[w_snapshot[i, 0], w_snapshot[i+1, 0]],
[w_snapshot[i, 1], w_snapshot[i+1, 1]],
'-', lw=1, c='red'
)
ax.set_title(f'Step = {step}')
ax.set_aspect('equal')
plt.tight_layout()
plt.show()
def main():
# 1) generate two point-clouds
disk1 = sample_disk((1, 1), 0.5, 500)
disk2 = sample_disk((3, 1), 0.5, 500)
dataset = np.vstack([disk1, disk2])
# 2) train and capture snapshots
weight_snapshots = train_kohonen(dataset, num_neurons=100, total_steps=1000)
# 3) plot all snapshots together
plot_snapshots(dataset, weight_snapshots)
if __name__ == "__main__":
main()
Output: