|
| 1 | +#-*- coding:utf-8 -*- |
| 2 | +''' |
| 3 | +Author: Stephen Lee |
| 4 | +Date: 2017.9.21 |
| 5 | +
|
| 6 | +BP neural network with three layers |
| 7 | +''' |
| 8 | + |
| 9 | +import numpy as np |
| 10 | +import matplotlib.pyplot as plt |
| 11 | + |
| 12 | +class Bpnw(): |
| 13 | + |
| 14 | + def __init__(self,n_layer1,n_layer2,n_layer3,rate_w=0.3,rate_t=0.3): |
| 15 | + ''' |
| 16 | + :param n_layer1: number of input layer |
| 17 | + :param n_layer2: number of hiden layer |
| 18 | + :param n_layer3: number of output layer |
| 19 | + :param rate_w: rate of weight learning |
| 20 | + :param rate_t: rate of threshold learning |
| 21 | + ''' |
| 22 | + self.num1 = n_layer1 |
| 23 | + self.num2 = n_layer2 |
| 24 | + self.num3 = n_layer3 |
| 25 | + self.rate_weight = rate_w |
| 26 | + self.rate_thre = rate_t |
| 27 | + self.thre2 = -2*np.random.rand(self.num2)+1 |
| 28 | + self.thre3 = -2*np.random.rand(self.num3)+1 |
| 29 | + self.vji = np.mat(-2*np.random.rand(self.num2, self.num1)+1) |
| 30 | + self.wkj = np.mat(-2*np.random.rand(self.num3, self.num2)+1) |
| 31 | + |
| 32 | + def sig(self,x): |
| 33 | + return 1 / (1 + np.exp(-1*x)) |
| 34 | + |
| 35 | + def sig_plain(self,x): |
| 36 | + return 1 / (1 + np.exp(-1*x)) |
| 37 | + |
| 38 | + def do_round(self,x): |
| 39 | + return round(x, 3) |
| 40 | + |
| 41 | + def trian(self,patterns,data_train, data_teach, n_repeat, error_accuracy,draw_e = bool): |
| 42 | + ''' |
| 43 | + :param patterns: the number of patterns |
| 44 | + :param data_train: training data x; numpy.ndarray |
| 45 | + :param data_teach: training data y; numpy.ndarray |
| 46 | + :param n_repeat: echoes |
| 47 | + :param error_accuracy: error accuracy |
| 48 | + :return: None |
| 49 | + ''' |
| 50 | + data_train = np.asarray(data_train) |
| 51 | + data_teach = np.asarray(data_teach) |
| 52 | + print('-------------------Start Training-------------------------') |
| 53 | + print(' - - Shape: Train_Data ',np.shape(data_train)) |
| 54 | + print(' - - Shape: Teach_Data ',np.shape(data_teach)) |
| 55 | + rp = 0 |
| 56 | + all_mse = [] |
| 57 | + mse = 10000 |
| 58 | + while rp < n_repeat and mse >= error_accuracy: |
| 59 | + alle = 0 |
| 60 | + final_out = [] |
| 61 | + for g in range(np.shape(data_train)[0]): |
| 62 | + net_i = data_train[g] |
| 63 | + out1 = net_i |
| 64 | + |
| 65 | + net_j = out1 * self.vji.T - self.thre2 |
| 66 | + out2=self.sig(net_j) |
| 67 | + |
| 68 | + net_k = out2 * self.wkj.T - self.thre3 |
| 69 | + out3 = self.sig(net_k) |
| 70 | + |
| 71 | + # learning process |
| 72 | + pd_k_all = np.multiply(np.multiply(out3,(1 - out3)),(data_teach[g]-out3)) |
| 73 | + pd_j_all = np.multiply(pd_k_all * self.wkj,np.multiply(out2,1-out2)) |
| 74 | + #upgrade weight |
| 75 | + self.wkj = self.wkj + pd_k_all.T * out2 *self.rate_weight |
| 76 | + self.vji = self.vji + pd_j_all.T * out1 * self.rate_weight |
| 77 | + #upgrade threshold |
| 78 | + self.thre3 = self.thre3 - pd_k_all * self.rate_thre |
| 79 | + self.thre2 = self.thre2 - pd_j_all * self.rate_thre |
| 80 | + #calculate sum of error |
| 81 | + errors = np.sum(abs((data_teach[g] - out3))) |
| 82 | + |
| 83 | + alle = alle + errors |
| 84 | + final_out.extend(out3.getA().tolist()) |
| 85 | + final_out3 = [list(map(self.do_round,each)) for each in final_out] |
| 86 | + |
| 87 | + rp = rp + 1 |
| 88 | + mse = alle/patterns |
| 89 | + all_mse.append(mse) |
| 90 | + def draw_error(): |
| 91 | + yplot = [error_accuracy for i in range(int(n_repeat * 1.2))] |
| 92 | + plt.plot(all_mse, '+-') |
| 93 | + plt.plot(yplot, 'r--') |
| 94 | + plt.xlabel('Learning Times') |
| 95 | + plt.ylabel('All_mse') |
| 96 | + plt.grid(True,alpha = 0.7) |
| 97 | + plt.show() |
| 98 | + print('------------------Training Complished---------------------') |
| 99 | + print(' - - Training epoch: ', rp, ' - - Mse: %.6f'%mse) |
| 100 | + print(' - - Last Output: ', final_out3) |
| 101 | + if draw_e: |
| 102 | + draw_error() |
| 103 | + |
| 104 | + def predict(self,data_test): |
| 105 | + ''' |
| 106 | + :param data_test: data test, numpy.ndarray |
| 107 | + :return: predict output data |
| 108 | + ''' |
| 109 | + data_test = np.asarray(data_test) |
| 110 | + produce_out = [] |
| 111 | + print('-------------------Start Testing-------------------------') |
| 112 | + print(' - - Shape: Test_Data ',np.shape(data_test)) |
| 113 | + print(np.shape(data_test)) |
| 114 | + for g in range(np.shape(data_test)[0]): |
| 115 | + |
| 116 | + net_i = data_test[g] |
| 117 | + out1 = net_i |
| 118 | + |
| 119 | + net_j = out1 * self.vji.T - self.thre2 |
| 120 | + out2 = self.sig(net_j) |
| 121 | + |
| 122 | + net_k = out2 * self.wkj.T - self.thre3 |
| 123 | + out3 = self.sig(net_k) |
| 124 | + produce_out.extend(out3.getA().tolist()) |
| 125 | + res = [list(map(self.do_round,each)) for each in produce_out] |
| 126 | + return np.asarray(res) |
| 127 | + |
| 128 | + |
| 129 | +def main(): |
| 130 | + #I will fish the mian function later |
| 131 | + pass |
| 132 | + |
| 133 | +if __name__ == '__main__': |
| 134 | + main() |
0 commit comments