Foto del docente

Emanuele Mingione

Professore associato

Dipartimento di Matematica

Settore scientifico disciplinare: MATH-04/A Fisica matematica

Contenuti utili

PLS 2026, Hopfield corrotti

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation


# ==================================================
# Parametri
# ==================================================
L = 28
N = L * L

n_steps = 400
noise_level = 0.01

# pesi dei pattern (stabili: 3,1,0)
a_1 = 1.0
a_7 = 0.0
a_3 = 1.0
a_0 = 1.0


# ==================================================
# CARICA PATTERN
# (devono essere già creati come negli script prima)
# ==================================================
# pattern0, pattern1, pattern3, pattern7
# dimensione: (784,)


# ==================================================
# Pesi sinaptici di Hopfield
# ==================================================
J = (
a_7 * np.outer(pattern7, pattern7) / N
+ a_3 * np.outer(pattern3, pattern3) / N
+ a_1 * np.outer(pattern1, pattern1) / N
+ a_0 * np.outer(pattern0, pattern0) / N
)

np.fill_diagonal(J, 0)


# ==================================================
# Energia di Hopfield
# ==================================================
def energy(s, W):
return -0.5 * np.dot(s, np.dot(W, s)) / N


# ==================================================
# Rumore
# ==================================================
noise = np.random.choice(
[-1, 1],
size=N,
p=[noise_level, 1 - noise_level]
)


# ==================================================
# Stato iniziale: pattern corrotto
# ==================================================
spins = pattern0 * noise

E_in = energy(spins, J)


# ==================================================
# Setup figura
# ==================================================
fig, ax = plt.subplots(figsize=(4, 4))

img = ax.imshow(
spins.reshape(L, L),
cmap="gray",
vmin=-1,
vmax=1
)

ax.axis("off")
ax.set_title("Hopfield: pattern corrotto")


# ==================================================
# Update function
# ==================================================
def update(frame):

# stampa energie finali
if frame == n_steps - 1:
print("E_0 =", energy(pattern0, J))
print("E_1 =", energy(pattern1, J))
print("E_3 =", energy(pattern3, J))
print("E_7 =", energy(pattern7, J))
print("E_iniziale =", E_in)
print("E_finale =", energy(spins, J))

# 10 aggiornamenti asincroni per frame
for _ in range(10):

i = np.random.randint(N)
h = np.dot(J[i], spins)

if h != 0:
spins[i] = np.sign(h)

img.set_data(spins.reshape(L, L))
return (img,)


# ==================================================
# Animazione
# ==================================================
ani = FuncAnimation(
fig,
update,
frames=n_steps,
interval=20,
blit=True
)

plt.show()