import numpy as np import pandas as pd import matplotlib.pyplot as plt def load_data(): df_orig_train = pd.read_csv('mnist.csv') 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, epochs: int = 20): """__init__ Initializes a newly created Restricted 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.epochs = epochs # 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) # 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): # 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) def run(self, v0): # activate hidden layer h0 = self.activate(v0) v1 = self.reactivate(h0) return h0, v1 rbm = RBM(28 ** 2, 100, 0.2, epochs=1) for i in range(100): # normalize mnist data and train number = mnist[i] / 255 rbm.train(number) # plot results rows, columns = (9, 9) fig = plt.figure(figsize=(10, 7)) fig.canvas.manager.set_window_title("Reconstruction of MNIST Numbers using a Restricted Boltzmann Machine") for i in range((rows * columns)): if i % 3 == 0: number = mnist[i] / 255 (hidden, visible) = rbm.run(number) results = [hidden.reshape((10, 10)), visible.reshape((28, 28)), number.reshape((28, 28))] for j, item in enumerate(results): fig.add_subplot(rows, columns, i + j + 1) plt.imshow(item, cmap='gray') plt.axis('off') plt.show()