1.3.Softmax回归

回归和分类

回归估计一个连续值

分类预测一个离散类别

Softmax回归实际是一个分类问题

在这里插入图片描述

从回归到多类分类

对类别进行一位有效编码

y = [ y 1 , y 2 , ⋯   , y n ] T y=[y_1,y_2,\cdots,y_n]^T y=[y1,y2,,yn]T,如果是第i类,则值为1,否则为0

使用均方损失训练,最大值预测为(即softmax函数)
y ^ = a r g m a x i   o i \hat y = argmax_i\ o_i y^=argmaxi oi
需要更置信的识别正确类(大余量):

o y − o i ≥ Δ ( y , i ) o_y -o_i\ge \Delta(y,i) oyoiΔ(y,i)

校验比例

输出匹配概率(非负,和为1)
y ^ = s o f t m a x ( o ) y ^ i = e x p ( o i ) ∑ k e x p ( o k ) \hat y = softmax(o)\\ \hat y_i =\frac{exp(o_i)}{\sum_k exp(o_k)} y^=softmax(o)y^i=kexp(ok)exp(oi)
概率 y y y y ^ \hat y y^的区别作为损失

交叉熵损失

交叉熵用来衡量两个概率的区别 H ( p , q ) = ∑ i − p i l o g ( q i ) H(p,q)=\sum_i - p_ilog(q_i) H(p,q)=ipilog(qi)

将它作为损失函数:
l ( y , y ^ ) = − ∑ i y i l o g y ^ i = − l o g y ^ y (假设是第 y 类) l(y,\hat y)=-\sum_i y_ilog\hat y_i = -log \hat y_y (假设是第y类) l(y,y^)=iyilogy^i=logy^y(假设是第y类)
​ 关心正确类的预测值

其梯度是真实概率和预测概率的区别
∂ o i l ( y , y ^ ) = s o f t m a x ( o ) i − y i \partial_{o_i}l(y,\hat y) =softmax(o)_i -y_i oil(y,y^)=softmax(o)iyi

损失函数

均方损失(L2 Loss)


l ( y , y ′ ) = 1 2 ( y − y ′ ) 2 l(y,y')=\frac 12 (y-y')^2 l(y,y)=21(yy)2
​ 在梯度下降时,预测值与真实值相差较远时,梯度会较大,但在离原点比较远时,可能并不希望有较大的梯度,这种情况下可以使用L1 Loss。

绝对值损失(L1 Loss)

l ( y , y ′ ) = ∣ y − y ′ ∣ l(y,y')=|y-y'| l(y,y)=yy

​ 好处就是,无论离原点多远,梯度下降时的导数都是正负1,但在比较接近时,可能就出现振荡了

Huber’s Robust Loss

​ 结合两种的好处
1

读取多类分类的数据集

图像分类数据集

​ 使用Fashion-MNIST数据集

import torch
import torchvision
from torch.utils import data
from torchvision import transforms
from d2l import torch as d2l

# 看一下图片的形状

def get_fashion_mnist_labels(labels):
    """返回Fashion-MNIST数据集的文本标签"""
    text_labels = [
        't-shirt', 'trouser', 'pullover', 'dress', 'coat', 'sandal', 'shirt', 'sneaker', 'bag', 'ankle boot'
    ]

    return [text_labels[int(i)] for i in labels]


def show_images(imgs, num_rows, num_cols, titles=None, scale=1.5):
    "画图"
    figsize = (num_cols * scale, num_rows * scale)
    fig, axes = d2l.plt.subplots(num_rows, num_cols, figsize=figsize)
    axes = axes.flatten()
    for i, (ax, img) in enumerate(zip(axes, imgs)):
        if torch.is_tensor(img):
            # 是图片张量
            ax.imshow(img.numpy())
        else:
            # PIL图片
            ax.imshow(img)
        ax.axes.get_xaxis().set_visible(False)
        ax.axes.get_yaxis().set_visible(False)
        if titles:
            ax.set_title(titles[i])
    d2l.plt.show()  # 加上show图片才会显示
    return axes


def get_dataloader_workers():
    '''使用4个进程来读取数据'''
    return 4


def load_data_fashion_mnist(batch_size, resize=None):  #resize可以改变图片的大小
    """下载Fashion-MNIST数据集,然后将其加载到内存中"""
    trans = [transforms.ToTensor()]# 将图片转换成tensor
# 将图片下载,train表示是训练数集,transform表示是tensor而不是图片,download表示从网上下载
    if resize:
        trans.insert(0, transforms.Resize(resize))
    trans = transforms.Compose(trans)
    # 将图片下载,train表示是训练数集,transform表示是tensor而不是图片,download表示从网上下载
    mnist_train = torchvision.datasets.FashionMNIST(
        root="./data", train=True, transform=trans, download=True)
    # 训练数据集的下载,则train是False
    mnist_test = torchvision.datasets.FashionMNIST(
        root="./data", train=False, transform=trans, download=True)
    print(len(mnist_train))
    print(len(mnist_test))
    print(mnist_train[0][0].shape)  # 黑白图片,所以channel为1,train[0]表示取第一个元素,第二个[0]表示是取图片,[1]表示取标签
    return (data.DataLoader(mnist_train, batch_size, shuffle=True,
                            num_workers=get_dataloader_workers()),
            data.DataLoader(mnist_test, batch_size, shuffle=False,
                            num_workers=get_dataloader_workers()))

d2l.use_svg_display()  # 使用svg来显示图片
# 通过ToTenseor实例将图像数据从PIL类型变换成32位浮点数格式
# 并除以255使得所有像素的值均在0到1之间

# 将数据集放进dataloader里面,指定一个batch_size,我们就可以得到一个批次的数据
X, y = next(iter(data.DataLoader(mnist_train, batch_size=18)))
# show_images(X.reshape(18, 28, 28), 2, 9, titles=get_fashion_mnist_labels(y))

batch_size = 256

train_iter = data.DataLoader(mnist_train, batch_size=batch_size, shuffle=True, num_workers=get_dataloader_workers())
timer = d2l.Timer()
for X, y in train_iter:
    continue

print(f'{timer.stop():.2f} seconds')
  • 45
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值