【深度学习】从感知机到多层感知机,以及多层感知机(MLP)的实现

一、感知机

感知机是一个二分类的单层网络模型。
在这里插入图片描述
感知机模型的表达式为:
o ^ = { 1 , < ω ⃗ , x ⃗ > + b > 0 0 , < ω ⃗ , x ⃗ > + b ≤ 0 \hat{o}=\begin{cases}1,<\vec{\omega},\vec{x}>+b>0\\0,<\vec{\omega},\vec{x}>+b\le 0\end{cases} o^={1,<ω ,x >+b>00,<ω ,x >+b0可以看出,感知机的特点是输出只有0和1,输出的是离散值,感知机的损失函数为:
ι ( ω ⃗ , b ) = { 1 , − o ^ × o > 0 0 , − o ^ × o ≤ 0 \iota(\vec{\omega},b)=\begin{cases}1,-\hat{o}\times o>0\\0,-\hat{o}\times o\le 0\end{cases} ι(ω ,b)={1,o^×o>00,o^×o0其中, o ⃗ \vec{o} o 是真实标签。损失函数相当于拿计算的结果与真实的标签作比较,发现符号相反就输出1(分类失败),发现符号相同就输出0(分类成功)。之后,对损失函数求偏导进行梯度下降更新权重和偏差,损失函数就会一直往0去下降,从而令判断越来越准确。
但是,这种单层的感知机有一个致命的问题,它只能分割线性空间(从表达式中也可以看出来),如果样本按照XOR(异或)函数的样子进行分布,是无法分割开来的。(假设样本有二维的特征,那么下图中的样本分布,感知机是无法分割的。无论怎么分割都无法用一条线将红色和绿色分开)。 这种缺陷使得1969年感知机被提出之后一直不被重视。
在这里插入图片描述

二、多层感知机

十多年之后,多层感知机被提出,才解决了单层感知机不能拟合XOR函数的问题。
在这里插入图片描述
还是假设样本有两个特征。既然单层感知机只能分割出一个平面,那就构造两个单层感知机,这样就能分割出两个平面,这两个平面共同作用(这种作用不能是线性组合,而是另外的非线性作用)得到一个最终的结果,这个结果就可以表示XOR。如图所示。可以看到,网络的第一层分别是两个单层感知机。第二层将两个单层感知机的结果进行了组合。将第一层称为隐藏层。每个隐藏层的大小是一个超参数,隐藏层的数量也是一个超参数。多层感知机经过感知机的叠加,能够划分出非线性空间。但是这种叠加不是普通的线性叠加。下面来解释激活函数就能够明白。

2.1、激活函数

所谓激活,就是将输入隐藏层的线性组合的结果利用非线性函数转化一下再进行输出,非线性函数就被称为激活函数。为什么隐藏层中要使用激活函数进行激活呢?因为如果不激活,隐藏层输出的将会是一个线性组合,整个网络拟合出的函数还是一个线性空间。试想一个网络,添加了很多个隐藏层,但是都没有激活,最终的输出结果还是一个线性组合!那么隐藏层相当于没加(这种现象叫做层数坍塌)。这个网络还是最简单的线性分割,是无法划分非线性空间的。

上边的多层感知机,隐藏层输出之前,会经过激活函数(阶跃函数)的变换,这样隐藏层神经单元输出的值再次进行线性组合即可拟合出XOR函数。
详解:异或运算的运算规则完全可以由与运算和或运算代替:
x ⊕ y = x × y ‾ + x ‾ × y x\oplus y=x\times \overline{y}+\overline{x}\times y xy=x×y+x×y加号代表或运算,乘号代表与运算。单层感知机的结果经过阶跃函数的激活是可以拟合出与运算的,而两个与运算进行线性组合又可以表示或运算。 多层感知机经过反复输出预测值、计算损失、梯度下降之后,第一层的两个单层感知机就会逐渐变成与运算,而第二层会逐渐变成或运算。这就是多层感知机能够拟合出XOR函数的本质。

除了阶跃函数之外,还有以下函数是非常常见的激活函数:

sigmoid函数

在这里插入图片描述

tanh函数

在这里插入图片描述

ReLU函数

在这里插入图片描述

softmax函数

softmax函数在我写的上一篇文章中有详细介绍。

三、实战——pytorch实现多层感知机解决多分类问题

接下来,我们使用构建拥有一层隐藏层的多层感知机,并使用ReLU作为激活函数,训练一个多层感知机模型来解决多分类问题。

import torch
import matplotlib.pyplot as plt
import numpy as np
from torch.utils import data
from torchvision import datasets
from torchvision import transforms
from torch import nn


def get_train_test_loader(image_size=28, train_batch_size=10, test_batch_size=10, num_workers=0, is_download=True):
    """
    获得训练数据生成器和验证数据生成器,这个数据集总共有10个类别(即10个标签)
    :param image_size: 图片的大小,取28
    :param train_batch_size: 数据生成器的批量大小
    :param num_workers: 数据生成器每次读取时调用的线程数量
    :param is_download: 是否要下载数据集(如果还未下载设置为True)
    :return: 训练数据生成器和验证数据生成器
    """
    data_transform = transforms.Compose([
        # 设置图片大小
        transforms.Resize(image_size),
        # 转化为tensor张量
        transforms.ToTensor()
    ])

    train_data = datasets.FashionMNIST(root='../data', train=True, download=is_download, transform=data_transform)
    test_data = datasets.FashionMNIST(root='../data', train=False, download=is_download, transform=data_transform)
    train_loader = data.DataLoader(train_data, batch_size=train_batch_size, shuffle=True, num_workers=num_workers,
                                   drop_last=True)
    test_loader = data.DataLoader(test_data, batch_size=test_batch_size, shuffle=False, num_workers=num_workers,
                                  drop_last=True)
    return train_loader, test_loader


def accuracy(y_hat, y):
    """模型训练完成后,判断预测结果的准确率"""
    if y_hat.shape[0] < 2 and y_hat.shape[1] < 2:
        raise ValueError("dimesion error")
    # 得到预测的y_hat每一行中最大概率所在的索引(索引即类别)
    y_hat = y_hat.argmax(axis=1)
    # 判断预测类别是否与实际类别相等
    judge = y_hat.type(y.dtype) == y
    # 现在cmp是一个bool类型的向量,转成0和1,统计1的数量
    return float(judge.type(y.dtype).sum()) / len(y)


def init_weights(m):
    """将网络中每一个线性层的所有权重都利用标准差为0.01的正态分布进行初始化,b没有初始化,所以初始为0"""
    if type(m) == nn.Linear:
        nn.init.normal_(m.weight, std=0.01)


# 学习率
lr = 0.03
# 批量大小
batch_size = 100
test_batch_size = 10000
# 最开始一个展平层用来给输入的x整形,接下来第一层是线性层,结果经过RuLU激活之后,进入下一个线性层,之后结果进行输出。隐藏层共有392个神经元
net = nn.Sequential(nn.Flatten(), nn.Linear(784, 392), nn.ReLU(), nn.Linear(392, 10))
# apply会将net中的每一层都作为参数进入init_weights,当发现是线性层,会对线性层的w自动初始化
net.apply(init_weights)
# 损失函数是交叉熵函数,参数是y_hat和y,注意,会对传入的y_hat先进行一次softmax处理
loss = nn.CrossEntropyLoss()
# 梯度下降
trainer = torch.optim.SGD(net.parameters(), lr=lr)

# 获取数据生成器以及数据
train_loader, test_loader = get_train_test_loader(train_batch_size=batch_size, test_batch_size=test_batch_size,
                                                  is_download=False)
train_loader_test, _ = get_train_test_loader(train_batch_size=60000, is_download=False)
# 学习代数
num_epoch = 10

# 用来正常显示中文标签
plt.rcParams['font.sans-serif'] = ['SimHei']
# 用来正常显示负号
plt.rcParams['axes.unicode_minus'] = False
# 交互模式
plt.ion()
fig = plt.figure()
ax = fig.add_subplot()
ax.grid(True, axis="y")
epoch_x, validate_accuracy_y, test_accuracy_y, loss_y = [], [], [], []
line_validate, = ax.plot(epoch_x,validate_accuracy_y,color='black',linestyle="--",label="训练集准确率")
line_test, = ax.plot(epoch_x,test_accuracy_y,color='blue',label="测试集准确率")
line_loss, = ax.plot(epoch_x,loss_y,color='red',label="损失函数")
ax.set(xticks=np.arange(0,12,1),xlim=(0,11),yticks=np.arange(0,1.1,0.1),ylim=(0,1))
ax.legend()


for i in range(num_epoch):
    epoch_x.append(i + 1)
    for x, y in train_loader:
        # 模型得到预测值
        y_hat = net(x)
        # 损失函数
        l = loss(y_hat, y)
        print(f"\r{batch_size}个批量样本损失为{l}", end="", flush=True)
        trainer.zero_grad()
        # 求偏导
        l.backward()
        # 梯度下降
        trainer.step()
    with torch.no_grad():
        for x, y in train_loader_test:
            y_hat = net(x)
            l = loss(y_hat, y)
            loss_y.append(l)
            print(f"\n第{i}代,所有训练样本损失为{l}")
            validate_accuracy = accuracy(y_hat, y)
            print(f"验证集预测正确率:{validate_accuracy}")
            validate_accuracy_y.append(validate_accuracy)
        for x, y in test_loader:
            test_accuracy = accuracy(net(x), y)
            print(f"测试集预测正确率:{test_accuracy}")
            test_accuracy_y.append(test_accuracy)
        print("=" * 25)
        line_validate.set_data(epoch_x,validate_accuracy_y)
        line_test.set_data(epoch_x,test_accuracy_y)
        line_loss.set_data(epoch_x,loss_y)
        plt.draw()
        plt.pause(0.1)
plt.ioff()
plt.show()

效果如图所示:
在这里插入图片描述

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
课程导语:    人工智能可谓是现阶段最火的行业,在资本和技术协同支持下正在进入高速发展期。当今全球市值前五大公司都指向同一发展目标:人工智能。近几年,人工智能逐渐从理论科学落地到现实中,与生活越来越息息相关,相关的各种职位炙手可热,而深度学习更是人工智能无法绕开的重要一环。 从AlphaGo打败李世石开始,深度学习技术越来越引起社会各界的广泛关注。不只学术界,甚至在工业界也取得了重大突破和广泛应用。其中应用最广的研究领域就是图像处理和自然语言处理。而要入门深度学习,CNN和RNN作为最常用的两种神经网络是必学的。网上关于深度学习的资料很多,但大多知识点分散、内容不系统,或者以理论为主、代码实操少,造成学员学习成本高。本门课程将从最基础的神经元出发,对深度学习的基础知识进行全面讲解,帮助大家迅速成为人工智能领域的入门者,是进阶人工智能深层领域的基石。 讲师简介:赵辛,人工智能算法科学家。2019年福布斯科技榜U30,深圳市海外高层次人才(孔雀人才)。澳大利亚新南威尔士大学全奖博士,SCI收录其发表过的10篇国际期刊学术文章。曾任深圳市微埃智能科技有限公司联合创始人。CSDN人工智能器学习、深度学习方向满分级精英讲师。授课风格逻辑严谨、条理清晰、循序渐进、循循善诱,化枯燥为如沐春风,所教学生人数过万。 课程设计: 本课程分为5大模块,19小节,共计540时长(约9小时): 第一部分,课程介绍、目标与内容概览。主要学习人工智能深度学习应用场景;熟悉深度学习主流技术;掌握使用keras解决深度学习主要问题(神经网络、卷积神经网络、循环神经网络),以及深度学习主要内容:神经网络、卷积神经网络、循环神经网络;案例简介。 第二部分,深度学习之多层感知器(MLP)。主要学习多层感知器(MLP);MLP实现非线性分类;深度学习实战准备;Python调用keras实现MLP。 MLP技术点实战案例:第三部分,深度学习之卷积神经网络(CNN)。主要学习卷积神经网络 ; CNN模型分析;主流CNN模型; Python调用keras实现CNN; CNN技术点实战案例:第四部分,深度学习之循环神经网络(RNN)。主要学习循环神经网络;RNN模型分析;Python调用keras实现RNN。 RNN技术点实战案例: 第五部分,综合提升。主要进行迁移学习;混合模型;实战准备+综合实战,以及最后进行课程内容总结。 混合模型技术点实战案例
mlp多层感知与深度学习密切相关。深度学习是一种器学习的方法,它基于神经网络的多层结构进行建模和训练。多层感知(MLP)是最简单的神经网络结构之一,也是深度学习中常用的模型之一。 MLP由多个计算层组成,包括输入层、若干个隐层和输出层。每个隐层都由多个隐单元组成,而隐单元的个数是根据数据集的复杂度来确定的。对于简单的数据集,可以选择较少的隐单元,而对于复杂的数据集,可以选择更多的隐单元,甚至可以添加多个隐层。 例如,当我们使用MLP进行分类任务时,可以使用两个隐层,每个隐层都包含10个隐单元。这样的设置可以通过修改MLPClassifier类的hidden_layer_sizes属性来实现。具体的代码如下所示: ``` mlp = MLPClassifier(solver='lbfgs', random_state=0, hidden_layer_sizes=[10, 10]) ``` 这个设置意味着我们有两个隐层,每个隐层都有10个隐单元。 因此,通过使用MLP多层感知,我们可以实现深度学习中的模型构建和训练,以解决各种器学习问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [深度学习简介与MLP多层感知](https://blog.csdn.net/qq_43355223/article/details/86593078)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值