网络机器人吧社区

H42:干货,自己动手实现机器学习算法:神经网络(附神经网络课程,2月5日晚20:00前限时免费)

智能江湖 2018-11-16 06:24:23

转载自 听风居士博客(http://blog.csdn.net/zhouzx2010)  

神经网络的一些原理这不做介绍,不清楚的可以搜索相关博客和数据,资料相对较多。

下面开始正题

一、神经网络的构成

       输入层(input layer), 隐藏层 (hidden layers), 输入层 (output layers)

二、神经网络的算法的核心过程:

2.1. 前向传播求损失 

由输入层向前传送

                                   

                                   

                    

                                   

                                   

2.2. 反向传播更新w

 

三、代码实现

3.1.定义激活函数

激活函数一般有双曲函数和逻辑函数

#xhe_tmpurl   1.1 双曲函数(tanh)


其导数:



   1.2  逻辑函数(logistic function)

 其导数f'(x)=f(x)*[1-f(x)]

 

代码:

[python] view plain copy

  1. #!/usr/bin/env  

  2. # -*- coding:utf-8 -*-  

  3. import numpy as np  

  4. def tanh(x):  

  5.     return np.tanh(x)  

  6. def tanh_derivative(x):  

  7.     return 1.0 - np.tanh(x) * np.tanh(x)  

  8. def logistic(x):  

  9.     return 1 / (1 + np.exp(-x))  

  10. def logistic_derivative(x):  

  11.     return logistic(x) * (1 - logistic(x) )  



3.2 然后定义两层的神经网络的class,初始化激活函数,和权值:

给权值随机赋值,权值的范围[-0.25,0.25)

[python] view plain copy

  1. class NeuralNetworkWith2layers:  

  2.     def __init__(self, layers, activation='tanh'):  

  3.         if activation == 'Logistic':  

  4.             self.activation = logistic  

  5.             self.activation_deriv = logistic_derivative  

  6.         elif activation == 'tanh':  

  7.             self.activation = tanh  

  8.             self.activation_deriv = tanh_derivative  

  9.         self.weights = []  

  10.         for i in range(1, len(layers)-1):  

  11.             # 初始化 权值范围 [-0.25,0.25)  

  12.             # [0,1) * 2 - 1 => [-1,1) => * 0.25 => [-0.25,0.25)  

  13.             self.weights.append( (2*np.random.random((layers[i-1] + 1, layers[i] + 1 ))-1 ) * 0.25 )  

  14.             self.weights.append( (2*np.random.random((layers[i] + 1, layers[i+1] ))-1 ) * 0.25 )  


3.3下面实现神经网络的核心训练逻辑向前传播计算损失和相互传播更新w

3.3.1、函数申明:

  1. def fit(self, X, y, learning_rate=0.2, epochs = 10000):

参数X为样本数据,y为标签数据,learning_rate 为学习率默认0.2,epochs 为迭代次数默认值10000

3.3.2、数据预处理:

[python] view plain copy

  1. X = np.atleast_2d(X)  

  2. X = np.column_stack((X, np.ones(len(X))))  

  3. y = np.array(y)  


上面代码,给X加了一个值为1的维度,y变成numpy中的array类型

3.3.3、数据训练

[python] view plain copy

  1. def fit(self, X, y, learning_rate=0.2, epochs = 10000):  

  2.     X = np.atleast_2d(X)  

  3.     temp = np.ones([X.shape[0], X.shape[1]+1])  

  4.     temp[:,0:-1] = X  

  5.     X = temp  

  6.     y = np.array(y)  

  7.     for k in range(epochs):  

  8.         i = np.random.randint(X.shape[0])  

  9.         a = [X[i]]  

  10.         # 正向计算  

  11.         for l in range(len(self.weights)):  

  12.             a.append(self.activation( np.dot(a[l], self.weights[l])) )  

  13.         # 反向传播  

  14.         error = y[i] - a[-1]  

  15.         deltas = [error * self.activation_deriv(a[-1])]  

  16.         # starting backprobagation  

  17.         layerNum = len(a) - 2  

  18.         for j in range(layerNum, 0, -1): # 倒数第二层开始  

  19.             deltas.append(deltas[-1].dot(self.weights[j].T) * self.activation_deriv(a[j]))  

  20.         deltas.reverse()  

  21.         # 更新权值  

  22.         for i in range(len(self.weights)):  

  23.             layer = np.atleast_2d(a[i])  

  24.             delta = np.atleast_2d(deltas[i])  

  25.             self.weights[i] += learning_rate * layer.T.dot(delta)  


正向计算部分:

    将每层的计算节点值保存在二维数组a中,下面反向传播更新权值时候会用到该数据。计算过程如下图所示:

 

反向传播部分:

    该部分的计算公式如下:


       根据误差(error)反向传送

                                   对于输出层:

                                   对于隐藏层:

                                                       

                                   权重更新:  

                                   偏向更新    

                                                     

其中delta保存每层节点的Err值,最后利用前面的节点值a和现在的delta更新权值。

3.3.4、预测

预测的过程就是一个向前计算输出值的过程:

[python] view plain copy

  1. def predict(self, x):  

  2.     x = np.array(x)  

  3.     temp = np.ones(x.shape[0] + 1)  

  4.     temp[0:-1] = x  

  5.     a = temp  

  6.     for l in range(0, len(self.weights)):  

  7.         a = self.activation(np.dot(a, self.weights[l]))  

  8.     return a  


至此,神经网络的算法就完成了。大功告成!


完整代码:https://github.com/tingfengjushi/mymllib/tree/master/NeuralNetwork

四、神经网络代码测试

现在用刚才写的神经网络算法,来训练一个实现“异或“的神经网络。

输入数据如下:

0 0 0

0 1 1

1 0 1

1 1 0

前两列是x,最后一列是y 

当x两个维度值是相同时候返回0,不同时候返回1,就是 

“异或“。

代码如下:

[python] view plain copy

  1. #!/usr/bin/env  

  2. # -*- coding:utf-8 -*-  

  3. from NeuralNetwork import NeuralNetwork  

  4. from DeepNeuralNetwork import DeepNeuralNetwork  

  5. import numpy as np  

  6. nn = NeuralNetwork([221], 'tanh')  

  7. #nn = DeepNeuralNetwork([2, 2, 1], 'tanh')  

  8. x = np.array([[0,0],[0,1],[1,0],[1,1]])  

  9. y = np.array([0,1,1,0])  

  10. nn.fit(x, y)  

  11. for i in [[0,0],[0,1],[1,0],[1,1]]:  

  12.     print (i, nn.predict(i))  


执行结果:

 

 可以看到执行结果已经很不错了


本期小编给大家提供的是神经网络算法的课程哦,课程有一定难度,建议有一定数学和编程基础的朋友去学习。

领取智能江湖资料包H41

今日重点


重点摘要:

课程截图

【领取方式】

公众号后台回复H42

Copyright © 网络机器人吧社区@2017