In [37]:
import numpy as np import torch from torch.utils import data import torchvision from torchvision import transforms from d2l import torch as d2l
In [ ]:
# 感知机 # 就是一个线性分类器 # 二分类: -1或者1 # 多分类: 多个二分类的结合
感知机收敛问题 [

](https://img2024.cnblogs.com/blog/3517150/202505/3517150-20250520231439442-176712619.png)
[

](https://img2024.cnblogs.com/blog/3517150/202505/3517150-20250520231439160-378259175.png)
多层感知机¶
In [ ]:
# XOR就是算法里面的异或运算 # 异或运算符是指: 参与运算的两个值,如果两个相应位相同,则结果为0,否则为1。即:0^0=0, 1^0=1, 0^1=1, 1^1=0 # 线性模型有局限性,比如它假设特征与输出是线性关系,这在很多实际情况中不成立,如体温与死亡率的关系、图像分类问题等。为克服线性模型的限制,可在网络中加入隐藏层,将多个全连接层堆叠在一起,形成多层感知机
单隐藏层¶
[

](https://img2024.cnblogs.com/blog/3517150/202505/3517150-20250520231439116-1060894686.png)
一堆激活函数¶
引入非线性:激活函数通过引入非线性,使得神经网络能够学习和表示复杂的模式和关系。如果没有激活函数,无论神经网络有多少层,它的表现力都相当于一个简单的线性模型。
增加模型的表达能力:通过使用不同的激活函数,神经网络可以更好地拟合训练数据,从而提高模型的准确性和泛化能力。
帮助缓解梯度消失问题:在深层神经网络中,反向传播时的梯度可能会变得非常小,导致难以训练。一些激活函数(如ReLU及其变体)有助于缓解这个问题。
加快训练速度:选择合适的激活函数可以加快神经网络的训练速度。例如,ReLU函数在正区间内斜率为1,能够有效加速训练过程。
保持数据的分布:某些激活函数(如tanh和sigmoid)可以将输入数据压缩到有限的范围内,有助于保持数据的分布,避免数值过大导致的计算不稳定。 [

](https://img2024.cnblogs.com/blog/3517150/202505/3517150-20250520231438925-233407951.png)
[

](https://img2024.cnblogs.com/blog/3517150/202505/3517150-20250520231438787-960874160.png) [

](https://img2024.cnblogs.com/blog/3517150/202505/3517150-20250520231438925-1554478135.png)
多类分类¶
定义:[

](https://img2024.cnblogs.com/blog/3517150/202505/3517150-20250520231438876-1966202942.png)
[

](https://img2024.cnblogs.com/blog/3517150/202505/3517150-20250520231438822-902829240.png)
总结¶
·多层感知机使用隐藏层和激活函数来得到非线性模型
·常用激活函数是Sigmoid,Tanh,ReLU
·使用Softmax来处理多类分类
·超参数为隐藏层数,和各个隐藏层大小
In [2]:
# 多层感知机的从零开始实现 batcch_size = 256 train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size=batcch_size)
In [3]:
# 实现一个具有单隐藏层的多层感知机,它包含256个隐藏单元 import torch.nn as nn num_inputs = 784 num_outputs = 10 num_hiddens1 = 256 W1=nn.Parameter(torch.randn(num_inputs, num_hiddens1, requires_grad=True) * 0.01) b1=nn.Parameter(torch.zeros(num_hiddens1, requires_grad=True)) W2=nn.Parameter(torch.randn(num_hiddens1, num_outputs, requires_grad=True) * 0.01) b2=nn.Parameter(torch.zeros(num_outputs, requires_grad=True)) params=[W1,b1,W2,b2]
In [4]:
# 实现ReLU激活函数 def relu(X): a = torch.zeros_like(X) return torch.max(X, a)
In [5]:
# 实现模型 def net(X): X=X.reshape((-1, num_inputs)) # 将X展平 H = relu(X @ W1 + b1) # 第一层全连接层 return (H @ W2 + b2) # 第二层全连接层 loss=nn.CrossEntropyLoss() # 交叉熵损失函数
In [35]:
# 以前的d2l自带的代码,运行使用 def accuracy(y_hat, y): #@save """计算预测正确的数量""" if len(y_hat.shape) > 1 and y_hat.shape[1] > 1: y_hat = y_hat.argmax(axis=1) cmp = y_hat.type(y.dtype) == y return float(cmp.type(y.dtype).sum()) class Accumulator: #@save """在n个变量上累加""" def __init__(self, n): self.data = [0.0] * n def add(self, *args): self.data = [a + float(b) for a, b in zip(self.data, args)] def reset(self): self.data = [0.0] * len(self.data) def __getitem__(self, idx): return self.data[idx] from IPython import display def evaluate_accuracy(net, data_iter): #@save """计算在指定数据集上模型的精度""" if isinstance(net, torch.nn.Module): net.eval() # 将模型设置为评估模式 metric = Accumulator(2) # 正确预测数、预测总数 with torch.no_grad(): for X, y in data_iter: metric.add(accuracy(net(X), y), y.numel()) return metric[0] / metric[1] def train_epoch_ch3(net, train_iter, loss, updater): #@save """训练模型一个迭代周期(定义见第3章)""" # 将模型设置为训练模式 if isinstance(net, torch.nn.Module): net.train() # 训练损失总和、训练准确度总和、样本数 metric = Accumulator(3) for X, y in train_iter: # 计算梯度并更新参数 y_hat = net(X) l = loss(y_hat, y) if isinstance(updater, torch.optim.Optimizer): # 使用PyTorch内置的优化器和损失函数 updater.zero_grad() l.mean().backward() updater.step() else: # 使用定制的优化器和损失函数 l.sum().backward() updater(X.shape[0]) metric.add(float(l.sum()), accuracy(y_hat, y), y.numel()) # 返回训练损失和训练精度 return metric[0] / metric[2], metric[1] / metric[2]
In [38]:
num_epochs = 10 lr = 0.01 updater = torch.optim.SGD(params, lr=lr) # 随机梯度下降优化器 # 训练模型 train_ch3(net, train_iter, test_iter, loss, num_epochs, updater) # 训练模型
[
](https://img2024.cnblogs.com/blog/3517150/202505/3517150-20250520231438646-714527379.svg)
In [ ]:
# softmax回归的简洁实现(https://zh.d2l.ai/chapter_linear-networks/softmax-regression-concise.html) import torch from torch import nn from d2l import torch as d2l batch_size = 256 train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size) # PyTorch不会隐式地调整输入的形状。因此, # 我们在线性层前定义了展平层(flatten),来调整网络输入的形状 net = nn.Sequential(nn.Flatten(), nn.Linear(784, 10)) def init_weights(m): if type(m) == nn.Linear: nn.init.normal_(m.weight, std=0.01) net.apply(init_weights); loss = nn.CrossEntropyLoss(reduction='none') trainer = torch.optim.SGD(net.parameters(), lr=0.1) num_epochs = 10 d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, trainer)
评论加载中…