Pytorch 学习笔记(一)examples中的Image classification (MNIST) using Convnets模型。

在安装好pytorch环境之后开始跑代码。

一、解析代码

1.导入包

import argparse #用于解析命令行参数
import torch
import torch.nn as nn  #构建神经网络的核心模块
import torch.nn.functional as F #包含了许多神经网络的功能函数,例如激活函数和损失函数等
import torch.optim as optim  #优化器
from torchvision import datasets, transforms #torchvision是PyTorch的一个拓展包,提供数据集、模型架构和图形变化等功能,transforms提供了图形变化的功能
from torch.optim.lr_scheduler import StepLR #调整学习率的一个模块

2.定义神经网络模型

class Net(nn.Module): #定义了一个名为Net的神经网络类,继承自nn.Module(父类)(在pytorch中所有的神经网络都应该继承此类)
    def __init__(self): #初始化
        super(Net, self).__init__() #执行父类的构造函数,使能够调用父类的属性
        self.conv1 = nn.Conv2d(1, 32, 3, 1) #二维卷积层
        self.conv2 = nn.Conv2d(32, 64, 3, 1)
        self.dropout1 = nn.Dropout(0.25) #丢弃层
        self.dropout2 = nn.Dropout(0.5)  
        self.fc1 = nn.Linear(9216, 128) #全连接层
        self.fc2 = nn.Linear(128, 10)

    def forward(self, x):  #前向传播方法,x是输入数据
        x = self.conv1(x) 
        x = F.relu(x)
        x = self.conv2(x)
        x = F.relu(x)
        x = F.max_pool2d(x, 2) #使用2*2的最大池化来减少空间维度
        x = self.dropout1(x)
        x = torch.flatten(x, 1) #将多维输入x展平成一维
        x = self.fc1(x) 
        x = F.relu(x)
        x = self.dropout2(x) 
        x = self.fc2(x)
        output = F.log_softmax(x, dim=1) #应用log_softmax函数,该函数是softmax函数的对数版本,常用于多分类的对数层,dim=1指定维度
        return output

3.定义训练函数

def train(args, model, device, train_loader, optimizer, epoch):  #model指建立好的网络模型,device是指模型在哪个设备上运行,train_loader是指数据集,optimizer是优化器,epoch是当前训练的轮次
    model.train() #将模型设置为训练模式
    for batch_idx, (data, target) in enumerate(train_loader):
        data, target = data.to(device), target.to(device)#将数据和标签移动到指定设备
        optimizer.zero_grad() #重置参数梯度为0
        output = model(data) #执行前向传播
        loss = F.nll_loss(output, target) #计算负对数似然损失(Negative Log Likelihood Loss, NLL Loss)
        loss.backward() #计算反向传播
        optimizer.step() #更新模型参数
        if batch_idx % args.log_interval == 0:  #每隔一个批次输出一下
            print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
                epoch, batch_idx * len(data), len(train_loader.dataset),
                100. * batch_idx / len(train_loader), loss.item()))
            if args.dry_run:  #为了方便测试的代码
                break

4.定义测试函数

def test(model, device, test_loader):
    model.eval()  #将模型变成评估模式
    test_loss = 0  #初始化测试集上的总损失
    correct = 0  #记录正确的图片个数
    with torch.no_grad(): #测试集禁用梯度
        for data, target in test_loader:
            data, target = data.to(device), target.to(device)
            output = model(data) 
            test_loss += F.nll_loss(output, target, reduction='sum').item()  # sum up batch loss 计算负对数似然损失,所有样本的,.item()将损失值转换成Python标量
            pred = output.argmax(dim=1, keepdim=True)  # get the index of the max log-probability 
            correct += pred.eq(target.view_as(pred)).sum().item() 

    test_loss /= len(test_loader.dataset) 

    print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
        test_loss, correct, len(test_loader.dataset),
        100. * correct / len(test_loader.dataset)))

 5.主函数

def main():
    # Training settings 使用argparse库来解析命令行参数
    parser = argparse.ArgumentParser(description='PyTorch MNIST Example')
    parser.add_argument('--batch-size', type=int, default=64, metavar='N',
                        help='input batch size for training (default: 64)')
    parser.add_argument('--test-batch-size', type=int, default=1000, metavar='N',
                        help='input batch size for testing (default: 1000)')
    parser.add_argument('--epochs', type=int, default=14, metavar='N',
                        help='number of epochs to train (default: 14)')
    parser.add_argument('--lr', type=float, default=1.0, metavar='LR',
                        help='learning rate (default: 1.0)')
    parser.add_argument('--gamma', type=float, default=0.7, metavar='M',
                        help='Learning rate step gamma (default: 0.7)')
    parser.add_argument('--no-cuda', action='store_true', default=False,
                        help='disables CUDA training')
    parser.add_argument('--no-mps', action='store_true', default=False,
                        help='disables macOS GPU training')
    parser.add_argument('--dry-run', action='store_true', default=False,
                        help='quickly check a single pass')
    parser.add_argument('--seed', type=int, default=1, metavar='S',
                        help='random seed (default: 1)')
    parser.add_argument('--log-interval', type=int, default=10, metavar='N',
                        help='how many batches to wait before logging training status')
    parser.add_argument('--save-model', action='store_true', default=True,
                        help='For Saving the current Model')
    args = parser.parse_args()
    use_cuda = not args.no_cuda and torch.cuda.is_available()
    # use_mps = not args.no_mps and torch.backends.mps.is_available()

    torch.manual_seed(args.seed)

    if use_cuda:
        device = torch.device("cuda")
    # elif use_mps:
    #     device = torch.device("mps")  mps好像只有mac电脑才能用
    else:
        device = torch.device("cpu")

    train_kwargs = {'batch_size': args.batch_size}
    test_kwargs = {'batch_size': args.test_batch_size}
    if use_cuda:  
        cuda_kwargs = {'num_workers': 1,  #cuda_kwargs 是一个字典,代表使用CUDA时,DataLoader 的一些额外参数, 数据加载的子进程数
                       'pin_memory': True,  
                       'shuffle': True}   #打乱数据顺序,仅对训练数据有用
        train_kwargs.update(cuda_kwargs) 
        test_kwargs.update(cuda_kwargs)

    transform=transforms.Compose([   #使用图像变换工具变换
        transforms.ToTensor(),
        transforms.Normalize((0.1307,), (0.3081,))
        ])
    dataset1 = datasets.MNIST('../data', train=True, download=True,
                       transform=transform)
    dataset2 = datasets.MNIST('../data', train=False,
                       transform=transform)
    train_loader = torch.utils.data.DataLoader(dataset1,**train_kwargs)
    test_loader = torch.utils.data.DataLoader(dataset2, **test_kwargs)
   
    model = Net().to(device)  #创建一个Net类的示例,并传到CPU和GPU上
    optimizer = optim.Adadelta(model.parameters(), lr=args.lr) #优化器优化参数

    scheduler = StepLR(optimizer, step_size=1, gamma=args.gamma) #调整学习率
    for epoch in range(1, args.epochs + 1):
        train(args, model, device, train_loader, optimizer, epoch)
        test(model, device, test_loader)
        scheduler.step()

    if args.save_model:
        torch.save(model.state_dict(), "mnist_cnn.pt")

6.最后一步 

if __name__ == '__main__':
    main()

7.结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值