softmax识别FashionMNIST数据集代码详解

softmax回归

一、softmax用来干什么?

  1. 单一的线性模型只能处理二分类问题,对于多分类问题,引入softmax回归

  2. 线性回归模型适用于输出为连续值的情景。在另一类情景中,模型输出可以是一个像图像类别这样的离散值。对于这样的离散值预测问题,我们可以使用诸如softmax回归在内的分类模型。和线性回归不同,softmax回归的输出单元从一个变成了多个,且引入了softmax运算使输出更适合离散值的预测和训练

二、代码

1.引入库

import torch
import torchvision.transforms as transforms
import matplotlib.pyplot as plt
import torchvision
from d2l import torch as d2l

train_data=torchvision.datasets.FashionMNIST(root='~/data',train=True,download=True,transform=transforms.ToTensor())
test_data=torchvision.datasets.FashionMNIST(root='~/data',train=False,download=True,transform=transforms.ToTensor())

说明1、train_data,test_data,分别是FashionMNIST数据集的训练集和测试集,其中对于下载下来的图像集,需要把它转换为tensor类型,否则返回的是PIL图像,并且此时的尺寸由(H W C)变为(C H W)

2.验证第一张图像的尺寸和类别

print(train_data[0][0].shape,train_data[0][1])
#torch.Size([1, 28, 28])  9

3.展示前十张图片

def show_images(images):
    plt.Figure()
    _,figs = plt.subplots(1,10,figsize=(12,12))# 这里的_表示我们忽略(不使用)的变量
    #plt.subplots(a,b,size)表示生成a行b列个子图,并且大小为size
    for f, img in zip(figs,images):#zip,将生成一个[(figs,images)]的迭代器
        f.imshow(img.view(28,28).numpy())#imshow()实现热图绘制
        f.axes.get_xaxis().set_visible(False)#不显示该子图的x坐标和y坐标
        f.axes.get_yaxis().set_visible(False)
    plt.show()

x=[]
for i in range(20):
    x.append(train_data[i][0])
show_images(x)
#标签名字懒得百度了

在这里插入图片描述

4.设置批量大小为256

batch_size=256
#将训练集和测试集每次读取256张图片,也可以开多个进程来读取数据
train_iter=torch.utils.data.DataLoader(train_data, batch_size, shuffle=True)
test_iter=torch.utils.data.DataLoader(test_data,batch_size,shuffle=False)
for x,y in train_iter:
    print(x.shape,y.shape)
    break

在这里插入图片描述

5.参数初始化

num_inputs=784
num_outputs=10
w=torch.normal(0,0.01,size=(num_inputs,num_outputs),requires_grad=True)#784*10
b=torch.ones(num_outputs,requires_grad=True)#10*1
lr=0.1

6.定义线性模型,softmax模型,损失函数,准确度,梯度下降函数

def linear(x,w,b):
    return (torch.mm(x.view(-1,num_inputs),w)  + b)
    #在第四步可以看到x.shape=([256,1,28,28])-->x.shape([256,784])
    #这里的-1是根据最后一个维度的num_inputs值自动算出的
    #相乘之后矩阵为256*10,对应的是该批量大小中每张图片对应的十个输出 return 256*10

def softmax(y):
    y_exp=y.exp()
    partition=y_exp.sum(dim=1,keepdim=True)#按行求和,并保持原来维度不变,否则维度不满足广播机制,y_exp/p会报错
    return y_exp / partition  #返回的size 还是256*10

def cross_entropy(y_hat,y):
    return -torch.log(y_hat[range(len(y_hat)), y])/len(y) #len(y_hat)和len(y)的值都是256
    #这里运用了掩模mask ,根据Pi*log(Qi)其中p是i对应的真实值(只有0,1),q是i对应的预测值
    #运用mask所以选择正确值所对应的预测值,再除以均值(图像个数len(y) or len(y_hat))

def evaluate_accuracy(data_iter,params):
    acc_sum,n=0.0,0
    #思想很简单 所有正确的值的个数/总个数
    for x,y in data_iter:
        acc_sum += (softmax(linear(x,w,b)).argmax(dim=1)==y).float().sum().item()
        n += len(y)
    return acc_sum / n

def sgd(params,lr):
    with torch.no_grad():
        for param in params:
            param -= lr * param.grad
            param.grad.zero_()
#一定得用 -=  如果用 param=param- 返回的地址已经变了,也就是param 不再是叶子结点 会出错

这里有with torch.no_grad解释

7.训练模型

def Train(train_iter, test_iter,w,b,lr):
    for epoch in range(4): 
        train_loss,train_acc,=0.0,0.0
        for x,y in train_iter:
            y_hat=softmax(linear(x,w,b))
            loss=cross_entropy(y_hat,y)
            loss.sum().backward()
            sgd([w,b],lr)
        train_loss = loss.sum().item()
        train_acc = evaluate_accuracy(train_iter,[w,b])
        test_acc = evaluate_accuracy(test_iter, [w,b])
        print('epoch %d,loss %.4f, train_acc %.4f,test_acc %.4f' %(epoch+1,train_loss, train_acc, test_acc))

Train(train_iter,test_iter,w,b,lr)

因为学习率设置为了0.1,所以第一遍的训练结果就达到了78.7%,测试结果达到了77.7%
大家可以多尝试不同 lr,测试一下
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Lins H

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

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

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

打赏作者

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

抵扣说明:

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

余额充值