Pytorch之简洁版Softmax多分类

上一篇文章中,我们自己手动实现了对于softmax操作和交叉熵的计算,可其实这些在Pytorch框架中已经被实现了,我们直接拿来使用即可。但是,为了能够对这些内容有着更深刻的理解,通常我们都会自己手动实现一次,然后在今后的使用中就可以直接拿现成的来用了。在接下来这篇文章中,笔者将首先介绍如何调用Pytorch中的交叉熵损失函数,然后再同时借助nn.Linear()来实现一个简洁版的Softmax回归。

1 交叉熵损失函数

在前一篇文章中,我们首先分别自己实现了softmax和交叉熵的操作;然后再将两者结合实现了交叉熵损失函数的计算过程。但其实这两步通过Pytorch中的CrossEntropyLoss()就能实现。

def softmax(x):
    s = torch.exp(x)
    return s / torch.sum(s, dim=1, keepdim=True)

def crossEntropy(y_true, logits):
    c = -torch.log(logits.gather(1, y_true.reshape(-1, 1)))
    return torch.sum(c)

logits = torch.tensor([[0.5, 0.3, 0.6], [0.5, 0.4, 0.3]])
y = torch.LongTensor([2, 1])
c = crossEntropy(y, softmax(logits)) / len(y)
print(c)

loss = torch.nn.CrossEntropyLoss(reduction='mean')  
# 返回的均值是除以的每一批样本的个数(不一定是batchsize,因为最后一个Batch的样本可能很少)
cc = loss(logits, y)
print(cc)

#结果:
tensor(1.0374)
tensor(1.0374)

从上述代码可以看出,仅仅用Pytorch中的两行代码就能实现我们需要的功能。同时,需要注意的是当CrossEntropyLoss中指定参数reduction='mean'时,返回的均值是总损失除以输入的样本数量,而不是batchsize或者batchsize*cc表示类别数)。

2 实现Softmax分类模型

在上一篇文章中,我们已经实现了用于载入数据的函数loadDataset(),用于计算分类准确率的函数accuracy()以及用于模型评估(本质上也是准确计算)的函数evaluate()。因此,接下来我们只需要用Pytorch封装好的API实现网络模型即可。

2.1 Softmax模型实现

def train():
    input_nodes = 28 * 28
    output_nodes = 10
    epochs = 5
    lr = 0.1
    batch_size = 256
    train_iter, test_iter = loadDataset(batch_size)
    net = nn.Sequential(nn.Flatten(),
                        nn.Linear(input_nodes, output_nodes))
    loss = nn.CrossEntropyLoss(reduction='mean')
    optimizer = torch.optim.SGD(net.parameters(), lr=lr)  # 定义优化

同之前实现简洁版的线性回归一样,通过Pytorch封装好的API,仅仅两行代码就能够实现Softmax分类模型。其中nn.Flatten()用于将输入“拉平”成一个向量,在此处就是将输入的图片展成一个784维的向量。同时,在倒数第2行代码中,我们还直接调用了Pytorch中的交叉熵损失函数。最后1行代码我们定义了一个SGD优化器。接下来,就是通过一个循环来对网络进行训练:

     for epoch in range(epochs):
            for i, (x, y) in enumerate(train_iter):
                logits = net(x)
                l = loss(logits, y)
                optimizer.zero_grad()
                l.backward()
                optimizer.step()  # 执行梯度下降

上述代码的含义在之前的文章中已经介绍过,在此就不再赘述。同时,完整示例代码可在引用[2]中进行获取。

2.2 运行结果

if __name__ == '__main__':
    mnist_train, mnist_test = loadDataset()
    train(mnist_train, mnist_test)

#结果
Epochs[5/2]---batch[234/150]---acc 0.8438---loss 0.5209
Epochs[5/2]---batch[234/200]---acc 0.8086---loss 0.559
Epochs[5/2]--acc on test 0.8158
Epochs[5/3]---batch[234/0]---acc 0.8438---loss 0.4491
Epochs[5/3]---batch[234/50]---acc 0.8047---loss 0.5441
Epochs[5/3]---batch[234/100]---acc 0.8203---loss 0.5268
Epochs[5/3]---batch[234/150]---acc 0.8125---loss 0.4648
Epochs[5/3]---batch[234/200]---acc 0.875---loss 0.4342
Epochs[5/3]--acc on test 0.8124

3 总结

在这篇文章中,笔者首先介绍了Pytorch封装好的softmax交叉熵损失函数CrossEntropyLoss(),同时将其计算结果与我们自己实现的方法的结果进行了对比;接着笔者通过Pytorch封装好的接口快速的实现了一个Softamx分类器,同时还介绍了nn.Flatten()的作用。

本次内容就到此结束,感谢您的阅读!如果你觉得上述内容对你有所帮助,欢迎关注并传播本公众号!若有任何疑问与建议,请添加笔者微信’nulls8’加群进行交流。青山不改,绿水长流,我们月来客栈见!

引用

[1]动手深度学习

[2]示例代码:https://github.com/moon-hotel/DeepLearningWithMe

推荐阅读

[1]Pytorch之Softmax多分类任务

[2]想明白多分类必须得谈逻辑回归

[3]Pytorch之Linear与MSELoss

[4]Pytorch之拟合正弦函数你会吗?

[5]你告诉我什么是深度学习

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页