神经网络搭建 的 基本构架介绍(附代码)

参考教程:B站up主:我是土堆
1. dir ( ) 与 help ( ) 函数 —— 学习时常用
import torch

# 打印 package 下的子分类
print(dir(torch))
print(dir(torch.cuda))
print(dir(torch.cuda.is_available))

# 打印 函数的使用方法
print(help(torch.cuda.is_available))
2. 快捷键

Tab — 缩进、Ctrl — 查看函数具体信息、Ctrl + / — 注释

3. GPU训练
# 利用GPU训练神经网络:提升训练速度,远快于CPU

import torch

# 方法一:针对 “神经网络模型” “损失函数” “数据(训练集、验证集的值及其对应标签)” 使用 GPU 训练
if torch.cuda.is_available():
    model_name = model_name.cuda()
    loss_fn = loss_fn.cuda()
    zhi = zhi.cuda()
    label = label.cuda()

# 方法二:设置 “训练设备”
Device = torch.device("cuda")
# 若电脑含多张显卡:
# 指定训练设备为第一个cuda
Device = torch.device("cuda:0")
# 指定训练设备为第二个cuda
Device = torch.device("cuda:1")

Device = torch.device("cpu")

# 语法糖
Device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

# 以下两种写法等价
model_name = model_name.to(Device)
model_name.to(Device)
loss_fn = loss_fn.to(Device)
loss_fn.to(Device)

# 注意:训练集、验证集的值及其对应标签 仅能以该形式设置训练设备
zhi = zhi.to(Device)
label = label.to(Device)
4. pytorch 框架下的 “数据加载”

两个实用类:dataset ( ) 及 dataloader ( ):

注:Epoch & Iteration & Batchsize:

Epoch: 所有训练样本都已输入至模型内一次,称为一个 Epoch

Iteration:一批 (一个Batch) 样本输入至模型内,称为一个 Iteration

(输入一个 Batch / 经历一次 Iteration,更新一次模型参数)

Batchsize:批 (Batch) 大小,决定一个 Epoch 有多少个 Iteration:

也即:num (Iteration) = num (train_data) / Batchsize

5. nn.Module:神经网络搭建 的 基本骨架
import torch
from torch import nn

# "container" —— 神经网络的基础模板,可修改其为更复杂的结构
# 继承父类 "nn.Module"
class model_name (nn.Module):
    def __init__(self):
        super().__init__()
    # 前向传播,input-神经网络的输入
    def forward(self,input):
        output = input + 1
        return output

# 模型实例创建
module_1 = model_name()

# 创建一个张量,作为模型的输入
x = torch.tensor(2.)

# 输出:经神经网络处理后的结果
y = module_1(x)
print(y)
6. 卷积操作

理解:“卷积” 操作内的 "步幅 stride" 及 "外围填充 padding" 的设置:

空洞卷积,可增加 “感受野”:(设置 "dilation" 参数)

Q:写出:output_1、output_2、output_3的结果

import torch
import torch.nn.functional as F

# 创建被卷积的 tensor(外围有n个[] → n维tensor)
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]])

# 创建卷积核
kernel = torch.tensor([[1,2,1],
                       [0,1,0],
                       [2,1,0]])

# 变幻被卷积的 tensor 和卷积核的 shape
input = torch.reshape(input, (1,1,5,5))
kernel = torch.reshape(kernel,(1,1,3,3))

output_1 = F.conv2d(input,kernel,stride=1)
print(output_1)

# 调整步幅 stride(stride可以为数字或元组,如:tuple(1,2) —— 横向步幅:1,纵向步幅:2)
output_2 = F.conv2d(input,kernel,stride=2)
print(output_2)

# 用 “0” 填充 input 的外围一层(padding可以为数字或元组)
output_3 = F.conv2d(input,kernel,stride=2,padding=1)
print(output_3)
7. 池化操作

Q:写出:output 的结果,若 "ceil_mode=False",output 又将为何值?

import torch
from torch import nn
from torch.nn import MaxPool2d

# 创建被池化的 tensor(外围有n个[] → n维tensor)
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)

# 定义含 “池化层” 的网络模型
class pool_net(nn.Module):

    def __init__(self):
        super(pool_net, self).__init__()
        # 定义 “池化核” 的大小,注意:默认情况下,stride = kernel_size
        self.pool_layer = MaxPool2d(kernel_size=3, ceil_mode=True)

    def forward(self, input):
        output = self.pool_layer(input)
        return output

# 变幻被池化的 tensor
input = torch.reshape(input, (-1, 1, 5, 5))

# 将 input 置于定义好的池化网络内
model = pool_net()
output = model(input)
print(output)
8. 常用的非线性激活函数

引入非线性激活函数的目的:

旨在帮助网络学习数据中的复杂模式,对所有隐藏层及输出层添加 “非线性” 的操作,使得神经网络的输出更为复杂、表达能力更强

注意:绝大多数神经网络借助某形式的梯度下降进行参数优化,故:激活函数需要是可微分的

(或者至少是几乎完全可微分的)

9. 线性层(全连接层) 

概念:各神经元都与上下层各神经元相连,一个简单的 “线性层(全连接层)” 如下所示:

具体函数:

# in_features & out_features:输入(出)特征数;bias:偏置项(默认为True)
torch.nn.Linear (in_features, out_features, bias=True, device=None, dtype=None)

tip:torch.flatten ( ) 函数被用于 “拉平” 矩阵

10. Drop - out 操作:丢弃部分数据,避免过拟合

11. Sequential 的使用

Q:练习:写出下列图示的网络结构(使用 pytorch 框架):

 代码如下:

 1)不使用 Sequential 时的解答:

import torch
from torch import nn
from torch.nn import Flatten

# 搭建图示网络
class M (nn.Module):

    # 定义后续将使用的网络模块
    def __init__ (self):
        super(M, self).__init__()
        self.conv_1 = nn.Conv2d(3, 32, 5, padding=2)
        self.pool_1 = nn.MaxPool2d(2)
        self.conv_2 = nn.Conv2d(32, 32, 5, padding=2)
        self.pool_2 = nn.MaxPool2d(2)
        self.conv_3 = nn.Conv2d(32, 64, 5, padding=2)
        self.pool_3 = nn.MaxPool2d(2)
        self.flat = Flatten()
        self.linear_1 = nn.Linear(1024, 64)
        self.linear_2 = nn.Linear(64, 10)

    # 定义前向传播
    def forward(self, input):
        input = self.conv_1(input)
        input = self.pool_1(input)
        input = self.conv_2(input)
        input = self.pool_2(input)
        input = self.conv_3(input)
        input = self.pool_3(input)
        input = self.flat(input)
        input = self.linear_1(input)
        input = self.linear_2(input)
        return input

# 初始化上述定义的神经网络
m1 = M()

# 测试
q = torch.ones((64,3,32,32))
t = m1(q)
print(t.shape)

# 预计输出:torch.Size([64, 10])

 2)使用 Sequential 时的解答:(有助于简化网络搭建过程)

import torch
from torch import nn
from torch.nn import Flatten, Sequential


# 搭建图示网络
class M (nn.Module):
    # 定义后续将使用的网络模块
    def __init__ (self):
        super(M, self).__init__()
        # 使用 Sequential,有助于简化网络搭建过程,如下所示,以此类推
        self.model1 = Sequential (
        nn.Conv2d(3, 32, 5, padding=2),
        nn.MaxPool2d(2),
        nn.Conv2d(32, 32, 5, padding=2),
        nn.MaxPool2d(2),
        nn.Conv2d(32, 64, 5, padding=2),
        nn.MaxPool2d(2),
        Flatten(),
        nn.Linear(1024, 64),
        nn.Linear(64, 10)
        )
    # 定义前向传播
    def forward(self, input):
        input = self.model1(input)
        return input

# 初始化上述定义的神经网络
m1 = M()

# 测试
q = torch.ones((64,3,32,32))
t = m1(q)
print(t.shape)
12. Pytorch 下现有模型 的 引入及使用
import torch
import torchvision
from torch import nn


# 以 VGG16 神经网络为例
# 不含预训练参数的网络结构
vgg16_False = torchvision.models.vgg16(pretrained = False)
# 含有预训练参数的网络结构
vgg16_True = torchvision.models.vgg16(pretrained = True)

# 向 pytorch 框架提供的神经网络添加模块,进行结构修改
vgg16_False.add_module('linear_1',nn.Linear(1000,10))
13. 模型的保存及加载

方法一:同时保存:模型的网络结构 及 模型参数:

import torch
import torchvision

# method 1
# 以 torchvision 内的 vgg 模型为例
model_vgg = torchvision.models.vgg16(pretrained=False)
# 模型保存(输入 待保存的模型 及 模型保存的路径名称)
torch.save(model_vgg, 'vgg.path')

# 模型加载(注意:若“保存”与“加载”不在同一python文件内,则需"import")
model_load = torch.load('vgg.path')
print(model_load)

方法二:仅保存:模型参数(占用内存更小):

import torch
import torchvision

# method 2
# 以 torchvision 内的 vgg 模型为例
model_vgg = torchvision.models.vgg16(pretrained=False)
# 模型保存(输入 待保存的模型 及 模型保存的路径名称)
torch.save(model_vgg.state_dict(), 'vgg.path')

# 模型加载
vgg_16 = torchvision.models.vgg16(pretrained=False)
model_load = vgg_16.load_state_dict(torch.load('vgg.path'))
print(model_load)

14. 损失函数 及 优化器

注:损失函数 “指导” 网络参数的优化更新,借助于 “优化器” 

代码示例如下:

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值