深度学习pytorch--softmax回归(三)

前两篇链接:
深度学习pytorch–softmax回归(一)
深度学习pytorch–softmax回归(二)

本文使用框架来实现模型。

获取和读取数据

我们仍然使用Fashion-MNIST数据集和上一节中设置的批量大小。

#获取数据集
mnist_train=torchvision.datasets.FashionMNIST('./Datasets/FashionMNIST',train=True,download=False,transform=transforms.ToTensor())
mnist_test=torchvision.datasets.FashionMNIST('./Datasets/FashionMNIST',train=False,download=False,transform=transforms.ToTensor())

#读取数据集
batch_size=256
num_workers=0 #多进程加速数据读取,0则不使用多进程
train_iter = torch.utils.data.DataLoader(mnist_train, batch_size=batch_size, shuffle=True, num_workers=num_workers)
test_iter = torch.utils.data.DataLoader(mnist_test, batch_size=batch_size, shuffle=False, num_workers=num_workers)

定义和初始化模型

在softmax回归(一)中提到,softmax回归的输出层是一个全连接层,所以我们用一个线性模块就可以了。因为前面我们数据返回的每个batch样本x的形状为(batch_size, 1, 28, 28), 所以我们要先用view()x的形状转换成(batch_size, 784)才送入全连接层。

num_inputs = 784
num_outputs = 10

class LinearNet(nn.Module):   
    def __init__(self,num_inputs,num_outputs):
        super().__init__()
        self.linear=nn.Linear(num_inputs,num_outputs)
    def forward(self,x):
        y=self.linear(x.view(x.shape[0], -1)) #等价于view(-1,num_inputs),这里是因为不想再引入num_inputs参数所以换种形式写
        return y

net=LinearNet(num_inputs,num_outputs)

然后,我们使用均值为0、标准差为0.01的正态分布随机初始化模型的权重参数。

init.normal_(net.linear.weight, mean=0, std=0.01)
init.constant_(net.linear.bias, val=0) 

softmax和交叉熵损失函数

如果做了上一次实验,那么你可能意识到了分开定义softmax运算和交叉熵损失函数可能会造成数值不稳定。因此,PyTorch提供了一个包括softmax运算和交叉熵损失计算的函数。它的数值稳定性更好。

Cross_loss = nn.CrossEntropyLoss()

定义优化算法

我们使用学习率为0.1的小批量随机梯度下降作为优化算法。

optimizer = torch.optim.SGD(net.parameters(), lr=0.1)

模型评价

和上一实验一样

def evaluate_accuracy(data_iter,net): #在所有样本上的准确率
    acc_sum,n=0.0,0
    for X,y in data_iter:
        acc_sum+=(net(X).argmax(dim=1) == y).float().sum().item()
        n+=y.shape[0] #获取总数量(此处每批256)
    return acc_sum / n

训练模型

和上一实验步骤一样。

num_epochs = 5
for epoch in range(num_epochs):
    train_loss_sum=0.0
    train_acc_sum=0.0
    n=0 #用来计算数据总数

    for X,y in train_iter:
        y_hat=net(X)
        loss=Cross_loss(y_hat,y).sum()
        loss.backward()
        optimizer.step()
        optimizer.zero_grad()

        train_loss_sum+=loss.item()
        train_acc_sum+=(y_hat.argmax(dim=1) == y).sum().item()
        n+=y.shape[0]
    test_acc=evaluate_accuracy(test_iter,net)
    print('epoch {}, loss {:.4f}, train acc {:.3f}, test acc {:.3f}'
            .format(epoch + 1, train_loss_sum / n, train_acc_sum / n, test_acc))   

输出:

epoch 1, loss 0.0031, train acc 0.745, test acc 0.790
epoch 2, loss 0.0022, train acc 0.812, test acc 0.807
epoch 3, loss 0.0021, train acc 0.825, test acc 0.806
epoch 4, loss 0.0020, train acc 0.832, test acc 0.810
epoch 5, loss 0.0019, train acc 0.838, test acc 0.823

小结

  • PyTorch提供的函数往往具有更好的数值稳定性。
  • 可以使用PyTorch更简洁地实现softmax回归。

完整代码

#使用框架来实现softmax回归
import torch
import torchvision
import torchvision.transforms as transforms
import torch.nn as nn
from torch.nn import init 
import torch.optim as optim

#获取数据集
mnist_train=torchvision.datasets.FashionMNIST('./Datasets/FashionMNIST',train=True,download=False,transform=transforms.ToTensor())
mnist_test=torchvision.datasets.FashionMNIST('./Datasets/FashionMNIST',train=False,download=False,transform=transforms.ToTensor())

#读取数据集
batch_size=256
num_workers=0 #多进程加速数据读取,0则不使用多进程
train_iter = torch.utils.data.DataLoader(mnist_train, batch_size=batch_size, shuffle=True, num_workers=num_workers)
test_iter = torch.utils.data.DataLoader(mnist_test, batch_size=batch_size, shuffle=False, num_workers=num_workers)

#定义模型
num_inputs = 784
num_outputs = 10

class LinearNet(nn.Module):   
    def __init__(self,num_inputs,num_outputs):
        super().__init__()
        self.linear=nn.Linear(num_inputs,num_outputs)
    def forward(self,x):
        y=self.linear(x.view(x.shape[0], -1)) #等价于view(-1,num_inputs),这里是因为不想再引入num_inputs参数所以换种形式写
        return y

net=LinearNet(num_inputs,num_outputs)

#初始化模型参数
init.normal_(net.linear.weight, mean=0, std=0.01)
init.constant_(net.linear.bias, val=0) 

#softmax和交叉熵
Cross_loss = nn.CrossEntropyLoss() #包括了softmax运算和交叉熵损失计算s
#定义优化算法
optimizer = optim.SGD(net.parameters(), lr=0.1)
#模型评价
def evaluate_accuracy(data_iter,net): #在所有样本上的准确率
    acc_sum,n=0.0,0
    for X,y in data_iter:
        acc_sum+=(net(X).argmax(dim=1) == y).float().sum().item()
        n+=y.shape[0] #获取总数量(此处每批256)
    return acc_sum / n
#训练模型
num_epochs = 5
for epoch in range(num_epochs):
    train_loss_sum=0.0
    train_acc_sum=0.0
    n=0 #用来计算数据总数

    for X,y in train_iter:
        y_hat=net(X)
        loss=Cross_loss(y_hat,y).sum()
        loss.backward()
        optimizer.step()
        optimizer.zero_grad()

        train_loss_sum+=loss.item()
        train_acc_sum+=(y_hat.argmax(dim=1) == y).sum().item()
        n+=y.shape[0]
    test_acc=evaluate_accuracy(test_iter,net)
    print('epoch {}, loss {:.4f}, train acc {:.3f}, test acc {:.3f}'
            .format(epoch + 1, train_loss_sum / n, train_acc_sum / n, test_acc))      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值