Day-25 PyTorch 的 CNN Model

  • 我们昨天提过 CNN 的结构就是两层 卷积层 + 池化层 的结构,并在後面接一个简单的 NN
  • 那就让我们来看看 PyTorch 有什麽办法做到上面的状况吧~

PyTorch CNN

  • 第一步当然是建立 Model 框架
class ConvNet(nn.Module):

    def __init__(self):
        # model layers
        
    def forward(self, x):
        # model structure
  • 那首先我们要把第一层的卷积层跟池化层做出来,因此我们要分别宣告 nn.Conv2dnn.MaxPool2d,那位啥这边是使用 MaxPool 的原因我们昨天有解释过了,那我们先看 code 在解释一下里面的参数
  • 下面的程序码是基於手写辨识资料集做撰写的,後面我们对照资料集应该会更加理解,我们先解释要注意哪些部份来建立 CNN
import torch
import torch.nn as nn
import torch.nn.functional as F

class ConvNet(nn.Module):
    def __init__(self):
        super(ConvNet, self).__init__()
        # image shape is 1 * 28 * 28, where 1 is one color channel
        # 28 * 28 is the image size
        self.conv1 = nn.Conv2d(in_channels=1, out_channels=3, kernel_size=5)    # output shape = 3 * 24 * 24
        self.pool = nn.MaxPool2d(kernel_size=2, stride=2)                       # output shape = 3 * 12 * 12
        # intput shape is 3 * 12 * 12
        self.conv2 = nn.Conv2d(in_channels=3, out_channels=9, kernel_size=5)    # output shape = 9 * 8 * 8
        # add another max pooling, output shape = 9 * 4 * 4
        self.fc1 = nn.Linear(9*4*4, 100)
        self.fc2 = nn.Linear(100, 50)
        # last fully connected layer output should be same as classes
        self.fc3 = nn.Linear(50, 10)

        
    def forward(self, x):
        # first conv
        x = self.pool(F.relu(self.conv1(x)))
        # second conv
        x = self.pool(F.relu(self.conv2(x)))
        # flatten all dimensions except batch
        x = torch.flatten(x, 1)
        # fully connected layers
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)

        return x
  • 那我们一个一个来看,首先我们宣告了第一个卷积层,那卷积层中有几个基本参数要给,分别是
    • in_channels:输入的图片通道数,这边大部分会是图片的颜色状况,例如灰阶图片只有一个通道,RGB 的图片会有三个通道
    • out_channels:输出的通道数,这边基本上没有特别的限制,可以视自己喜好给予,只要记住往下一层送时,这边会变成另外一层的 in_channels
    • kernel_size:这也就是我们的 feature filter 的 size,有两种表达参数的方式,
      • 第一是如上面示范一样,给予单参数,会被视为 num * num 的 feature filter
      • 另一种是写成 kernel_size = (num1, num2) 就会是 num1 * num2 的 feature filter,请注意,feature filter 并没有规定一定要是正方形,因此可以视喜好调整
    • stride:在 feature filter 遍历图片时,每次移动的步数可以不是一格一格移动,此参数就会设定每次卷积移动的步伐大小,那预设会是 1,因此我们上面没有特别调整
  • 那这样我们就可以设定好一个卷积层要做的行为了,第二步就是给予池化层,那池化层一样有些参数可以给,分别是
    • kernal_size:同上叙述的,也就是 pooling 每次要覆盖的资料量
    • stride:同上叙述,也就是池化每次的步数
  • 那我们在注解的部分已经有说明了每个行为之後的资料形状,因此应该有辅助大家理解每一个操作之後的资料状况
  • 那我们在做完两次卷积+池化之後,我们要摊平资料并丢到 fully connected 做训练,这个部分可以是任意简单的神经网络,因此我们这边设计成一个三层的 feed-forward network
  • 最後依照整个流程把神经网络的 forward 建立起来就建立好资料了~

每日小结

  • 到今天我们成功建立了一个在深度学习领域中有代表性地位的神经网络架构,到这里还是要强调一句,为何我们前面要时常强调基础概念一定要建立好,因为到今天我们整个架构的建立,仍然没有脱离对神经网络架构的建立重现,因此只要我们知道整个网络架构,要实现是非常非常简单的
  • 我们到这里也算是达到深度学习领域的一个小里程碑了,那最後最後当然要使用看看 CNN 的威力来致敬这个伟大的神经网络啦~从明天开始就让我们开始辨识手写数字吧~

<<:  [ Day 25 ] 实作一个 React.js 网站 1/5

>>:  Day25 :【TypeScript 学起来】Class 的继承、修饰符、abstract、static

卡夫卡的藏书阁【Book29】- Kafka - MirroMaker 2

“I need solitude for my writing; not 'like a herm...

Day_07 有线网路应用(一)

接下来几篇都会是有线网路的应用,让设备与树莓派都可以连上网路,当成主路由、无线分享器或区网无线接入的...

django新手村11-----缓存

缓存对於服务器的好处,在於使用者会将数据加载到内存,减少了对资料库的访问 终端输入 python m...

Day14:内建的 suspend 函式,好函式不用吗? (3)

这是我们内建的 suspend 函式第三篇,让我们看看有哪些吧: joinAll() 还记得 joi...

不只懂 Vue 语法:为什麽要用 Vuex? Vuex 基本架构是怎样?

问题回答 使用 Vuex 是为了当元件之间都需要共用资料时,使用一个像是公用容器来管理资料,我们把所...