【Python与机器学习 7-1】人工神经网络 ANN——MLP

神经网络基本组成

神经网络由输入层(input layer),隐藏层(hidden layers),输出层(output layer)三部分组成,如下图。
输入层(input layer)是由训练集的样本特征向量传入。
每层由神经元(neuron)或单元(unit)组成。
这里写图片描述
经过连接节点的权重(weight)传入下一层,上一层的输出是下一层的输入,一层中的加权求和,然后根据非线性方程转化为下一层的输入。

即一个神经元,可以把它分成左半球和右半球两部分。左半球为上一层加权求和的结果,为此神经元的输入。右半球为加权求和结果即左半球值通过非线性方程转化后的值,为此神经元的输出。

激活函数

这个非线性方程就是激活函数,通过激活函数就可以把线性的值转成非线性的值。
常用的激活函数有三种,Sigmoid,Tanh和ReLU。其中sklearn中神经网络默认选择的是ReLU。

下图为这三种激活函数的结果,可以看出:Sigmoid和Tanh都是曲线,Sigmoid是把x归一化到0到1范围,Tanh归一化到-1到1范围。ReLU是折线,若x<0则输出0,否则y=x。
这里写图片描述

MLP (Multi-Layer Perceptron) 多层感知器

单层MLP

MLP为多层感知器,我们首先来看只有一个隐含层的MLP,如下图。
和上面介绍过的一样,h0的输入值就是x0*w00+x1*w10+x2*w20+x3*w30,输出值就是用激活函数,即tanh(x0*w00+x1*w10+x2*w20+x3*w30)。
最后y的值就是前一层即隐含层的权重和。
这里写图片描述

多层MLP

多层MLP也就是有多个隐含层
这里写图片描述

sklearn中使用MLP

初始化模型

ann_model = MLPClassifier(hidden_layer_sizes=[unit,], activation=’logistic’, solver=’lbfgs’, random_state=0)

训练模型

ann_model.fit(X_train, y_train)

参数:

  • hidden_layer_sizes: 隐藏层个数,为一个列表,列表的长度为隐藏层的个数,列表中第i个位置上的数为第i个隐藏层的神经元个数
  • activation: 为激活函数,relu, logistic, tanh
  • solver:优化算法,lbfgs, sgd, adam。adam适用于较大的数据集,lbfgs适用于较小的数据集。

①ANN建模

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.linear_model import LogisticRegression

# 加载数据集
fruits_df = pd.read_table('fruit_data_with_colors.txt')

X = fruits_df[['width', 'height']]
y = fruits_df['fruit_label'].copy()

# 将不是apple的标签设为0
y[y != 1] = 0
# 分割数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=1/4, random_state=0)

②单层ANN(MLP)

from sklearn.neural_network import MLPClassifier
from ml_visualization import plot_class_regions_for_classifier

# 神经元个数
units = [1, 10, 100]
for unit in units:
    # 激活函数:relu, logistic, tanh
    # 优化算法:lbfgs, sgd, adam。adam适用于较大的数据集,lbfgs适用于较小的数据集。
    #初始化模型
    ann_model = MLPClassifier(hidden_layer_sizes=[unit], activation='logistic', solver='lbfgs', random_state=0)
    #训练模型
    ann_model.fit(X_train, y_train)
    print('神经元个数={},准确率:{:.3f}'.format(unit, ann_model.score(X_test, y_test)))
    #用自己写的函数画出下图
    plot_class_regions_for_classifier(ann_model, X_test.values, y_test.values, title='Unit={}'.format(unit))

结果:
上面的代码结果只有下图的第一行,第二行是把激活函数换成relu得到的结果,可以看到每层的节点个数越多,模型越复杂,越复杂就会导致过拟合现象。因此就要使用正则化防止过拟合,下面将介绍ANN如何防止过拟合。
这里写图片描述

③ 多层ANN
多层ann也就是把hidden_layer_sizes=[10, 10],这个参数的列表中多放几个数,放几个数就有几层

ann_model = MLPClassifier(hidden_layer_sizes=[10, 10], activation='relu', solver='lbfgs', random_state=0)
ann_model.fit(X_train, y_train)
print('准确率:{:.3f}'.format(ann_model.score(X_test, y_test)))
plot_class_regions_for_classifier(ann_model, X_test.values, y_test.values)

结果:
这里写图片描述

ANN过拟合

使用正则化防止ANN过拟合

sklearn中 alpha为正则化强度

我们通过下面的例子来看正则化对模型复杂度的影响

# alpha
aplhas = [0.001, 0.01, 0.1, 1.0]
for alpha in aplhas:
    ann_model = MLPClassifier(hidden_layer_sizes=[100, 100], activation='tanh', solver='lbfgs', random_state=0,
                             alpha=alpha)
    ann_model.fit(X_train, y_train)
    print('alpha={},准确率:{:.3f}'.format(alpha, ann_model.score(X_test, y_test)))
    plot_class_regions_for_classifier(ann_model, X_test.values, y_test.values, title='Alpha={}'.format(alpha))

从结果可以看到alpha值越大,模型越复杂,即正则化的程度越低
这里写图片描述

展开阅读全文

没有更多推荐了,返回首页