文章目录

3.2、softmax 回归3.2.1、softmax运算3.2.2、交叉熵损失函数3.2.3、PyTorch 从零实现 softmax 回归3.2.4、简单实现 softmax 回归

3.2、softmax 回归

3.2.1、softmax运算

softmax 函数是一种常用的激活函数,用于将实数向量转换为概率分布向量。它在多类别分类问题中起到重要的作用,并与交叉熵损失函数结合使用。

y

^

=

s

o

f

t

m

a

x

(

o

)

     其中    

y

^

i

=

e

x

p

(

o

j

)

k

e

x

p

(

o

k

)

\hat{y} = softmax(o) \ \ \ \ \ 其中\ \ \ \ \hat{y}_i = \frac{exp(o_j)}{\sum_{k}exp(o_k)}

y^​=softmax(o)     其中    y^​i​=∑k​exp(ok​)exp(oj​)​

其中,

o

o

o为小批量的未规范化的预测,

y

^

\hat{y}

y^​为输出概率,是一个正确的概率分布【

y

i

=

1

\sum{y_i} =1

∑yi​=1 】

3.2.2、交叉熵损失函数

通过测量给定模型编码的比特位,来衡量两概率分布之间的差异,是分类问题中常用的 loss 函数。

H

(

P

,

Q

)

=

Σ

P

(

x

)

l

o

g

(

Q

(

x

)

)

H(P, Q) = -Σ P(x) * log(Q(x))

H(P,Q)=−ΣP(x)∗log(Q(x))

真实概率分布是从哪里得知的? 真实标签的概率分布是由数据集中的标签信息提供的,通常使用单热编码表示。 softmax() 如何与交叉熵函数搭配的? softmax 函数与交叉熵损失函数常用于多分类任务中。softmax 函数用于将模型输出转化为概率分布形式,交叉熵损失函数用于衡量模型输出概率分布与真实标签的差异,并通过优化算法来最小化损失函数,从而训练出更准确的分类模型。

3.2.3、PyTorch 从零实现 softmax 回归

(非完整代码)

#在 Notebook 中内嵌绘图

%matplotlib inline

import torch

import torchvision

from torch.utils import data

from torchvision import transforms

from d2l import torch as d2l

#,将图形显示格式设置为 SVG 格式,以在 Notebook 中以矢量图形的形式显示图像。这有助于提高图像的清晰度和可缩放性。

d2l .use_svg_display()

在线下载数据集 Fashion-MNIST

#将图像数据转换为张量形式

trans = transforms.ToTensor()

mnist_train = torchvision.datasets.FashionMNIST(root="../data"

,train=True,transform=trans,download=True)

mnist_test = torchvision.datasets.FashionMNIST(root="../data"

,train=False,transform =trans,download=True)

len(mnist_train),len(mnist_test)

绘图(略)

读取小批量数据集

batch_size = 256

def get_dataloader_workers():

"""使用4进程读取"""

return 4

train_iter = data.DataLoader(mnist_train,batch_size,shuffle=True,

num_workers=get_dataloader_workers())

timer = d2l.Timer()

for X,y in train_iter:

continue

print(f'{timer.stop():.2f}sec')

定义softmax操作

def softmax(X):

X_exp = torch.exp(X)

partition = X_exp.sum(1, keepdim=True)

return X_exp / partition # 这里应用了广播机制

定义损失函数

def cross_entropy(y_hat, y):

return - torch.log(y_hat[range(len(y_hat)), y])

cross_entropy(y_hat, y)

分类精度

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())

评估

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]

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]

3.2.4、简单实现 softmax 回归

导入前面已下载数据集 Fashion-MNIST

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)

初始化模型

#nn.Flatten() 层的作用是将输入数据展平,将二维输入(如图像)转换为一维向量。因为线性层(nn.Linear)通常期望接收一维输入。

#nn.Linear(784,10) 将输入特征从 784 维降低到 10 维,用于图像分类问题中的 10 个类别的预测 784维向量->10维向量

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);

#计算交叉熵损失函数,用于衡量模型预测与真实标签之间的差异。参数 reduction 控制了损失的计算方式。

#reduction='none' 表示不进行损失的降维或聚合操作,即返回每个样本的独立损失值。

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)

文章链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: