PyTorch中的模型创建

img

最全最详细的PyTorch神经网络创建~ 话不多说直接开始~

神经网络的创建步骤

  1. 定义模型类,需要继承nn.Module
  2. 定义各种层,包括卷积层、池化层、全连接层、激活函数等等
  3. 编写前向传播,规定信号是如何传输的

可以用 torchsummary 查看网络结构,如果没有的话,使用pip命令进行安装

Module: 神经网络的模板

代码语言:javascript

复制

import torch.nn as nn
import torch.nn.functional as F

class Model(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = nn.Conv2d(1,20, 5)
        self.conv2 = nn.Conv2d(20, 50, 5)

    def forward(self, x):
        x = F.relu(self.conv1(x))
        return  F.relu(self.conv2(x))
神经网络中常见的各种层

常见的层包括:卷积层,池化层,全连接层,正则化层,激活层

导入层有两种方法: 一种是将其看作一个类,在torch.nn里面 另一种是将其看作一个函数,在torch.nn.functional里面可以调用

全连接层

全连接层又称为线性层,所以函数名叫 Linear,执行的操作是𝑦=𝑥𝐴𝑇+𝑏

代码语言:javascript

复制

torch.nn.Linear(in_features, out_features, bias=True, device=None, dtype=None)
  • in_feature代表输入数
  • out_features代表输出数,即神经元数量

代码语言:javascript

复制

m = nn.Linear(2,3)
input = torch.randn(5, 2)
ouput = m(input)
print(ouput.size())

输出:torch.Size([5, 3])

先搭建个只有一层的网络,用 torchsummry 查看网络结构

代码语言:javascript

复制

from torch import nn
from torchsummary import summary
class NeuralNetwork( nn . Module):
    def _init_( self) :
        super()._init___()
        self.fc = nn.Linear(10,1,bias=False)# 如果 bias=True(默认),则有11个参数
def forward(self, x):
    x = self.fc(x)
    return x
if _name_ == '_main__':
    network = NeuralNetwork()# print( network)
    summary ( network,(10,))

自定义输入到网络中,得到输出

代码语言:javascript

复制

import torch
from torch import nn
from torchsummary import summary
class NeuralNetwork ( nn.Module):
    def _init_( self):
        super()._init___()
        self.fc = nn.Linear( 10,1)
    def forward(self,x ):
        x = self.fc(x)
        return x
if _name_ == '_main_':
    network = NeuralNetwork()

    input = torch.randn(10)
    print("input = " ,input)
    output = network( input)
    print( "output = ", output)
    result = output. detach( ) .numpy()
    print( "result = " , result)

多个 FC 层之间可以连接起来

代码语言:javascript

复制

class NeuralNetwork( nn.Module) :
    def _init_( self):
        super()._init_()
        self.fc_1 = nn.Linear ( 1000, 100)
        self.fc_2 = nn.Linear ( 100,10)
        self.fc_3 = nn.Linear( 10,5)
    def forward( self,x):
        ×= self.fc_1(x)
        ×= self.fc_2(x)
        x= self.fc_3(x)
        return x
激活函数

常见的激活函数包括 sigmoidrelu,以及softmax

Sigmoid

sigmoid是早期的激活函数

img

  • 将所有值压缩到0-1之间
ReLU

ReLU激活函数常放在全连接层、以及卷积层后面

img

调用方法都放在 nn.ReLU()

Softmax

softmax是在分类当中经常用到的激活函数,用来放在全连接网络的最后一层,Softmax函数通常用于多类分类问题的输出层,将输出转换为概率分布的形式。

img

代码语言:javascript

复制

import torch
import torch.nn as nn
m=nn.Softmax( dim=1)
input = torch.randn(43)
output = m( input)
  • nn.softmax的dim参数表示在哪个维度上进行softmax操作。默认值为1,表示在输入张量的第二个维度(即列)上进行softmax操作。
随机失活方法Dropout

FC层过多,容易对其中某条路径产生依赖,从而使得某些参数未能训练起来

为了防止上述问题,在 FC层之间通常还会加入随机失活功能,也就是Dropout

它通过在训练过程中随机失活一部分神经元,从而增强模型的泛化能力。

代码语言:javascript

复制

m=nn.Dropout( p=0.5)
input = torch.randn(68)
output = m( input)
  • 将一个列表,随机将一些值变为0
全连接网络处理一维信息

img

搭建以上的网络结构 ,组合全连接层,dropout层,激活函数,我们就可以构建出一个完整的全连接网络结构:

代码语言:javascript

复制

import torch
from torch import nn
from torchsummary import summary
class NeuralNetwork( nn.Module):
    def _init_( self):
        super()._init_()
        self.relu = nn.ReLU()
        self.softmax = nn.softmax(dim=1)
        self.dropout = nn.Dropout(0.5)
        self.fc_1 = nn.Linear(1000, 100)
        self.fc_2 = nn.Linear(100,10)
        self.fc_3 = nn.Linear(10, 5)
    def forward(self, x):
        x = x.view(-11000)# view的存在,可以自动适应batchsize
        x = self.dropout( self.relu( self.fc_1(x) ) )
        x = self.dropout( self.relu( self.fc_2(x) ) )
        x= self.softmax ( self.fc_3(x))
        return x
全连接网络处理二维图像

使用全连接网络处理二维图像信息,当二维特征(Feature Map)转为一维特征时,需要从高维压缩成一维,这时候可以用 tensor.view(),或者用nn.Flatten(start_dim=1)

代码语言:javascript

复制

import torch
import torch.nn as nn

# 创建一个输入张量
input_tensor = torch.randn(2, 3, 4)

# 创建Flatten层
flatten_layer = nn.Flatten(start_dim=1)

# 对输入张量进行展平操作
output_tensor = flatten_layer(input_tensor)

print("Input Tensor:")
print(input_tensor)
print("Output Tensor:")
print(output_tensor)



# 输出
Input Tensor:
tensor([[[-0.5968, -0.0790,  0.0597, -0.2250],
         [ 0.1564, -0.1564, -0.0790, -0.1564],
         [-0.1564, -0.1564, -0.1564, -0.1564]],

        [[ 0.1564, -0.1564, -0.1564, -0.1564],
         [-0.1564, -0.1564, -0.1564, -0.1564],
         [-0.1564, -0.1564, -0.1564, -0.1564]]])
Output Tensor:
tensor([[-0.5968, -0.0790,  0.0597, -0.2250,  0.1564, -0.1564, -0.0790, -0.1564],
        [-0.1564, -0.1564, -0.1564, -0.1564, -0.1564, -0.1564, -0.1564, -0.1564]])
卷积层

二维卷积

img

torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True, padding_mode=‘zeros’, device=None, dtype=None)

  • in_channels: 输入通道数
  • out_channels: 输出通道数(卷积核数量)
  • kernel_size: 卷积核大小
  • stride: 卷积步长
  • padding: 边缘补零
  • dilation: 扩散卷积
  • group: 分组卷积
  • bias: 是否带有偏置

代码语言:javascript

复制

import torch
import torch.nn as nn
#使用方形卷积核,以及相同的步长
m = nn.conv2d(16333, stride=2)
#使用非方形的卷积核,以及非对称的步长和补零
m = nn.conv2d(16,33,(35),stride=(21),padding=(42))
#使用非方形的卷积核,以及非对称的步长,补零和膨胀系数
m = nn.Conv2d(16,33,(35),stride=(21),padding=(42),dilation=(31))
input = torch.randn(201650100)
output = m( input)
print(output.shape)

转置卷积就是卷积的逆操作,也称为逆卷积、反卷积

torch.nn.ConvTranspose2d(in_channels, out_channels, kernel_size, stride=1, padding=0, output_padding=0, groups=1, bias=True, dilation=1, padding_mode=‘zeros’, device=None, dtype=None)

  • 输入:(𝑁,𝐶𝑖𝑛,𝐻𝑖𝑛,𝑊𝑖𝑛)或者(𝐶𝑖𝑛,𝐻𝑖𝑛,𝑊𝑖𝑛)
  • 输出:(𝑁,𝐶𝑜𝑢𝑡,𝐻𝑜𝑢𝑡,𝑊𝑜𝑢𝑡)或者(𝐶𝑜𝑢𝑡,𝐻𝑜𝑢𝑡,𝑊𝑜𝑢𝑡)

转置卷积是一种卷积神经网络中的操作,它的作用是将输入的特征图进行上采样,从而增加特征图的尺寸。转置卷积通常用于生成器网络中,将低分辨率的图像转换为高分辨率的图像。

代码语言:javascript

复制

import torch
import torch.nn as nn

# 定义一个转置卷积层
transposed_conv = nn.ConvTranspose2d(in_channels=3, out_channels=64, kernel_size=4, stride=2, padding=1)

# 创建一个输入张量,形状为 (batch_size, in_channels, height, width)
input_tensor = torch.randn(1, 3, 32, 32)

# 使用转置卷积层处理输入张量
output_tensor = transposed_conv(input_tensor)

print("输入张量的形状:", input_tensor.shape)
print("输出张量的形状:", output_tensor.shape)
搭建全卷积网络结构案例

代码语言:javascript

复制

import torch.nn as nn
import torch.nn.functional as F
import torch
from torchsummary import summary

class FCN(nn.Module):
    def __init__(self,num_classes):
        super(FCN,self).__init__()
        self.conv1 = nn.Conv2d(in_channels=3, out_channels=32, kernel_size=3).cuda()  # kernel_size=3, 卷积核大小
        self.conv2 = nn.Conv2d(in_channels=32, out_channels=64, kernel_size=3).cuda()
        self.conv3 = nn.Conv2d(in_channels=64, out_channels=128, kernel_size=3).cuda()

        self.upsample1 = nn.ConvTranspose2d(in_channels=128, out_channels=64, kernel_size=3).cuda()
        self.upsample2 = nn.ConvTranspose2d(in_channels=64, out_channels=32, kernel_size=3).cuda()
        self.upsample3 = nn.ConvTranspose2d(in_channels=32, out_channels=num_classes, kernel_size=3).cuda()
        # 最后的upsample3 输出通道数和标签类别一致

    def forward(self, x):
        x = F.relu(self.conv1(x))
        x = F.relu(self.conv2(x))
        x = F.relu(self.conv3(x))
        x = F.relu(self.upsample1(x))
        x = F.relu(self.upsample2(x))
        x = F.relu(self.upsample3(x))
        return  x

# 10个类别的图像分割
num_classes = 10
# 每个像素都会得到一个10维的特征向量,表示它属于每个类别的概率
fcn_model = FCN(num_classes)

print(fcn_model)
summary(fcn_model, (3, 224, 224))

输出:

代码语言:javascript

复制

FCN(
  (conv1): Conv2d(3, 32, kernel_size=(3, 3), stride=(1, 1))
  (conv2): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1))
  (conv3): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1))
  (upsample1): ConvTranspose2d(128, 64, kernel_size=(3, 3), stride=(1, 1))
  (upsample2): ConvTranspose2d(64, 32, kernel_size=(3, 3), stride=(1, 1))
  (upsample3): ConvTranspose2d(32, 10, kernel_size=(3, 3), stride=(1, 1))
)
----------------------------------------------------------------
        Layer (type)               Output Shape         Param #
================================================================
            Conv2d-1         [-1, 32, 222, 222]             896
            Conv2d-2         [-1, 64, 220, 220]          18,496
            Conv2d-3        [-1, 128, 218, 218]          73,856
   ConvTranspose2d-4         [-1, 64, 220, 220]          73,792
   ConvTranspose2d-5         [-1, 32, 222, 222]          18,464
   ConvTranspose2d-6         [-1, 10, 224, 224]           2,890
================================================================
Total params: 188,394
Trainable params: 188,394
Non-trainable params: 0
----------------------------------------------------------------
Input size (MB): 0.57
Forward/backward pass size (MB): 121.57
Params size (MB): 0.72
Estimated Total Size (MB): 122.86
----------------------------------------------------------------
搭建卷积+全连接的网络结构

代码语言:javascript

复制

import torch.nn as nn
import torch.nn.functional as F
import torch
from torchsummary import summary

class ConvNet(nn.Module):
    def __init__(self,num_classes=10):
        super(ConvNet,self).__init__()
        self.conv1 = nn.Conv2d(in_channels=3, out_channels=32, kernel_size=3).cuda()  # kernel_size=3, 卷积核大小
        self.conv2 = nn.Conv2d(in_channels=32, out_channels=64, kernel_size=3).cuda()

        # 全连接层
        self.flatten = nn.Flatten(start_dim=1).cuda()
        # 将输入张量从第1个维度开始展平
        self.fc1 = nn.Linear(64*28*28, 50).cuda()
        # 输入图像的大小为64x28x28,输出特征数为50
        self.fc2 = nn.Linear(50, num_classes).cuda()
        # 输入特征数为512,输出特征数为num_classes

    def forward(self, x):
        x = self.conv1(x)
        x = self.conv2(x)
        x = self.flatten(x)
        x = self.fc1(x)
        x = self.fc2(x)
        return  x

# 10个类别的图像分割
num_classes = 10
# 每个像素都会得到一个10维的特征向量,表示它属于每个类别的概率
conv_net = ConvNet(num_classes)

bacth_size = 4
input_tensor = torch.randn(bacth_size, 3, 32, 32).cuda()    # 输入是4张32x32的RGB图像
output = conv_net(input_tensor)

print(output.shape)
summary(conv_net, (3, 32, 32))

输出:

代码语言:javascript

复制

torch.Size([4, 10])
----------------------------------------------------------------
        Layer (type)               Output Shape         Param #
================================================================
            Conv2d-1           [-1, 32, 30, 30]             896
            Conv2d-2           [-1, 64, 28, 28]          18,496
           Flatten-3                [-1, 50176]               0
            Linear-4                   [-1, 50]       2,508,850
            Linear-5                   [-1, 10]             510
================================================================
Total params: 2,528,752
Trainable params: 2,528,752
Non-trainable params: 0
----------------------------------------------------------------
Input size (MB): 0.01
Forward/backward pass size (MB): 0.99
Params size (MB): 9.65
Estimated Total Size (MB): 10.64
----------------------------------------------------------------

Process finished with exit code 0
池化层

池化包含最大池化和平均池化,有一维池化,二维池化,三维池化,在这里以二维池化为例

最大池化就是求一个区域中的最大值,来代替该区域。

torch.nn.MaxPool2d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False)

img

输入参数 kernel_sizestridepaddingdilation可以是

  • 一个 int :代表长宽使用同样的参数
  • 两个int组成的元组:第一个int用在H维度,第二个int用在W维度

代码语言:javascript

复制

#长宽一致的池化,核尺寸为3x3,池化步长为2
m1 = nn.MaxPool2d( 3,stride=2)
#长宽不一致的池化
m2 = nn.MaxPool2d(( 32), stride=(21))
input = torch.randn(432424)
output1 = m1( input)
output2 = m2(input)
print( "input.shape = " ,input.shape)
print( "output1.shape = ", output1.shape)
print( "output2.shape = " , output2.shape)

input.shape = torch.size( [4,3,24,24]) output1.shape = torch.size([4,3,11,11]) output2.shape = torch.size([4,3,11,23])

平均池化

平均池化就是用一个区域中的平均数来代替本区域

torch.nn.AvgPool2d(kernel_size, stride=None, padding=0, ceil_mode=False, count_include_pad=True, divisor_override=None)

代码语言:javascript

复制

import torch
import torch.nn as nn
#长宽一致的池化,核尺寸为3x3,池化步长为2
m1 = nn.AvgPool2d( 3, stride=2)
#长宽不一致的池化
m2 = nn.AvgPool2d((32), stride=(21))
input = torch.randn( 432424)
output1 = m1( input)
output2 = m2(input)
print( "input.shape = " , input. shape)
print( "output1.shape = ", output1.shape)
print( "output2.shape = " , output2.shape)

input.shape = torch.size([4,3,24,24]) output1.shape = torch.size([4,3,11,11]) output2.shape = torch.size([4,3,11,23])

BN层

BN,即Batch Normalization,是对每一个batch的数据进行归一化操作,可以使得网络训练更稳定,加速网络的收敛。

img

代码语言:javascript

复制

#批量归一化层(具有可学习参数)
m_learnable = nn.BatchNorm2d( 100)
#批量归一化层(不具有可学习参数>
m_non_learnable = nn.BatchNorm2d(100,affine=False)
#随机生成输入数据
input = torch.randn(201003545)
#应用具有可学习参数的批量归一化层
output_learnable = m_learnable( input)
# 应用不具有可学习参数的批量归一化层
output_non_learnable = m_non_learnable(input)
print( "input.shape = ", input.shape)
print( "output_learnable.shape = ", output_learnable.shape)
print( "output_non_learnable.shape = ", output_non_learnable.shape)

input.shape = torch.size( [20,100,35,45]) output_learnable.shape = torch.size( [20,100,35,45]) output_non_learnable.shape = torch.size([20,100,35,45])

如何学习AI大模型 ?

“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。

这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。

我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。

我意识到有很多经验和知识值得分享给大家,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。【保证100%免费】🆓

对于0基础小白入门:

如果你是零基础小白,想快速入门大模型是可以考虑的。

一方面是学习时间相对较短,学习内容更全面更集中。
二方面是可以根据这些资料规划好学习计划和方向。

😝有需要的小伙伴,可以VX扫描下方二维码免费领取🆓

👉1.大模型入门学习思维导图👈

要学习一门新的技术,作为新手一定要先学习成长路线图,方向不对,努力白费。

对于从来没有接触过AI大模型的同学,我们帮你准备了详细的学习成长路线图&学习规划。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。(全套教程文末领取哈)
在这里插入图片描述

👉2.AGI大模型配套视频👈

很多朋友都不喜欢晦涩的文字,我也为大家准备了视频教程,每个章节都是当前板块的精华浓缩。

在这里插入图片描述
在这里插入图片描述

👉3.大模型实际应用报告合集👈

这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。(全套教程文末领取哈)

在这里插入图片描述

👉4.大模型落地应用案例PPT👈

光学理论是没用的,要学会跟着一起做,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。(全套教程文末领取哈)

在这里插入图片描述

👉5.大模型经典学习电子书👈

随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。(全套教程文末领取哈)
img

在这里插入图片描述

👉6.大模型面试题&答案👈

截至目前大模型已经超过200个,在大模型纵横的时代,不仅大模型技术越来越卷,就连大模型相关的岗位和面试也开始越来越卷了。为了让大家更容易上车大模型算法赛道,我总结了大模型常考的面试题。(全套教程文末领取哈)

在这里插入图片描述
👉学会后的收获:👈
基于大模型全栈工程实现(前端、后端、产品经理、设计、数据分析等),通过这门课可获得不同能力;

能够利用大模型解决相关实际项目需求: 大数据时代,越来越多的企业和机构需要处理海量数据,利用大模型技术可以更好地处理这些数据,提高数据分析和决策的准确性。因此,掌握大模型应用开发技能,可以让程序员更好地应对实际项目需求;

基于大模型和企业数据AI应用开发,实现大模型理论、掌握GPU算力、硬件、LangChain开发框架和项目实战技能, 学会Fine-tuning垂直训练大模型(数据准备、数据蒸馏、大模型部署)一站式掌握;

能够完成时下热门大模型垂直领域模型训练能力,提高程序员的编码能力: 大模型应用开发需要掌握机器学习算法、深度学习

这份完整版的 AI 大模型学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

😝有需要的小伙伴,可以Vx扫描下方二维码免费领取🆓

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值