Skip to content

softmax回归的简单实现

深度学习框架的高级API能够使实现线性回归变得更加容易。 同样,通过深度学习框架的高级API也能更方便地实现softmax回归模型。

如 09-2节 所示,继续使用Fashion-MNIST数据集,并保持批量大小为256。

1. 导入所需库

python
import torch
import torchvision
from torch.utils import data
from torch import transforms

2. 读取小批量数据

定义一个数据导入函数。输入需要的批量大小和数据格式,即可得到相应的小批量训练集和测试集。

python
def load_data(batchsize,resize=None):
    trans = [transforms.ToTensor()]   #初始定义一个转化方式
    if resize:
        trans = trans.insert(0,transforms.Resize(resize))   
    trans = transforms.Compose(trans)
    #trans是一个列表,trans.insert(插入位置,插入的元素)表示在列表的指定位置插入新元素
    #transforms.Resize:用于调整图像的大小。可以接受一个或两个整数参数,分别代表目标图像的宽和高。
    #这句的目的是图像数据经过后续之前,先调整大小
    #transforms.Compose()整合所有的操作
 
    mnist_train = torchvision.dataset.FashionMNIST(root='.../data',train=True,download=False,transform=trans)    
    mnist_test = torchvision.dataset.FashionMNIST(root='.../data',train=False,download=False,transform=trans)
    #前面已经下载过数据,故download=False
 
    return data.DataLoader(mnist_train,batchsize,shuffle=True,num_workers=4),data.DataLoader(mnist_test,batchsize,shuffle=True,num_workers=4)
    #num_workers=4表示分配4个进程用于读取数据

在这里,我们获得256个样本的数据,数据格式不变。所以每次输出的一组训练集的大小为[256,1,28,28],测试集的大小为[256]

python
batch_size = 256
train_iter,test_iter = load_data(batch_size)

3. 初始化模型

python
from torch import nn
 
#定义回归函数
net = nn.Sequential(nn.Flatten(),nn.Linear(num_input,num_output))
#把数据拉直,即第二步中resize的作用
 
#初始化参数
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.01)

4. 训练模型并预测

python
num_epochs = 10
train_loss = []
train_acc = []
for epoch in range(num_epochs):
    metric = Accumulator(3)
    
    for x, y in train_iter:
        # 计算梯度并更新参数
        y_hat = net(x)
        l = loss(y_hat, y)
        #使⽤定制的优化器和损失函数
        trainer.zero_grad()
        l.mean().backward()
        trainer.step()
        metric.add(float(l.sum()), accuracy(y_hat, y), y.numel())
        # 返回训练损失和训练精度
    train_loss.append(metric[0] / metric[2])
    train_acc.append(metric[1] / metric[2])
    test = pred(test_iter)
    test_acc.append(test[0]/test[1])
    print("epoch:{}".format(epoch+1)+' '+'loss:{}'.format(metric[0] / metric[2]) + ' '+ 'acc:{}'.format(metric[1] / metric[2])

图片

京ICP备2024093538号-1