Pytorch学习笔记day5——不小心玩坏了mnist数据集训练的代码

全体目光向我看齐!今天是day5!
好吧我错了,周末偷了个懒,今天我们继续。前几天把mnist指令集跑通了,还没细看。今天仔细的改一改

在GPU上运行代码

Pytorch似乎不说的话默认是在CPU上跑,跑起来还是有点慢的,而且CPU负载直接就拉满了。
在这里插入图片描述
在这里插入图片描述
最后跑了100s

上到GPU上,首先需要设置device为GPU

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")   

然后将网络的参数放到device上,并且训练的data和target也要放上来。后面预测结果,就自动在device上面了

model = Net().to(device)  # Net上的参数要在GPU上
...
for epoch in range(epochs):
        for batch_idx, (data, target) in enumerate(train_loader): #自动打batch
            data, target = data.to(device), target.to(device)  # data和target要放在GPU上
            optimizer.zero_grad()   
            output = model(data)  # output自动算完在GPU上
            loss = criterion(output, target) 
            loss.backward()   # 回传的梯度,隐式生成,也放在GPU上
            optimizer.step()

在这里插入图片描述
在这里插入图片描述
emmmm,GPU根本跑不满,最后也没有快特别多,估计是数据密度不够。以后找找有没有更大规模的例子吧。

调整网络结构

# 定义模型
class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(1, 10, kernel_size=3) #输入为1,输出为10,卷积核大小3
        self.conv2 = nn.Conv2d(10, 20, kernel_size=4)
        self.fc = nn.Linear(20 * 5 * 5, 10)
 
    def forward(self, x):
        batch_size = x.size(0)   #第一个维度是batch维度,图片为1*28*28时,输入为64*1*28*28
        x = torch.relu(self.conv1(x))  # 输入64*1*28*28, 输出64*10*26*26
        x = torch.max_pool2d(x, 2, 2)  # 输入64*10*26*26, 输出64*10*13*13,池化层
        x = torch.relu(self.conv2(x))  # 输入64*10*13*13, 输出64*20*10*10
        x = torch.max_pool2d(x, 2, 2)  # 输入64*20*10*10, 输出64*20*5*5
        x = x.view(batch_size, -1)     # 输入64*20*5*5, 输出64*500
        x = self.fc(x)                 # 输入64*500, 输出64*10
        return x

可以看到12828是一张图片,size 1=1说明这是一张黑白照片。然后每个像素点,会被Conv2d展开成10个输出。而kernel_size是卷积的窗口大小,输入是2828而卷积窗口大小是5,输出就是2424。这里我稍微改了改网络规格,不过似乎精度影响不大
在这里插入图片描述
现在的情况是Adam这个优化算法,loss振荡还是比较明显的,我们把batch_size从64做大到128,然后学习率从0.01下降到1e-3,原来只学10epoch,现在学个30epoch。训练结果如下
在这里插入图片描述
好的精度上来了一点,想继续凹精度应该还可以,比如继续增加网络规模。

不过下面我们看看这个,标准化的函数

transform = transforms.Compose([
        transforms.ToTensor(),
        transforms.Normalize((0.1307,), (0.3081,))
    ])

可以参考一下这篇博客 https://zhuanlan.zhihu.com/p/476220305
这里简单理解就是,第一个输入0.1307是均值,第二个输入0.3081是方差。我们尝试把均值改极端一点

transform = transforms.Compose([
        transforms.ToTensor(),
        transforms.Normalize((300,), (0.3081,))
    ])

然后就成功的把他精度给玩坏了
在这里插入图片描述

疑惑点

最后这个我是有点不理解的

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(1, 10, kernel_size=3) #输入为1,输出为10,卷积核大小5
        self.conv2 = nn.Conv2d(10, 20, kernel_size=4)
        self.fc = nn.Linear(20 * 5 * 5, 10)
 
    def forward(self, x):
        batch_size = x.size(0)   #第一个维度是batch维度,图片为1*28*28时,输入为64*1*28*28
        x = torch.relu(self.conv1(x))  # 输入64*1*28*28, 输出64*10*26*26
        x = torch.max_pool2d(x, 2, 2)  # 输入64*10*26*26, 输出64*10*13*13,池化层
        x = torch.relu(self.conv2(x))  # 输入64*10*13*13, 输出64*20*10*10
        x = torch.max_pool2d(x, 2, 2)  # 输入64*20*10*10, 输出64*20*5*5
        x = x.view(batch_size, -1)     # 输入64*20*5*5, 输出64*500
        x = self.fc(x)                 # 输入64*500, 输出64*10
        return x

这里不是对数字分类吗?输出为啥是10?不应该是输出10是各个数字的概率,然后过个softmax啥的,最后预测是某种分类吗?
在这里插入图片描述
在这里插入图片描述
这…为啥呢?我手动给他加了让它输出成一维的

# 定义模型
class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(1, 10, kernel_size=3) #输入为1,输出为10,卷积核大小5
        self.conv2 = nn.Conv2d(10, 20, kernel_size=4)
        self.fc = nn.Linear(20 * 5 * 5, 10)
        self.fc2 = nn.Linear(10, 1)
 
    def forward(self, x):
        batch_size = x.size(0)   #第一个维度是batch维度,图片为1*28*28时,输入为64*1*28*28
        x = torch.relu(self.conv1(x))  # 输入64*1*28*28, 输出64*10*26*26
        x = torch.max_pool2d(x, 2, 2)  # 输入64*10*26*26, 输出64*10*13*13,池化层
        x = torch.relu(self.conv2(x))  # 输入64*10*13*13, 输出64*20*10*10
        x = torch.max_pool2d(x, 2, 2)  # 输入64*20*10*10, 输出64*20*5*5
        x = x.view(batch_size, -1)     # 输入64*20*5*5, 输出64*500
        x = self.fc(x)                 # 输入64*500, 输出64*10
        x = self.fc2(x)
        return x

然后果不其然就挂掉了,不过这个好像确实也不对。浮点数的预测结果和target肯定数据类型就对不上
在这里插入图片描述
注释掉这两行

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(1, 10, kernel_size=3) #输入为1,输出为10,卷积核大小5
        self.conv2 = nn.Conv2d(10, 20, kernel_size=4)
        self.fc = nn.Linear(20 * 5 * 5, 10)
        #self.fc2 = nn.Linear(10, 1)
 
    def forward(self, x):
        batch_size = x.size(0)   #第一个维度是batch维度,图片为1*28*28时,输入为64*1*28*28
        x = torch.relu(self.conv1(x))  # 输入64*1*28*28, 输出64*10*26*26
        x = torch.max_pool2d(x, 2, 2)  # 输入64*10*26*26, 输出64*10*13*13,池化层
        x = torch.relu(self.conv2(x))  # 输入64*10*13*13, 输出64*20*10*10
        x = torch.max_pool2d(x, 2, 2)  # 输入64*20*10*10, 输出64*20*5*5
        x = x.view(batch_size, -1)     # 输入64*20*5*5, 输出64*500
        x = self.fc(x)                 # 输入64*500, 输出64*10
        #x = self.fc2(x)
        return x

回退到原来的结果了理论,但是实际上他居然又挂掉了
在这里插入图片描述
这次好像是…GPU出问题了,刚才被我玩坏了…重启了一下pyder又可以用了。好吧今天先到这里吧,洗漱去了~

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是用PyTorch实现LeNet模型并训练Mnist数据集的示例代码: ```python import torch import torch.nn as nn import torch.optim as optim import torchvision.datasets as dsets import torchvision.transforms as transforms # 定义LeNet模型 class LeNet(nn.Module): def __init__(self): super(LeNet, self).__init__() self.conv1 = nn.Conv2d(1, 6, 5) self.pool1 = nn.MaxPool2d(kernel_size=2) self.conv2 = nn.Conv2d(6, 16, 5) self.pool2 = nn.MaxPool2d(kernel_size=2) self.fc1 = nn.Linear(16*4*4, 120) self.fc2 = nn.Linear(120, 84) self.fc3 = nn.Linear(84, 10) def forward(self, x): x = self.pool1(torch.relu(self.conv1(x))) x = self.pool2(torch.relu(self.conv2(x))) x = x.view(-1, 16*4*4) x = torch.relu(self.fc1(x)) x = torch.relu(self.fc2(x)) x = self.fc3(x) return x # 设置超参数 batch_size = 100 learning_rate = 0.001 num_epochs = 5 # 加载Mnist数据集 train_dataset = dsets.MNIST(root='./data', train=True, transform=transforms.ToTensor(), download=True) test_dataset = dsets.MNIST(root='./data', train=False, transform=transforms.ToTensor(), download=True) # 创建数据加载器 train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True) test_loader = torch.utils.data.DataLoader(dataset=test_dataset, batch_size=batch_size, shuffle=False) # 创建LeNet模型和优化器 model = LeNet() optimizer = optim.Adam(model.parameters(), lr=learning_rate) # 训练模型 total_step = len(train_loader) for epoch in range(num_epochs): for i, (images, labels) in enumerate(train_loader): images = images labels = labels # 前向传播 outputs = model(images) loss = nn.CrossEntropyLoss()(outputs, labels) # 反向传播和优化 optimizer.zero_grad() loss.backward() optimizer.step() # 输出训练状态 if (i+1) % 100 == 0: print('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}' .format(epoch+1, num_epochs, i+1, total_step, loss.item())) # 测试模型 model.eval() with torch.no_grad(): correct = 0 total = 0 for images, labels in test_loader: images = images labels = labels outputs = model(images) _, predicted = torch.max(outputs.data, 1) total += labels.size(0) correct += (predicted == labels).sum().item() print('Test Accuracy of the model on the 10000 test images: {} %'.format(100 * correct / total)) ``` 这个代码可以在Mnist数据集训练LeNet模型,并在测试集上计算模型的准确率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值