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

机器学习(神经网络)

2017-11-19 16:38 218 查看
1.背景:

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

1.2最著名的算法是1980年的backpropagation

2.多层向前神经网络

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

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

输入层、隐藏层、输出层



2.3每层由单元组成

2.4输入层是由训练集的实例特征向量传入

2.5经过连接节点的权重传入下一层,一层的输出是下一层的输入

2.6隐藏层的个数可以是任意的,输入层有一层,输出层有一层

2.7每个单元也可以被称作神经节点,根据生物学来源定义

2.8一层中加权的求和,然后根据非线性方程转化输出

2.9作为多层先前神经网络,理论上,如果有足够多的隐藏层和足够大的训练集,可以模拟出任何方程

3.设计神经网络结构

3.1使用神经网络训练数据之前,必须确定神经网络的层数,以及每层单元的个数

3.2特征向量在被传入输入层时通常先被标准化到0-1之间(为了加速学习过程)

3.3离散型变量可以被编码成每一个输入单元对应一个特征值可能赋的值

3.4神经网络既可以用来做分类问题,也可以解决回归问题

4.backpropagation算法

4.1通过迭代性来处理训练集中的实例

4.2对比经过神经网络后输入层预测值与真实值之间

4.3反方向(从输出层=>隐藏层=>输入层),以最小误差来更新每个连接的权重

5.算法详细介绍

输入:D:数据集,l:学习率,一个多层向前神经网络

输出:一个训练好的神经网络

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

5.2对于每一个训练实例x执行以下步骤:

5.2.1:由输入层向前传送



5.2.2:根据误差反向传送



5.3终止条件

(1)权重的更新低于某个阈值

(2)预测的错误率低于某个阈值

(3)达到一定的循环次数

练习1:

# -*- coding:utf-8 -*-

import numpy as np

import numpy as np

#定义激活函数和相应的导数,双曲函数和逻辑函数
def tanh(x):   #定义双曲函数
return np.tanh(x)

def tanh_deriv(x):  #定义双曲函数的导数
return 1.0-np.tanh(x)*np.tanh(x)  #更新权重的时候需要用到双曲函数的倒数

def logistic(x):    #定义逻辑函数
return 1.0/(1+np.exp(-x))

def logistic_derivative(x):  #定义逻辑函数的导数
return logistic(x)*(1-logistic(x))

#定义一个神经网络的类
class NeuralNetwork:
#构造函数,初始化实例,,layers表示每层神经网络上的神经元个数元组,默认激活函数是双曲线函数
def __init__(self,layers,activation='tanh'):

#判断激活函数是双曲函数还是逻辑函数,初始化激活函数
if activation == 'logistic':
self.activation = logistic
self.activation_deriv = logistic_derivative
elif activation == 'tanh':
self.activation = tanh
self.activation_deriv = tanh_deriv

#初始化权重值,随机赋值
self.weights = []   #在当前类中
for i in range(1,len(layers)-1):
#该神经网络只有两层,所以初始化两层网络之间的权重值(随机值)
self.weights.append((2*np.random.random((layers[i-1]+1,layers[i]+1))-1)*0.25) #输入层到隐藏层之间的权重
self.weights.append((2*np.random.random((layers[i]+1,layers[i+1]))-1)*0.25)  #隐藏层到输出层之间的权重

#创建模型,学习率置为0.2,循环系数次数10000
def fit(self,x,y,learning_rate=0.2,epochs=10000):
x = np.atleast_2d(x)   #将x转化为矩阵形式确认x的维度至少是2维的
temp = np.ones([x.shape[0],x.shape[1]+1]) #将矩阵置1,对bias进行初始化
temp[:,0:-1] = x   #将x赋值给temp
x = temp #最后一列为bias
y = np.array(y)

#抽样循环
for k in range(epochs):
i = np.random.randint(x.shape[0])   #随机抽取一行
a = [x[i]]  #将取出的一行将其转换为列表

#正向更新
for l in range(len(self.weights)):
a.append(self.activation(np.dot(a[l],self.weights[l])))  #计算输入层的输出
error = y[i]-a[-1]  #计算输出层的输出误差
deltas = [error*self.activation_deriv(a[-1])]  #计算更新后的误差

#反向误差更新
for l in range(len(a)-2,0,-1):
#更新隐藏层的误差
deltas.append(deltas[-1].dot(self.weights[l].T)*self.activation_deriv(a[l]))
#颠倒顺序
deltas.reverse()
#计算权重更新
for i in range(len(self.weights)):
layer = np.atleast_2d(a[i])
delta = np.atleast_2d(deltas[i])
#权重更新
self.weights[i] += learning_rate*layer.T.dot(delta)
#预测标签
def predict(self,x):
x = np.array(x)
temp = np.ones(x.shape[0]+1)
temp[0:-1] = x
a = temp
for l in range(0,len(self.weights)):
a = self.activation(np.dot(a,self.weights[l]))
return a

nn = NeuralNetwork([2,2,1],'tanh')
x = np.array([[0,0],[0,1],[1,0],[1,1]])
y = np.array([0,1,1,0])

nn.fit(x, y)
for i in [[0,0],[0,1],[1,0],[1,1]]:
print(i,nn.predict(i))


运行结果:

[0, 0] [ 0.0002198]
[0, 1] [ 0.99836399]
[1, 0] [ 0.9983378]
[1, 1] [ 0.00535758]


练习2(手写数字图像识别):

数据集展示:

from sklearn.datasets import load_digits

digits = load_digits()
print(digits.data.shape)

import pylab as pl
pl.gray()
pl.matshow(digits.images[0])
pl.show()


运行结果:

(1797, 64)


运行效果:



代码实现:

# -*- coding:utf-8 -*-

import numpy as np
#下载数据集模块
from sklearn.datasets import load_digits
#将结果用矩阵
d9e8
形式展示
from sklearn.metrics import confusion_matrix,classification_report
#将数据转化为0,1二维数字
from sklearn.preprocessing import LabelBinarizer
#交叉验证模块
from sklearn.cross_validation import train_test_split

#定义激活函数和相应的导数,双曲函数和逻辑函数
def tanh(x):   #定义双曲函数
return np.tanh(x)

def tanh_deriv(x):  #定义双曲函数的导数
return 1.0-np.tanh(x)*np.tanh(x)  #更新权重的时候需要用到双曲函数的倒数

def logistic(x):    #定义逻辑函数
return 1.0/(1+np.exp(-x))

def logistic_derivative(x):  #定义逻辑函数的导数
return logistic(x)*(1-logistic(x))

#定义一个神经网络的类
class NeuralNetwork:
#构造函数,初始化实例,,layers表示每层神经网络上的神经元个数元组,默认激活函数是双曲线函数
def __init__(self,layers,activation='tanh'):

#判断激活函数是双曲函数还是逻辑函数,初始化激活函数
if activation == 'logistic':
self.activation = logistic
self.activation_deriv = logistic_derivative
elif activation == 'tanh':
self.activation = tanh
self.activation_deriv = tanh_deriv

#初始化权重值,随机赋值
self.weights = []   #在当前类中
for i in range(1,len(layers)-1):
#该神经网络只有两层,所以初始化两层网络之间的权重值(随机值)
self.weights.append((2*np.random.random((layers[i-1]+1,layers[i]+1))-1)*0.25) #输入层到隐藏层之间的权重
self.weights.append((2*np.random.random((layers[i]+1,layers[i+1]))-1)*0.25)  #隐藏层到输出层之间的权重

#创建模型,学习率置为0.2,循环系数次数10000
def fit(self,x,y,learning_rate=0.2,epochs=10000):
x = np.atleast_2d(x)   #将x转化为矩阵形式确认x的维度至少是2维的
temp = np.ones([x.shape[0],x.shape[1]+1]) #将矩阵置1,对bias进行初始化
temp[:,0:-1] = x   #将x赋值给temp
x = temp #最后一列为bias
y = np.array(y)

#抽样循环
for k in range(epochs):
i = np.random.randint(x.shape[0])   #随机抽取一行
a = [x[i]]  #将取出的一行将其转换为列表

#正向更新
for l in range(len(self.weights)):
a.append(self.activation(np.dot(a[l],self.weights[l])))  #计算输入层的输出
error = y[i]-a[-1]  #计算输出层的输出误差
deltas = [error*self.activation_deriv(a[-1])]  #计算更新后的误差

#反向误差更新
for l in range(len(a)-2,0,-1):
#更新隐藏层的误差
deltas.append(deltas[-1].dot(self.weights[l].T)*self.activation_deriv(a[l]))
#颠倒顺序
deltas.reverse()
#计算权重更新
for i in range(len(self.weights)):
layer = np.atleast_2d(a[i])
delta = np.atleast_2d(deltas[i])
#权重更新
self.weights[i] += learning_rate*layer.T.dot(delta)
#预测标签
def predict(self,x):
x = np.array(x)
temp = np.ones(x.shape[0]+1)
temp[0:-1] = x
a = temp
for l in range(0,len(self.weights)):
a = self.activation(np.dot(a,self.weights[l]))
return a

#加载数据集
digits = load_digits()
#x为数据集的特征向量
x = digits.data
#Y为数据集的标记
y = digits.target
#数据预处理,将其标准化到0-1之间
x -= x.min()
x /= x.max()

nn = NeuralNetwork([64,100,10],'logistic')  #实例化一个神经网络
x_train,x_test,y_train,y_test = train_test_split(x,y)  #将数据集划分为训练集和测试集的特征向量
labels_train = LabelBinarizer().fit_transform(y_train)  #将标记转换为0,1类别数
labels_test =  LabelBinarizer().fit_transform(y_test)
print("start fitting")

#训练模型
nn.fit(x_train,labels_train,epochs=3000)

#存储预测值
predictions = []
#循环训练集个数次循环
for i in range(x_test.shape[0]):
#预测测试集
o = nn.predict(x_test[i])
#选择概率最大的数
predictions.append(np.argmax(o))

#将结果整合在矩阵中
print(confusion_matrix(y_test,predictions))
#预测精确度
print(classification_report(y_test,predictions))


运行结果:

D:\Anaconda3\lib\site-packages\sklearn\cross_validation.py:41: DeprecationWarning: This module was deprecated in version 0.18 in favor of the model_selection module into which all the refactored classes and functions are moved. Also note that the interface of the new CV iterators are different from that of this module. This module will be removed in 0.20.
"This module will be removed in 0.20.", DeprecationWarning)
start fitting
[[47  0  0  0  0  0  0  0  0  0]
[ 0 47  0  0  0  1  0  0  0  3]
[ 0  0 33  0  0  0  0  0  0  0]
[ 0  0  1 41  0  2  0  0  0  1]
[ 0  1  0  0 45  0  0  1  0  0]
[ 0  0  0  0  1 46  0  0  0  0]
[ 0  1  0  0  0  0 38  0  0  0]
[ 0  0  0  0  0  0  0 48  1  0]
[ 0  6  1  0  0  1  0  1 41  0]
[ 0  0  1  1  0  0  0  1  0 39]]
precision    recall  f1-score   support

0       1.00      1.00      1.00        47
1       0.85      0.92      0.89        51
2       0.92      1.00      0.96        33
3       0.98      0.91      0.94        45
4       0.98      0.96      0.97        47
5       0.92      0.98      0.95        47
6       1.00      0.97      0.99        39
7       0.94      0.98      0.96        49
8       0.98      0.82      0.89        50
9       0.91      0.93      0.92        42

avg / total       0.95      0.94      0.94       450
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐