花书学习Day1:实现softmax回归

大部分借鉴了花书的代码,使用的数据集是FashionMNIST,其图像为2828像素,为方便学习与理解,将其展平为2828=784,由于数据集有十类,因此设置为10个输出。

import torch
import torch.optim as optim
from torch import nn
if __name__ == '__main__':
    batch_size = 256
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    train_iter, test_iter = load_data_fashion_mnist(batch_size)
    net = nn.Sequential(nn.Flatten(), nn.Linear(784, 10))
    def init_weights(m):
        if isinstance(m, nn.Linear):
            nn.init.normal_(m.weight, mean=0, std=0.01)
    net.apply(init_weights)
    loss = nn.CrossEntropyLoss()
    optimizer = optim.SGD(net.parameters(), lr=0.1)
    num_epochs = 10
    net.to(device)
    loss.to(device)
    for epoch in range(num_epochs):
        for X, y in train_iter:
            X = X.to(device)
            y = y.to(device)
            l = loss(net(X).to(device), y)
            optimizer.zero_grad()
            l.backward()
            optimizer.step()
    X, y = next(iter(test_iter))
    X = X.to(device)
    y = y.to(device)
    with torch.no_grad():
        net.eval()
        probs = torch.softmax(net(X).to(device), dim=1)
        print(accuracy(probs, y) / len(y))

在写代码时,发现似乎代码中没有显式地使用softmax层进行分类,因此询问DeepSeek,了解到nn.CrossEntropyLoss()实际内部会自动地隐式执行softmax运算,等价于先对net(X)应用LogSoftmax,再计算负对数似然损失NLLLoss,因此上述net和loss可换为:
python3[] net=nn.Sequential(nn.Flatten(), nn.Linear(784, 10), nn.Softmax(dim=1)) l = nn.NLLLoss()
上述代码中,读取数据集的代码和计算准确度的代码如下所示:
`python3[]
def accuracy(y_hat, y):
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 load_data_fashion_mnist(batch_size, resize=False): #@save
trans=[transforms.ToTensor()]
if resize:
trans.insert(0, transforms.Resize(resize))
trans = transforms.Compose(trans)
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)
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()))
`

posted @ 2026-07-15 10:34  muzili51  阅读(6)  评论(0)    收藏  举报