【Pytorch深度学习实践】B站up刘二大人之SoftmaxClassifier-代码理解与实现(8/9)

这是刘二大人系列课程笔记的倒数第二个博客了,介绍的是多分类器的原理和代码实现,下一个笔记就是basicCNN和advancedCNN了;

写在前面:

  • 这节课的内容,主要是两个部分的修改:
    • 一是数据集:直接采用了内置的MNIST的数据集,那dataloaderdataset自然也是内置的,那也就不用自己写dataset再去继承Dataset类;
    • 再有是把traintest写成了函数形式,直接在main函数当中调用即可;
  • 除了本节课想要实现的代码,刘老师在本节课前一半讲了这些内容:
    • 下了很大功夫讲清楚了softmax这个函数的机理:y_pred = np.exp(z) / np.exp(z).sum();
    • 还有交叉熵损失函数是什么一回事,非常流畅简洁地给我讲懂了这个公式的意思:loss = (- y * np.log(y_pred)).sum();
    • 根据这两个函数的理论,用numpy的计算法则把公式实现了,之后才去调用了pytorch当中写好了的函数;
    • 还强调了NLL-Loss的概念,并且留了思考题,为什么会:CrossEntropyLoss <==> LogSoftmax + NLLLoss?
    • 到了pytorch当中,里面有SoftmaxSoftmax_log两个函数版本;
    • 总结来说,刘老师的课讲的非常透彻,不过,还是那句话,这并不是初学者一遍就能听懂的,要么有点基础,要么就得多听几遍。我想,最关键的要把握住:这节课讲了什么,是从numpy开始实现,还是调用pytorch调用已经写好的函数直接实现;他们的原理是一样,不过在代码里的表示还有很大不同。这只是我的一点感受。最后,再次感谢刘洪普老师的分享,收获非常大,受教了!

Lecture09 —— SoftmaxClassifier 多分类器的实现

说在前面:

  • 这节课的内容,主要是两个部分的修改:
    • 一是数据集:直接采用了内置的MNIST的数据集,那dataloaderdataset自然也是内置的,那也就不用自己写dataset再去继承Dataset类;
    • 再有是把traintest写成了函数形式,直接在main函数当中调用即可;
  • 除了本节课想要实现的代码,刘老师在本节课前一半讲了这些内容:
    • 下了很大功夫讲清楚了softmax这个函数的机理:y_pred = np.exp(z) / np.exp(z).sum();
    • 还有交叉熵损失函数是什么一回事,非常流畅简洁地给我讲懂了这个公式的意思:loss = (- y * np.log(y_pred)).sum();
    • 根据这两个函数的理论,用numpy的计算法则把公式实现了,之后才去调用了pytorch当中写好了的函数;
    • 还强调了NLL-Loss的概念,并且留了思考题,为什么会:CrossEntropyLoss <==> LogSoftmax + NLLLoss?
    • 到了pytorch当中,里面有SoftmaxSoftmax_log两个函数版本;

完整代码:

#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
@author: 24_nemo
@file: 09_SoftmaxClassifier_handType.py
@time: 2022/04/11
@desc:
"""

import torch
from torchvision import transforms
from torchvision import datasets
from torch.utils.data import DataLoader
import torch.nn.functional as F
import torch.optim as optim

batch_size = 64
transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.1307,), (0.3081,))
])

train_dataset = datasets.MNIST(root='../dataset/mnist',
                               train=True,
                               download=True,
                               transform=transform)

train_loader = DataLoader(train_dataset,
                          shuffle=True,
                          batch_size=batch_size)

test_dataset = datasets.MNIST(root='../dataset/mnist/',
                              train=False,
                              download=True,
                              transform=transform)

test_loader = DataLoader(test_dataset,
                         shuffle=False,
                         batch_size=batch_size)


class Net(torch.nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.l1 = torch.nn.Linear(784, 512)
        self.l2 = torch.nn.Linear(512, 256)
        self.l3 = torch.nn.Linear(256, 128)
        self.l4 = torch.nn.Linear(128, 64)
        self.l5 = torch.nn.Linear(64, 10)

    def forward(self, x):
        x = x.view(-1, 784)
        x = F.relu(self.l1(x))
        x = F.relu(self.l2(x))
        x = F.relu(self.l3(x))
        x = F.relu(self.l4(x))
        return self.l5(x)


model = Net()

criterion = torch.nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5)


def train(epoch):
    running_loss = 0.0
    for batch_size, data in enumerate(train_loader, 0):
        inputs, target = data
        optimizer.zero_grad()  # 在优化器优化之前,进行权重清零;

        outputs = model(inputs)
        loss = criterion(outputs, target)
        loss.backward()
        optimizer.step()

        running_loss += loss.item()
        if batch_size % 300 == 299:
            print('[%d, %5d] loss: %.3f' % (epoch + 1, batch_size + 1, running_loss / 300))


def test():
    correct = 0
    total = 0
    with torch.no_grad():
        for data in test_loader:
            images, labels = data
            outputs = model(images)
            _, predicted = torch.max(outputs.data, dim=1)
            total += labels.size(0)
            correct += (predicted == labels).sum().item()
    print('Accuracy on test set: %d %%' % (100 * correct / total))


if __name__ == '__main__':
    for epoch in range(100):
        train(epoch)
        test()

运行结果(截图时仍在运行):

【Pytorch深度学习实践】B站up刘二大人之SoftmaxClassifier-代码理解与实现(8/9)_第1张图片

这些东西记下来:

  • 这就是开头说的,利用numpy的计算规则,把交叉熵函数实现的例子,代码里还包含softmax的函数实现,虽然知识一行代码,却解开了我困扰很久不能理解的问题。
import torch
y = torch.LongTensor([0])
z = torch.Tensor([[0.2, 0.1, -0.1]])
criterion = torch.nn.CrossEntropyLoss()
loss = criterion(z, y)
print(loss)

结果:

【Pytorch深度学习实践】B站up刘二大人之SoftmaxClassifier-代码理解与实现(8/9)_第2张图片

上一篇:

【Pytorch深度学习实践】B站up刘二大人之Dataset&DataLoader-代码理解与实现(7/9)

下一篇:

【Pytorch深度学习实践】B站up刘二大人之BasicCNN & Advanced CNN -代码理解与实现(9/9)

目录:

【Pytorch深度学习实践】B站up刘二大人课程笔记——目录与索引(已完结)

你可能感兴趣的:(深度学习/PyTorch,Python/Pycharm,图像处理,深度学习,python,计算机视觉)