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

自己动手做ML算法系列(2)– Neural Network

2016-08-07 16:05 316 查看
看了不少书,上了不少在线课程,我想最好的学习方式还是实现它 – 今天的又一个练习是做神经网络

数据: SKlearn的Iris

数据长这样:



每一列代表一朵花, 前4个column每一个表示一种属性,从左到右分别是:花萼长度,花萼宽度,花瓣长度,花瓣宽度

最后一列表示该花的分类:

0 -> Setosa

1 -> Versicolour

2 -> Virginica

开始导入包和处理数据:

from sklearn.datasets import load_iris
from sklearn.metrics import classification_report
from sklearn.cross_validation import train_test_split, cross_val_score
from sklearn.preprocessing import StandardScaler
import pandas as pd
import numpy as np

iris = load_iris()  # 导入数据
X = np.array(iris.data[:])  # 转换成ndarray
X = np.insert(X, 0, 1, axis=1) # 在每一行前面添加bias 变量, 方便之后的训练
y = iris.target # 获得分类信息

# 下面将单个分类变成向量,因为要被用作神经网络的最后一层
tmp = []
for i in y:
if i == 0:
tmp.append([1,0,0])   # i==0表示分类为第一种,所以给它1的probability, 以此类推
elif i == 1:
tmp.append([0,1,0])
else:
tmp.append([0,0,1])
y = tmp

X_train, X_test, y_train, y_test = train_test_split(X, y)  # 用默认的test_size = 0.25

# 下面将data 标准化, 即使得数据平均数为0,以及标准差为1
X_scaler = StandardScaler()
X_train = X_scaler.fit_transform(X_train)
X_test = X_scaler.fit_transform(X_test)


下面讲一讲这个神经网络的设置。

我想搭建一个5 x 6 x 6 x 3的网络。明明一朵花只有4个变量,为什么第一列网络是5呢?那是因为我们需要在第一列添加一个bias variable。 如此类推。

这个网络长这样:



最左一列是输入,最右列是输出,灰色的是bias变量

代码:

# A L=4 neural networks

w1 = np.random.random((6,5)) - .5 # The weight for first layer (input layer)
w2 = np.random.random((6,6)) - .5 # Second layer
w3 = np.random.random((3,6)) - .5 # 3rd layer (output layer)

alpha = 0.05 # Learning rate, 学习比率

def sigmoid(x, deriv=False):  # 定义Activation Function
if deriv:
return x*(1-x)    # 这里计算sigmoid函数的偏微分,需要注意的是,这个简化是因为我们只会放入之前算好的值
return 1/(1+np.exp(-x))

for iter in xrange(10000):  # 进行1万次pass
# Forward
l1 = X_train
l2 = sigmoid(np.dot(l1, w1.T))  # 算出第二列神经元的值, 以此类推
l3 = sigmoid(np.dot(l2, w2.T))
l4 = sigmoid(np.dot(l3, w3.T))

# Back, 向后推进
l4_error = (y_train-l4)*sigmoid(l4,deriv=True) # 计算输出神经元的错误值
l3_error = np.dot(l4_error, w3)*sigmoid(l3, deriv=True)  # 计算倒数第二层的错误值
l2_error = np.dot(l3_error, w2)*sigmoid(l2, deriv=True) # 计算第二层的错误值
# 注意, 不需要计算第一层,因为第一层是输入,错误值没有意义

# Update, 更新每一层的weight
w1 += alpha*np.dot(l2_error.T, l1)
w2 += alpha*np.dot(l3_error.T, l2)
w3 += alpha*np.dot(l4_error.T, l3)

print 'Training complete'


运行完之后,再用一小段code来分析结果:

# Reporting
l1 = X_test
l2 = sigmoid(np.dot(l1, w1.T))
l3 = sigmoid(np.dot(l2, w2.T))
l4 = sigmoid(np.dot(l3, w3.T))
y_pred = l4

def toInt(l):  # 将向量变成单一的整数值,便于比较
tmp = []
for y in l:
j = None
for i in xrange(len(y)):
if y[i] > 0.5:
j = i
if j == None:
j = 3
tmp.append(j)
return tmp

y_pred = toInt(y_pred)
y_test = toInt(y_test)

print classification_report(y_test, y_pred)


结果是:

precision    recall  f1-score   support

0       1.00      1.00      1.00        10
1       0.94      1.00      0.97        16
2       1.00      0.92      0.96        12

avg / total       0.98      0.97      0.97        38


我发现每次运行得出的结果有不小的变化,拿precision来说,取值范围有0.89~1.00。 这是因为每次取的训练样本和测试样本都不一样的原因。

另外,学习比率alpha不能太大,0.1以上准确度就几乎为0了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  神经网络 算法 python