gnn/uebungen/aufgabe3/uebung3.py

107 lines
3.1 KiB
Python

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()