Python机器学习日记(八)

神经网络

“多层感知器”--MLP算法,也被称为前馈神经网络。

首先看一下一个线性模型的一般公式:

                             y^ = w[0]*x[0]+w[1]*x[1]+...+w[p]*x[p]+b

其中y^表示对y的估计值,x[0]到x[p]是样本特征值,w表示每个特征值的权重,y-hat可以看成是所有特征值的加权求和。用下面这个图来表示这一过程。

 在MLP模型中,算法在过程里添加了隐藏层,然后在隐藏层重复进行上述加权求和计算,最后再把隐藏层所计算的结果用来生成最终结果,如下图所示:

 这样模型要学习的特征系数或者说权重,就会多很多了。在每一个输入的特征和隐藏单元之间都有一个系数,每个隐藏单元和最终结果之间也都有一个系数。

为了让模型变得比普通线性模型更强大,需要进行一些其他的处理:在生成隐藏层后,我们要对结果进行非线性矫正(relu)或者双曲正切处理(tanh)通过这两种方式处理后的结果来计算最终结果y。

接下来进行代码展示

import numpy as np
import  matplotlib.pyplot as plt

line = np.linspace(-5,5,200)
#生成一个等差数列

plt.plot(line,np.tanh(line),label='tanh')
plt.plot(line,np.maximum(line,0),label='relu')
#画出非线性矫正的图形表示

plt.legend(loc='best')
# 设置图注位置
plt.xlabel('x')
plt.ylabel('relu(x) and tanh(x)')
plt.show()

 根据图中信息可以看出,tanh函数把特征x的值压缩进到-1,1的区间内,-1代表的是x中较小的值,而1代表较大的值。relu函数则把小于0的x值全部去掉,用0代替,这样刚才的公式经过tanh处理后会变成:

 h[0]=tanh( w[0]*x[0]+w[1]*x[1]+...+w[p]*x[p]+b)

 h[1]=tanh( w[0]*x[0]+w[1]*x[1]+...+w[p]*x[p]+b)

 h[2]=tanh( w[0]*x[0]+w[1]*x[1]+...+w[p]*x[p]+b)

...

y^ = v[0]h[1]+v[1]h[1]+...+v[n]h[n]

在权重系数w之外,我们又多了一个权重系数v,用来通过隐藏层h来计算y-hat的结果

w,v都是通过对数据的学习得出的,用户要设置的参数就是隐藏层中节点的数量。在大量的数据中往往要添加更多的隐藏层,如下图所示:

 这也是后续要学习的“深度学习”中“深度”的来源


神经网络的参数设置

以MLP算法中的MLP分类器为例,研究一下该分类器模型的使用方法:

from sklearn.neural_network import MLPClassifier
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
wine = load_wine()
X = wine.data[:,:2]
y = wine.target
#下面拆分数据集
X_train,X_test,y_train,y_test = train_test_split(X,y,random_state=0)
#定义分类器 
mlp = MLPClassifier(solver='lbfgs')
mlp.fit(X_train,y_train)

在这里介绍一下hidden_layer_sizes参数,默认情况下值为【100,】意味着,模型中只有一个隐藏层,而隐藏层的节点数是100,如果将其定义为【10,10】那就意味着模型中有两个隐藏层,且每层有10个节点。接下来用图像展示一下MLP分类的情况:

import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap

#使用不同色块表示不同分类
cmap_light = ListedColormap(['#FFAAAA','#AAFFAA','#AAAAFF'])
cmap_blod = ListedColormap(['#FF0000','#00FF00','#0000FF'])
x_min,x_max = X_train[:,0].min()-1,X_train[:,0].max()+1
y_min,y_max = X_train[:,1].min()-1,X_train[:,1].max()+1
xx,yy = np.meshgrid(np.arange(x_min,x_max,.02),np.arange(y_min,y_max,.02))
Z = mlp.predict(np.c_[xx.ravel(),yy.ravel()])

Z = Z.reshape(xx.shape)
plt.figure()
plt.pcolormesh(X,yy,Z,cmap=cmap_light)

#将数据特征用散点图表示出来
plt.scatter(X[:.0],X[:,1],c=y,edgecolors='k',s=60)
plt.xlim(xx.min(),xx.max())
plt.ylim(yy.min(),yy.max())
plt.title("MLPClassifier:solver=lbfgs")
plt.show()

 接下来试着把隐藏层的节点数变少,将节点数变为10

节点数为10的时候,决定边界丢失了很多细节。在每一个隐藏层当中,节点数就代表了决定边界中最大的直线数,这个数值越大没决定边界看起来越平滑。增加隐藏层的数量和把activation参数改为tanh都可以让决定边界更细腻。 接下来试着增加隐藏层数量。

 接下来再使用cativation=‘tanh’

 这时边界完全变成了平滑的曲线,这就是对样本特征进行双曲线正切化后的结果,还可以通过调节alpha的值来进行模型复杂度控制。下面把alpha的值增加到1:

 增加alpha参数的值会加大模型正则化的程度,也就是会让模型更加的简单。在神经算法网络中,样本特征的权重是在模型开始学习前就已经随机生成的,而随机生成 的权重会导致模型的形态也完全不一样。只要模型的复杂度不变,期预测结果的准确率也不会受到什么影响。


神经网络实例----手写识别

from sklearn.datasets import fetch_openml
from sklearn.model_selection import train_test_split
from sklearn.neural_network import MLPClassifier
mnist = fetch_openml('mnist_784')
X,y = mnist["data"],mnist["target"]
X_train,X_test,y_train,y_test = train_test_split(X,y,train_size=5000,test_size=1000,random_state=62)

mlp_hw = MLPClassifier(solver='lbfgs',hidden_layer_sizes=[100,100],activation='relu',
                       alpha=1e-5,random_state=62)
mlp_hw.fit(X_train,y_train)
print('测试数据集得分:{:.2f}'.format(mlp_hw.score(X_test,y_test)*100))

接下来将测试图像转化为模型可读取的numpy数组 

from PIL import Image
image = Image.open('4.png').convert('F')
image = image.resize((28,28))
#调整图像大小
arr=[]
#将图像中的像素作为预测数据点的特征
for i in range(28):
    for j in range(28):
        pixel = 1.0 - float(image.getpixel((j,i)))/255.
        arr.append(pixel)

arr1 = np.array(arr).reshape(1,-1)
print('图中的数字式:{:,.0f}'.format(mlp_hw.predict(arr1)[0]))

输出结束

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值