finalized code + cleanup

main
romanamo 2024-05-09 01:12:49 +02:00
parent ef7be8ac54
commit 176ed663c1
1 changed files with 49 additions and 37 deletions

View File

@ -1,5 +1,3 @@
from typing import Tuple
import numpy as np import numpy as np
import pandas as pd import pandas as pd
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
@ -7,95 +5,109 @@ import matplotlib.pyplot as plt
def load_data(): def load_data():
df_orig_train = pd.read_csv('mnist_test_final.csv') df_orig_train = pd.read_csv('mnist_test_final.csv')
df_digits = df_orig_train.drop('label',axis=1) df_digits = df_orig_train.drop('label', axis=1)
return df_digits.to_numpy() return df_digits.to_numpy()
mnist = load_data() mnist = load_data()
def sigmoid(x): def sigmoid(x):
return 1.0 / (1.0 + np.exp(-x)) # Sigmoidfunktion return 1.0 / (1.0 + np.exp(-x)) # Sigmoidfunktion
class RBM: class RBM:
def __init__(self, visible_size: int, hidden_size: int, learnrate: float=0.1) -> None: def __init__(self, visible_size: int, hidden_size: int, learnrate: float = 0.1, epochs=20):
"""__init__ Initializes a newly created Ristricted Bolzmann Machine.
Args:
visible_size (int): amount of neurons inside the visible layer
hidden_size (int): amount of neurons inside the hidden layer
learnrate (float, optional): learnrate eta in [0;1]. Defaults to 0.1.
epochs (int, optional): training epochs. Defaults to 20.
"""
self.learnrate = learnrate self.learnrate = learnrate
self.visible_size = visible_size self.visible_size = visible_size
self.hidden_size = hidden_size self.hidden_size = hidden_size
self.k = 2 self.epochs = epochs
self.epochs = 10
self.reset() self.reset()
def reset(self) -> None: def reset(self):
# initialize/reset learnable attributes
self.weights = np.random.randn(self.visible_size, self.hidden_size) self.weights = np.random.randn(self.visible_size, self.hidden_size)
self.visible_bias = np.zeros(self.visible_size) * 0.1 self.visible_bias = np.zeros(self.visible_size) * 0.1
self.hidden_bias = np.zeros(self.hidden_size) * 0.1 self.hidden_bias = np.zeros(self.hidden_size) * 0.1
def activate(self, v0): def activate(self, v0):
return sigmoid(np.matmul(v0.T, self.weights) + self.hidden_bias) return sigmoid(np.matmul(v0.T, self.weights) + self.hidden_bias)
def reactivate(self, h0): def reactivate(self, h0):
return sigmoid(np.matmul(self.weights, h0.T) + self.visible_bias) return sigmoid(np.matmul(self.weights, h0.T) + self.visible_bias)
def contrastive_divergence(self, v0, h0, v1, h1): def contrastive_divergence(self, v0, h0, v1, h1):
# calculate gradients
postive_gradient = np.outer(v0, h0) postive_gradient = np.outer(v0, h0)
negative_gradient = np.outer(v1, h0) negative_gradient = np.outer(v1, h0)
# Adjust weights by delta
self.weights += self.learnrate * (postive_gradient - negative_gradient) self.weights += self.learnrate * (postive_gradient - negative_gradient)
return self.weights # Adjust biases by delta
self.visible_bias += self.learnrate * (v0 - v1)
self.hidden_bias += self.learnrate * (h0 - h1)
def train(self, v0): def train(self, v0):
for _ in range(self.epochs): for _ in range(self.epochs):
h0 = self.activate(v0) # Aktivieren versteckter Schicht # activate hidden layer
v1 = self.reactivate(h0) # Reaktivieren sichtbarer Schicht h0 = self.activate(v0)
# reactivate visible layer
v1 = self.reactivate(h0)
#activate next hidden layer
h1 = self.activate(v1) h1 = self.activate(v1)
# Adjust weights
self.contrastive_divergence(v0, h0, v1, h1) self.contrastive_divergence(v0, h0, v1, h1)
self.visible_bias += self.learnrate * (v0 - v1)
self.hidden_bias += self.learnrate * (h0 - h1)
def run(self, v0):
return h0, v1 # activate hidden layer
def run(self, v0 : np.ndarray) -> Tuple[np.ndarray, np.ndarray]:
"""run Runs the Restricted Boltzmann machine on some input vector v0.
Args:
v0 (np.ndarray): 1-dimensional Input vector
Returns:
Tuple[np.ndarray, np.ndarray]: (hidden activation, visible reactivation)
"""
h0 = self.activate(v0) h0 = self.activate(v0)
v1 = self.reactivate(h0) v1 = self.reactivate(h0)
return h0, v1 return h0, v1
rbm = RBM(28**2, 256, 0.1, epochs=3)
def validate(idx): def validate(idx):
#flatten and normalize mnist data
test = mnist[idx].flatten()/255 test = mnist[idx].flatten()/255
# train bolzmann machine and run
rbm.train(test) rbm.train(test)
(hid, out) = rbm.run(test) (hid, out) = rbm.run(test)
return (hid.reshape((5, 5)), out.reshape((28,28))) return (hid.reshape((16, 16)), out.reshape((28, 28)))
# plot results
rbm = RBM(28**2, 25, 0.1) rows, columns = (4, 6)
rows, columns = (4,4)
fig = plt.figure(figsize=(10, 7)) fig = plt.figure(figsize=(10, 7))
for i in range((rows * columns)): for i in range((rows * columns)):
if i % 2 == 0: if i % 2 == 0:
(hid, out) = validate(i) (hid, out) = validate(i)
fig.add_subplot(rows, columns, i+1)
# hidden layer
fig.add_subplot(rows, columns, i+1)
plt.imshow(hid, cmap='gray') plt.imshow(hid, cmap='gray')
fig.add_subplot(rows, columns, i+2) plt.axis('off')
# visible layer
fig.add_subplot(rows, columns, i+2)
plt.imshow(out, cmap='gray') plt.imshow(out, cmap='gray')
plt.axis('off') plt.axis('off')
plt.show() plt.show()