您当前的位置: 首页 >  算法

wendy_ya

暂无认证

  • 1浏览

    0关注

    342博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

PyTorch实战案例(三)——利用PyTorch实现多层感知机算法

wendy_ya 发布时间:2021-11-07 11:39:39 ,浏览量:1

目录
    • 一、案例描述
    • 二、Fashion-MNIST数据集介绍
      • 2.1 加载数据集
      • 2.2 根据数字标签获取文本标签
      • 2.3 图像及标签可视化
    • 三、代码详解
      • 3.1 构建加载数据集函数
      • 3.2 实现单隐藏层的多层感知机
      • 3.3 开始训练
      • 3.4 损失可视化
      • 3.5 测试准确率
    • 四、完整代码

一、案例描述

本文将介绍PyTorch的一个基础案例——多层感知机算法。 案例为:利用PyTorch设计神经网络拟合对Fashion-MNIST数据集进行分类。

二、Fashion-MNIST数据集介绍 2.1 加载数据集

加载数据集利用datasets.FashionMNIST()函数,其用法如下: datasets.FashionMNIST(root, train=True, transform=None, download=False)

  • root:数据集存放的目录;
  • train:bool类型,True代表训练集,False代表测试集;
  • transform:图片变换方式,常需要将PIL图片或者numpy.ndarray转成Tensor类型的,此时利用语句transforms.ToTensor()
  • download:True——从互联网上下载数据,并把数据放在root目录下,如果数据之前下载过,将处理过的数据放在root目录下。

加载数据集代码如下:

#ToTensor()函数将图像数据从PIL类型转换为32为浮点数格式
train_dataset=datasets.FashionMNIST(root='../data',train=True,transform=transforms.ToTensor(),download=True)
test_dataset=datasets.FashionMNIST(root='../data',train=False,transform=transforms.ToTensor(),download=True)

可以通过len()函数查看数据集的长度:

len(train_dataset),len(test_dataset)

运行结果: (60000, 10000)

也可以查看训练集的第一个样本数据的形状:

train_dataset[0][0].shape

运行结果: torch.Size([1, 28, 28])

也可以查看训练集的第一个样本标签:

train_dataset[0][1]

运行结果: 9

【总结】:第一个[]内数字表示第几个数据样本,第二个[]内数字表示数据or标签,0代表数据,1代表标签。

2.2 根据数字标签获取文本标签

因为Fashion-MNIST数据集的标签为0-9的数字标签,要想直观查看标签内容,需要将其转为文本标签,转换代码如下,输入labels是0-9的数字,输出是对应的文本标签:

def get_fashion_mnist_labels(labels):
    '''返回Fashion-MNIST数据集的文本标签'''
    text_labels=['t-shirt','trouser','pullover','dress','coat','sandal','shirt','sneaker','bag','ankle boot']
    return [text_labels[int(i)]for i in labels]
2.3 图像及标签可视化

绘制图像及对应标签函数如下:

def show_images(imgs,num_rows,num_cols,titles=None,scale=1.5):
    '''绘制图像及对应标签'''
    figsize=(num_cols*scale,num_rows*scale)  #图像的长宽(尺寸)
    _,axes=plt.subplots(num_rows,num_cols,figsize=figsize)  #子图
    axes=axes.flatten()  #将axes展平成一维
    for i,(ax,img)in enumerate(zip(axes,imgs)):
        ax.axis('off')   #隐藏坐标轴
        if torch.is_tensor(img):
            #图片张量
            ax.imshow(img.numpy())
            
        else:
            #PIL图片
            ax.imshow(img)
        ax.set_title(titles[i])#设置标题为标签

调用函数显示图像及对应标签,将batch_size设置为18,显示2行9列的数据集样本:

#显示图像及对应标签
x,y=next(iter(data.DataLoader(train_dataset,batch_size=18)))
show_images(x.reshape(18,28,28),2,9,titles=get_fashion_mnist_labels(y))

运行结果: 在这里插入图片描述

三、代码详解 3.1 构建加载数据集函数

定义加载数据集函数:

#定义加载数据集函数
def load_data_fashion_mnist(batch_size):
    '''下载Fashion-MNIST数据集然后加载到内存中'''
    train_dataset=datasets.FashionMNIST(root='../data',train=True,transform=transforms.ToTensor(),download=True)
    test_dataset=datasets.FashionMNIST(root='../data',train=False,transform=transforms.ToTensor(),download=True)
    return (data.DataLoader(train_dataset,batch_size,shuffle=True),
           data.DataLoader(test_dataset,batch_size,shuffle=False))

然后,调用该函数,设置batch_size为256:

batch_size=256
train_iter,test_iter=load_data_fashion_mnist(batch_size)
3.2 实现单隐藏层的多层感知机

实现单隐藏层的多层感知机,其中有256个隐藏单元:

net=nn.Sequential(
                nn.Flatten(),
                nn.Linear(784,256),
                nn.ReLU(),
                nn.Linear(256,10))

可以初始化模型参数(也可以不进行初始化):

#初始化线性层的网络参数
def init_weights(m):
    if type(m)==nn.Linear:
        nn.init.normal_(m.weight,std=0.01)

将初始化的模型参数应用到网络中:

net.apply(init_weights)

然后定义交叉熵损失函数:

#损失函数
loss_function=nn.CrossEntropyLoss()

定义SGD优化器:

#优化器
optimizer=torch.optim.SGD(net.parameters(),lr=0.01)
3.3 开始训练

开始训练代码如下:

#开始训练
num_epochs=10
train_loss = []
for epoch in range(num_epochs):
    for batch_idx, (x, y) in enumerate(train_iter):
#         x = x.view(x.size(0), 28 * 28)
        out = net(x)
        y_onehot =F.one_hot(y,num_classes=10).float()    # 转为one-hot编码
        
        loss = loss_function(out, y_onehot)  # 均方差
        # 清零梯度
        optimizer.zero_grad()
        loss.backward()
        # w' = w -lr * grad
        optimizer.step()
        train_loss.append(loss.item())
        if batch_idx % 10 == 0:
            print(epoch, batch_idx, loss.item())
3.4 损失可视化

绘制损失曲线:

#绘制损失曲线
plt.figure(figsize=(16,8))
plt.grid(True,linestyle='--',alpha=0.5)
plt.plot(train_loss,label='loss')
plt.legend(loc="best")

运行结果: 在这里插入图片描述

3.5 测试准确率

测试准确率:

total_correct = 0
for batch_idx,(x,y) in enumerate(test_iter):
#     x = x.view(x.size(0),28*28)
    out = net(x)
    pred = out.argmax(dim=1)
    correct = pred.eq(y).sum().float().item()
    total_correct += correct
        
total_num = len(test_iter.dataset)
test_acc=total_correct/total_num
print(total_correct,total_num)
print("test acc:",test_acc)

准确率为:77.19% 这对于一个简单神经网络而言,已经很不错了。

四、完整代码

完整代码可以参考:https://download.csdn.net/download/didi_ya/37979714

ok,以上便是本文的全部内容了,看完了之后记得一定要亲自独立动手实践一下呀~

关注
打赏
1659256378
查看更多评论
立即登录/注册

微信扫码登录

0.0445s