您的位置:首页 > 理论基础 > 计算机网络

神经网络NN简单理解以及算法

2017-08-15 16:07 225 查看

1.什么是神经网络

1.1 背景 :

以人脑中的神经网络为启发,历史上出现过很多不同版本

最著名的算法是1980年的 backpropagation

1.2 多层向前神经网络(Multilayer Feed-Forward Neural Network)

Backpropagation被使用在多层向前神经网络上

多层向前神经网络由以下部分组成:

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



每层由单元Unit组成

连接Unit之间有权重weights

输入层用来输入数据

隐藏层数量可以是任意的

理论上有足够多的数据以及足够多的隐藏层,该网络可以模拟出任何方程

需要进行非线性的转换

以上构成2层的神经网络 输入层不作为一层

2. 主要算法介绍

2.1 关于非线性转化方程(non-linear transformation function)

代码中叫做 sigmoid / sigmoidDer (命名不当,理解就好)

- 双曲函数(tanh) 以及 导数

numpy库提供了tanh函数 : numpy.tanh(x)

导数为 : 1.0−tanh(x)2

- 逻辑函数(logistic function) 以及 导数

函数为 : logistic(x)=11+e−x

导数为 : logistic(x)⋅(1−logistic(x))

2.2 BackPropagation 算法

简单的说就是通过迭代性的来处理训练集中的实例,经过神经网络后输入层预测值(predicted value)与真实值(target value)之间的误差不断调整权重weight来使其更加准确,最后反向计算误差来更新连接之间的权重weight

算法大致流程 :

建立神经网络

算法输入数据集 学习率(步长alpha)

初始化权重(weights)和偏向(bias): 随机初始化在-1到1之间,或者-0.5到0.5之间,每个单元有一个偏向

向前更新传送

根据误差反向更新(weights)

终止条件

2.3 基于算法的几个公式





向前更新传送过程

公式1:Oj=∑iOiwij+θj

按照上图就是 Oj=y1w1j+y2w2j+...+ynwnj+θj

根据误差(error)反向传送过程

公式2 : 对于输出层 Errj=Oj(1−Oj)(Tj−Oj) 其中T为target,就是实际结果,Oj(1−Oj) 正好是logistic函数的导数,眼熟不…

公式3 : 对于隐藏层 Errj=Oj(1−Oj)∑kwjk⋅Errk 由于计算的时候是从后向前计算的 最后需要逆置一下

公式4 : 对于weights wij=alpha⋅Errj⋅Oi

3. 简单算法实现

注意:本简单实现算法迭代过程使用了随机化,可以更改其条件达到更好的精确性

# coding:utf-8

from numpy import *

def tan(x):
return tanh(x)

def tanDer(x):  # tanh的导数
return 1.0 - tanh(x) * tanh(x)

def logistic(x):
return 1 / (1 + exp(-x))

def logisticDer(x):  # logistic的导数
return logistic(x) * (1 - logistic(x))

class NN(object):
def __init__(self, layer, sigmoid=tan, sigmoidD=tanDer):  # layer是个列表 分别存着每一层的元素个数
self.weights = []
self.sigmoid = sigmoid
self.sigmoid_der = sigmoidD
for i in range(1, len(layer) - 1):  # 随机 生成weight 和  bias
self.weights.append((2 * random.random((layer[i - 1] + 1, layer[i] + 1)) - 1) * 0.25)
self.weights.append((2 * random.random((layer[i] + 1, layer[i + 1])) - 1) * 0.25)

def fit(self, x, y, alpha=0.02, loopNum=10000):  # 步长与循环次数 默认0.02 / 10000
x = atleast_2d(x)  # 至少2维
tempx = ones([x.shape[0], x.shape[1] + 1])  # 多加一列
tempx[:, 0:-1] = x  # 最后一列的1是常数
x = tempx
y = array(y)
for k in range(loopNum):  # 随机选择下标
index = random.randint(x.shape[0])
units = [x[index]]  # 当前单元(Unit)格的数值
for i in range(len(self.weights)):  # 进过两次运算后计算出输出层(预测值) -- 公式 1
units.append(self.sigmoid(dot(units[i], self.weights[i])))  # dot all a1b1+a2b2.....

error = y[index] - units[-1]  # Tj - Oj
deltas = [error * self.sigmoid_der(units[-1])]  # 反向 输出层误差 -- 公式 2
for i in range(len(units) - 2, 0, -1):
# 隐藏层误差 -- 公式 3
deltas.append(deltas[-1].dot(self.weights[i].T) * self.sigmoid_der(units[i]))
deltas.reverse()  # 从后往前更新 所以逆转一下
for i in range(len(self.weights)):
unit = atleast_2d(units[i])
delta = atleast_2d(deltas[i])
self.weights[i] += alpha * unit.T.dot(delta)  # 根据公式不断更新weights -- 公式 4

def predict(self, x):
x = array(x)
temp = ones(x.shape[0] + 1)
temp[0:-1] = x
unit = temp
for i in range(0, len(self.weights)): # 不用保留之前层的数值,只保留最后一层数值,并且放入到sigmoid函数中
unit = self.sigmoid(dot(unit, self.weights[i]))  # 数值*weight参数
return unit

if __name__ == '__main__':

'''简单数学逻辑运算'''
x = array([[0, 0], [0, 1], [1, 0], [1, 1]])
y = array([1, 0, 0, 1])
nn = NN([2, 2, 1], tan, tanDer)
nn.fit(x, y)
for i in [[0, 0], [0, 1], [1, 0], [1, 1]]:
print i,int(nn.predict(i) > 0.5)
print '01 is over\n'
'''从numpy库导入数据进行数字识别'''
from sklearn.datasets import load_digits
from sklearn.metrics import confusion_matrix, classification_report
from sklearn.preprocessing import LabelBinarizer
from sklearn.cross_validation import train_test_split

digits = load_digits()
X = digits.data
y = digits.target
X -= X.min()
X /= X.max()  # for X range : 0-1

nn = NN([64, 500, 10], logistic)
X_train, X_test, y_train, y_test = train_test_split(X, y)  # 随机切分数据集
labels_train = LabelBinarizer().fit_transform(y_train)  # 二值化label
labels_test = LabelBinarizer().fit_transform(y_test)  # 比如1就是 01000000000
print "start fitting number"
nn.fit(X_train, labels_train, alpha=0.001, loopNum=50000)
predictions = []  # 预测值
for i in range(X_test.shape[0]):
o = nn.predict(X_test[i])
predictions.append(argmax(o))  # argmax(o) 返回o数组中最大的元素的下标
print confusion_matrix(y_test, predictions)  # 对比数值
print classification_report(y_test, predictions)  # 分类报告
# print predictions


4. 输出数据 以及 简单分析

'''
[0, 0] 1
[0, 1] 0
[1, 0] 0
[1, 1] 1
01 is over

start fitting number
[[42  0  0  0  0  0  0  0  0  0]
[ 0 33  1  0  0  0  0  0  2  7]
[ 0  0 40  0  0  0  0  0  0  0]
[ 0  1  0 40  0  3  0  2  3  0]
[ 0  0  0  0 47  0  0  0  2  0]
[ 0  0  0  0  0 43  0  0  0  3]
[ 0  0  0  0  0  0 41  0  0  0]
[ 0  0  0  0  0  1  0 47  1  1]
[ 0  3  0  0  0  1  0  1 43  0]
[ 0  0  0  0  0  2  0  0  1 39]]

precision    recall  f1-score   support

0       1.00      1.00      1.00        42
1       0.89      0.77      0.82        43
2       0.98      1.00      0.99        40
3       1.00      0.82      0.90        49
4       1.00      0.96      0.98        49
5       0.86      0.93      0.90        46
6       1.00      1.00      1.00        41
7       0.94      0.94      0.94        50
8       0.83      0.90      0.86        48
9       0.78      0.93      0.85        42

avg / total       0.93      0.92      0.92       450

'''
# 分析
# 关于01的与或运算应该是很准确了 原始数据进行了sigmoid函数计算
# 关于数字识别 第一个矩阵对角线上说明正确的个数
# 第二个矩阵 有正确率以及反向正确率 450张训练正确率93%尚可
# 可以改变参数比如步长,随机循环次数等等.....


什么是神经网络
1 背景

2 多层向前神经网络Multilayer Feed-Forward Neural Network

主要算法介绍
1 关于非线性转化方程non-linear transformation function

2 BackPropagation 算法

3 基于算法的几个公式

简单算法实现

输出数据 以及 简单分析
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  神经网络 算法