多层感知机(神经网络)

一、感知机(逻辑回归、二分类)定义:

感知机其实就是一个逻辑回归模型,解决的是二分类问题。
逻辑回归模型其实就是加入了激活函数后的线性回归模型,加入激活函数的作用是使得输出层单一神经元的单一输出值限制在0和1之间,更适合于二分类问题。
在这里插入图片描述
感知机的训练过程同线性回归,只不过在线性回归的基础上输出之前加入了激活函数进行映射。

二、感知机不能解决XOR问题:

由于逻辑回归模型只能通过一条直线将样本数据划分为两个分类,因此对于下面的样本,无论如何训练模型,得到的决策边界都不能将样本正确的划分。
在这里插入图片描述
因此对于上述问题,应该如何解决?

答案是将多个逻辑回归模型堆叠多层,就能很好的解决上述问题,这就是多层感知机的由来。
在这里插入图片描述
其中黄色的逻辑回归模型、蓝色的逻辑回归模型将样本分别分为两类。最后通过灰色的逻辑回归模型使用蓝色黄色的输出特征作为输入将样本最终分为两类。

三、多层感知机定义:

多层感知机(神经网络)是逻辑回归和Softmax回归的推广,将逻辑回归和Softmax回归堆叠来解决原来单一模型不能解决的问题。其中隐藏层h1–h5为逻辑回归模型,用于根据输入特征分别解决一个二分类问题,输出层o1–o3组成一个Softmax回归模型,根据隐藏层输出的特征进行三分类问题的预测。

在这里插入图片描述

四、训练过程:

1.参数维度:

在这里插入图片描述

  • 输入层维度固定,由数据决定。
  • 隐藏层神经元个数是个超参数,因此隐藏层参数矩阵W、b的行数固定,由输入层维度决定,但是列数不固定,由神经元个数决定。
  • 输出层参数矩阵W、b的列数固定,由分类数目决定,但是行数不固定,由隐藏层神经元个数决定。

对于多隐藏层情况,每个隐藏层都有各自的W、b参数,其中隐藏层层数也是一个超参数。
在这里插入图片描述
注意每一层都是一个全连接层全连接层概念

2.常用激活函数:

2.1Sigmoid激活函数:

在这里插入图片描述

2.2Tanh激活函数:

在这里插入图片描述

2.3ReLU激活函数:

在这里插入图片描述

3.训练过程举例:******

以十分类模型的一次训练过程为例,其中隐藏层一层,隐藏层神经元个数为256:
1.获取一个batch,里面包含batch_size张图片。
2.将batch_size张图片展成一维(例如24×24的图片展成784),获得输入维度为:batch_size×784×1(图片数×特征维度[784×1])。
3.隐藏层参数W维度计算为784×256,参数b维度计算为1×256。
4.每张图片的所有特征分别输入隐藏层的各个神经元hi及其激活函数计算预测值yi,一张图片的输出维度为256×1,隐藏层对整个batch的输出维度为batch_size×256×1,作为输出层输入(隐藏层相当于提取特征)。
5.输出层参数W维度计算为256×10,参数b维度计算为1×10。
6.将隐藏层输出特征矩阵作为隐藏层输入,输出层是一个softmax回归模型。
7.接下来的操作同softmax回归,每个1×256×1的特征分别作为输入计算预测值,输出维度1×10的预测结果。
8.整个batch中的输出组合成维度batch_size×10。
9.使用softmax回归将输出映射成概率,维度为batch_size×10,并且每行概率之和为1。
10.使用交叉熵损失函数计算batch中所有图片的概率损失,并取均值。
11.反向传播算法计算各个参数wmn、bn关于损失函数的梯度。
12.梯度下降算法修改参数值。
13.输入下一个batch进行训练。

五、底层代码实现:

import torch
from torch import nn
from d2l import torch as d2l
# 1.获取数据,封装成一个dataloader
batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)

num_inputs, num_outputs, num_hiddens = 784, 10, 256# 实现的多层感知机,其中隐藏层数为1,隐藏层中神经元个数为256
# 2.初始化参数值
# 隐藏层(全连接层)
W1 = nn.Parameter(
    torch.randn(num_inputs, num_hiddens, requires_grad=True) * 0.01)# 可学习参数W维度为 num_inputs×num_hiddens
b1 = nn.Parameter(torch.zeros(num_hiddens, requires_grad=True))# 可学习参数b维度为1×num_hiddens
# 输出层
W2 = nn.Parameter(
    torch.randn(num_hiddens, num_outputs, requires_grad=True) * 0.01)# 可学习参数W维度为num_hiddens×num_outputs
b2 = nn.Parameter(torch.zeros(num_outputs, requires_grad=True))# 可学习参数b维度为1×num_outputs

params = [W1, b1, W2, b2]

# 3.实现激活函数
def relu(X):
    a = torch.zeros_like(X)
    return torch.max(X, a)

# 4.损失函数
loss = nn.CrossEntropyLoss()

# 5.实现模型
def net(X):
    X = X.reshape((-1, num_inputs))#将输入X拉成二维矩阵,即batch_size×num_inputs(这里把特征拉成一维)
    H = relu(X @ W1 + b1)# 隐藏层
    return (H @ W2 + b2)# 输出层

# 6.训练过程
num_epochs, lr = 10, 0.1
updater = torch.optim.SGD(params, lr=lr)
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, updater)

六、Pytorch版代码:

import torch
from torch import nn
from d2l import torch as d2l

# 1.网络架构
net = nn.Sequential(nn.Flatten(),# 将输入数据展平
                    nn.Linear(784, 256),# 隐藏层为全连接层
                    nn.ReLU(),# 隐藏层输出需经过激活函数
                    nn.Linear(256, 10)# 输出层也是全连接层
                    )
# 2.初始化参数
def init_weights(m):
    if type(m) == nn.Linear:
        nn.init.normal_(m.weight, std=0.01)

net.apply(init_weights);

# 3.训练过程
batch_size, lr, num_epochs = 256, 0.1, 10
loss = nn.CrossEntropyLoss()
trainer = torch.optim.SGD(net.parameters(), lr=lr)

train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, trainer)
### Python 实现多层感知机 (MLP) 神经网络 为了构建一个多层感知机(MLP),可以利用现有的强大库,如 TensorFlow 或 PyTorch;然而,在此示例中,将展示如何使用较为基础的方式通过 NumPy 来实现一个简单的 MLP 模型[^1]。 下面是一个基本的两层全连接神经网络(即具有单隐藏层的多层感知器),该网络接受二维输入并输出一维预测值: ```python import numpy as np class NeuralNetwork: def __init__(self, input_size=2, hidden_size=3, output_size=1): # 初始化权重矩阵和偏置向量 self.W1 = np.random.randn(input_size, hidden_size) self.b1 = np.zeros(hidden_size) self.W2 = np.random.randn(hidden_size, output_size) self.b2 = np.zeros(output_size) def sigmoid(self, z): """Sigmoid activation function""" return 1 / (1 + np.exp(-z)) def forward(self, X): """ 前向传播计算过程 参数: X : 输入特征矩阵 返回: y_pred : 预测结果 """ h = self.sigmoid(np.dot(X, self.W1) + self.b1) y_pred = self.sigmoid(np.dot(h, self.W2) + self.b2) return y_pred # 创建实例对象 nn = NeuralNetwork() # 测试前向传播功能 X_test = np.array([[0.5, 0.8]]) y_output = nn.forward(X_test) print(f'Predicted Output: {y_output}') ``` 这段代码定义了一个名为 `NeuralNetwork` 的类来表示我们的简单神经网络结构。它包含了两个主要部分:初始化随机分配给各层之间的连接权值以及执行前馈运算的方法——`forward()` 函数用于接收一批样本作为输入,并返回这批样本对应的预测标签。 在这个例子中选择了 Sigmoid 作为激活函数应用于每一层之后的结果上。值得注意的是实际应用时可能还需要考虑加入反向传播算法来进行训练阶段中的梯度更新操作[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

姓蔡小朋友

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值