pytorch学习(六)—定义一个CNN网络

作者: 侠之大者_7d3f | 来源:发表于2018-12-22 00:21 被阅读3次

    CNN网络

    前面的文章都是pytorch中的一些基础内容,现在终于开始学习如何定义CNN网络了。Exceting!


    目的

    使用pytorch定义一个简单LetNet-5的网络。


    开发/实验环境

    • Ubuntu 18.04
    • pytorch 1.0
    • pycharm
    • Anaconda 3 , python 3.6.6

    关于CNN网络

    CNN (Convolution Neural Network) 卷积神经网络主要卷积层,激活层,池化层,Dropout, batch Normal 等层按照一定的顺序组成。不同的深度学习框架中,网络的定义方式有所差别,本人学习过Caffe, 回忆一下caffe中CNN网络如何定义。

    Caffe框架当初设计的原则是不需要写代码,网络定义采用prototxt文件。prototxt文件和JSON很相似。


    pytorch 中 卷积神经网络的定义方式

    关于LetNet-5

    LetNet-5是最经典的CNN网络之一,由卷积层激活层池化层全连接层组成。

    image.png

    定义CNN网络

    import torch
    import torch.nn as nn
    import torch.nn.functional as F
    
    
    '''
    CNN计算
    
    (H - k +2 * P) / S + 1
    (W - k +2 * P) / S + 1
    
    LetNet-5 
    input: 32*32*3
    
    out_conv1 = (32-5)+1 = 28 
    max_pool1 = 28 / 2 = 14
    out_conv2 = (14 - 5) + 1 = 10
    max_pool2 = 10 / 2 = 5
    '''
    
    '''
    
    定义一个神经网络
    
    https://pytorch.org/tutorials/beginner/blitz/neural_networks_tutorial.html#sphx-glr-beginner-blitz-neural-networks-tutorial-py
    '''
    
    
    class Net(nn.Module):
        def __init__(self):
            super(Net, self).__init__()
            #  conv1层,输入的灰度图,所以 in_channels=1, out_channels=6 说明使用了6个滤波器/卷积核,
            # kernel_size=5卷积核大小5x5
            self.conv1 = nn.Conv2d(in_channels=1, out_channels=6, kernel_size=5)
            # conv2层, 输入通道in_channels 要等于上一层的 out_channels
            self.conv2 = nn.Conv2d(in_channels=6, out_channels=16, kernel_size=5)
            # an affine operarion: y = Wx + b
            # 全连接层fc1,因为32x32图像输入到fc1层时候,feature map为: 5x5x16
            # 因此,全连接层的输入特征维度为16*5*5,  因为上一层conv2的out_channels=16
            # out_features=84,输出维度为84,代表该层为84个神经元
            self.fc1 = nn.Linear(16*5*5, 120)
            self.fc2 = nn.Linear(in_features=120, out_features=84)
            self.fc3 = nn.Linear(in_features=84, out_features=10)
    
        def forward(self, x):
            # Max pooling over a (2, 2) window
            x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
            # If the size is a square you can only specify a single number
            x = F.max_pool2d(F.relu(self.conv2(x)), 2)
            # 特征图转换为一个1维的向量
            x = x.view(-1, self.num_flat_features(x))
            x = F.relu(self.fc1(x))
            x = F.relu(self.fc2(x))
            x = self.fc3(x)
            return x
    
        def num_flat_features(self, x):
            size = x.size()[1:]     # all dimensions except the batch dimension
            num_features = 1
            for s in size:
                num_features *= s
            return num_features
    
    
    net = Net()
    print(net)
    
    

    输出:


    image.png

    网络的参数

    网络可学习(learnable)参数: w权重, b偏置

    # The learnable parameters of a model are returned by net.parameters()
    params = list(net.parameters())
    

    测试一个样例

    LetNet-5 输入样本为:32x32x1 的图像
    torch.randn(1, 1, 32, 32) 输出一个1(nSample)x1(channels)x32(width)x32(width)的Tensor

    # Try a random 32x32 input
    input = torch.randn(1, 1, 32, 32)
    out = net(input)
    print(out)
    

    输入tensor: 1x1x32x32


    image.png

    输出tensor:1x10 (10个类别的概率)


    image.png image.png

    End

    参考:
    https://pytorch.org/docs/stable/nn.html#pooling-layers

    相关文章

      网友评论

        本文标题:pytorch学习(六)—定义一个CNN网络

        本文链接:https://www.haomeiwen.com/subject/rwpbkqtx.html