自己动手做ML算法系列(2)– Neural Network
2016-08-07 16:05
316 查看
看了不少书,上了不少在线课程,我想最好的学习方式还是实现它 – 今天的又一个练习是做神经网络
数据: SKlearn的Iris
数据长这样:
每一列代表一朵花, 前4个column每一个表示一种属性,从左到右分别是:花萼长度,花萼宽度,花瓣长度,花瓣宽度
最后一列表示该花的分类:
0 -> Setosa
1 -> Versicolour
2 -> Virginica
开始导入包和处理数据:
下面讲一讲这个神经网络的设置。
我想搭建一个5 x 6 x 6 x 3的网络。明明一朵花只有4个变量,为什么第一列网络是5呢?那是因为我们需要在第一列添加一个bias variable。 如此类推。
这个网络长这样:
最左一列是输入,最右列是输出,灰色的是bias变量
代码:
运行完之后,再用一小段code来分析结果:
结果是:
我发现每次运行得出的结果有不小的变化,拿precision来说,取值范围有0.89~1.00。 这是因为每次取的训练样本和测试样本都不一样的原因。
另外,学习比率alpha不能太大,0.1以上准确度就几乎为0了。
数据: 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了。
相关文章推荐
- 自己动手做ML算法系列(1)– Gradient Descent
- 自己动手做网络爬虫系列——1
- 自己动手做网络爬虫系列——2 CrawlScript基本语法。
- 【SoftKeyboard研究系列】自己动手做最简单的SoftKeyboard
- 自己动手做按钮 [转]
- DirectShow系列讲座之三——开发自己的Filter
- 自己动手做漂亮的界面(B)
- zend studio系列 --- 自己的常用总结
- 自己动手做一个迷你 Linux 系统
- directX基础学习系列7 网格(自己创建)
- 在NT系列操作系统里让自己“消失”
- 想要自己动手做Image图片验证码吗?对比用户输入和验证码相同与否那么请注意下面的代码!
- 自己动手做一个局域网聊天工具(一)
- iOS开发系列--打造自己的“美图秀秀”
- 企业库应用实践系列一:创建第一个自己的Application Block _转http://www.cnblogs.com/lvwuhuijun/articles/1366094.html
- 快速安装自己的Sublime系列
- Hugo hexo 搭建博客系列1:自己的服务器
- AJAX系列2:采用自己写的函数实现
- 自己实现atoi系列(atoi函数)
- Android自己定义组件系列【6】——进阶实践(3)