概述

受到生物学的启发,人工神经网络是由一系列简单的单元相互紧密联系构成的,每个单元有一定数量的实数输入和唯一的实数输出。神经网络的一个重要的用途就是接受和处理传感器产生的复杂的输入并进行自适应性的学习。人工神经网络算法模拟生物神经网络,是一种模式匹配算法,通常用于解决分类和回归问题。

传统神经网络结构比较简单,训练时随机初始化输入参数,并开启循环计算输出结果,与实际结果进行比较从而得到损失函数,并更新变量使损失函数结果值极小,当达到误差阈值时即可停止循环。

神经网络的训练目的是希望能够学习到一个模型,实现输出一个期望的目标值。学习的方式是在外界输入样本的刺激下不断改变网络的连接权值。传统神经网络主要分为以下几类:前馈型神经网络、反馈型神经网络和自组织神经网络。本实验主要讲解的是前馈型神经网络

前馈神经网络

前馈神经网络是一种单向多层的网络结构,即信息是从输入层开始,逐层向一个方向传递,一直到输出层结束。所谓“前馈”是指输入信号的传播为前向,在此过程中不断调整各层的权值参数,而反传播时是将误差逐层向后传递,从而实现使用权值参数对特征的记忆,即通过反向传播(BP)算法来计算法各层网络中神经元之间的权重。BP算法具有非线性映射能力,理论上可逼近连续函数,从而实现对模型的学习。
在这里插入图片描述

BP算法

神经网络的学习就是根据训练数据集来调整神经元之间的连接权重,以及每个功能神经元的阈值。

多层前馈神经网络的学习采用向传播(BP)算法,该算法的得到利用了导数的链式法则和sigmoid激活函数的性质。
在这里插入图片描述

实验步骤

1 安装并引入必要的库

在该实验中,我们使用的是scikit-learn自带的鸢尾花数据集iris进行分类。鸢尾花数据集一共有150个数据,分为三类,每类50个数据。每个数据包含4个属性:萼片长度、萼片宽度、花瓣长度、花瓣宽度。

!pip install numpy==1.16.0
!pip install scikit-learn==0.22.1
!pip install matplotlib==3.1.0

import numpy as np
from sklearn.neural_network import MLPClassifier 
from sklearn import datasets
import matplotlib.pyplot as plt
%matplotlib inline

2 数据处理

我们这里使用iris数据集的前两个属性sepal length和sepal width,因为两个特征方便在二维图形上表现;然后对数据进行混洗;最后取出最后的30个数据作为测试集。

iris = datasets.load_iris()
X = iris.data[:,0:2]
Y = iris.target
data = np.hstack((X,Y.reshape(Y.size,1)))
np.random.seed(0)
np.random.shuffle(data)
X = data[:,0:2]
Y = data[:,-1]
X_train = X[0:-30]
X_test = X[-30:]
y_train = Y[0:-30]
y_test = Y[-30:]

3 拟合预测

定义两个绘图函数:

plot_samples:用于绘制样本点

plot_classifier_predict_meshgrid:用于绘制分类器对平面上每个点进行分类预测的分布图

def plot_samples(ax,x,y):
    n_classes = 3
    plot_colors = "bry" # 颜色数组。每个类别的样本使用一种颜色
    for i, color in zip(range(n_classes), plot_colors):
        idx = np.where(y == i)
        ax.scatter(x[idx, 0], x[idx, 1], c=color,label=iris.target_names[i], cmap=plt.cm.Paired) # 绘图

def plot_classifier_predict_meshgrid(ax,clf,x_min,x_max,y_min,y_max):
    plot_step = 0.02 # 步长
    xx, yy = np.meshgrid(np.arange(x_min, x_max, plot_step),np.arange(y_min, y_max, plot_step))
    Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
    Z = Z.reshape(xx.shape)
    ax.contourf(xx, yy, Z, cmap=plt.cm.Paired) # 绘图

让我们利用scikit-learn提供的MLPClassifier()函数进行拟合预测,绘图分析。

fig=plt.figure()
ax=fig.add_subplot(1,1,1)
classifier=MLPClassifier(activation='logistic',max_iter=10000,hidden_layer_sizes=(30,))
classifier.fit(X_train,y_train)
train_score=classifier.score(X_train,y_train)
test_score=classifier.score(X_test,y_test)
x_min, x_max = X_train[:, 0].min() - 1, X_train[:, 0].max() + 2
y_min, y_max = X_train[:, 1].min() - 1, X_train[:, 1].max() + 2
plot_classifier_predict_meshgrid(ax,classifier,x_min,x_max,y_min,y_max)
plot_samples(ax,X_train,y_train)
ax.legend(loc='best')
ax.set_xlabel(iris.feature_names[0])
ax.set_ylabel(iris.feature_names[1])
ax.set_title("train score:%f;test score:%f"%(train_score,test_score))
plt.show()

在这里插入图片描述
从图中可以看到,分类器在训练数据上的预测精度为80.83%,在测试集上的预测精度为80%

4 调参

在这里插入图片描述

4.1 不同的隐含层对于多层神经网络分类器的影响

fig=plt.figure()
hidden_layer_sizes=[(10,),(30,),(100,),(5,5),(10,10),(30,30)] # 候选的 hidden_layer_sizes 参数值组成的数组
for itx,size in enumerate(hidden_layer_sizes):
    ax=fig.add_subplot(2,3,itx+1)
    classifier=MLPClassifier(activation='logistic',max_iter=10000,hidden_layer_sizes=size)
    classifier.fit(X_train,y_train)
    train_score=classifier.score(X_train,y_train)
    test_score=classifier.score(X_test,y_test)
    x_min, x_max = X_train[:, 0].min() - 1, X_train[:, 0].max() + 2
    y_min, y_max = X_train[:, 1].min() - 1, X_train[:, 1].max() + 2
    plot_classifier_predict_meshgrid(ax,classifier,x_min,x_max,y_min,y_max)
    plot_samples(ax,X_train,y_train)
    ax.legend(loc='best',fontsize='xx-small')
    ax.set_xlabel(iris.feature_names[0])
    ax.set_ylabel(iris.feature_names[1])
    ax.set_title("layer_size:%s" % str(size))
    print("layer_size:%s;train score:%.2f;test score:%.2f"%(size,train_score,test_score))
plt.show()

在这里插入图片描述

4.2 不同的激活函数对于多层神经网络分类器的影响

fig=plt.figure()
fig.set_size_inches(16,8)
ativations=["logistic","tanh","relu"]
for itx,act in enumerate(ativations):
    ax=fig.add_subplot(1,3,itx+1)
    classifier=MLPClassifier(activation=act,max_iter=10000,hidden_layer_sizes=(30,))
    classifier.fit(X_train,y_train)
    train_score=classifier.score(X_train,y_train)
    test_score=classifier.score(X_test,y_test)
    x_min, x_max = X_train[:, 0].min() - 1, X_train[:, 0].max() + 2
    y_min, y_max = X_train[:, 1].min() - 1, X_train[:, 1].max() + 2
    plot_classifier_predict_meshgrid(ax,classifier,x_min,x_max,y_min,y_max)
    plot_samples(ax,X_train,y_train)
    ax.legend(loc='best',fontsize='xx-small')
    ax.set_xlabel(iris.feature_names[0])
    ax.set_ylabel(iris.feature_names[1])
    ax.set_title("activation:%s" % act)
    print("activation:%s;train score:%.2f;test score:%.2f"%(act,train_score,test_score))
plt.show()

在这里插入图片描述
可以看到,不同的激活函数对性能有影响,但是相互之间没有显著差别。

4.3 优化算法对多层神经网络分类器的影响

fig=plt.figure()
fig.set_size_inches(16,8)
solvers=["lbfgs","sgd","adam"] 
for itx,solver in enumerate(solvers):
    ax=fig.add_subplot(1,3,itx+1)
    classifier=MLPClassifier(activation="tanh",max_iter=10000,hidden_layer_sizes=(30,),solver=solver)
    classifier.fit(X_train,y_train)
    train_score=classifier.score(X_train,y_train)
    test_score=classifier.score(X_test,y_test)
    x_min, x_max = X_train[:, 0].min() - 1, X_train[:, 0].max() + 2
    y_min, y_max = X_train[:, 1].min() - 1, X_train[:, 1].max() + 2
    plot_classifier_predict_meshgrid(ax,classifier,x_min,x_max,y_min,y_max)
    plot_samples(ax,X_train,y_train)
    ax.legend(loc='best',fontsize='xx-small')
    ax.set_xlabel(iris.feature_names[0])
    ax.set_ylabel(iris.feature_names[1])
    ax.set_title("solvers:%s" % solver)
    print("solvers:%s;train score:%.2f;test score:%.2f"%(solver,train_score,test_score))
plt.show()

在这里插入图片描述
可以看到,不同的优化算法对性能有影响,但是相互之间没有显著差别。

练习

根据本实验的调参的例子,考察learning_rate_init初始学习率对多层神经网络分类器的影响。

import numpy as np
from sklearn.neural_network import MLPClassifier 
from sklearn import datasets
import matplotlib.pyplot as plt
%matplotlib inline

def plot_samples(ax,x,y):
    n_classes = 3
    plot_colors = "bry" 
    for i, color in zip(range(n_classes), plot_colors):
        idx = np.where(y == i)
        ax.scatter(x[idx, 0], x[idx, 1], c=color,label=iris.target_names[i], cmap=plt.cm.Paired) 

def plot_classifier_predict_meshgrid(ax,clf,x_min,x_max,y_min,y_max):
    plot_step = 0.02 
    xx, yy = np.meshgrid(np.arange(x_min, x_max, plot_step),np.arange(y_min, y_max, plot_step))
    Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
    Z = Z.reshape(xx.shape)
    ax.contourf(xx, yy, Z, cmap=plt.cm.Paired) 

iris = datasets.load_iris()
X = iris.data[:,0:2]
Y = iris.target
data = np.hstack((X,Y.reshape(Y.size,1)))
np.random.seed(0)
np.random.shuffle(data)
X = data[:,0:2]
Y = data[:,-1]
X_train = X[0:-30]
X_test = X[-30:]
y_train = Y[0:-30]
y_test = Y[-30:]

fig=plt.figure()
etas=[0.1,0.01,0.001,0.0001]
for itx,eta in enumerate(etas):
    ax=fig.add_subplot(2,2,itx+1)
    classifier=MLPClassifier(activation="tanh",max_iter=1000000,hidden_layer_sizes=(30,),solver='sgd',learning_rate_init=eta)
    classifier.fit(X_train,y_train)
    train_score=classifier.score(X_train,y_train)
    test_score=classifier.score(X_test,y_test)
    x_min, x_max = X_train[:, 0].min() - 1, X_train[:, 0].max() + 2
    y_min, y_max = X_train[:, 1].min() - 1, X_train[:, 1].max() + 2
    plot_classifier_predict_meshgrid(ax,classifier,x_min,x_max,y_min,y_max)
    plot_samples(ax,X_train,y_train)
    ax.legend(loc='best',fontsize='xx-small')
    ax.set_xlabel(iris.feature_names[0])
    ax.set_ylabel(iris.feature_names[1])
    ax.set_title("etas:%s" % eta)
    print("etas:%s;train score:%.2f;test score:%.2f"%(etas,train_score,test_score))
plt.show()

在这里插入图片描述

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐