Pytorch基础之神经网络(上)

352 阅读5分钟
参与拿奖:本文已参与「新人创作礼」活动,一起开启掘金创作之路

1.神经网络

随着神经科学、认知科学的发展,我们已经知道人类的智能行为都和大脑活动有关。 人类的大脑是一个可以产生意识、思想和情感的器官。受到人脑神经系统的启发,早期的 神经科学家构造了一种模仿人脑神经系统的数学模型,称为人工神经网络,简称神经网 络。在机器学习领域,神经网络是指由很多人工神经元构成的网络结构模型,这些人工神 经元之间的连接强度是可学习的参数。

1.1 神经元

image.png

1.2 多层感知机

image.png 多层感知器可以分为3个部分:输入层、隐藏层、输出层,其中隐藏层可以包括一层 或者多层;每一层都由若干神经元组成,每个神经元承担的计算功能包括线性加权和非线 性变换;层与层之间通过权值建立联系,后一层的每个神经元与前一层的每个神经元都产 生连接。

输入信号通过不断地进行线性变换(线性加权)和非线性变换(激活函数),逐渐将 输入信号向后一层传递,直到输出层。其中输入层和输出层的神经元个数往往是通过先验 的知识确定的,而隐藏层中每层的神经元个数以及使用的层数都是超参数。

1.3 激活函数

激活函数是神经网络中一个十分重要的概念,它的非线性使得神经网络几乎可以任意 逼近任何非线性函数。如果不使用激活函数,无论神经网络有多少层,其每一层的输出都 是上一层输入的线性组合,这样构成的神经网络仍然是一个线性模型,表达能力有限。

1.3.1 S型激活函数

image.png

image.png

1.3.2 ReLU及其变种

image.png

image.png

image.png

image.png

image.png

image.png

image.png

1.4 神经网络的训练过程

神经网络的运行过程分为三步:前向传播、反向传播、参数更新,通过不断迭代进行 模型参数的更新,以从数据中挖掘出有价值的信息,如图2-8所示。 1)前向传播:给定输入和参数,逐层向前进行计算,最后输出预测结果;

2)反向传播:基于前向传播得到的预测结果,使用损失函数得到损失值,然后计算 相关参数的梯度,该计算方法称为反向传播(back-propagation);

3)参数更新:使用梯度下降算法对参数进行更新,重复上述过程,逐步迭代,直到 模型收敛。

image.png

2.卷积操作

2.1 初始化数据

# input 输入数据
# weight 卷积核
# 移动步长 stride=(h,w) 设置移动格子数(包括左右和上下)

import torch
input=torch.tensor([[1,2,0,3,1],[0,1,2,3,1],[1,2,1,0,0],[5,2,3,1,1],[2,1,0,1,1]])
weight_kernel=torch.tensor([[1,2,1],[0,1,0],[2,1,0]])
print(input,weight_kernel)

image.png

将创建的数据以及卷积核reshape一下

# torch.reshape(input,(1,1,5,5)).shape #转换数据形状
input=torch.reshape(input,(1,1,5,5))
kernel=torch.reshape(weight_kernel,(1,1,3,3))

image.png

2.2 卷积操作

import torch.nn.functional as F
output=F.conv2d(input,kernel,stride=1)
print(output) #卷积结果

output1=F.conv2d(input,kernel,stride=2)
print(output1)

image.png

这里第一个卷积操作使用的是2维卷积核,卷积核大小为3x3,步长为1,原始数据为5x5的张量,卷积之后维数变为3x3;第二个卷积操作也是使用的2维卷积核,卷积核大小为3x3,原始数据为5x5的张量,卷积步长变为2,卷积之后结果维数变为2x2。

计算方式如下:

image.png

其中H表示原始数据的维数,p表示padding的数目,k表示卷积核大小,s表示步长。上述例子中,第一个卷积操作的计算公式为(5+0-3)//1+1,第二个卷积操作计算公式为(5+0-3)//2+1。

2.3 卷积实例

# kernel_size 卷积核大小
import torch
import torchvision
from torch.utils.data import DataLoader
import torch.nn as nn
from torch.nn import Conv2d #卷积
from torch.utils.tensorboard import SummaryWriter


# 加载数据集
dataset=torchvision.datasets.CIFAR10('./data/02 data',train=False,transform=torchvision.transforms.ToTensor(),download=True)

dataloader=DataLoader(dataset,batch_size=64)

class myConv(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1=Conv2d(in_channels=3,out_channels=6,kernel_size=3,stride=1,padding=0)#卷积层
    
    def forward(self,x): #前向传播
        x=self.conv1(x)
        return x
    
my_conv=myConv()
# print(my_conv)


writer=SummaryWriter("myConv")
step=0
for data in dataloader:
    imgs,targets=data
    output=my_conv(imgs)
    writer.add_images("input",imgs,step)
    
    output=torch.reshape(output,(-1,3,30,30))
    writer.add_images("output",output,step)
    
    step+=1
    print(imgs.shape,output.shape)
writer.close()  
        

image.png

3.池化

3.1 概念

池化操作的主要目的是降维,以降低计算量,并在训练初期提供一些平移不变性。 常用的两种池化操作是平均池化和最大值池化。

池化操作就是使用一个固定大小的滑窗在输入上滑动,每次将滑窗内的元素聚合为一 个值作为输出。根据聚合方式的不同,可以分为平均池化和最大值池化。

image.png

3.2 实例

import torch
from torch import nn
from torch.nn import MaxPool2d
from torch.utils.data import DataLoader


input=torch.tensor([[1,2,0,3,1],[0,1,2,3,1],[1,2,1,0,0],[5,2,3,1,1],[2,1,0,1,1]],dtype=torch.float32)
input=torch.reshape(input,(-1,1,5,5))
print(input.shape)



class myConv(nn.Module):
    def __init__(self):
        super().__init__()
        self.maxpool1=MaxPool2d(kernel_size=3,ceil_mode=True) #池化
    def forward(self,input):
        output=self.maxpool1(input)
        return output
        
my_conv2=myConv()
output=my_conv2(input)
print(output)

from torch.utils.tensorboard import SummaryWriter
dataset=torchvision.datasets.CIFAR10('./data/02 data',train=False,transform=torchvision.transforms.ToTensor(),download=True)
dataloader=DataLoader(dataset,batch_size=64)

writer=SummaryWriter("myConvPooling")
step=0
for data in dataloader:
    imgs,targets=data
    writer.add_images("input",imgs,step)
    output=my_conv2(imgs)
    writer.add_images("output",output,step)
    step+=1
writer.close()

image.png

参考资料

[1] 深入浅出图神经网络

[2] b站课程链接

[3] 手敲代码链接