前言:
神经网络(Neual Network)是一种模拟神经系统的计算模型,它由许多个互相连接的人工神经元组成,来处理复杂的输入和输出关系,我们都知道,神经元由树突、细胞体、轴突构成,那么我们不妨假设树突为输入端,中间的细胞体为处理函数,神经末梢为输出。
在构建过程中,输入系统处理数据尤为重要,那么不妨来用权值来实现,使用正确的权值可以影响预测能力和实用性。
在之前的学习中可以知道拟合是机器对数据学习的一种方式,那么在神经网络中,激活函数对输入信号进行非线性变换,可以拟合测试数据传入下一层神经元。
题目:
乳腺癌是以肿瘤形态危害女性健康的乳腺疾病;现有乳腺癌肿瘤数据,本例以此利用神经网络预测出相关患者乳腺癌肿瘤是良性还是恶性。
本例数据集采用SKL库内置乳腺癌样本集;其中,样本维数为30,良性与恶性样本数分别为357与212。其导入方法如下:
from sklearn.datasets import load_breast_cancer
x=cancer.data #特征向量
y=cancer.target #类别标记
请将数据划分为60%与40%的训练数据与测试数据并利用训练数据构建神经网络模型并求取测试数据的预测精度(利用柱状图比较数据归一与未归一化的模型精度)。
题解分析:
在本题中,要求我们采用skl.库中的内置乳腺癌本集,然后要求我们采用神经网络预测,输出测试精度,并求取归一化和为归一化的柱状图。在输入数据的过程中,依题干要求,我们需要向神经元(数据处理单元)输入归一化和未归一化的数据,调用多层感知机函数,系统模块自动学习拟合测试数据。在调用mlpclassifier函数时,它会使用反向传播算法来调整权重和偏置,以最小化损失函数。最后求取精度并创建柱状图。值得一提的是,多层感知机张使用的一种优化器算法就是梯度下降法。此外还可以选择不同的优化器:例如‘sgd’、‘adam’、‘lbfgs’等
实验步骤:
1、导入多层感知机和数据集
2、将数据集分为训练数据和测试数据
3、进行数据归一化处理,用于比较性能
4、创建多层感知机实例并设置参数(层数、节点、数量等)
5、拟合训练数据,用fit方法将训练数据传入模型
6、依题干要求评估测试数据的精度
实现过程:
导入科学计算库、导入绘图库
从datasets内置导入乳腺癌数据
导入分类数据模型、归一化处理函数
导入多层感知机
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn import preprocessing
from sklearn.neural_network import MLPClassifier
载入乳腺癌模型的训练数据X,y
分类成为训练数据和测试数据
x1_train等表示未经过归一化处理的数据x2_则表示归一化处理的数据,测试数据和训练数据比率为4:6
cancer = load_breast_cancer()
X,y = cancer.data,cancer.target
x1_train,x1_test,y1_train,y1_test = train_test_split(X,y,test_size=0.4)
X1 = preprocessing.scale(X)
x2_train,x2_test,y2_train,y2_test = train_test_split(X1,y,test_size=0.4)
------------从这里开始无关紧要,都是绘图与函数内容-----------
建立一个函数,可以实现不同的神经元个数,不同的激活函数,传入两个参数求取函数外部归一化和未归一化的训练数据的精度,并用测试数据测试,归一化后的数据精度用acc2表示,未归一化的数据精度用acc1表示hidden_layer_sizes 是神经元的个数,activation 则是激活函数的类型,用.fit 拟合测试数据,构建关于测试数据的模型,用.score求取测试精度。
def choi_func(nue_num,act_fun):
ann1 = MLPClassifier(solver='lbfgs',hidden_layer_sizes=(nue_num),activation=str(act_fun),random_state=1)
ann1.fit(x1_train,y1_train)
#未归一化处理的测试精度
acc1 = ann1.score(x1_test, y1_test)
#归一化处理的测试精度
ann2 = MLPClassifier(solver='lbfgs',hidden_layer_sizes=(nue_num),activation=str(act_fun),random_state=1)
ann2.fit(x2_train,y2_train)
#归一化处理后的结果
acc2 = ann2.score(x2_test,y2_test)
fprint(acc1,acc2,act_fun,nue_num)
用matplotlib库模块绘图,绘制未归一化(UNnor.)和归一化(nor.)关于精度的柱状图因为在上个函数的主体里,可以显示采用的神经元个数,激活函数。测试精度保留两位小数。
def fprint(a,b,c,d):
plt.figure()
plt.bar('UNnor.',a,color='r',width = 0.5,label = 'UnNormal')
plt.bar('nor.',b,color='b',width = 0.5,label = 'Normal')
plt.xlabel('{} Function | {} Neu.s'.format(c,d),color = 'y')
plt.ylabel('Accurate')
plt.title('Differ. from UNnor. and Nor.',color ='r')
plt.grid(True,color = 'black')
plt.legend(loc='upper left')
plt.text('UNnor.',a,format(a,'.2f'))
plt.text(1,b,format(b,'.2f'))
代码展示:
可以通过循环的方式构建多种,多神经元,多种激活函数的实现,并且可以展示精度。最后比较其归一化和未归一化的处理,总结实验。
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn import preprocessing
from sklearn.neural_network import MLPClassifier
#导入数据
cancer = load_breast_cancer()
X,y = cancer.data,cancer.target
#数据未归一化
x1_train,x1_test,y1_train,y1_test = train_test_split(X,y,test_size=0.4)
#数据归一化
X1 = preprocessing.scale(X)
x2_train,x2_test,y2_train,y2_test = train_test_split(X1,y,test_size=0.4)
def switch(nue_num,act_fun):
function = np.array(['identity','logistic','tanh','relu'])
if act_fun in function:
choi_func(nue_num, act_fun)
def choi_func(nue_num,act_fun):
ann1 = MLPClassifier(solver='lbfgs',hidden_layer_sizes=(nue_num),activation=str(act_fun),random_state=1)
ann1.fit(x1_train,y1_train)
#未归一化处理的测试精度
acc1 = ann1.score(x1_test, y1_test)
#归一化处理的测试精度
ann2 = MLPClassifier(solver='lbfgs',hidden_layer_sizes=(nue_num),activation=str(act_fun),random_state=1)
ann2.fit(x2_train,y2_train)
#归一化处理后的结果
acc2 = ann2.score(x2_test,y2_test)
fprint(acc1,acc2,act_fun,nue_num)
def fprint(a,b,c,d):
plt.figure()
plt.bar('UNnor.',a,color='r',width = 0.5,label = 'UnNormal')
plt.bar('nor.',b,color='b',width = 0.5,label = 'Normal')
plt.xlabel('{} Function | {} Neu.s'.format(c,d),color = 'y')
plt.ylabel('Accurate')
plt.title('Differ. from UNnor. and Nor.',color ='r')
plt.grid(True,color = 'black')
plt.legend(loc='upper left')
plt.text('UNnor.',a,format(a,'.2f'))
plt.text(1,b,format(b,'.2f'))
while True:
print('输入0退出')
print('请输入神经元个数:')
num = int(input())
if num == 0:
break
else:
print('请输入激活函数:')
fun = input()
switch(num, fun)
实验总结:
注意:因测试后的总结数据量过于庞大,将不给出实验后的预测精度的数据,请同学们自行练习
1、归一化和未归一化后的数据对求取精度的影响
在实验后,普遍的,未归一化的测试精度比归一化的测试精度来的差,这说明,归一化处理可以提高测试的精度,达到我们希望的预期,归一化处理可以消除数值间的量级差异,使得特征值的大小范围在相同的区间内,可以提高模型的稳定与收敛速度。
简单来说,那些非常异于常态化的训练数据和测试数据将在归一化处理后缩放,更加公平和准确,将更快达到收敛状态。
2、神经元个数对载入数据后求取测试数据精度的影响
在实验过程中,如果神经元的过多或者过少会导致在拟合训练数据的过拟合和欠拟合,当然过大的神经元个数在拟合的过程中会发生迭代错误(?在本次实验中不同的神经元对不同的激活函数的测试精度各不相同,在采用‘identity’激活函数时,精度随着神经元的个数愈来愈大,而‘tanh’激活函数则不然,且在使用不同激活函数统一神经元的个数的情况下,也造成了测试的预测精度各不相同,综上所述,选取合适的神经元个数和激活函数,能够提高多层感知模型的预测精度和泛化能力。
尾声:
在本次实验中,真的查阅了很多资料,而且因为我的高数不好,搞不懂多层感知机用梯度下降是如何实现的,应有很多不足的地方,欢迎各位同学批评指正!