#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Created on Thu Sep 28 08:23:56 2023 @author: Mohamad Mohannad al Kawadri (mohamad.mohannad.al.kawadri@nmbu.no), Trygve Børte Nomeland (trygve.borte.nomeland@nmbu.no) """ from abc import ABC, abstractmethod import numpy as np from copy import deepcopy from torchvision import datasets, transforms class Network: def __init__(self, layers, W_file_list, b_file_list): self.layers = layers self.W_file_list = W_file_list self.b_file_list = b_file_list self.x = input def run(self, x): result = x for n, W_file, b_file in zip(self.layers, self.W_file_list, self.b_file_list): y = deepcopy(result) l = n(y, W_file = W_file, b_file = b_file) result = l.run() return result def evaluate(self, x, expected_value): result = list(self.run(x)) max_value_index = result.index(max(result)) return int(max_value_index) == expected_value class Layer: def __init__(self, x, W_file, b_file): self.x = x files = read(W_file, b_file) self.W = files.get('W') self.b = files.get('b') @abstractmethod def run(self): pass class SigmaLayer(Layer): def run(self): return layer(self.W, self.x, self.b) class ReluLayer(Layer): def run(self): return relu_layer(self.W, self.x, self.b) def read(W_file, b_file): return {'W': np.loadtxt(W_file), 'b': np.loadtxt(b_file)} # define activation function def sigma(y): if y > 0: return y else: return 0 sigma_vec = np.vectorize(sigma) def relu_scalar(x): if x > 0: return x else: return 0 relu = np.vectorize(relu_scalar) # define layer function for given weight matrix, input and bias def layer(W, x, b): return sigma_vec(W @ x + b) def relu_layer(W, x, b): return sigma_vec(W @ x + b) # Function from example file "read.py" def get_mnist(): return datasets.MNIST(root='./data', train=True, transform=transforms.ToTensor(), download=True) # Function from example file "read.py" def return_image(image_index, mnist_dataset): image, label = mnist_dataset[image_index] image_matrix = image[0].detach().numpy() # Grayscale image, so we select the first channel (index 0) return image_matrix.reshape(image_matrix.size), image_matrix, label def evalualte_on_mnist(image_index, expected_value): mnist_dataset = get_mnist() x, image, label = return_image(image_index, mnist_dataset) network = Network([ReluLayer, ReluLayer, ReluLayer], ['W_1.txt', 'W_2.txt', 'W_3.txt'], ['b_1.txt', 'b_2.txt', 'b_3.txt']) return network.evaluate(x, expected_value) def run_on_mnist(image_index): mnist_dataset = get_mnist() x, image, label = return_image(image_index, mnist_dataset) network = Network([ReluLayer, ReluLayer, ReluLayer], ['W_1.txt', 'W_2.txt', 'W_3.txt'], ['b_1.txt', 'b_2.txt', 'b_3.txt']) return network.run(x) def main(): print(f'Check if network works on image 19961 (number 4): {evalualte_on_mnist(19961, 4)}') print(f'Check if network works on image 10003 (number 9): {evalualte_on_mnist(10003, 9)}') print(f'Check if network works on image 117 (number 2): {evalualte_on_mnist(117, 2)}') print(f'Check if network works on image 1145 (number 3): {evalualte_on_mnist(1145, 3)}') print(f'Values image 19961 (number 4): {run_on_mnist(19961)}') if __name__ == '__main__': main()