Pytorch入门之softmax回归

    科技2025-01-21  5

    softmax回归

    主要用于分类问题,通过将前几层网络的输出得分转为相应分类的概率,然后选取概率最高的类别作为此次分类的的结果。比如经过四分类问题经过softmax处理后的结果为[0.1,0.3,0.1,0.5],则最后属于第四类,因为0.5最大了。

     

    其实softmax处理分类问题和用线性回归处理回归问题大致相同

    只不过线性回归在全连接层后用的恒等函数Relu函数输出,然后利用均方误差计算loss,然后反向传播利用SGD训练参数。

    而softmax处理分类问题呢,是在全连接层后的输出利用全连接的形式计算每个类别的概率值,然后利用交叉熵(cross entropy)计算loss,然后反向传播利用SGD训练参数。

    关于基于pytorch处理线性回归,可以参考我的另一篇博客https://blog.csdn.net/MR_kdcon/article/details/108936131

     

    那就开始了,下面这个是我整个网络的结构图(连接线太麻烦了,请忽略)

     

    准备工作:读取数据集

    数据集:采用Fashion-MNIST数据,这是一个每个类别有6,000张训练集和1,000张,一共10个类别,分别是t-shirt(T恤)、trouser(裤⼦)、pullover(套衫)、 dress(连⾐裙)、coat(外套)、sandal(凉鞋)、shirt(衬衫)、sneaker(运动鞋)、 bag(包)和ankle boot(短靴)

     

    读入Fashion-MNIST数据集,需要导入torchvision包,用于构建计算机模型

    torchvison.dataset包里有一些加载数据的函数以及常用的数据集接口,常用于导入数据集,例如需要导入Fashion-MNIST数据集,第一次下载将从网上直接下载

    root='~/Datasets/FashionMNIST' # root既是第一次下载存的地址,也是第二次以后读取的地址 # 或者 root='./FashionMNIST',即保存在当前目录下 transform = transforms.ToTensor() # 将所有数据转为Tensor mnist_train = torchvision.datasets.FashionMNIST(root=root, train=True, download=True, transform=transform) mnist_test = torchvision.datasets.FashionMNIST(root=root, train=False, download=True, transform=transform)

    torchvision.transforms常用于做一些图片变换,例如裁剪、旋转等。transforms.ToTensor() 将尺⼨为 (H x W x C) 且数据位于 [0, 255] 的 PIL 图⽚或者数据类型为 np.uint8 NumPy 数组转换为尺寸为 (C x H x W) 且数据类型为 torch.float32 且位于 [0.0, 1.0] Tensor

    这里读取的数据mnist_train、mnist_test格式为:[(X1,y1),(X2,y2)...] ,

    其中X1:(1, 28, 28),表示1通道(灰度图)分辨率为28*28的图像

    y:Tensor标量,表示标签,如tensor(9),他其实对应了查找表中的 'ankle boot'。

    note:

    1、torchvison.models包包含常用的模型结构,常用于预训练,如VGG、AlexNet等

     

    导入数据集:

    train_iter = torch.utils.data.DataLoader(mnist_train, batch_size=batch_size, shuffle=True, num_workers=num_workers) test_iter = torch.utils.data.DataLoader(mnist_test, batch_size=batch_size, shuffle=False, num_workers=num_workers)

    mnist_train、mnist_test为torch.utils.data.Dataset的子类,故可以直接用torch.utils.data.DataLoader直接导入

    note:

    train_iter格式: [(X1,y1),(X2,y2)...] X1:(batch, 1, 28, 28) y:(batch,),标签不是one-hot形式

     

    到了正式开始的时候了

    1、创建网络

    根据图中所画的,网络类中只需要一个全连接层

    自行创建模型类,继承nn.Module (也可以用nn.Sequential(nn.Module的子类)

    class Net(nn.Module): def __init__(self, feature_in, feature_out): super().__init__() self.linear = nn.Linear(feature_in, feature_out) def forward(self, datain): out = self.linear(datain.view(datain.shape[0], -1)) # (batchsize, 10) return out

     法二:利用

    # 搭建网络 network = Net(784, 10)

    note:需要注意的是,全连接层的输入必须是个二维Tensor,故需要进行转换,即(batchsize,1,28,28)转为(batchsize,784)

    这样全连接的输出y_hat就是(batchsize, 10)

     

    2、参数初始化及loss函数、SGD例化

    # 初始化已经在类的例化中完成了 loss = nn.CrossEntropyLoss() optimizer = optim.SGD(network.parameters(), lr=0.5)

    note:分类问题常调用的nn.CrossEntropyLoss()是一个包含了softmax函数和cross_entropy函数的一个函数。

     

    3、前向推理、后向传播、训练(采用100个epoch)

    for epoch in range(100): for X, y in data_iter: output = net(X) # batch ls = loss(output, y).sum optimizer.zero_grad() ls.backward() optimizer.step() # 更新以及对梯度求平均

     

    4、测试

    在测试集上对每一个epoch计算损失、正确率。由于没有其他的优化措施,所以最终识别率在83%左右

    选取了前十张图的识别效果(仅有一个判断错误)

    Processed: 0.008, SQL: 8