学习记录 —— pytorch example for MNIST

代码来自:mnist

 

from __future__ import print_function
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

class Net(nn.Module):
    def __init__(self):
        super(Net,self).__init__()
        self.conv1 = nn.Conv2d(1, 10, kernel_size=5)
        self.conv2 = nn.Conv2d(10, 20, kernel_size=5)
        self.conv2_drop = nn.Dropout2d()
        self.fc1 = nn.Linear(320, 50)
        self.fc2 = nn.Linear(50, 10)

    def forward(self, x):
        x = F.relu(F.max_pool2d(self.conv1(x), 2))
        x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2))
        x = x.view(-1, 320)
        x = F.relu(self.fc1(x))
        x = F.dropout(x, training=self.training)
        x = self.fc2(x)
        return F.log_softmax(x, dim=1)

导入包,pytorch的一些函数功能见:pytorch中文文档

定义Net类,定义初始化。在定义一个类的时候 

 def __init__(self):

是必须的,其中对于 self 的理解,这里说的比较详细:self

这里有个 super()

 super(Net,self).__init__()

非常好用的继承。

 

接下来就是对于

self.conv1 = nn.Conv2d(1, 10, kernel_size=5)

nn.Conv2d()及参数的理解:

在这里,2维卷积和tf里的思路是一样的,tf 2维卷积有个文章理解的比较详细:Conv2d

pytorch有一篇文章:Conv2d

有个

x.view(-1, 320)

后面还有一个

target.view_as(pred)

与reshape操作是一样的,将其变换成为指定的形状。

def train(args, model, device, train_loader, optimizer, epoch):
    model.train() # When using PyTorch for training and testing, be sure to specify the train/eval for the instantiated model.
    for batch_idx, (data, target) in enumerate(train_loader):
        data, target = data.to(device), target.to(device)
        optimizer.zero_grad()
        output =  model(data)
        loss = F.nll_loss(output, target)
        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()))

def test(args, 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
            pred = output.max(1,keepdim=True)[1]# 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)))
optimizer.zero_grad() 是指将梯度清零
optimizer.step()是指更新全部的参数

其中在定义train()\test()时,要特别注意,使用PyTorch进行训练和测试时一定注意要把实例化的model指定train/eval

model.train()/model.eval()

对于在搭建网络中的问题,会看到在搭网络的时候需要搭一个 forward()前传,但是反传就不需要再搭了,直接使用即可。这是因为

在pytorch中只需要定义forward函数即可, 反向传播backward的部分在你使用autograd时会自动生成.

forward函数中可以对Tensor进行任何操作.

一个模块可学习的参数都在net.parameters

理解 backward()

 

我用的笔记本跑的,将batch_size调整到了4,原先是64,结果如图:

MNIIST识别效果非常好,因为minist几乎是线性可分的。

来自科大佬举例:

K:只是说几乎线性可分,我打个比方,我甚至可以用某个点有没有黑色来区分某两类,

S:但是线性可分 对于10类图片来说, 我怎么能可视化的理解呢

K:线性可分意味着一个超平面能把它分开,可视化嘛,也许可以降到三维来可视化

S:一个超平面分开10类吗还是 一个分开两类 要好几个分开10类

K:一个分开两类~

S:我其实是想知道 他为啥好分

K:几乎线性,我的意思是超平面也会分错,所以SVM才会有个惩罚系数

欸。。。 所以为什么好分呢

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值