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