diff --git a/uebungen/uebung3.py b/uebungen/uebung3.py index 5aa1627..f65dd85 100644 --- a/uebungen/uebung3.py +++ b/uebungen/uebung3.py @@ -1,5 +1,3 @@ -from typing import Tuple - import numpy as np import pandas as pd import matplotlib.pyplot as plt @@ -7,95 +5,109 @@ import matplotlib.pyplot as plt def load_data(): 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() + mnist = load_data() + def sigmoid(x): return 1.0 / (1.0 + np.exp(-x)) # Sigmoidfunktion + 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.visible_size = visible_size self.hidden_size = hidden_size - self.k = 2 - self.epochs = 10 + self.epochs = epochs 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.visible_bias = np.zeros(self.visible_size) * 0.1 self.hidden_bias = np.zeros(self.hidden_size) * 0.1 def activate(self, v0): return sigmoid(np.matmul(v0.T, self.weights) + self.hidden_bias) - + def reactivate(self, h0): return sigmoid(np.matmul(self.weights, h0.T) + self.visible_bias) - + def contrastive_divergence(self, v0, h0, v1, h1): + # calculate gradients postive_gradient = np.outer(v0, h0) negative_gradient = np.outer(v1, h0) + # Adjust weights by delta 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): for _ in range(self.epochs): - h0 = self.activate(v0) # Aktivieren versteckter Schicht - v1 = self.reactivate(h0) # Reaktivieren sichtbarer Schicht + # activate hidden layer + h0 = self.activate(v0) + + # reactivate visible layer + v1 = self.reactivate(h0) + + #activate next hidden layer h1 = self.activate(v1) + # Adjust weights self.contrastive_divergence(v0, h0, v1, h1) - - self.visible_bias += self.learnrate * (v0 - v1) - self.hidden_bias += self.learnrate * (h0 - h1) - - return h0, v1 - - 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) - """ + def run(self, v0): + # activate hidden layer h0 = self.activate(v0) v1 = self.reactivate(h0) return h0, v1 +rbm = RBM(28**2, 256, 0.1, epochs=3) def validate(idx): - + #flatten and normalize mnist data test = mnist[idx].flatten()/255 + + # train bolzmann machine and run rbm.train(test) (hid, out) = rbm.run(test) - return (hid.reshape((5, 5)), out.reshape((28,28))) + return (hid.reshape((16, 16)), out.reshape((28, 28))) - -rbm = RBM(28**2, 25, 0.1) - -rows, columns = (4,4) +# plot results +rows, columns = (4, 6) fig = plt.figure(figsize=(10, 7)) + for i in range((rows * columns)): if i % 2 == 0: (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') - 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.axis('off') plt.show() -