网站地图优化,手机制作封面教程网站,百度网盘电话人工服务,甘肃网站建站系统平台在上一篇文章中#xff0c;笔者介绍了什么是Softmax回归及其原理。因此在接下来的这篇文章中#xff0c;我们就来开始动手实现一下Softmax回归#xff0c;并且最后要完成利用Softmax模型对Fashion MINIST进行分类的任务。在开始实现Softmax之前#xff0c;我们先来了解一下… 在上一篇文章中笔者介绍了什么是Softmax回归及其原理。因此在接下来的这篇文章中我们就来开始动手实现一下Softmax回归并且最后要完成利用Softmax模型对Fashion MINIST进行分类的任务。在开始实现Softmax之前我们先来了解一下Fashion MINIST这一数据集。1 数据集1.1 FashionMNIST数据集FashionMNIST虽然名字里面有MNIST这个词但是其与手写体识别一点关系也没有仅仅只是因为FashionMNIST数据集在数据集规模、类别数量和图片大小上与MINIST手写体数据集一致。图 1. Fashion MINIST数据集如图1所示便为Fashion MNIST数据集的部分可视化结果其包含有训练集6万张和测试集1万张每张图片的大小为[28,28]。在Pytorch中我们可以通过如下代码对其进行载入def load_dataset(): mnist_train torchvision.datasets.FashionMNIST(root~/Datasets/FashionMNIST, trainTrue, downloadTrue,transformtransforms.ToTensor()) mnist_test torchvision.datasets.FashionMNIST(root~/Datasets/FashionMNIST, trainFalse, downloadTrue,transformtransforms.ToTensor()) return mnist_train, mnist_test其中参数root表示指定数据集的保存目录train表示返回训练集还是测试集download表示数据集不存在时是否需要下载transform表示指定一种转换方法而指定transforms.ToTensor()就是将尺寸为(H x W x C)且数据位于[0,255]的PIL图片或者数据类型为np.unit8的numpy数组转换为尺寸为(C x H x W)且数据类型为torch.float32范围在的Tensor。同时我们还可以通过代码image mnist_train[0][0]和labelmnist_train[0][1]来分别访问一张图片和其对应的标签值。1.2 构造数据集在模型实际训练过程中数据读取经常是训练的性能瓶颈。同时为了能够更好的训练模型我们通常会对数据进行打乱以及分批(batch)的将数据输入的模型中。在Pytorch中我们可以通过DataLoader这个类来方便的完成上述功能。start time.time()train_iter torch.utils.data.DataLoader(mnist_test, batch_size1024, shuffleTrue, num_workers2)for x_test, y_test in train_iter: print(x_test.shape) print(%.2f sec % (time.time() - start))#结果torch.Size([1024, 1, 28, 28])torch.Size([1024, 1, 28, 28])torch.Size([1024, 1, 28, 28])torch.Size([1024, 1, 28, 28])torch.Size([1024, 1, 28, 28])torch.Size([1024, 1, 28, 28])torch.Size([1024, 1, 28, 28])torch.Size([1024, 1, 28, 28])torch.Size([1024, 1, 28, 28])torch.Size([784, 1, 28, 28])2.60 sec其中batsh_size表示指定每次返回batsh_size个样本shuffleTrue表示对数据集进行打乱num_workers2表示用两个进程来读取数据。但需要注意的是这里的数据集mnist_test是Pytorch内置的那如果是我们自己读入的数据集该怎么使用DataLoader呢我们只需要首先将自己的数据集转换成tensor然后再通过TensorDataset这个类来构造一个数据集即可。def make_dataset(): x torch.linspace(0, 100, 100, dtypetorch.float32).reshape(-1, 2) y torch.randn(50 ) dataset torch.utils.data.TensorDataset(x, y) return dataset此时返回的dataset数据集也就同样能够通过DataLoader进行读取。2 Softmax多分类在实现这个分类模型之前我们先来介绍一下几个需要用到的函数。2.1 softmax计算实现在上一篇文章中我们介绍了softmax的计算公式其实现可以通过如下代码来完成def softmax(x): s torch.exp(x) return s / torch.sum(s, dim1, keepdimTrue)# 此处触发了广播机制a torch.tensor([[1,2,3.],[2,3,1.]])print(softmax(a))#结果tensor([[0.0900, 0.2447, 0.6652], [0.2447, 0.6652, 0.0900]])其中torch.exp()为计算每个元素的指数次方sum(s, dim1, keepdimTrue)表示计算得到每一行的和最后是按位除操作。需要注意的是传入的x必须是浮点类型的不然会报错。2.2 交叉熵计算实现假设我们现在有两个样本其预测得到的概率分布为[0.1,0.3,0.6]和[0.5,0.4,0.1]。同时正确的标签分布为[0,0,1]和[0,1,0]则对应的交叉熵为。但是我们在用代码实现的时候完全不用这么麻烦只需要通过正确的标签找到预测概率分布中对应的值再取对数即可。例如[0,0,1]和[0,1,0]这两个真实分布对应的标签就应该是2和1(从0开始)因此我们只需要分别取[0.1,0.3,0.6]和[0.5,0.4,0.1]中第2个元素0.6和第1个原始0.4再取对数就能实现交叉熵的计算。上述过程通过如下代码便可完成def crossEntropy(logits,y): c -torch.log(logits.gather(1,y.reshape(-1,1))) return torch.sum(c)# 注意这里返回的是和logits torch.tensor([[0.1, 0.3, 0.6], [0.5, 0.4, 0.1]])y torch.LongTensor([2, 1])c crossEntropy(logits,y)print(c)#结果tensor(1.4271)其中.gather()就是根据指定维度和索引选择对应位置上的元素。同时需要注意的是logits的每一行为一个样本的概率分布因此我们需要在行上进行索引操作故gather()的第一个参数应该是1这一点一定要注意。2.3 准确率计算实现在前面介绍softmax时说到对于每个样本的预测类别我们会选择对应概率值最大的类别作为输出结果。因此在计算预测的准确率时我们首先需要通过torch.argmax()这个函数来返回预测得到的标签。y_true torch.tensor([[2,1]])logits torch.tensor([[0.1,0.3,0.6],[0.5,0.4,0.1]])y_pred logits.argmax(1)print(y_pred)#结果tensor([2, 0])最后我们将预测得到的标签同正确标签进行对比即可求得准确率。def accuracy(y_true,logits): acc (logits.argmax(1) y_true).float().mean() return acc.item()print(accuracy(y_true,logits))#结果0.52.4 评估模型一般我们训练得到一个模型后都需要对其在测试集上进行评估也就是在测试集上计算其总的准确率。因此我们首先需要计算得到所有预测对的样本(而不仅仅只是一个batch)然后再除以总的样本数即可。def evaluate(data_iter, forward, input_nodes, w, b): acc_sum, n 0.0, 0 for x, y in data_iter: logits forward(x, input_nodes, w, b) acc_sum (logits.argmax(1) y).float().sum().item() n len(y) return acc_sum / n2.5 分类模型实现w torch.tensor(np.random.normal(0, 0.5, [input_nodes, output_nodes]), dtypetorch.float32, requires_gradTrue)b torch.tensor(np.random.randn(output_nodes), dtypetorch.float32, requires_gradTrue)for epoch in range(epochs): for i, (x, y) in enumerate(train_iter): logits forward(x, input_nodes, w, b) l crossEntropy(y, logits) l.backward() gradientDescent([w, b], lr) acc accuracy(y, logits) if i % 50 0: print(Epoches[{}/{}]---batch[{}/{}]---acc{:.4}---loss {:.4}.format( epoches, epoch, len(mnist_train) // batch_size, i, acc,l)) acc evaluate(test_iter, forward, input_nodes, w, b) print(Epoches[{}/{}]--acc on test{:.4}.format(epochs, epoch, acc))# 结果Epochs[8000/20]--acc on test0.8323Epochs[8000/21]---batch[468/0]---acc0.8516---loss 47.13Epochs[8000/21]---batch[468/50]---acc0.8203---loss 67.22Epochs[8000/21]---batch[468/100]---acc0.9219---loss 38.74Epochs[8000/21]---batch[468/150]---acc0.8516---loss 57.39Epochs[8000/21]---batch[468/200]---acc0.8281---loss 74.76Epochs[8000/21]---batch[468/250]---acc0.8672---loss 55.32Epochs[8000/21]---batch[468/300]---acc0.8281---loss 60.19可以看到大约20轮迭代后softmax模型在测试集上的准确率就达到了0.83左右。3 总结在这篇文章中笔者首先介绍了FashionMNIST数据集。然后接着介绍了如何使用Pytorch中的DataLoader来构造训练数据迭代器。最后介绍了如何通过Pytorch来一步步的实现Softmax分类模型包括如何实现softmax操作、如何快捷的计算交叉熵、如何计算模型的准确率等等。本次内容就到此结束感谢您的阅读本次内容就到此结束感谢您的阅读如果你觉得上述内容对你有所帮助欢迎关注并传播本公众号若有任何疑问与建议请添加笔者微信nulls8进行交流。青山不改绿水长流我们月来客栈见引用[1]动手深度学习[2]示例代码https://github.com/moon-hotel/DeepLearningWithMe推荐阅读[1]想明白多分类必须得谈逻辑回归[2]Pytorch之Linear与MSELoss[3]Pytorch之拟合正弦函数你会吗[4]你告诉我什么是深度学习[5]《跟我一起深度学习》终于来了