ml-finance-python

python scripts for finance machine learning

git clone https://9o.is/git/ml-finance-python.git

multilayer_perceptron.py

(4390B)


      1 from __future__ import print_function, division
      2 import numpy as np
      3 import math
      4 from sklearn import datasets
      5 
      6 from mlfromscratch.utils import train_test_split, to_categorical, normalize, accuracy_score, Plot
      7 from mlfromscratch.deep_learning.activation_functions import Sigmoid, Softmax
      8 from mlfromscratch.deep_learning.loss_functions import CrossEntropy
      9 
     10 class MultilayerPerceptron():
     11     """Multilayer Perceptron classifier. A fully-connected neural network with one hidden layer.
     12     Unrolled to display the whole forward and backward pass.
     13 
     14     Parameters:
     15     -----------
     16     n_hidden: int:
     17         The number of processing nodes (neurons) in the hidden layer. 
     18     n_iterations: float
     19         The number of training iterations the algorithm will tune the weights for.
     20     learning_rate: float
     21         The step length that will be used when updating the weights.
     22     """
     23     def __init__(self, n_hidden, n_iterations=3000, learning_rate=0.01):
     24         self.n_hidden = n_hidden
     25         self.n_iterations = n_iterations
     26         self.learning_rate = learning_rate
     27         self.hidden_activation = Sigmoid()
     28         self.output_activation = Softmax()
     29         self.loss = CrossEntropy()
     30 
     31     def _initialize_weights(self, X, y):
     32         n_samples, n_features = X.shape
     33         _, n_outputs = y.shape
     34         # Hidden layer
     35         limit   = 1 / math.sqrt(n_features)
     36         self.W  = np.random.uniform(-limit, limit, (n_features, self.n_hidden))
     37         self.w0 = np.zeros((1, self.n_hidden))
     38         # Output layer
     39         limit   = 1 / math.sqrt(self.n_hidden)
     40         self.V  = np.random.uniform(-limit, limit, (self.n_hidden, n_outputs))
     41         self.v0 = np.zeros((1, n_outputs))
     42 
     43     def fit(self, X, y):
     44 
     45         self._initialize_weights(X, y)
     46 
     47         for i in range(self.n_iterations):
     48 
     49             # ..............
     50             #  Forward Pass
     51             # ..............
     52 
     53             # HIDDEN LAYER
     54             hidden_input = X.dot(self.W) + self.w0
     55             hidden_output = self.hidden_activation(hidden_input)
     56             # OUTPUT LAYER
     57             output_layer_input = hidden_output.dot(self.V) + self.v0
     58             y_pred = self.output_activation(output_layer_input)
     59 
     60             # ...............
     61             #  Backward Pass
     62             # ...............
     63 
     64             # OUTPUT LAYER
     65             # Grad. w.r.t input of output layer
     66             grad_wrt_out_l_input = self.loss.gradient(y, y_pred) * self.output_activation.gradient(output_layer_input)
     67             grad_v = hidden_output.T.dot(grad_wrt_out_l_input)
     68             grad_v0 = np.sum(grad_wrt_out_l_input, axis=0, keepdims=True)
     69             # HIDDEN LAYER
     70             # Grad. w.r.t input of hidden layer
     71             grad_wrt_hidden_l_input = grad_wrt_out_l_input.dot(self.V.T) * self.hidden_activation.gradient(hidden_input)
     72             grad_w = X.T.dot(grad_wrt_hidden_l_input)
     73             grad_w0 = np.sum(grad_wrt_hidden_l_input, axis=0, keepdims=True)
     74 
     75             # Update weights (by gradient descent)
     76             # Move against the gradient to minimize loss
     77             self.V  -= self.learning_rate * grad_v
     78             self.v0 -= self.learning_rate * grad_v0
     79             self.W  -= self.learning_rate * grad_w
     80             self.w0 -= self.learning_rate * grad_w0
     81 
     82     # Use the trained model to predict labels of X
     83     def predict(self, X):
     84         # Forward pass:
     85         hidden_input = X.dot(self.W) + self.w0
     86         hidden_output = self.hidden_activation(hidden_input)
     87         output_layer_input = hidden_output.dot(self.V) + self.v0
     88         y_pred = self.output_activation(output_layer_input)
     89         return y_pred
     90 
     91 
     92 def main():
     93     data = datasets.load_digits()
     94     X = normalize(data.data)
     95     y = data.target
     96 
     97     # Convert the nominal y values to binary
     98     y = to_categorical(y)
     99 
    100     X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.4, seed=1)
    101 
    102     # MLP
    103     clf = MultilayerPerceptron(n_hidden=16,
    104         n_iterations=1000,
    105         learning_rate=0.01)
    106 
    107     clf.fit(X_train, y_train)
    108     y_pred = np.argmax(clf.predict(X_test), axis=1)
    109     y_test = np.argmax(y_test, axis=1)
    110 
    111     accuracy = accuracy_score(y_test, y_pred)
    112     print ("Accuracy:", accuracy)
    113 
    114     # Reduce dimension to two using PCA and plot the results
    115     Plot().plot_in_2d(X_test, y_pred, title="Multilayer Perceptron", accuracy=accuracy, legend_labels=np.unique(y))
    116 
    117 if __name__ == "__main__":
    118     main()