任务描述

本关任务:用sklearn构建神经网络模型,并通过鸢尾花数据集中鸢尾花的4种属性与种类对神经网络模型进行训练。我们会调用你训练好的神经网络模型,来对未知的鸢尾花进行分类。

相关知识

为了完成本关任务,你需要掌握:1.神经网络是如何训练,2.前向传播,3.反向传播,4.sklearn中的神经网络。

数据集介绍

鸢尾花数据集是一类多重变量分析的数据集。通过花萼长度,花萼宽度,花瓣长度,花瓣宽度4个属性预测鸢尾花卉属于(SetosaVersicolourVirginica)三个种类中的哪一类。

想要使用该数据集可以使用如下代码:

 
  1. #获取训练数据
  2. train_data = pd.read_csv('./step2/train_data.csv')
  3. #获取训练标签
  4. train_label = pd.read_csv('./step2/train_label.csv')
  5. train_label = train_label['target']
  6. #获取测试数据
  7. test_data = pd.read_csv('./step2/test_data.csv')

数据集中部分数据与标签如下图所示:

神经网络是如何训练

神经网络的训练方法跟逻辑回归相似:

也是使用梯度下降算法来更新模型的参数,既然要使用梯度下降算法,就要知道损失函数对参数的梯度。在神经网络中,由于有多层的网络,所以使得我们的网络非常不好训练,这么多参数的梯度求起来非常麻烦。反向传播算法出现,为我们解决了这一个问题,它能够快速的计算这些梯度。反向传播算法一共分为两部分:前向传播与反向传播。

前向传播

前向传播指的是数据x从神经网络输入层,与当层的权重相乘,再加上当层的偏置,所得到的值经过激活函数激活后,再输入到下一层。最后,在输出层所得到的值经过softmax函数转化为网络对数据的预测。

Z[1]=XW[1]+B[1]

A[1]=f(Z[1])

Z[2]=A[1]W[2]+B[2]

A=softmax(Z[2])

其中,输出层的Z值要经过softmax函数,转化为预测值。softmax函数公式如下:

ak​=sumi=1n​exp(zi​)exp(zk​)​

输出层的A为预测值,是一个向量。有多少类别,A就有多长。隐藏层的A[L]为激活值,L代表是第L层隐藏层。W为权重,是一个矩阵,上一层神经网络有多少个神经元,它就有多少行,当层神经网络有多少神经元,它就有多少列。B为偏置,是一个向量,长度与当层神经元个数一样。神经网络使用的损失函数为交叉熵损失函数:

其中ai​代表样本被预测为第i个类别的可能性,yi​代表样本为第i个类别的真实可能性。交叉熵损失函数公式如下:

L(y,a)=−sumi=1n​yi​lnai​

前向传播的主要目的就是得到预测值,再算出交叉熵损失函数。

交叉熵

交叉熵(cross entropy)是深度学习中常用的一个概念,一般用来求目标与预测值之间的差距。机器学习是用网络训练出来的分布q来表示真实分布p,此时当两者的交叉熵越小时,模型训练的结果越接近样本的真实分布,这也是交叉熵被用来作为损失函数的原因。

在机器学习中,P往往用来表示样本的真实分布,比如[1,0,0]表示当前样本属于第一类。Q用来表示模型所预测的分布,比如[0.7,0.2,0.1]直观的理解就是如果用P来描述样本,那么就非常完美。而用Q来描述样本,虽然可以大致描述,但是不是那么的完美,信息量不足,需要额外的一些“信息增量”才能达到和P一样完美的描述。如果我们的Q通过反复训练,也能完美的描述样本,那么就不再需要额外的“信息增量”,Q等价于P

反向传播

我们通过前向传播能够求出损失函数,而反向传播就是利用前向传播得到的损失函数对参数求梯度,即每个参数的偏导。

之所以称为反向传播,是因为我们在利用链式法则的时候对各个参数求偏导的传播顺序跟前向传播相反,如我们要求loss对w1​的偏导,则要先求出lossa的偏导,再求出a对z2的偏导,再求出z2对a1的偏导,再求出a1对z1的偏导,再求出z1对w1的偏导,然后全部相乘就得到loss对w1​的偏导了。公式如下:

partialw[1]partialloss​=partiala[2]partialloss​.partialz[2]partiala[2]​.partiala[1]partialz[2]​.partialz[1]partiala[1]​.partialw[1]partialz[1]​

所以反向传播的目的就是求出损失函数对各个参数的梯度。最后我们就可以用梯度下降算法来训练我们的神经网络模型了。

sklearn中的神经网络

MLPClassifier的构造函数中有四个常用的参数可以设置:

  • solverMLP的求解方法lbfs在小数据上表现较好,adam较为鲁棒,sgd在参数调整较优时会有最佳表现(分类效果与迭代次数);sgd标识随机梯度下降;

  • alpha:正则项系数,默认为L2正则化,具体参数需要调整;

  • hidden_layer_sizeshidden_layer_sizes=(3, 2)设置隐藏层size2层隐藏层,第一层3个神经元,第二层2个神经元。

  • max_iter:最大训练轮数。

sklearn中其他分类器一样,MLPClassifier类中的fit函数用于训练模型,fit函数有两个向量输入:

  • X:大小为**[样本数量,特征数量]**的ndarray,存放训练样本;

  • Y:值为整型,大小为**[样本数量]**的ndarray,存放训练样本的分类标签。

MLPClassifier类中的predict函数用于预测,返回预测标签,predict函数有一个向量输入:

  • X:大小为**[样本数量,特征数量]**的ndarray,存放预测样本。

MLPClassifier的使用代码如下:

 
  1. from sklearn.neural_network import MLPClassifier
  2. mlp = MLPClassifier(solver='lbfgs',max_iter =10,
  3. alpha=1e-5,hidden_layer_sizes=(3,2))
  4. mlp.fit(X_train, Y_train)
  5. result = mlp.predict(X_test)

编程要求

使用sklearn构建神经网络模型,利用训练集数据与训练标签对模型进行训练,然后使用训练好的模型对测试集数据进行预测,并将预测结果保存到./step2/result.csv中。保存格式如下:

测试说明

我们会获取你的预测结果与真实标签对比,预测正确率高于95%视为过关。


开始你的任务吧,祝你成功!

#encoding=utf8
import os
import pandas as pd

if os.path.exists('./step2/result.csv'):
    os.remove('./step2/result.csv')
    
#********* Begin *********#
#获取训练数据
train_data = pd.read_csv('./step2/train_data.csv')
#获取训练标签
train_label = pd.read_csv('./step2/train_label.csv')
train_label = train_label['target']
#获取测试数据
test_data = pd.read_csv('./step2/test_data.csv')
from sklearn.neural_network import MLPClassifier#调用MLP
mlp = MLPClassifier(solver='lbfgs',max_iter =10,
           alpha=1e-5,hidden_layer_sizes=(3,2))#直接复制的题目,没改参数
mlp.fit(train_data, train_label)
result = mlp.predict(test_data)
save_df = pd.DataFrame({'result':result})
save_df.to_csv('./step2/result.csv',index=0)#保存
#********* End *********#

如果不能通过的话修改一下 mlp=MLPClassifier()里参数的值,比如

#encoding=utf8
import os
import pandas as pd

if os.path.exists('./step2/result.csv'):
    os.remove('./step2/result.csv')
    
#********* Begin *********#
#获取训练数据
train_data = pd.read_csv('./step2/train_data.csv')
#获取训练标签
train_label = pd.read_csv('./step2/train_label.csv')
train_label = train_label['target']
#获取测试数据
test_data = pd.read_csv('./step2/test_data.csv')
from sklearn.neural_network import MLPClassifier#调用MLP
mlp = MLPClassifier(solver='lbfgs',max_iter =30,
           alpha=1e-4,hidden_layer_sizes=(20,))#
mlp.fit(train_data, train_label)
result = mlp.predict(test_data)
save_df = pd.DataFrame({'result':result})
save_df.to_csv('./step2/result.csv',index=0)#保存

solver:权重优化算法,lbfgs、sgd、adam。

max_iter:最大迭代次数。

alpha:正则化项参数。

hidden_layer_sizes:tuple,第i个元素表示第i个隐藏层的神经元个数。

 

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐