1+ from utils .generate_data import get_iris
2+ from utils .deeplearning_utils import ActivationFunction , LossFunction , ActivationFunctionDerivative
3+ from utils .common_function import one_hot_encoding
4+ import numpy as np
5+ import matplotlib .pyplot as plt
6+
7+ def feed_forward (X , W1 , W2 , W3 , B1 , B2 , B3 , func = 'sigmoid' ):
8+ if func == 'sigmoid' :
9+ act_func = ActivationFunction .sigmoid
10+ elif func == 'tanh' :
11+ act_func = ActivationFunction .tanh
12+ elif func == 'relu' :
13+ act_func = ActivationFunction .relu
14+ Z1 = W1 .T .dot (X ) + B1
15+ A1 = act_func (Z1 )
16+ Z2 = W2 .T .dot (A1 ) + B2
17+ A2 = act_func (Z2 )
18+ Z3 = W3 .T .dot (A2 ) + B3
19+ Y_pred = ActivationFunction .softmax (Z3 )
20+
21+ params = {'A1' : A1 , 'A2' : A2 ,
22+ 'Z1' : Z1 , 'Z2' : Z2 , 'Z3' : Z3 }
23+ return Y_pred , params
24+
25+ def back_propagation (params , T , Y_pred , W3 , W2 , X , func = 'sigmoid' ):
26+ if func == 'sigmoid' :
27+ dri_func = ActivationFunctionDerivative .sigmoid
28+ elif func == 'tanh' :
29+ dri_func = ActivationFunctionDerivative .tanh
30+ elif func == 'relu' :
31+ dri_func = ActivationFunctionDerivative .relu
32+
33+ dW3 = params ['A2' ].dot (T - Y_pred ) #same shape as W3
34+ dB3 = np .sum (T - Y_pred , axis = 0 , keepdims = True ).T #same shape as B3
35+ dW2 = params ['A1' ].dot ((W3 .dot ((T - Y_pred ).T ) * dri_func (params ['A2' ])).T )
36+ dB2 = np .sum (W3 .dot ((T - Y_pred ).T ) * dri_func (params ['A2' ]), axis = 1 , keepdims = True )
37+ dW1 = X .dot ((W2 .dot (W3 .dot ((T - Y_pred ).T ) * dri_func (params ['A2' ])) * dri_func (params ['A1' ])).T )
38+ dB1 = np .sum (W2 .dot (W3 .dot ((T - Y_pred ).T ) * dri_func (params ['A2' ])) * dri_func (params ['A1' ]), axis = 1 , keepdims = True )
39+
40+ gradient_params = {'dW3' : dW3 , 'dB3' : dB3 ,
41+ 'dW2' : dW2 , 'dB2' : dB2 ,
42+ 'dW1' : dW1 , 'dB1' : dB1 }
43+ return gradient_params
44+
45+ def gradient_descent (W1 , W2 , W3 , B1 , B2 , B3 , gradient_params , lr = 0.001 ):
46+ W1 = W1 + lr * gradient_params ['dW1' ]
47+ W2 = W2 + lr * gradient_params ['dW2' ]
48+ W3 = W3 + lr * gradient_params ['dW3' ]
49+ B1 = B1 + lr * gradient_params ['dB1' ]
50+ B2 = B2 + lr * gradient_params ['dB2' ]
51+ B3 = B3 + lr * gradient_params ['dB3' ]
52+ return W1 , W2 , W3 , B1 , B2 , B3
53+
54+ def classification_rate (Y , P ):
55+ n_correct = 0
56+ n_total = 0
57+ for i in range (len (Y )):
58+ n_total += 1
59+ if Y [i ] == P [i ]:
60+ n_correct += 1
61+ return float (n_correct ) / n_total
62+
63+ if __name__ == '__main__' :
64+ X , Y = get_iris ()
65+ T , _ = one_hot_encoding (Y )
66+ n_iter = 1000
67+
68+ N , D = X .shape
69+ X = X .T
70+ M1 = 8
71+ M2 = 6
72+ K = 3
73+ for func in ['sigmoid' , 'tanh' , 'relu' ]:
74+ W1 = np .random .randn (D , M1 ) / np .sqrt (D )
75+ W2 = np .random .randn (M1 , M2 ) / np .sqrt (M1 )
76+ W3 = np .random .randn (M2 , K ) / np .sqrt (M2 )
77+ B1 = np .expand_dims (np .random .randn (M1 ), 1 )
78+ B2 = np .expand_dims (np .random .randn (M2 ), 1 )
79+ B3 = np .expand_dims (np .random .randn (K ), 1 )
80+ loss_list = []
81+
82+ for i in range (n_iter ):
83+ Y_pred , params = feed_forward (X , W1 , W2 , W3 , B1 , B2 , B3 , func )
84+ grad_param = back_propagation (params , T , Y_pred .T , W3 , W2 , X )
85+ loss_list .append (LossFunction .CrossEntropy (T , Y_pred .T ))
86+ W1 , W2 , W3 , B1 , B2 , B3 = gradient_descent (W1 , W2 , W3 , B1 , B2 , B3 , grad_param )
87+
88+ plt .plot (loss_list )
89+ plt .show ()
90+ Y_pred_label = np .argmax (Y_pred .T , axis = 1 )
91+ print (f"Classification Rate using { func } : { classification_rate (Y , Y_pred_label )} " )
92+
0 commit comments