├── DeepLearningEnginesCode └── Python │ ├── Ch02_LinearNetwork │ ├── README.md │ └── main.py │ ├── Ch03_Perceptron │ ├── README.md │ └── main.py │ ├── Ch04_BackpropNetwork │ ├── README.md │ └── main.py │ ├── Ch05_HopfieldNet │ ├── README.md │ ├── fullcue.png │ ├── main.py │ ├── noisycue.png │ ├── partialcue.png │ ├── patterns │ │ ├── train1.jpg │ │ ├── train2.jpg │ │ └── train3.jpg │ └── trainingpatterns.png │ ├── Ch07_RestrictedBoltzmannMachine │ ├── LICENSE │ ├── README.md │ ├── __pycache__ │ │ └── rbm.cpython-37.pyc │ ├── data │ │ └── mnist │ │ │ ├── processed │ │ │ └── test.pt │ │ │ └── raw │ │ │ ├── t10k-images-idx3-ubyte │ │ │ ├── t10k-labels-idx1-ubyte │ │ │ └── train-labels-idx1-ubyte │ └── main.py │ ├── Ch08_VariationalAutoencoder │ ├── README.md │ ├── main.py │ ├── requirements.txt │ └── results │ │ ├── reconstruction_1.png │ │ ├── reconstruction_10.png │ │ ├── reconstruction_2.png │ │ ├── reconstruction_3.png │ │ ├── reconstruction_4.png │ │ ├── reconstruction_5.png │ │ ├── reconstruction_6.png │ │ ├── reconstruction_7.png │ │ ├── reconstruction_8.png │ │ ├── reconstruction_9.png │ │ ├── sample_1.png │ │ ├── sample_10.png │ │ ├── sample_2.png │ │ ├── sample_3.png │ │ ├── sample_4.png │ │ ├── sample_5.png │ │ ├── sample_6.png │ │ ├── sample_7.png │ │ ├── sample_8.png │ │ └── sample_9.png │ ├── Ch09_ConvolutionalNetwork │ ├── README.md │ ├── main.py │ └── requirements.txt │ ├── Ch10_ReinforcementLearning │ ├── README.md │ ├── cartpole.gif │ └── main.py │ ├── README.md │ ├── howToGetPytorch.md │ └── tex │ ├── 1cbdf1c3ec380d9a41eb881ea74212cb.svg │ ├── 24be74da2f8b6c84350a80f0f0aea3c4.svg │ ├── 3e335f12ff462788f309ddef63e7ae01.svg │ ├── 48bed7afb24ae234d519a74f1c4c036e.svg │ ├── 4b09e1c80baeb7726ec2a0c26bc0f7c6.svg │ ├── 68b61e54061c3878c30181b9458cd6ef.svg │ ├── 8eb8508fe6faf08a760f0850ee76fc03.svg │ ├── 8fd5bb0eeaa8887f6a312c99359a3b93.svg │ ├── aed827aaffba4b207537cec436f2447d.svg │ ├── b1a0230d1f59a2608a513b0f56650ee3.svg │ ├── ccc47f81c25f969de60a446f1e4439cc.svg │ └── dc5d51913f93ee3838bcf37504118959.svg ├── LICENSE └── README.md /DeepLearningEnginesCode/Python/Ch02_LinearNetwork/README.md: -------------------------------------------------------------------------------- 1 | # Linear Associative Network 2 | 3 | * Author: Stuart Wilson, modified by JVStone. 4 | * Date created: 2016. 5 | * Original Source: Personal communication. 6 | * License: MIT. 7 | * Description: Learns to map 4 2D input vectors to 4 scalars, using gradient descent. 8 | -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch02_LinearNetwork/main.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Linear associative net. 5 | """ 6 | 7 | import numpy as np 8 | # use pylab for ploting. 9 | import pylab as pl 10 | 11 | ########## Define class MLP ########## 12 | class LinearNetwork(): 13 | 14 | ########## Define Methods for LinearNetwork class ########## 15 | # Initialize network topology 16 | def __init__(self,nInput,nOutput): 17 | 18 | # set number of units in each layer 19 | self.nInput = nInput 20 | self.nOutput = nOutput 21 | 22 | # define weights between input and output layers 23 | # use of +1 input units defines bias unit in input layer 24 | # example in book does not have bias term, so this is an extra in code. 25 | self.W = np.random.rand(self.nOutput,self.nInput+1) 26 | 27 | # space to store change in weights 28 | self.dw = np.zeros([self.nOutput,self.nInput+1]) 29 | 30 | # define vector to store state of output layer 31 | self.state = np.zeros([self.nOutput]) 32 | 33 | # define vector to store delta terms of output layer 34 | self.deltaO = np.zeros([self.nOutput]) 35 | 36 | # Iterate the network by one step 37 | def step(self,inp,tar,alpha): 38 | # get input vector with bias unit by appending 1 to end of input vector using 39 | # example in book does not have bias term, so this is an extra in code. 40 | input = np.append([inp], [1.0]) 41 | 42 | # use input layer state to get output layer state 43 | for k in range(self.nOutput): 44 | # get total input u to output unit 45 | u = np.dot(self.W[k,:],input) 46 | # use u to find state of output unit 47 | self.state[k] = self.activation(u) 48 | 49 | # Learning algorithm 50 | if (alpha>0.): 51 | # get delta terms of output layer units 52 | for k in range(self.nOutput): 53 | self.deltaO[k] = (self.state[k] - tar[k]) 54 | 55 | for k in range(self.nOutput): 56 | self.dw[k,:] -= alpha * self.deltaO[k] * input 57 | 58 | # Define linear unit activation function 59 | def activation(self,x): 60 | return x 61 | 62 | 63 | ########## set parameters ########## 64 | # set random seed so get same sequence of random numbers each time prog is run. 65 | np.random.seed(1) 66 | nip = 2 # num input units 67 | nop = 1 # num output units 68 | # Initialize network 69 | M = LinearNetwork(nip,nop) 70 | 71 | # Input vectors 72 | inputvectors = np.array([[0,0],[0,1],[1,0],[1,1]]) 73 | 74 | # targets for XOR, not used here, but left here for comparison 75 | # target = np.array([[0],[1],[1],[0]]) 76 | 77 | # targets for simple linearly separable problem 78 | targets = np.array([[0],[1],[0],[1]]) 79 | 80 | # Timesteps = number of learning trials 81 | numiter = 20 82 | 83 | # num training vectors 84 | T = targets.shape[0] 85 | 86 | # set learning rate alpha 87 | alpha = 0.2 88 | 89 | # Store cost function values E 90 | E = np.zeros(numiter) 91 | 92 | ########## Run learning ########## 93 | for iter in range(numiter): 94 | 95 | # reset weight changes to zero 96 | M.dw = M.dw*0 97 | 98 | Et = 0. 99 | 100 | for t in range(T): 101 | 102 | # find weight change for one association for one step 103 | inputvector = inputvectors[t] 104 | target = targets[t] 105 | 106 | # get network output and delta term at output 107 | M.step(inputvector,target,alpha) 108 | 109 | # Compute the error 110 | dif =(target - M.state) 111 | Et += np.sum(dif*dif) 112 | 113 | E[iter] = Et 114 | 115 | # update weights 116 | for k in range(M.nOutput): 117 | M.W[k,:] += M.dw[k,:] 118 | 119 | # Print comparison of target and output 120 | for k in range(T): 121 | inputvector = inputvectors[k,:] 122 | target = targets[t] 123 | M.step(inputvector,target,0.) 124 | print('input vector:' + str(inputvector)) 125 | print( 'target: ' + str(target) + ', output: ' + ("%.2f" % M.state)) 126 | 127 | ########## Plot ########## 128 | F = pl.figure(0,figsize=(4,4)) 129 | f = F.add_subplot(111) 130 | f.plot(E) 131 | f.set_aspect(np.diff(f.get_xlim())/np.diff(f.get_ylim())) 132 | f.set_xlabel('Training epoch') 133 | f.set_ylabel('Error') 134 | f.set_title('Error during training') 135 | pl.show() 136 | 137 | ########## The End ########## 138 | -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch03_Perceptron/README.md: -------------------------------------------------------------------------------- 1 | # Perceptron 2 | 3 | * Run code using main.py. 4 | * Original Source: https://github.com/Honghe/perceptron/tree/master/perceptron 5 | * Author: Honghe, modified by JVS. 6 | * Date created: 2013 7 | * License: None, copied with permission from author. 8 | * Description: Uses perceptron algorithm to classify two linearly separable classes, and produces graphical output during training. 9 | * Note also see: https://github.com/rasbt/stat479-deep-learning-ss19/blob/master/L09_mlp/code/xor-problem.ipynb 10 | -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch03_Perceptron/main.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Perceptron 5 | Original Source: https://github.com/Honghe/perceptron/tree/master/perceptron 6 | Author: Honghe, modified by JVS. 7 | """ 8 | 9 | import matplotlib.pyplot as plt 10 | import numpy as np 11 | 12 | # set random seed so get same sequence of random numbers each time prog is run. 13 | # np.random.seed(20) 14 | 15 | class Perceptron(object): 16 | """docstring for Perceptron""" 17 | def __init__(self): 18 | super(Perceptron, self).__init__() 19 | self.w = [np.random.rand() * 2 - 1 for _ in range(2)] # weights 20 | self.learningRate = 0.001 21 | 22 | def response(self, x): 23 | # perceptron output 24 | y = x[0] * self.w[0] + x[1] * self.w[1] # dot product between w and x 25 | # y = sum([i * j for i, j in zip(self.w, x)]) # more pythonic 26 | #y = np.dot(x[0:1],self.w) 27 | y=y*1.0 28 | if y >= 0: 29 | res = 1.0 30 | else: 31 | res = -1.0 32 | return res 33 | 34 | def updateWeights(self, x, iterError): 35 | """ 36 | upates the wights status, w at time t+1 is 37 | w(t+1) = w(t) + learningRate * (d - r) * x 38 | iterError is (d - r) 39 | """ 40 | self.w[0] += self.learningRate * iterError * x[0] 41 | self.w[1] += self.learningRate * iterError * x[1] 42 | #self.w = \ 43 | #[i + self.learningRate * iterError * j for i, j in zip(self.w, x)] 44 | 45 | def train(self, data): 46 | """ 47 | Trains all the vector in data. 48 | Every vector in data must three elements. 49 | The third element of x (ie x[2]) is the label(desired output) 50 | """ 51 | learned = False 52 | iteration = 0 53 | while not learned: 54 | numcorrect = 0 55 | globalError = 0.0 56 | for x in data: # for each input vector 57 | r = self.response(x) 58 | if x[2] != r: # if have a wrong response 59 | iterError = x[2] - r # desired response - actual response 60 | self.updateWeights(x, iterError) 61 | globalError += abs(iterError) 62 | else: 63 | numcorrect += 1 64 | print('num correctly classified = %s' % numcorrect) 65 | iteration += 1 66 | if globalError == 0.0 or iteration >= 100: # stop criteria 67 | print('iterations = %s' % iteration) 68 | learned = True # stop learning 69 | 70 | ########## Plot ########## 71 | plotinterval = 2 72 | if (iteration % plotinterval == 0): 73 | plotData(data,self.w) 74 | plt.pause(0.001) 75 | 76 | def generateData(n): 77 | """ 78 | generates a 2D linearly separable dataset with 2n samples. 79 | The third element of the sample is the correct response. 80 | """ 81 | # class A=blue dots has all y values above 0 82 | xb = (np.random.rand(n) * 2 -1) 83 | yb = (np.random.rand(n) * 2 -1) / 2 + 0.55 84 | 85 | # class B=red dots has all y values below 0 86 | xr = (np.random.rand(n) * 2 -1) 87 | yr = (np.random.rand(n) * 2 -1) / 2 - 0.55 88 | 89 | inputs = [] 90 | inputs.extend([[xb[i], yb[i], 1] for i in range(n)]) 91 | inputs.extend([[xr[i], yr[i], -1] for i in range(n)]) 92 | return inputs 93 | 94 | def plotData(data,w): 95 | plt.clf() 96 | for x in data: 97 | if x[1] < 0: 98 | plt.plot(x[0], x[1], 'ob') 99 | else: 100 | plt.plot(x[0], x[1], 'or') 101 | # plot the decision boundary. 102 | # The decision boundary is orthogonal to w. 103 | n = np.linalg.norm(w) # aka the length of p.w vector 104 | ww = w / n # a unit vector 105 | ww1 = [ww[1], -ww[0]] 106 | ww2 = [-ww[1], ww[0]] 107 | plt.ion() 108 | plt.plot([ww1[0], ww2[0]], [ww1[1], ww2[1]], '--k') 109 | plt.title('Two classes separated by a line orthogonal to the weight vector') 110 | plt.show() 111 | 112 | trainset = generateData(80) # train set generation 113 | # testset = generateData(20) # test set generation 114 | 115 | p = Perceptron() 116 | 117 | plotData(trainset,p.w) 118 | p.train(trainset) 119 | plotData(trainset,p.w) 120 | 121 | ########## The End ########## 122 | -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch04_BackpropNetwork/README.md: -------------------------------------------------------------------------------- 1 | # Chapter 4: The Backpropagation Algorithm 2 | 3 | * Run code using main.py. 4 | * Author: Sunil Ray, modified by JVS. 5 | * Date created: March 2017 6 | * License: None, copied with permission from the author. 7 | * Original Source: https://www.analyticsvidhya.com/blog/2017/05/neural-network-from-scratch-in-python-and-r/ 8 | * Description: A three layer backprop network with 2 input units, 2 hidden units and 1 output unit that learns the exclusive-OR (XOR) problem. 9 | * For a simple example of how to use Pytorch to make a three layer backprop network, see 10 | https://pytorch.org/tutorials/beginner/examples_nn/two_layer_net_nn.html 11 | * For testing backprop on the MNIST data set of digits using the sklearn (scikit-learn) package, see https://github.com/scikit-learn/scikit-learn/blob/master/benchmarks/bench_mnist.py 12 | -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch04_BackpropNetwork/main.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Created on Mon Dec 3 11:45:14 2018 5 | backprop for the XOR problem. 6 | 19th March 2019 JVS modified code and added graphics. 7 | """ 8 | 9 | import numpy as np 10 | import matplotlib.pyplot as plt 11 | 12 | # set random seed so get same sequence of random numbers each time prog is run. 13 | np.random.seed(1) 14 | 15 | ########## set input and output values ########## 16 | 17 | # set input vectors for XOR 18 | #Input array 19 | X = np.array([[0,0], [0,1], [1,0] , [1,1]]) 20 | 21 | # set output values for XOR 22 | targetvectors = np.array([[0],[1],[1],[0]]) 23 | 24 | # define unit activcation function as sigmoid function 25 | def sigmoid (x): 26 | return 1/(1 + np.exp(-x)) 27 | 28 | # define derivative of Sigmoid Function 29 | def derivatives_sigmoid(x): 30 | return x * (1 - x) 31 | 32 | ########## set parameters ########## 33 | niter = 3000 # number of training iterations 34 | plotinterval = 100 # interval between plotting graphs 35 | 36 | errors = np.zeros(niter) # record of errors during training 37 | numcorrects = np.zeros(niter) # number of correct outputs during training 38 | 39 | # decide if want to have sigmoidal or linear output units 40 | sigmoidalOutputUnits = 0 41 | 42 | if (sigmoidalOutputUnits): 43 | lr = 0.5 # learning rate 44 | else: 45 | lr = 0.1 # learning rate 46 | 47 | inputlayer_neurons = X.shape[1] # number of units in input layer 48 | hiddenlayer_neurons = 2 # number of hidden layer units 49 | output_neurons = 1 # number of units in output layer 50 | 51 | # weight and bias initialization 52 | # weights between input and hidden layer 53 | wh = np.random.uniform(size=(inputlayer_neurons,hiddenlayer_neurons)) 54 | # biases of hidden layer units 55 | bh = np.random.uniform(size=(1,hiddenlayer_neurons)) 56 | 57 | # weights of output layer units 58 | wout = np.random.uniform(size=(hiddenlayer_neurons,output_neurons)) 59 | # biases of output layer units 60 | bout = np.random.uniform(size=(1,output_neurons)) 61 | 62 | ########## SET UP GRAPHS ########## 63 | # set interactive plotting on, so graphs appear outside of console. 64 | plt.ion() 65 | 66 | fig, axes = plt.subplots(1,2) 67 | axerror = axes[0] 68 | axnumcorrect = axes[1] 69 | 70 | axerror.set_xlabel('Epoch') 71 | axerror.set_ylabel('Error') 72 | 73 | axnumcorrect.set_ylabel('Number correct') 74 | axnumcorrect.set_xlabel('Epoch') 75 | 76 | # set state of bias unit; this code works if set to -1 or +1. 77 | biasunitstate = -1.0 78 | 79 | ########## LEARN ########## 80 | for iter in range(niter): 81 | 82 | # Forward Propogation 83 | hidden_layer_input1 = np.dot(X,wh) # input from input layer 84 | hidden_layer_input = hidden_layer_input1 + bh*biasunitstate # add input from bias unit 85 | hiddenlayer_states = sigmoid(hidden_layer_input) 86 | 87 | output_layer_input1 = np.dot(hiddenlayer_states,wout) 88 | output_layer_input= output_layer_input1 + bout * biasunitstate 89 | 90 | # Backpropagation 91 | # get derivatives of errors wrt unit inputs ... 92 | # ... of output layer 93 | if (sigmoidalOutputUnits): 94 | output = sigmoid(output_layer_input) 95 | slope_output_layer = derivatives_sigmoid(output) 96 | else: # output units are linear 97 | output = output_layer_input 98 | slope_output_layer = output*0 + 1 # each derivative = 1 99 | 100 | d = targetvectors - output # delta terms = errors in output layer 101 | 102 | # get derivatives of errors wrt unit inputs of hidden units 103 | slope_hidden_layer = derivatives_sigmoid(hiddenlayer_states) 104 | 105 | # get delta terms of output units = d_output 106 | d_output = d * slope_output_layer 107 | 108 | Error_at_hidden_layer = d_output.dot(wout.T) 109 | d_hiddenlayer = Error_at_hidden_layer * slope_hidden_layer 110 | 111 | # update weights of output units 112 | wout += hiddenlayer_states.T.dot(d_output) * lr 113 | # update biases of output units 114 | bout += np.sum(d_output, axis=0,keepdims=True) * biasunitstate * lr 115 | 116 | # update weights and biases of hidden units 117 | wh += X.T.dot(d_hiddenlayer) * lr 118 | bh += np.sum(d_hiddenlayer, axis=0,keepdims=True) * biasunitstate * lr 119 | 120 | error = np.linalg.norm(d) 121 | errors[iter] = error 122 | 123 | # count number of correct responses 124 | a = (output<0.5) 125 | b = (targetvectors<0.5) 126 | numcorrect = sum(a==b) 127 | numcorrects[iter] = numcorrect 128 | 129 | ########## Plot ########## 130 | if (iter % plotinterval == 0): 131 | axerror.plot(errors[0:niter],'k') 132 | plt.show() 133 | plt.pause(0.001) 134 | axnumcorrect.plot(numcorrects[0:niter],'k') 135 | plt.show() 136 | plt.pause(0.001) 137 | 138 | ########## Print results ########## 139 | print('Target values') 140 | print(targetvectors) 141 | print('Output values') 142 | print(output) 143 | error=np.linalg.norm(d) 144 | #print(i) 145 | print('Final error:') 146 | print(error) 147 | ########## The End ########## 148 | -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch05_HopfieldNet/README.md: -------------------------------------------------------------------------------- 1 | # Chapter 5: Hopfield Net 2 | 3 | * Run code using main.py. 4 | * Author: Tom Stafford 5 | * Date created: 2016 6 | * License: MIT, reproduced with permission 7 | * Original Source: https://github.com/tomstafford/emerge/blob/master/lecture4.ipynb 8 | * Description: Learns binary images. Recalls perfect versions from noisy input images. 9 | -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch05_HopfieldNet/fullcue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgvfwstone/ArtificialIntelligenceEngines/29245b20b8b9f40c8c9808661825dd2399b08c14/DeepLearningEnginesCode/Python/Ch05_HopfieldNet/fullcue.png -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch05_HopfieldNet/main.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Hopfield network. 5 | Comments in code by Tom Stafford. 6 | @author: Tom Stafford, modified by JimStone 7 | """ 8 | 9 | from IPython.display import HTML 10 | HTML('') 11 | 12 | # Import libraries we will use. 13 | import numpy as np # maths functions in python 14 | import os # for joining paths and filenames sensibly 15 | import glob # for finding files 16 | import pylab as plt # for graphing functions 17 | 18 | def from_jpg(name): 19 | #This function takes image files and converts them into a pattern of numbers 20 | #We can then use this pattern of numbers to teach the Hopfield Network 21 | #need to make this so it forces square shape 22 | from PIL import Image 23 | size=40,40 24 | im = Image.open(name).convert('L') 25 | jm = im.resize(size,Image.ANTIALIAS) 26 | vals=np.array(jm.getdata()) 27 | sgn = np.vectorize(lambda x: -1 if x<(255/2) else +1) 28 | return sgn(vals) 29 | 30 | def to_pattern(letter): 31 | #This converts string to -1/+1 array 32 | from numpy import array 33 | return array([+1 if c=='X' else -1 for c in letter.replace('\n','')]) 34 | 35 | def display(pattern): 36 | #This shows a pattern of numbers as an image 37 | # - i.e it is the reverse of the 'from_jpg' function 38 | from pylab import imshow, cm, show 39 | side=int(np.sqrt(len(pattern))) 40 | imshow(pattern.reshape((side,side)),cmap=cm.binary, interpolation='nearest') 41 | show() 42 | 43 | def train(patterns): 44 | #This trains a network to remember the patterns it is given 45 | # - since it is important I'll comment each line 46 | from numpy import zeros, outer, diag_indices #import functions for vector calculus 47 | r,c = patterns.shape #take the patters and make them vectors. There is a neuron for each pixel in the patterns 48 | W = zeros((c,c)) #there is a weight between each neuron in the network 49 | for p in patterns: # for each pattern 50 | W = W + outer(p,p) # change the weights to reflect the correlation between pixels 51 | W[diag_indices(c)] = 0 # neurons are not connected to themselves (ie the weight is 0) 52 | return W/r #send back the normalised weights 53 | 54 | def recall(W, patterns, steps=5): 55 | #The tests the network. You give it a pattern and see what it produces 56 | from numpy import vectorize, dot #vector calculus functions 57 | sgn = vectorize(lambda x: -1 if x<0 else +1) # convert input pattern into a -1/+1 pattern 58 | for _ in range(steps): #over a number of iterations (defined by 'steps') 59 | patterns = sgn(dot(patterns,W)) #adjust the neuron activity to reflect the weights 60 | return patterns #return the final pattern 61 | 62 | def degrade(patterns,noise): 63 | #This allows you to add noise to a pattern 64 | sgn=np.vectorize(lambda x: x*-1 if np.random.random() 90 | 91 | #get files from 'patterns' directory. You can put your own pictures in there if you want 92 | files = glob.glob(os.path.join('patterns','*.jpg')) #where are the patterns stored? 93 | 94 | #from these files, define patterns of numbers 95 | patterns=np.array([from_jpg(p) for p in files]) #put individual patterns in array 96 | 97 | #remember how large the patterns are 98 | side=int(np.sqrt(len(patterns[0]))) #assume all patterns the same shape 99 | 100 | # Let's have a look at our patterns 101 | # Four axes, returned as a 2-d array 102 | f, axarr = plt.subplots(1,len(patterns)) 103 | 104 | for p in range(len(patterns)): 105 | #axarr[0, p].imshow(patterns[p].reshape((side,side)),cmap=cm.binary, interpolation='nearest') 106 | axarr[p].imshow(patterns[p].reshape((side,side)), cmap="binary") 107 | #axarr[0, p].set_title('Cue' + str(p)) 108 | 109 | # Fine-tune figure; hide x ticks for top plots and y ticks for right plots 110 | plt.setp([a.get_xticklabels() for a in axarr[:]], visible=False) 111 | plt.setp([a.get_yticklabels() for a in axarr[:]], visible=False) 112 | plt.suptitle('Our training patterns') 113 | plt.savefig('trainingpatterns.png') #save a file 114 | 115 | # The Hopfield Network learns patterns of association. In this case, the association is between pixels in the images. 116 | 117 | print("train weights") 118 | 119 | W = train(patterns) 120 | 121 | # We have defined a network which has 'learnt' associations between pixels. Now the fun begins. We can explore the emergent properties of this network to see just what networks of simple neurons can do. We can ask if the way the Hopfield network behaves has any lessons to teach us about human memory. 122 | 123 | # #simple recall 124 | # 125 | # In the graph below the first row shows the pattern the network is shown (the starting activity). The second row shows the pattern of activity after the neurons are allowed to send signals back and forth 126 | 127 | print("test with originals") 128 | 129 | # Four axes, returned as a 2-d array 130 | f, axarr = plt.subplots(2, len(patterns)) 131 | 132 | for p in range(len(patterns)): 133 | #axarr[0, p].imshow(patterns[p].reshape((side,side)),cmap=cm.binary, interpolation='nearest') 134 | axarr[0, p].imshow(patterns[p].reshape((side,side)), cmap="binary") 135 | axarr[0, p].set_title('Cue' + str(p)) 136 | #axarr[1, p].imshow(recall(W,patterns)[p].reshape((side,side)),cmap=cm.binary, interpolation='nearest') 137 | axarr[1, p].imshow(recall(W,patterns)[p].reshape((side,side)), cmap="binary") 138 | axarr[1, p].set_title('Recall' + str(p)) 139 | # Fine-tune figure; hide x ticks for top plots and y ticks for right plots 140 | plt.setp([a.get_xticklabels() for a in axarr[0, :]], visible=False) 141 | plt.setp([a.get_xticklabels() for a in axarr[1, :]], visible=False) 142 | plt.setp([a.get_yticklabels() for a in axarr[:, 0]], visible=False) 143 | plt.setp([a.get_yticklabels() for a in axarr[:, 1]], visible=False) 144 | plt.suptitle('Test with training patterns') 145 | plt.savefig('fullcue.png') 146 | 147 | # They should match. Graphically this isn't very interesting, but it means that the network doesn't move away from the pattern it is shown if it has been trained it before. Is this something like what our memories do when we recognise something? 148 | 149 | # #Recognition with noisy inputs 150 | # 151 | # You can recognise a face you've seen before in a new circumstances. You can recognise someone on a dark night, in the rain, even if they've changed their haircut. What does this mean to our network? Well, we can't give our patterns makeup, but we can alter them at random and see what how our network responds' 152 | 153 | noise=0.1 154 | 155 | #reload original patterns. 156 | #There's some variable reference / variable copying thing I don't understand that makes this necessary 157 | patterns=np.array([from_jpg(p) for p in files]) #put individual patterns in array 158 | 159 | print ("degrade patterns with noise") 160 | testpatterns=degrade(patterns,noise) 161 | 162 | # Four axes, returned as a 2-d array 163 | f, axarr = plt.subplots(2, len(patterns)) 164 | 165 | for p in range(len(testpatterns)): 166 | #axarr[0, p].imshow(patterns[p].reshape((side,side)),cmap=cm.binary, interpolation='nearest') 167 | axarr[0, p].imshow(testpatterns[p].reshape((side,side)), cmap="binary") 168 | axarr[0, p].set_title('Cue' + str(p)) 169 | #axarr[1, p].imshow(recall(W,patterns)[p].reshape((side,side)),cmap=cm.binary, interpolation='nearest') 170 | axarr[1, p].imshow(recall(W,testpatterns)[p].reshape((side,side)), cmap="binary") 171 | axarr[1, p].set_title('Recall' + str(p)) 172 | # Fine-tune figure; hide x ticks for top plots and y ticks for right plots 173 | plt.setp([a.get_xticklabels() for a in axarr[0, :]], visible=False) 174 | plt.setp([a.get_xticklabels() for a in axarr[1, :]], visible=False) 175 | plt.setp([a.get_yticklabels() for a in axarr[:, 0]], visible=False) 176 | plt.setp([a.get_yticklabels() for a in axarr[:, 1]], visible=False) 177 | plt.suptitle('Test with noisy cue') 178 | plt.savefig('noisycue.png') 179 | 180 | # In the cell above the amount of noise is defined as 0.1. That's 10% of pixels randomly switched. What happens if you change that number? How is the system responding? 181 | 182 | # What you are seeing is sometimes called 'graceful degredation'. That means that the system fails gradually - it doesn't need the exact right inputs to guess the right pattern. Consider: 183 | # 184 | # Yuo nca unredstnad thsi 185 | # 186 | # Human information processing is often very good at coping with noisy inputs. Computers, not so much. 187 | # 188 | 189 | # Recognition from partial cues 190 | 191 | print("test with partial cues") 192 | 193 | proportion=0.4 194 | 195 | # reload original patterns. 196 | # There's some variable reference / variable copying thing I don't understand that makes this necessary 197 | patterns=np.array([from_jpg(p) for p in files]) #put individual patterns in array 198 | 199 | testpatterns=[makepartial(p,proportion) for p in patterns] 200 | 201 | # Four axes, returned as a 2-d array 202 | f, axarr = plt.subplots(2, len(testpatterns)) 203 | 204 | for p in range(len(testpatterns)): 205 | #axarr[0, p].imshow(patterns[p].reshape((side,side)),cmap=cm.binary, interpolation='nearest') 206 | axarr[0, p].imshow(testpatterns[p].reshape((side,side)), cmap="hot") 207 | axarr[0, p].set_title('Cue' + str(p)) 208 | #axarr[1, p].imshow(recall(W,patterns)[p].reshape((side,side)),cmap=cm.binary, interpolation='nearest') 209 | axarr[1, p].imshow(recall(W,testpatterns)[p].reshape((side,side)), cmap="hot") 210 | axarr[1, p].set_title('Recall' + str(p)) 211 | # Fine-tune figure; hide x ticks for top plots and y ticks for right plots 212 | plt.setp([a.get_xticklabels() for a in axarr[0, :]], visible=False) 213 | plt.setp([a.get_xticklabels() for a in axarr[1, :]], visible=False) 214 | plt.setp([a.get_yticklabels() for a in axarr[:, 0]], visible=False) 215 | plt.setp([a.get_yticklabels() for a in axarr[:, 1]], visible=False) 216 | plt.suptitle('Test with partial cue') 217 | plt.savefig('partialcue.png') 218 | 219 | # So the network can recover the patterns it was trained on from a partial cue. 220 | 221 | ########## The End ########## 222 | -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch05_HopfieldNet/noisycue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgvfwstone/ArtificialIntelligenceEngines/29245b20b8b9f40c8c9808661825dd2399b08c14/DeepLearningEnginesCode/Python/Ch05_HopfieldNet/noisycue.png -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch05_HopfieldNet/partialcue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgvfwstone/ArtificialIntelligenceEngines/29245b20b8b9f40c8c9808661825dd2399b08c14/DeepLearningEnginesCode/Python/Ch05_HopfieldNet/partialcue.png -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch05_HopfieldNet/patterns/train1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgvfwstone/ArtificialIntelligenceEngines/29245b20b8b9f40c8c9808661825dd2399b08c14/DeepLearningEnginesCode/Python/Ch05_HopfieldNet/patterns/train1.jpg -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch05_HopfieldNet/patterns/train2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgvfwstone/ArtificialIntelligenceEngines/29245b20b8b9f40c8c9808661825dd2399b08c14/DeepLearningEnginesCode/Python/Ch05_HopfieldNet/patterns/train2.jpg -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch05_HopfieldNet/patterns/train3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgvfwstone/ArtificialIntelligenceEngines/29245b20b8b9f40c8c9808661825dd2399b08c14/DeepLearningEnginesCode/Python/Ch05_HopfieldNet/patterns/train3.jpg -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch05_HopfieldNet/trainingpatterns.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgvfwstone/ArtificialIntelligenceEngines/29245b20b8b9f40c8c9808661825dd2399b08c14/DeepLearningEnginesCode/Python/Ch05_HopfieldNet/trainingpatterns.png -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch07_RestrictedBoltzmannMachine/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Gabriel M. Bianconi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch07_RestrictedBoltzmannMachine/README.md: -------------------------------------------------------------------------------- 1 | # Chapter 7: Restricted Boltzmann Machine (RBM) 2 | 3 | * To run code, use main.py 4 | * Author: Gabriel Bianconi 5 | * Date created: 2017 6 | * License: MIT License, reproduced with permission 7 | * Original Source: https://github.com/GabrielBianconi/pytorch-rbm 8 | * Description: Applies a single RBM to the MNIST dataset of images of digits from 0-9. The trained model uses a SciPy-based logistic regression to classify outputs. It achieves 92.8% classification accuracy on the test set of images. 9 | * Requirements: The following packages are required: sklearn, torch, torchvision. 10 | * Notes from the author (Gabriel Bianconi): 11 | This project implements Restricted Boltzmann Machines (RBMs) using PyTorch (see `rbm.py`). Our implementation includes momentum, weight decay, L2 regularization, and CD-*k* contrastive divergence. We also provide support for CPU and GPU (CUDA) calculations. In addition, we provide an example file applying our model to the MNIST dataset (see `mnist_dataset.py`). The example trains an RBM, uses the trained model to extract features from the images, and finally uses a SciPy-based logistic regression for classification. It achieves 92.8% classification accuracy (this is obviously not a cutting-edge model). 12 | -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch07_RestrictedBoltzmannMachine/__pycache__/rbm.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgvfwstone/ArtificialIntelligenceEngines/29245b20b8b9f40c8c9808661825dd2399b08c14/DeepLearningEnginesCode/Python/Ch07_RestrictedBoltzmannMachine/__pycache__/rbm.cpython-37.pyc -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch07_RestrictedBoltzmannMachine/data/mnist/processed/test.pt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgvfwstone/ArtificialIntelligenceEngines/29245b20b8b9f40c8c9808661825dd2399b08c14/DeepLearningEnginesCode/Python/Ch07_RestrictedBoltzmannMachine/data/mnist/processed/test.pt -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch07_RestrictedBoltzmannMachine/data/mnist/raw/t10k-images-idx3-ubyte: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgvfwstone/ArtificialIntelligenceEngines/29245b20b8b9f40c8c9808661825dd2399b08c14/DeepLearningEnginesCode/Python/Ch07_RestrictedBoltzmannMachine/data/mnist/raw/t10k-images-idx3-ubyte -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch07_RestrictedBoltzmannMachine/data/mnist/raw/t10k-labels-idx1-ubyte: -------------------------------------------------------------------------------- 1 | '                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch07_RestrictedBoltzmannMachine/data/mnist/raw/train-labels-idx1-ubyte: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgvfwstone/ArtificialIntelligenceEngines/29245b20b8b9f40c8c9808661825dd2399b08c14/DeepLearningEnginesCode/Python/Ch07_RestrictedBoltzmannMachine/data/mnist/raw/train-labels-idx1-ubyte -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch07_RestrictedBoltzmannMachine/main.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | RBM network. 5 | @author: Gabriel Bianconi, modified by JimStone 6 | # This takes about 10 minutes to run on a 2015 mac. 7 | # Description: Applies a single 2-layer RBM to the MNIST dataset of images of digits from 0-9. The trained model uses a SciPy-based logistic regression to classify outputs. It achieves 92.8% classification accuracy on the test set of images. 8 | Result: 9237/10000 9 | """ 10 | import numpy as np 11 | from sklearn.linear_model import LogisticRegression 12 | import torch 13 | import torchvision.datasets 14 | import torchvision.models 15 | import torchvision.transforms 16 | 17 | ########## CONFIGURATION ########## 18 | 19 | BATCH_SIZE = 64 # batch size for training 20 | 21 | VISIBLE_UNITS = 784 # 784 = 28 x 28 images 22 | 23 | HIDDEN_UNITS = 128 24 | 25 | CD_K = 2 # number of contrastive divergence (CD) steps per training vector 26 | 27 | EPOCHS = 2 # number of times the entire data set is used to train RBM 28 | 29 | DATA_FOLDER = 'data/mnist' 30 | 31 | # CUDA = Compute Unified Device Architecture, a GPU processor. 32 | # Don't worry if you don't have this, the code can work without it. 33 | CUDA = torch.cuda.is_available() 34 | CUDA_DEVICE = 0 35 | 36 | if CUDA: 37 | torch.cuda.set_device(CUDA_DEVICE) 38 | 39 | ########## DEFINITIONS ########## 40 | 41 | class RBM(): 42 | 43 | def __init__(self, num_visible, num_hidden, k, learning_rate=1e-3, momentum_coefficient=0.5,weight_decay=1e-4, use_cuda=True): 44 | 45 | self.num_visible = num_visible 46 | self.num_hidden = num_hidden 47 | self.k = k # number of contrastive divergence steps 48 | self.learning_rate = learning_rate 49 | self.momentum_coefficient = momentum_coefficient 50 | self.weight_decay = weight_decay 51 | self.use_cuda = use_cuda 52 | 53 | # weights between input and hidden units 54 | self.weights = torch.randn(num_visible, num_hidden) * 0.1 55 | # bias terms of visible units 56 | self.visible_bias = torch.ones(num_visible) * 0.5 57 | # bias terms of hidden units 58 | self.hidden_bias = torch.zeros(num_hidden) 59 | 60 | # create space for momentum parameters 61 | self.weights_momentum = torch.zeros(num_visible, num_hidden) 62 | self.visible_bias_momentum = torch.zeros(num_visible) 63 | self.hidden_bias_momentum = torch.zeros(num_hidden) 64 | 65 | if self.use_cuda: 66 | self.weights = self.weights.cuda() 67 | self.visible_bias = self.visible_bias.cuda() 68 | self.hidden_bias = self.hidden_bias.cuda() 69 | 70 | self.weights_momentum = self.weights_momentum.cuda() 71 | self.visible_bias_momentum = self.visible_bias_momentum.cuda() 72 | self.hidden_bias_momentum = self.hidden_bias_momentum.cuda() 73 | 74 | def sample_hidden(self, visible_probabilities): 75 | # get input to each hidden unit 76 | hidden_activations = torch.matmul(visible_probabilities, self.weights) + self.hidden_bias 77 | # use hidden unit inputs to find prob(on)=hidden_probabilities 78 | hidden_probabilities = self._sigmoid(hidden_activations) 79 | return hidden_probabilities 80 | 81 | def sample_visible(self, hidden_probabilities): 82 | # get input to each visible unit 83 | visible_activations = torch.matmul(hidden_probabilities, self.weights.t()) + self.visible_bias 84 | # use visible unit inputs to find prob(on)=hidden_probabilities 85 | visible_probabilities = self._sigmoid(visible_activations) 86 | return visible_probabilities 87 | 88 | def _sigmoid(self, x): 89 | return 1 / (1 + torch.exp(-x)) 90 | 91 | def _random_probabilities(self, num): 92 | random_probabilities = torch.rand(num) 93 | 94 | if self.use_cuda: 95 | random_probabilities = random_probabilities.cuda() 96 | return random_probabilities 97 | 98 | # =========================================================== 99 | def contrastive_divergence(self, input_data): 100 | # input_data is 64 (batch size) by 784 (real valued pixels in input image) 101 | # =Positive phase================================================== 102 | # Positive phase = use 'clamped' visible unit states to sample hidden unit states. 103 | # sample_hidden() treats each real-valued pixel as a probability 104 | positive_hidden_probabilities = self.sample_hidden(input_data) # 64 x 128 hidden units 105 | # use positive_hidden_probabilities to get sample of binary hidden unit states 106 | positive_hidden_activations = (positive_hidden_probabilities >= self._random_probabilities(self.num_hidden)).float() # BATCH_SIZE = 64 x 128 hidden units 107 | 108 | positive_associations = torch.matmul(input_data.t(), positive_hidden_activations) 109 | # print((positive_associations.shape)) # torch.Size([784, 128]) HIDDEN_UNITS = 128 110 | # .t() = transpose: https://pytorch.org/docs/0.3.1/torch.html#torch.t 111 | # positive_associations measures correlation between visible and hidden unit states when visible units are clamped to training data. 112 | 113 | # =Negative phase================================================== 114 | # Negative phase, initialise with final binary positive_hidden_activations 115 | hidden_activations = positive_hidden_activations # 64 x 128 116 | 117 | for step in range(self.k): # number of contrastive divergence steps 118 | visible_probabilities = self.sample_visible(hidden_activations) 119 | hidden_probabilities = self.sample_hidden(visible_probabilities) 120 | hidden_activations = (hidden_probabilities >= self._random_probabilities(self.num_hidden)).float() 121 | 122 | negative_visible_probabilities = visible_probabilities 123 | negative_hidden_probabilities = hidden_probabilities 124 | # negative_associations measures correlation between visible and hidden unit states when visible units are not clamped to training data. 125 | negative_associations = torch.matmul(negative_visible_probabilities.t(), negative_hidden_probabilities) 126 | 127 | # Update weight change 128 | self.weights_momentum *= self.momentum_coefficient 129 | self.weights_momentum += (positive_associations - negative_associations) 130 | 131 | # Update visible bias terms 132 | self.visible_bias_momentum *= self.momentum_coefficient 133 | self.visible_bias_momentum += torch.sum(input_data - negative_visible_probabilities, dim=0) 134 | 135 | # Update hidden bias terms 136 | self.hidden_bias_momentum *= self.momentum_coefficient 137 | self.hidden_bias_momentum += torch.sum(positive_hidden_probabilities - negative_hidden_probabilities, dim=0) 138 | 139 | batch_size = input_data.size(0) 140 | 141 | self.weights += self.weights_momentum * self.learning_rate / batch_size 142 | self.visible_bias += self.visible_bias_momentum * self.learning_rate / batch_size 143 | self.hidden_bias += self.hidden_bias_momentum * self.learning_rate / batch_size 144 | 145 | self.weights -= self.weights * self.weight_decay # L2 weight decay 146 | 147 | # Compute reconstruction error 148 | error = torch.sum((input_data - negative_visible_probabilities)**2) 149 | 150 | return error 151 | # =========================================================== 152 | 153 | 154 | ########## DEFINITIONS DONE ########## 155 | 156 | ########## LOAD DATASET ########## 157 | print('Loading MNIST dataset of images of digits between 0 and 9 ...') 158 | 159 | # training data 160 | train_dataset = torchvision.datasets.MNIST(root=DATA_FOLDER, train=True, transform=torchvision.transforms.ToTensor(), download=True) 161 | train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=BATCH_SIZE) 162 | 163 | # test data 164 | test_dataset = torchvision.datasets.MNIST(root=DATA_FOLDER, train=False, transform=torchvision.transforms.ToTensor(), download=True) 165 | test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=BATCH_SIZE) 166 | 167 | 168 | ########## TRAINING RBM ########## 169 | print('Training RBM for %d epochs ...' % EPOCHS) 170 | # create RBM network with one visible and one hidden laayer 171 | rbm = RBM(VISIBLE_UNITS, HIDDEN_UNITS, CD_K, use_cuda=CUDA) 172 | 173 | for epoch in range(EPOCHS): 174 | epoch_error = 0.0 175 | 176 | for batch, _ in train_loader: 177 | batch = batch.view(len(batch), VISIBLE_UNITS) # flatten input data 178 | 179 | if CUDA: 180 | batch = batch.cuda() 181 | 182 | batch_error = rbm.contrastive_divergence(batch) 183 | 184 | epoch_error += batch_error 185 | 186 | print('Epoch Error (epoch=%d): %.4f' % (epoch, epoch_error)) 187 | 188 | 189 | ########## EXTRACT FEATURES ########## 190 | print('Extracting features...') 191 | 192 | train_features = np.zeros((len(train_dataset), HIDDEN_UNITS)) 193 | train_labels = np.zeros(len(train_dataset)) 194 | test_features = np.zeros((len(test_dataset), HIDDEN_UNITS)) 195 | test_labels = np.zeros(len(test_dataset)) 196 | 197 | for i, (batch, labels) in enumerate(train_loader): 198 | batch = batch.view(len(batch), VISIBLE_UNITS) # flatten input data 199 | 200 | if CUDA: 201 | batch = batch.cuda() 202 | 203 | train_features[i*BATCH_SIZE:i*BATCH_SIZE+len(batch)] = rbm.sample_hidden(batch).cpu().numpy() 204 | train_labels[i*BATCH_SIZE:i*BATCH_SIZE+len(batch)] = labels.numpy() 205 | 206 | for i, (batch, labels) in enumerate(test_loader): 207 | batch = batch.view(len(batch), VISIBLE_UNITS) # flatten input data 208 | 209 | if CUDA: 210 | batch = batch.cuda() 211 | 212 | test_features[i*BATCH_SIZE:i*BATCH_SIZE+len(batch)] = rbm.sample_hidden(batch).cpu().numpy() 213 | test_labels[i*BATCH_SIZE:i*BATCH_SIZE+len(batch)] = labels.numpy() 214 | 215 | 216 | ########## CLASSIFICATION ########## 217 | print('Fitting linear classifier ...') 218 | 219 | clf = LogisticRegression(solver='newton-cg',multi_class='auto') 220 | # train_features = 60,000 hidden unit outputs (1 per training vector) x 128 hidden units 221 | # use outputs of trained hidden units to fit linear classifier to correct labels ... 222 | clf.fit(train_features, train_labels) 223 | # use fitted linear classifier to classify test data ... test_features = 10,000 hidden layer states, 1 per test vector 224 | predictions = clf.predict(test_features) # predictions = 10,000 classifications (0-9) 225 | 226 | # compare 10,000 classification results on test data with correct class labels ... 227 | print('Result: %d/%d' % (sum(predictions == test_labels), test_labels.shape[0])) 228 | # prints out (for example, on test data) Result: 9244/10000 = 92.44% 229 | 230 | ########## THE END ########## 231 | -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/README.md: -------------------------------------------------------------------------------- 1 | # Variational Autoencoder 2 | 3 | * To run, use main.py 4 | * Author: Kingma, Botha (cpbotha@vxlabs.com), with modifcations by JVStone 5 | * Date created: 2018 6 | * License: MIT, reproduced with permission from the author 7 | * Original Source: https://github.com/dpkingma/examples/tree/master/vae 8 | * Description: Trained on MNIST images of digits. 9 | * Learns to map images of digits (from MNIST data set) from input to output via an informational bottleneck. 10 | * Notes from the author: This is an improved implementation of the paper (http://arxiv.org/abs/1312.6114) by Kingma and Welling. It uses ReLUs and the adam optimizer, instead of sigmoids and adagrad. These changes make the network converge much faster. 11 | * Notes from JVStone: JVS added graph of ELBO during training, plus reconstructed images after training. 12 | This is a combination of two vae main.py files, from 13 | https://github.com/pytorch/examples/tree/master/vae 14 | and 15 | https://github.com/dpkingma/examples/tree/master/vae 16 | -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/main.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Chapter 8: Variational Autoencoders 5 | Github directory: https://github.com/jgvfwstone/DeepLearningEngines/tree/master/DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder 6 | Author: Kingma, Botha, most comments by authors, with a few added comments by JVStone 7 | Date created: 2018 8 | License: MIT 9 | Original Source: https://github.com/dpkingma/examples/tree/master/vae 10 | Description: Data are MNIST images of digits. This is an improved implementation of the paper (http://arxiv.org/abs/1312.6114) by Kingma and Welling. It uses ReLUs and the adam optimizer, instead of sigmoids and adagrad. These changes make the network converge much faster. JVS added graph of ELBO during training, plus reconstructed images ater training. This is a combination of two vae main.py files, from https://github.com/pytorch/examples/tree/master/vae and https://github.com/dpkingma/examples/tree/master/vae 11 | 12 | The code below makes a VAE: 13 | ENCODER: 14 | 28x28 image = 784 input units -> 400 ReLU units -> two sets of 20 units (a 20-dim Gaussian) 15 | Each sample from 20-dim Gaussian yields 20 scalars z 16 | DECODER: 17 | z is input to decoder -> 400 ReLU units -> 784(=28x28) output units. 18 | 19 | The vae looks like this: 20 | VAE( 21 | (fc1): Linear(in_features=784, out_features=400, bias=True) # 784 input units = 28x28 22 | These 784 units project to two sets of 400 RELU units 23 | These 400 ReLU units project to two sets of 20 linear units 24 | set1 represents Gaussian means 25 | set2 represents Gaussian variances 26 | (relu): ReLU() 27 | (fc21): Linear(in_features=400, out_features=20, bias=True) 28 | (fc22): Linear(in_features=400, out_features=20, bias=True) 29 | Each sample from the 20 univariate Gaussians provides 20 scalars z represented by 20 linear units 30 | These 20 linear units are the input to the decoder. 31 | (fc3): Linear(in_features=20, out_features=400, bias=True) 32 | These 20 linear units project to 400 ReLU units, which project to 784 output units. 33 | (fc4): Linear(in_features=400, out_features=784, bias=True) 34 | (sigmoid): Sigmoid() 35 | ) 36 | """ 37 | from __future__ import print_function 38 | import argparse 39 | import torch 40 | import torch.utils.data 41 | from torch import nn, optim 42 | from torch.nn import functional as F 43 | from torchvision import datasets, transforms 44 | from torchvision.utils import save_image 45 | import matplotlib.pyplot as plt 46 | from torch.autograd import Variable 47 | 48 | ########## set parameter values ########## 49 | 50 | ZDIMS = 20 # number of latent variables 51 | 52 | BATCH_SIZE = 128 53 | 54 | numepochs = 2 55 | 56 | train_losses = [] # record of loss function values for plotting. 57 | 58 | 59 | ########## set parser ########## 60 | 61 | parser = argparse.ArgumentParser(description='VAE MNIST Example') 62 | 63 | parser.add_argument('--batch-size', type=int, default=BATCH_SIZE, metavar='N', 64 | help='input batch size for training (default: 128)') 65 | 66 | parser.add_argument('--epochs', type=int, default=numepochs, metavar='N', 67 | help='number of epochs to train (default: 10)') 68 | 69 | parser.add_argument('--no-cuda', action='store_true', default=False, 70 | help='enables CUDA training') 71 | 72 | parser.add_argument('--seed', type=int, default=1, metavar='S', 73 | help='random seed (default: 1)') 74 | 75 | parser.add_argument('--log-interval', type=int, default=10, metavar='N', 76 | help='how many batches to wait before logging training status') 77 | 78 | args = parser.parse_args() 79 | 80 | args.cuda = not args.no_cuda and torch.cuda.is_available() 81 | 82 | torch.manual_seed(args.seed) 83 | 84 | device = torch.device("cuda" if args.cuda else "cpu") 85 | 86 | # DataLoader instances will load tensors directly into GPU memory 87 | kwargs = {'num_workers': 1, 'pin_memory': True} if args.cuda else {} 88 | 89 | ########## create data loaders ########## 90 | 91 | # Download or load downloaded MNIST dataset 92 | # shuffle data at every epoch 93 | train_loader = torch.utils.data.DataLoader( 94 | datasets.MNIST('../data', train=True, download=True, 95 | transform=transforms.ToTensor()), 96 | batch_size=args.batch_size, shuffle=True, **kwargs) 97 | 98 | # Same for test data 99 | test_loader = torch.utils.data.DataLoader( 100 | datasets.MNIST('../data', train=False, transform=transforms.ToTensor()), 101 | batch_size=args.batch_size, shuffle=True, **kwargs) 102 | 103 | ########## define classes ########## 104 | 105 | class VAE(nn.Module): 106 | def __init__(self): 107 | super(VAE, self).__init__() 108 | 109 | # ENCODER 110 | # 28 x 28 pixels = 784 input pixels, 400 outputs 111 | self.fc1 = nn.Linear(784, 400) 112 | # rectified linear unit layer from 400 to 400 113 | self.relu = nn.ReLU() 114 | self.fc21 = nn.Linear(400, ZDIMS) # mu layer 115 | self.fc22 = nn.Linear(400, ZDIMS) # logvariance layer 116 | # this last layer is the bottleneck of ZDIMS=20 connections 117 | 118 | # DECODER 119 | # from bottleneck to hidden 400 120 | self.fc3 = nn.Linear(ZDIMS, 400) 121 | # from hidden 400 to 784 outputs 122 | self.fc4 = nn.Linear(400, 784) 123 | self.sigmoid = nn.Sigmoid() 124 | 125 | def encode(self, x): 126 | h1 = F.relu(self.fc1(x)) 127 | return self.fc21(h1), self.fc22(h1) 128 | 129 | def reparameterize(self, mu, logvar): 130 | 131 | """ 132 | THE REPARAMETERIZATION IDEA: 133 | 134 | For each training sample (we get 128 batched at a time) 135 | 136 | - take the current learned mu, stddev for each of the ZDIMS 137 | dimensions and draw a random sample from that distribution 138 | - the whole network is trained so that these randomly drawn 139 | samples decode to output that looks like the input 140 | - which will mean that the std, mu will be learned 141 | *distributions* that correctly encode the inputs 142 | - due to the additional KLD term (see loss_function() below) 143 | the distribution will tend to unit Gaussians 144 | 145 | Parameters 146 | ---------- 147 | mu : [128, ZDIMS] mean matrix 148 | logvar : [128, ZDIMS] variance matrix 149 | 150 | Returns 151 | ------- 152 | 153 | During training random sample from the learned ZDIMS-dimensional 154 | normal distribution; during inference its mean. 155 | """ 156 | 157 | if self.training: 158 | std = torch.exp(0.5*logvar) 159 | # type: Variable 160 | # - std.data is the [128,ZDIMS] tensor that is wrapped by std 161 | # - so eps is [128,ZDIMS] with all elements drawn from a mean 0 162 | # and stddev 1 normal distribution that is 128 samples 163 | # of random ZDIMS-float vectors 164 | eps = torch.randn_like(std) 165 | # - sample from a normal distribution with standard 166 | # deviation = std and mean = mu by multiplying mean 0 167 | # stddev 1 sample with desired std and mu, see 168 | # https://stats.stackexchange.com/a/16338 169 | # - so we have 128 sets (the batch) of random ZDIMS-float 170 | # vectors sampled from normal distribution with learned 171 | # std and mu for the current input 172 | return eps.mul(std).add_(mu) 173 | else: 174 | # During inference, we simply spit out the mean of the 175 | # learned distribution for the current input. We could 176 | # use a random sample from the distribution, but mu of 177 | # course has the highest probability. 178 | return mu 179 | 180 | def decode(self, z): 181 | h3 = F.relu(self.fc3(z)) 182 | return torch.sigmoid(self.fc4(h3)) 183 | 184 | def forward(self, x): 185 | mu, logvar = self.encode(x.view(-1, 784)) 186 | z = self.reparameterize(mu, logvar) 187 | return self.decode(z), mu, logvar 188 | 189 | # Reconstruction + KL divergence losses summed over all elements and batch 190 | # This loss is actually minus the ELBO (ie ELBO is a likelihood, which we want to maximise) 191 | # so we use Adam to minimise minus ELBO 192 | def loss_function(recon_x, x, mu, logvar): 193 | # next 2 lines are equivalent 194 | BCE = -F.binary_cross_entropy(recon_x, x.view(-1, 784), reduction='sum') 195 | #BCE = -F.binary_cross_entropy(recon_x, x.view(-1, 784), size_average=False) # deprecated 196 | # for binary_cross_entropy, see https://pytorch.org/docs/stable/nn.html 197 | 198 | # KLD is Kullback–Leibler divergence -- how much does one learned 199 | # distribution deviate from another, in this specific case the 200 | # learned distribution from the unit Gaussian 201 | 202 | # see Appendix B from VAE paper: 203 | # Kingma and Welling. Auto-Encoding Variational Bayes. ICLR, 2014 204 | # https://arxiv.org/abs/1312.6114 205 | # 0.5 * sum(1 + log(sigma^2) - mu^2 - sigma^2) 206 | KLD = 0.5 * torch.sum(1 + logvar - mu.pow(2) - logvar.exp()) 207 | 208 | # JVS: Kingma's repo = https://github.com/dpkingma/examples/blob/master/vae/main.py 209 | # BCE tries to make our reconstruction as accurate as possible 210 | # KLD tries to push the distributions as close as possible to unit Gaussian 211 | 212 | ELBO = BCE + KLD 213 | loss = -ELBO 214 | return loss 215 | 216 | def train(epoch): 217 | 218 | fig = plt.figure(1) 219 | plt.clf() # clear figure 220 | ax=fig.add_subplot(111) 221 | ax.set_xlabel('Batch number') 222 | ax.set_ylabel('minus ELBO') 223 | plt.xlim(0,epoch*len(train_loader)) 224 | 225 | model.train() 226 | train_loss = 0 227 | for batch_idx, (data, _) in enumerate(train_loader): 228 | # data = data.to(device) 229 | data = Variable(data) 230 | optimizer.zero_grad() 231 | recon_batch, mu, logvar = model(data) 232 | loss = loss_function(recon_batch, data, mu, logvar) 233 | loss.backward() 234 | train_loss = loss.item() / len(data) 235 | optimizer.step() 236 | train_losses.append(train_loss) 237 | if batch_idx % args.log_interval == 0: 238 | print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.1f}'.format( 239 | epoch, batch_idx * len(data), len(train_loader.dataset), 240 | 100. * batch_idx / len(train_loader), 241 | loss.item() / len(data))) 242 | plt.ion() 243 | plt.ylim(0,max(train_losses)) 244 | ax.plot(train_losses,c='black') 245 | plt.draw() 246 | plt.pause(0.001) 247 | print('====> Epoch: {} Average loss: {:.4f}'.format(epoch, train_loss )) 248 | 249 | def test(epoch): 250 | model.eval() 251 | test_loss = 0 252 | with torch.no_grad(): 253 | # each data is of BATCH_SIZE (default 128) samples 254 | for i, (data, _) in enumerate(test_loader): 255 | data = data.to(device) 256 | recon_batch, mu, logvar = model(data) 257 | test_loss += loss_function(recon_batch, data, mu, logvar).item() 258 | if i == 0: 259 | n = min(data.size(0), 8) 260 | # for the first 128 batch of the epoch, show the first 8 input digits 261 | # with right below them the reconstructed output digits 262 | comparison = torch.cat([data[:n], 263 | recon_batch.view(args.batch_size, 1, 28, 28)[:n]]) 264 | save_image(comparison.cpu(), 265 | 'results/reconstruction_' + str(epoch) + '.png', nrow=n) 266 | 267 | test_loss /= len(test_loader.dataset) 268 | print('====> Test set loss: {:.4f}'.format(test_loss)) 269 | 270 | ########## create VAE ########## 271 | 272 | model = VAE().to(device) 273 | optimizer = optim.Adam(model.parameters(), lr=1e-3) # adam does gradient DESCENT 274 | 275 | if __name__ == "__main__": 276 | for epoch in range(1, args.epochs + 1): 277 | test(epoch) 278 | train(epoch) 279 | 280 | with torch.no_grad(): 281 | # 64 sets of random ZDIMS-float vectors, i.e. 64 locations / MNIST 282 | # digits in latent space 283 | sample = torch.randn(64, 20).to(device) 284 | sample = model.decode(sample).cpu() 285 | # save out as an 8x8 matrix of MNIST digits 286 | # this will give you a visual idea of how well latent space can generate things 287 | # that look like digits 288 | save_image(sample.view(64, 1, 28, 28), 289 | 'results/sample_' + str(epoch) + '.png') 290 | 291 | # JVS plot feature (weight vector) of unit in 1st hidden layer 292 | fig, axes = plt.subplots(4, 4) 293 | fig.subplots_adjust(left=None, bottom=None, 294 | right=None, top=None, 295 | wspace=0, hspace=0) 296 | a = model.fc1.weight.detach() 297 | count=0 298 | for x in range(0,4): 299 | for y in range(0,4): 300 | count=count+1 301 | b=a[count] 302 | c=b.view(28,28) 303 | ax = axes[x,y] 304 | ax.imshow(c,cmap="gray") 305 | ax.set_xticks(()) 306 | ax.set_yticks(()) 307 | 308 | ########## The End ########## 309 | -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/requirements.txt: -------------------------------------------------------------------------------- 1 | torch 2 | torchvision 3 | tqdm 4 | six 5 | -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/results/reconstruction_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgvfwstone/ArtificialIntelligenceEngines/29245b20b8b9f40c8c9808661825dd2399b08c14/DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/results/reconstruction_1.png -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/results/reconstruction_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgvfwstone/ArtificialIntelligenceEngines/29245b20b8b9f40c8c9808661825dd2399b08c14/DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/results/reconstruction_10.png -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/results/reconstruction_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgvfwstone/ArtificialIntelligenceEngines/29245b20b8b9f40c8c9808661825dd2399b08c14/DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/results/reconstruction_2.png -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/results/reconstruction_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgvfwstone/ArtificialIntelligenceEngines/29245b20b8b9f40c8c9808661825dd2399b08c14/DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/results/reconstruction_3.png -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/results/reconstruction_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgvfwstone/ArtificialIntelligenceEngines/29245b20b8b9f40c8c9808661825dd2399b08c14/DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/results/reconstruction_4.png -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/results/reconstruction_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgvfwstone/ArtificialIntelligenceEngines/29245b20b8b9f40c8c9808661825dd2399b08c14/DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/results/reconstruction_5.png -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/results/reconstruction_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgvfwstone/ArtificialIntelligenceEngines/29245b20b8b9f40c8c9808661825dd2399b08c14/DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/results/reconstruction_6.png -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/results/reconstruction_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgvfwstone/ArtificialIntelligenceEngines/29245b20b8b9f40c8c9808661825dd2399b08c14/DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/results/reconstruction_7.png -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/results/reconstruction_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgvfwstone/ArtificialIntelligenceEngines/29245b20b8b9f40c8c9808661825dd2399b08c14/DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/results/reconstruction_8.png -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/results/reconstruction_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgvfwstone/ArtificialIntelligenceEngines/29245b20b8b9f40c8c9808661825dd2399b08c14/DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/results/reconstruction_9.png -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/results/sample_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgvfwstone/ArtificialIntelligenceEngines/29245b20b8b9f40c8c9808661825dd2399b08c14/DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/results/sample_1.png -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/results/sample_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgvfwstone/ArtificialIntelligenceEngines/29245b20b8b9f40c8c9808661825dd2399b08c14/DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/results/sample_10.png -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/results/sample_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgvfwstone/ArtificialIntelligenceEngines/29245b20b8b9f40c8c9808661825dd2399b08c14/DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/results/sample_2.png -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/results/sample_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgvfwstone/ArtificialIntelligenceEngines/29245b20b8b9f40c8c9808661825dd2399b08c14/DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/results/sample_3.png -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/results/sample_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgvfwstone/ArtificialIntelligenceEngines/29245b20b8b9f40c8c9808661825dd2399b08c14/DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/results/sample_4.png -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/results/sample_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgvfwstone/ArtificialIntelligenceEngines/29245b20b8b9f40c8c9808661825dd2399b08c14/DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/results/sample_5.png -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/results/sample_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgvfwstone/ArtificialIntelligenceEngines/29245b20b8b9f40c8c9808661825dd2399b08c14/DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/results/sample_6.png -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/results/sample_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgvfwstone/ArtificialIntelligenceEngines/29245b20b8b9f40c8c9808661825dd2399b08c14/DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/results/sample_7.png -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/results/sample_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgvfwstone/ArtificialIntelligenceEngines/29245b20b8b9f40c8c9808661825dd2399b08c14/DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/results/sample_8.png -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/results/sample_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgvfwstone/ArtificialIntelligenceEngines/29245b20b8b9f40c8c9808661825dd2399b08c14/DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder/results/sample_9.png -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch09_ConvolutionalNetwork/README.md: -------------------------------------------------------------------------------- 1 | # Chapter 9: Convolutional Backprop Network 2 | 3 | * Run code using main.py. 4 | * Author: Various 5 | * Date created: 2016 6 | * License: MIT 7 | * Original Source: https://github.com/pytorch/examples/blob/master/mnist 8 | * Description: Convolutional backprop network trained to recogise digits 0-9 from the MNIST data set. Output: Test set: Average loss: 0.0319, Accuracy: 9898/10000 (99%) 9 | -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch09_ConvolutionalNetwork/main.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Chapter 9: Deep Backprop Network: 5 | Convolutional backprop network trained on MNIST images of digits. 6 | 7 | Github directory: https://github.com/jgvfwstone/DeepLearningEngines/tree/master/DeepLearningEnginesCode/Python/Ch09_ConvolutionalNetwork 8 | Author: Various 9 | Date created: 10 | License: https://github.com/pytorch/examples/blob/master/LICENSE 11 | Original Source: https://github.com/pytorch/examples/blob/master/mnist 12 | Description: Convolutional backprop network trained to recogise digits 0-9 from the MNIST data set. 13 | After 10 epochs: 14 | Test set: Average loss: 0.0319, Accuracy: 9898/10000 (99%) 15 | """ 16 | 17 | from __future__ import print_function 18 | import argparse 19 | import torch 20 | import torch.nn as nn 21 | import torch.nn.functional as F 22 | import torch.optim as optim 23 | from torchvision import datasets, transforms 24 | 25 | ########## define classes ########## 26 | 27 | class Net(nn.Module): 28 | def __init__(self): # see https://pytorch.org/docs/stable/nn.html?highlight=conv2d#torch.nn.Conv2d 29 | super(Net, self).__init__() 30 | self.conv1 = nn.Conv2d(1, 20, 5, 1) 31 | self.conv2 = nn.Conv2d(20, 50, 5, 1) 32 | self.fc1 = nn.Linear(4*4*50, 500) 33 | self.fc2 = nn.Linear(500, 10) 34 | 35 | def forward(self, x): 36 | x = F.relu(self.conv1(x)) 37 | x = F.max_pool2d(x, 2, 2) 38 | x = F.relu(self.conv2(x)) 39 | x = F.max_pool2d(x, 2, 2) 40 | x = x.view(-1, 4*4*50) 41 | x = F.relu(self.fc1(x)) 42 | x = self.fc2(x) 43 | return F.log_softmax(x, dim=1) 44 | 45 | ########## define functions ########## 46 | 47 | def train(args, model, device, train_loader, optimizer, epoch): 48 | model.train() 49 | for batch_idx, (data, target) in enumerate(train_loader): 50 | data, target = data.to(device), target.to(device) 51 | optimizer.zero_grad() 52 | output = model(data) 53 | loss = F.nll_loss(output, target) 54 | loss.backward() 55 | optimizer.step() 56 | if batch_idx % args.log_interval == 0: 57 | print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format( 58 | epoch, batch_idx * len(data), len(train_loader.dataset), 59 | 100. * batch_idx / len(train_loader), loss.item())) 60 | 61 | def test(args, model, device, test_loader): 62 | model.eval() 63 | test_loss = 0 64 | correct = 0 65 | with torch.no_grad(): 66 | for data, target in test_loader: 67 | data, target = data.to(device), target.to(device) 68 | output = model(data) 69 | test_loss += F.nll_loss(output, target, reduction='sum').item() # sum up batch loss 70 | pred = output.max(1, keepdim=True)[1] # get the index of the max log-probability 71 | correct += pred.eq(target.view_as(pred)).sum().item() 72 | 73 | test_loss /= len(test_loader.dataset) 74 | 75 | print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format( 76 | test_loss, correct, len(test_loader.dataset), 77 | 100. * correct / len(test_loader.dataset))) 78 | 79 | def main(): 80 | numepochs = 2; 81 | batchsize = 64 82 | 83 | # Training settings 84 | parser = argparse.ArgumentParser(description='PyTorch MNIST Example') 85 | 86 | parser.add_argument('--batch-size', type=int, default=batchsize, metavar='N', 87 | help='input batch size for training (default: 64)') 88 | 89 | parser.add_argument('--test-batch-size', type=int, default=1000, metavar='N', 90 | help='input batch size for testing (default: 1000)') 91 | 92 | parser.add_argument('--epochs', type=int, default=numepochs, metavar='N', 93 | help='number of epochs to train (default: 10)') 94 | 95 | parser.add_argument('--lr', type=float, default=0.01, metavar='LR', 96 | help='learning rate (default: 0.01)') 97 | 98 | parser.add_argument('--momentum', type=float, default=0.5, metavar='M', 99 | help='SGD momentum (default: 0.5)') 100 | 101 | parser.add_argument('--no-cuda', action='store_true', default=False, 102 | help='disables CUDA training') 103 | 104 | parser.add_argument('--seed', type=int, default=1, metavar='S', 105 | help='random seed (default: 1)') 106 | 107 | parser.add_argument('--log-interval', type=int, default=10, metavar='N', 108 | help='how many batches to wait before logging training status') 109 | 110 | parser.add_argument('--save-model', action='store_true', default=False, 111 | help='For Saving the current Model') 112 | 113 | args = parser.parse_args() 114 | 115 | use_cuda = not args.no_cuda and torch.cuda.is_available() 116 | 117 | torch.manual_seed(args.seed) 118 | 119 | device = torch.device("cuda" if use_cuda else "cpu") 120 | 121 | kwargs = {'num_workers': 1, 'pin_memory': True} if use_cuda else {} 122 | train_loader = torch.utils.data.DataLoader( 123 | datasets.MNIST('../data', train=True, download=True, 124 | transform=transforms.Compose([ 125 | transforms.ToTensor(), 126 | transforms.Normalize((0.1307,), (0.3081,)) 127 | ])), 128 | batch_size=args.batch_size, shuffle=True, **kwargs) 129 | test_loader = torch.utils.data.DataLoader( 130 | datasets.MNIST('../data', train=False, transform=transforms.Compose([ 131 | transforms.ToTensor(), 132 | transforms.Normalize((0.1307,), (0.3081,)) 133 | ])), 134 | batch_size=args.test_batch_size, shuffle=True, **kwargs) 135 | 136 | model = Net().to(device) 137 | optimizer = optim.SGD(model.parameters(), lr=args.lr, momentum=args.momentum) 138 | 139 | for epoch in range(1, args.epochs + 1): 140 | train(args, model, device, train_loader, optimizer, epoch) 141 | test(args, model, device, test_loader) 142 | 143 | if (args.save_model): 144 | torch.save(model.state_dict(),"mnist_cnn.pt") 145 | 146 | if __name__ == '__main__': 147 | main() 148 | 149 | ########## The End ########## 150 | -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch09_ConvolutionalNetwork/requirements.txt: -------------------------------------------------------------------------------- 1 | torch 2 | torchvision 3 | -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch10_ReinforcementLearning/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Chapter 9: Reinforcement Learning 3 | 4 | * Requirements: Download the package gym before use (ie pip install gym). 5 | * Run code using main.py 6 | * Author: Anirudh Topiwala 7 | * Date created: 2017 8 | * License: None, copied with permission. 9 | * Original Source: https://github.com/anirudhtopiwala/CartPole-Problem-Reinforcement-Learning/blob/master/Qcartpole.py 10 | * Description: Learns to balance a pole on a cart using Q-learning, with graphical output of the cart pole. Based on PyTorch. This code was originally written as part of a student project, and the project report contains more details of the code and results: [Anirudh Topiwala's RL project](https://github.com/anirudhtopiwala/CartPole-Problem-Reinforcement-Learning) 11 | * Also see pytorch's own example here 12 | https://github.com/pytorch/examples/tree/master/reinforcement_learning 13 | -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch10_ReinforcementLearning/cartpole.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jgvfwstone/ArtificialIntelligenceEngines/29245b20b8b9f40c8c9808661825dd2399b08c14/DeepLearningEnginesCode/Python/Ch10_ReinforcementLearning/cartpole.gif -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/Ch10_ReinforcementLearning/main.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Cart pole using Q-learning. 5 | Author: Anirudh Topiwala with small modifications by JV Stone. 6 | https://github.com/anirudhtopiwala/CartPole-Problem-Reinforcement-Learning/blob/master/Qcartpole.py 7 | Learns to balance pole for 500 time steps in about 3000 episodes, but it is sensitive to initial conditions (ie rand seed). 8 | """ 9 | 10 | #S ubmission of Final Project Report : Anirudh Topiwala 11 | # Implementing Q learning On cart Pole Problem. 12 | # -*- coding: utf-8 -*- 13 | import gym 14 | import numpy as np 15 | import random 16 | import math 17 | from time import sleep 18 | 19 | ## Initialize the "Cart-Pole" environment 20 | env = gym.make('CartPole-v1') 21 | #env = gym.make('CartPole-v0') # JVS v0 no good here. 22 | 23 | # see https://github.com/openai/gym/wiki/Leaderboard#cartpole-v0 24 | ## Defining the environment related constants 25 | 26 | # Number of discrete states (bucket) per state dimension 27 | NUM_BUCKETS = (1, 1, 6, 3) # (x, x', theta, theta') JVS 28 | 29 | # Number of discrete actions 30 | NUM_ACTIONS = env.action_space.n # (left, right) 31 | 32 | # Bounds for each discrete state 33 | STATE_BOUNDS = list(zip(env.observation_space.low, env.observation_space.high)) 34 | STATE_BOUNDS[1] = [-1, 1] # JVS was [-2.4, 2.4] 35 | 36 | max_pole_angle_degrees = 5 # was 15 37 | STATE_BOUNDS[3] = [-math.radians(max_pole_angle_degrees), math.radians(max_pole_angle_degrees)] 38 | 39 | # Index of the action 40 | ACTION_INDEX = len(NUM_BUCKETS) 41 | 42 | ## Creating a Q-Table for each state-action pair 43 | q_table = np.zeros(NUM_BUCKETS + (NUM_ACTIONS,)) 44 | 45 | ## Learning related constants 46 | MIN_EXPLORE_RATE = 0.01 47 | MIN_LEARNING_RATE = 0.1 48 | 49 | ## Defining the simulation related constants 50 | NUM_EPISODES = 5000 51 | 52 | SOLVED_T = 1000 # number of steps to succeed. Jvs was 150 53 | 54 | MAX_T = 1000 # max number of steps allowed, must be > SOLVED_T 55 | 56 | STREAK_TO_END = 50 # if number of times MAX_T is achieved = STREAK_TO_END then stop. 57 | 58 | DEBUG_MODE = False #True 59 | 60 | def learncartpole(): 61 | 62 | global episode, explore_rate 63 | 64 | random.seed(1) 65 | env.seed(9) 66 | 67 | # Set learning related parameters 68 | learning_rate = get_learning_rate(0) 69 | explore_rate = get_explore_rate(0) 70 | discount_factor = 0.99 # since the world is unchanging 71 | 72 | num_streaks = 0 # num_streaks = number of consecutive times problem solved 73 | 74 | for episode in range(NUM_EPISODES): 75 | 76 | # Reset the environment 77 | obv = env.reset() 78 | 79 | # the initial state 80 | state_0 = state_to_bucket(obv) 81 | 82 | plot_interval = 200 83 | 84 | for t in range(MAX_T): 85 | if episode % plot_interval == 0: 86 | env.render() 87 | 88 | # Select an action 89 | action = select_action(state_0, explore_rate) 90 | 91 | # Execute the action 92 | obv, reward, done, _ = env.step(action) 93 | 94 | # Observe the result 95 | state = state_to_bucket(obv) 96 | 97 | # Update the Q based on the result 98 | best_q = np.amax(q_table[state]) 99 | 100 | q_table[state_0 + (action,)] += learning_rate * (reward + discount_factor*(best_q) - q_table[state_0 + (action,)]) 101 | 102 | # Setting up for the next iteration 103 | state_0 = state 104 | 105 | # Print data 106 | if (DEBUG_MODE): 107 | print("\nEpisode = %d" % episode) 108 | print("t = %d" % t) 109 | print("Action: %d" % action) 110 | print("State: %s" % str(state)) 111 | print("Reward: %f" % reward) 112 | print("Best Q: %f" % best_q) 113 | print("Explore rate: %f" % explore_rate) 114 | print("Learning rate: %f" % learning_rate) 115 | print("Streaks: %d" % num_streaks) 116 | print("") 117 | 118 | if done: 119 | #sleep(0.5) 120 | #print(q_table) 121 | if (t >= SOLVED_T): 122 | num_streaks += 1 123 | else: 124 | num_streaks = 0 125 | break 126 | 127 | #sleep(0.25) 128 | print("Episode %d finished after %d time steps, learn rate %.3f" % (episode, t, learning_rate)) 129 | 130 | # It's considered done when it's solved over 100 times consecutively 131 | if num_streaks > STREAK_TO_END: 132 | break 133 | 134 | # Update parameters 135 | explore_rate = get_explore_rate(episode) 136 | learning_rate = get_learning_rate(episode) 137 | #explore_rate = 0.1 # JVS 138 | ###################### End def simulate() ############## 139 | 140 | def select_action(state, explore_rate): 141 | # Select a random action 142 | if random.random() < explore_rate: 143 | action = env.action_space.sample() 144 | # Select the action with the highest q 145 | else: 146 | action = np.argmax(q_table[state]) 147 | return action 148 | 149 | def get_explore_rate(episode): 150 | return max(MIN_EXPLORE_RATE, min(1, 1.0 - math.log10((episode+1)/25.0))) #using Logrithmic decaying explore rate 151 | 152 | def get_learning_rate(t): 153 | return max(MIN_LEARNING_RATE, min(0.4, 1.0 - math.log10((t+1)/100.0))) #using Logrithmic decaying learning rate 154 | 155 | def state_to_bucket(state): 156 | bucket_indice = [] 157 | for i in range(len(state)): 158 | if state[i] <= STATE_BOUNDS[i][0]: 159 | bucket_index = 0 160 | elif state[i] >= STATE_BOUNDS[i][1]: 161 | bucket_index = NUM_BUCKETS[i] - 1 162 | else: 163 | # Mapping the state bounds to the bucket array 164 | bound_width = STATE_BOUNDS[i][1] - STATE_BOUNDS[i][0] 165 | offset = (NUM_BUCKETS[i]-1)*STATE_BOUNDS[i][0]/bound_width 166 | scaling = (NUM_BUCKETS[i]-1)/bound_width 167 | bucket_index = int(round(scaling*state[i] - offset)) 168 | bucket_indice.append(bucket_index) 169 | return tuple(bucket_indice) 170 | 171 | if __name__ == "__main__": 172 | learncartpole() 173 | -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/README.md: -------------------------------------------------------------------------------- 1 | # Code For Artificial Intelligence Engines Book 2 | 3 | **Author: James V Stone** 4 | 5 | This PYTHON code implements minimal examples, and is intended to demonstrate the basic principles that underpin each neural network. 6 | 7 | A PyTorch tutorial can be found here: 8 | https://pytorch.org/tutorials/beginner/nn_tutorial.html 9 | and 10 | https://github.com/pytorch/examples/ 11 | 12 | Alternatively, examples based on the scikit-learn package can be found at 13 | https://github.com/scikit-learn/scikit-learn 14 | 15 | **[Chapter 2: Linear Associative Network](https://github.com/jgvfwstone/ArtificialIntellgenceEngines/tree/master/DeepLearningEnginesCode/Python/Ch02_LinearNetwork)** 16 | 17 | **[Chapter 3: Perceptron](https://github.com/jgvfwstone/DeepLearningEngines/tree/master/DeepLearningEnginesCode/Python/Ch03_Perceptron)** 18 | 19 | **[Chapter 4: The Backpropagation Algorithm](https://github.com/jgvfwstone/DeepLearningEngines/tree/master/DeepLearningEnginesCode/Python/Ch04_BackpropNetwork)** 20 | 21 | **[Chapter 5: Hopfield Net](https://github.com/jgvfwstone/DeepLearningEngines/tree/master/DeepLearningEnginesCode/Python/Ch05_HopfieldNet)** 22 | 23 | **[Chapter 7: Restricted Boltzmann Machine](https://github.com/jgvfwstone/DeepLearningEngines/tree/master/DeepLearningEnginesCode/Python/Ch07_RestrictedBoltzmannMachine)** 24 | 25 | **[Chapter 8: Variational Autoencoder](https://github.com/jgvfwstone/DeepLearningEngines/tree/master/DeepLearningEnginesCode/Python/Ch08_VariationalAutoencoder)** 26 | 27 | **[Chapter 9: Convolutional Backprop Network](https://github.com/jgvfwstone/DeepLearningEngines/tree/master/DeepLearningEnginesCode/Python/Ch09_ConvolutionalNetwork)** 28 | 29 | **[Chapter 10: Reinforcement Learning](https://github.com/jgvfwstone/DeepLearningEngines/tree/master/DeepLearningEnginesCode/Python/Ch10_ReinforcementLearning)** 30 | 31 | **Notes on installing Python/Pytorch:** https://github.com/jgvfwstone/ArtificialIntelligenceEngines/blob/master/DeepLearningEnginesCode/Python/howToGetPytorch.md 32 | -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/howToGetPytorch.md: -------------------------------------------------------------------------------- 1 | 2 | Note: I am not expert in installing software. The text below is intended as a general guide, based on my own experience with Python. The book Artificial Intelligence Engines is mainly about the mathematics of neural networks, so this code is really an added extra. However, if you spot any errors here then please let me know. 3 | 4 | My own machine is a mac, so most information refers to Python on macs. 5 | 6 | Installing Python on a PC 7 | ================= 8 | 9 | See Pythonxy or WinPython. 10 | 11 | Installing Python on Unix (eg Mac/linux) 12 | ================= 13 | 14 | WARNING: DO NOT DELETE THE NATIVE VERSION OF PYTHON ON THE MAC OR LINUX BECAUSE THE OS NEEDS IT. JUST INSTALL A DIFFERENT (NEWER) VERSION AS BELOW. 15 | 16 | The simplest and most complete Python can be downloaded from Anaconda: 17 | 18 | https://www.anaconda.com/distribution/ 19 | 20 | To find out where the default version of python is stored, type this to unix shell: 21 | 22 | \$ which python3 23 | 24 | /Users/JimStone/anaconda3/bin/python3 25 | 26 | Or, to download the basic Python language go to: 27 | 28 | https://www.python.org/ 29 | 30 | Assuming you have Anaconda, it offers various programs to use with Python, including Python Notebooks. 31 | I use the IPython application called Spyder which can be launched from within Anaconda. 32 | 33 | In order to use standard neural network packages, you need to install (usually just one) software platforms: 34 | 35 | * Pytorch (owned by Facebook) 36 | * scikit-learn (funded by various public bodies) 37 | * TensorFlow (owned by Google) 38 | * Keras (open source) 39 | 40 | Most examples in this book rely on Pytorch. 41 | Both Pytorch and scikit-learn allow fairly easy access to the underlying Python code. 42 | 43 | Installing Pytorch 44 | ================= 45 | 46 | Install modules pytorch and torchvision: 47 | 48 | \$ conda install pytorch torchvision -c pytorch 49 | (The -c tells conda to look in pytorch online) 50 | 51 | Other usefull commands: 52 | 53 | \$ conda list 54 | 55 | \$ conda info 56 | 57 | Installing Modules Using pip 58 | ======================= 59 | 60 | For some reason conda cannot find all modules, so use pip for those. 61 | 62 | To use some graphical examples involving computer games you will need gym: 63 | 64 | Install gym into anaconda package 65 | 66 | \$ pip install gym 67 | 68 | To install scikit-learn do 69 | 70 | \$ pip install sklearn 71 | 72 | To make sure the files get put in the right place (ie in anaconda's domain), 73 | you may need to ensure you are using the pip that is part of anaconda: 74 | 75 | \$ cd /Users/JimStone/anaconda3/bin (/Users/JimStone is just an example) 76 | 77 | Then include ./ in command, to force anaconda's pip to be used: 78 | 79 | \$ ./pip install gym 80 | 81 | I get this response (because I installed it previously); note that gym was installed correctly in the anaconda directory (and not in my mac's default python directory): 82 | 83 | Requirement already satisfied: gym in /Users/JimStone/anaconda3/lib/python3.7/site-packages (0.10.11) 84 | etc 85 | 86 | If you need to tell pip where to install downloaded files then use the -t flag: 87 | 88 | \$ pip3 -t, --target adirectory 89 | 90 | Python, IPython, Notebooks and Jupyter Labs 91 | ================= 92 | 93 | These are the different interfaces for using Python, listed from most primitive to least. 94 | 95 | Python is often run from a command line using an IDLE; this the basic python. 96 | 97 | IPython is a more sophisticated interface that has integrated windows and displays variables (Spyder under Anaconda is an IPython application). 98 | 99 | Notebooks are great for teaching because they display code, comments and outputs in one graphical display. 100 | 101 | Jupyter Labs are an upgraded form of Notebook. 102 | 103 | You can export the code from a Notebook or Lab to run on its own (see below). 104 | 105 | Saving Notebook as Python Code 106 | =========================== 107 | 108 | Sometimes an online example is presented as a Jupyter Notebook or Jupyter Lab. 109 | You can save the Python code to run within a Python application (e.g. Spyder). 110 | 111 | From within Anaconda’s Jupyter Notebook, find the menu item: 112 | 113 | Download as … 114 | 115 | or from Jupyter Lab, find the menu item 116 | 117 | Export Notebook as … 118 | 119 | and download to file *.py. 120 | 121 | Final Notes 122 | ================ 123 | 124 | For examples that give continuous output you will need 125 | 126 | $ pip install tensorboardX 127 | 128 | Code in this repository does not require tensorboardX. 129 | 130 | If you want a solid book on scientific python then get this book: 131 | 132 | Learning Scientific Programming With Python by C Hill. 133 | 134 | Finally, to make latex look good in github see https://github.com/apps/texify 135 | -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/tex/1cbdf1c3ec380d9a41eb881ea74212cb.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/tex/48bed7afb24ae234d519a74f1c4c036e.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/tex/68b61e54061c3878c30181b9458cd6ef.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/tex/8eb8508fe6faf08a760f0850ee76fc03.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/tex/8fd5bb0eeaa8887f6a312c99359a3b93.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /DeepLearningEnginesCode/Python/tex/ccc47f81c25f969de60a446f1e4439cc.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Dr James V Stone 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Artificial Intelligence Engines 2 | 3 | Computer code collated from various sources for use with the book: 4 | 5 | [Artificial Intelligence Engines: A Tutorial Introduction to the Mathematics of Deep Learning](https://jamesstone.sites.sheffield.ac.uk/books/artificial-intelligence-engines) 6 | 7 | **by James V Stone** 8 | 9 | This file is: https://github.com/jgvfwstone/ArtificialIntelligenceEngines 10 | 11 | Note that the book is principally about the mathematics of deep learning. 12 | This repository is intended to provide 'taster' code, rather than an exercise in how to program deep learning networks. Because this code has been collated from different sources, the coding style varies between examples. 13 | 14 | Each example has been reproduced with permission from the author. 15 | 16 | **Downloading Single Files** 17 | 18 | Github normally insists you download the whole repository. 19 | However, to download a single file 20 | 1) go to the file so you can see it in the github user interface 21 | 2) click on the RAW button in the upper right 22 | 3) use the browser "save as ..." menu to save the file to your computer. 23 | 24 | **How To ...** 25 | There is a README file within each directory. 26 | 27 | **System Requirements** 28 | 29 | Each example has been tested on a mac (System Version: OS X 10.11.3), MacBook Air 1.6GHz. 30 | Python examples have been tested using the Spyder (3.3.2) python application with Python 3.7.0. 31 | --------------------------------------------------------------------------------