深度学习案例分享 | PyTorch 实现 Fashion-MNIST 服装数据分类

原文链接

大家好,我是小寒。

我们在上一篇文章分享了如何进行手写数字识别。

今天我们使用 LeNet-5 (它是最早发布的卷积神经⽹络之⼀)来实现 Fashion-MNIST 服装图⽚的分类任务。

读取数据集

Fashion-MNIST 数据集中的图像是一个 28*28 的灰度图像。我们通过 pytorch 的内置函数将 FashionMNIST 下载并读到内存中。

# 通过ToTensor实例将图像数据从PIL类型变换成32位浮点数格式,
# 并除以255使得所有像素的数值均在0到1之间
trans = transforms.ToTensor()
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)

Fashion-MNIST 由10个类别的图像组成,每个类别由训练数据集(train dataset)中的6000张图像和测试数据集(test dataset)中的1000张图像组成。

len(mnist_train), len(mnist_test)
60000,10000
可视化数据集

我们来显示看一下数据集中的图像样本是什么样的。

通过如下方式,我们来可视化的展示训练集中前几个样本。

# 显示数据集
mnist_show = torchvision.datasets.FashionMNIST(root="../data", train=True, transform=torchvision.transforms.ToTensor(), download=True)
images, label = next(iter(data.DataLoader(mnist_show, 20, shuffle=True)))
images=images.reshape(20,28,28)
fig,axes = plt.subplots(2,10,figsize=(15,3))  
axes = axes.flatten()   
for i, (ax, img) in enumerate(zip(axes, images)):
    if torch.is_tensor(img):
        ax.imshow(img.numpy())
    else:
        # PIL图⽚
        ax.imshow(img)
plt.show()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LSadFPKF-1661500243513)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4a0a45acea2f4f31b063cea5128d9b81~tplv-k3u1fbpfcp-zoom-1.image)]

LeNet-5 网络结构

总体来看,LeNet-5 由两个部分组成:

  • 两个卷积层。
  • 三个全连接层。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9vzvV2Yz-1661500243515)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/36120bab58b745bbbbb03d9bbf012992~tplv-k3u1fbpfcp-zoom-1.image)]

每个卷积块中的基本单元是⼀个卷积层、⼀个 sigmoid 激活函数和平均汇聚层。

每个卷积层使⽤ 5 × 5 卷积核和⼀个 sigmoid 激活函数。

第⼀卷积层有 6 个输出通道,⽽第⼆个卷积层有16个输出通道。

每个 2 ×2 的池操作(步幅2)通过空间下采样将维数减少4倍。卷积的输出形状由批量⼤⼩、通道数、⾼度、宽度决定。

为了将卷积块的输出传递给稠密块,我们必须在⼩批量中展平每个样本。换⾔之,我们将这个四维输⼊转换成全连接层所期望的⼆维输⼊。这⾥的⼆维表⽰的第⼀个维度索引⼩批量中的样本,第⼆个维度给出每个样本的平⾯向量表⽰。

LeNet-5 的稠密块有三个全连接层,分别有120、84和10个输出。因为我们在执⾏分类任务,所以输出层的10维对应于最后输出结果的数量。

下面我们看一下网络结构的定义。

net = nn.Sequential(
        nn.Conv2d(1, 6, kernel_size=5, padding=2), 
        nn.Sigmoid(),
        nn.AvgPool2d(kernel_size=2, stride=2),
        nn.Conv2d(6, 16, kernel_size=5), 
        nn.Sigmoid(),
        nn.AvgPool2d(kernel_size=2, stride=2),
        nn.Flatten(),
        nn.Linear(16 * 5 * 5, 120), 
        nn.Sigmoid(),
        nn.Linear(120, 84), 
        nn.Sigmoid(),
        nn.Linear(84, 10))

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0prOWTFJ-1661500243516)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a113d7703bbd482eaf89f9365c0a3baf~tplv-k3u1fbpfcp-zoom-1.image)]

X = torch.rand(size=(1, 1, 28, 28), dtype=torch.float32)
for layer in net:
    X = layer(X)
    print(layer.__class__.__name__, 'output shape: \t', X.shape)

输出如下所示:

Conv2d output shape: 	 torch.Size([1, 6, 28, 28])
Sigmoid output shape: 	 torch.Size([1, 6, 28, 28])
AvgPool2d output shape: 	 torch.Size([1, 6, 14, 14])
Conv2d output shape: 	 torch.Size([1, 16, 10, 10])
Sigmoid output shape: 	 torch.Size([1, 16, 10, 10])
AvgPool2d output shape: 	 torch.Size([1, 16, 5, 5])
Flatten output shape: 	 torch.Size([1, 400])
Linear output shape: 	 torch.Size([1, 120])
Sigmoid output shape: 	 torch.Size([1, 120])
Linear output shape: 	 torch.Size([1, 84])
Sigmoid output shape: 	 torch.Size([1, 84])
Linear output shape: 	 torch.Size([1, 10])

初始化模型参数

这里我们使用 Xavier 来进行参数的初始化。

def init_weights(m):
    if type(m) == nn.Linear or type(m) == nn.Conv2d:
        nn.init.xavier_uniform_(m.weight)

net.apply(init_weights)

定义损失函数和优化器

#交叉熵作为损失函数
loss = nn.CrossEntropyLoss()
#定义优化器
optimizer = torch.optim.SGD(net.parameters(), lr=0.1)

训练及预测

让我们看看 LeNet-5 在 Fashion-MNIST 数据集上的表现吧。

def train_ch6(net, train_iter, test_iter, num_epochs, lr, device):
    """⽤GPU训练模型"""
    #初始化权重
    def init_weights(m):
        if type(m) == nn.Linear or type(m) == nn.Conv2d:
            nn.init.xavier_uniform_(m.weight)
    net.apply(init_weights)
    print('training on', device)

    #net复制到相应的设备上
    net.to(device)

    #定义优化器
    optimizer = torch.optim.SGD(net.parameters(), lr=lr)
    #交叉熵作为损失函数
    loss = nn.CrossEntropyLoss()
    
    num_batches = len(train_iter)
    train_loss=[]
    train_accs=[]
    starttime = datetime.datetime.now()
    for epoch in range(num_epochs):
        #训练损失之和,训练正确数之和,样本数
        metric = Accumulator(3)
        net.train()
        for i, (X, y) in enumerate(train_iter):
            optimizer.zero_grad()
            X, y = X.to(device), y.to(device)
            y_hat = net(X)
            l = loss(y_hat, y)
            l.backward()
            optimizer.step()
            with torch.no_grad():
                metric.add(l * X.shape[0], accuracy(y_hat, y), X.shape[0])
            #训练损失、训练正确率
            train_l = metric[0] / metric[2]
            train_acc = metric[1] / metric[2]

        train_loss.append(train_l)
        train_accs.append(train_acc)
        print(f'ecoch {epoch+1}, loss {train_l:.3f}, train acc {train_acc:.3f}')

    endtime = datetime.datetime.now()
    time_second= (endtime - starttime).seconds
    print(f'总耗时 {time_second}')
    show_image(num_epochs, train_loss, train_accs)

    test_acc = evaluate_accuracy_gpu(net, test_iter)
    print(f'test acc {test_acc:.3f}')


device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print(device)
lr, num_epochs = 0.5, 50
train_ch6(net, train_iter, test_iter, num_epochs, lr, device)

我们在 GPU 上进行 50 轮的迭代训练,测试集的正确率可以达到89%。

cuda:0
training on cuda:0
ecoch 1, loss 2.320, train acc 0.100
ecoch 2, loss 2.079, train acc 0.219
ecoch 3, loss 1.058, train acc 0.589
ecoch 4, loss 0.859, train acc 0.670
ecoch 5, loss 0.751, train acc 0.709
ecoch 6, loss 0.691, train acc 0.729
ecoch 7, loss 0.648, train acc 0.746
ecoch 8, loss 0.611, train acc 0.762
ecoch 9, loss 0.581, train acc 0.777
ecoch 10, loss 0.556, train acc 0.786
ecoch 11, loss 0.531, train acc 0.797
ecoch 12, loss 0.510, train acc 0.806
ecoch 13, loss 0.491, train acc 0.815
ecoch 14, loss 0.478, train acc 0.821
ecoch 15, loss 0.463, train acc 0.827
ecoch 16, loss 0.452, train acc 0.832
ecoch 17, loss 0.441, train acc 0.837
ecoch 18, loss 0.434, train acc 0.839
ecoch 19, loss 0.425, train acc 0.843
ecoch 20, loss 0.420, train acc 0.845
ecoch 21, loss 0.408, train acc 0.851
ecoch 22, loss 0.403, train acc 0.851
ecoch 23, loss 0.396, train acc 0.855
...
ecoch 48, loss 0.303, train acc 0.888
ecoch 49, loss 0.305, train acc 0.886
ecoch 50, loss 0.300, train acc 0.889
总耗时 378
test acc 0.890

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BX3HR0li-1661500243517)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/22e3f0b901f547e6ba9f7b25b4f5c776~tplv-k3u1fbpfcp-zoom-1.image)]

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: pytorch fashion-mnist是使用pytorch框架的一个衣服图片分类任务数据集。它包含10个类别,共70,000张28×28的灰度图像。这个数据集可以用于测试和比较不同机器学习算法的性能,也可以用于学习深度学习和计算机视觉。 ### 回答2: Pytorch Fashion-MNIST是一个深度学习应用程序,它旨在处理类别多样、数量众多、复杂性高的模型。它利用了卷积神经网络(CNN)的强大功能,可以较好地处理这种类别众多、大量数据的情况。 Fashion-MNISTMNIST数据集的替代方案,用于测试和比较深度学习模型的性能。Fashion-MNIST包含了一组包括衣服、鞋类和包等物品的灰度图像,共计10个类别。每个图像都是28x28的分辨率,共有70000个样本,其中60000个是训练集,10000个是测试集。这个数据集的制作目的是验证深度学习模型对于更复杂、更具多样性的数据集的应用情况。 在使用PyTorch Fashion-MNIST时,我们需要先确定具体的模型。可以根据具体的要求、数据,选择不同的模型,如AlexNet、VGG、ResNet、Inception等等。在选择好模型后,我们需要对数据进行预处理。具体而言,我们可以进行归一化、数据增强、数据扩充等一系列操作,以增强模型的泛化能力。最后,我们可以进行训练和测试等操作,对模型进行评估,得出相应的性能指标。 总而言之,Pytorch Fashion-MNIST是一个非常实用的深度学习应用程序,能够处理复杂、多样性高的数据,并能够评估我们选择的模型在这些数据上的性能。它的使用非常广泛,可以应用于经典图像分类、物体检测、图像分割、神经网络可视化等领域。在未来,Pytorch Fashion-MNIST的应用前景非常广阔,同时,它的发展也将对深度学习模型的发展和性能提升带来很大的帮助。 ### 回答3: PyTorch是一个流行的深度学习框架,它提供了灵活的构建计算图的方式,可以实现高效的神经网络训练和推理。而Fashion-MNIST是一个常用的图像分类数据集,它包含10类不同的服装图像,每个类别共有6000张图像,其中包括训练集和测试集。 在PyTorch中使用Fashion-MNIST数据集可以实现训练和测试各种深度学习模型,例如CNN、RNN、GAN等。具体操作包括以下步骤: 1. 下载数据集:使用PyTorch内置的torchvision.datasets工具可以方便地下载和导入Fashion-MNIST数据集。 2. 数据预处理:对下载的数据进行预处理,包括归一化、缩放、旋转等操作,可以提高模型的训练和测试效果。 3. 定义模型:使用PyTorch的nn.Module类可以定义各种深度学习模型,例如LeNet、ResNet、VGG等经典模型。 4. 训练模型:使用PyTorch的优化器和损失函数,例如SGD、Adam、CrossEntropy等,可以实现模型的训练和参数更新。 5. 测试模型:使用测试集评估模型的性能,例如计算准确率、精确率、召回率等指标,可以判断模型是否过拟合或欠拟合。 总之,PyTorchFashion-MNIST结合可以实现快速构建和训练深度学习模型,加速图像分类、目标检测、语音处理等领域的研究和应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值