PyTorch卷积神经网络各层实现与介绍

news2024/10/6 0:30:36

本文将讲解,PyTorch卷积神经网络各层实现与介绍,包括:基本骨架–nn.Module的使用、卷积操作、卷积层、池化层、激活函数、全连接层的介绍。

😜 对于相关原理,可以跳转👉卷积神经网络CNN各层基本知识

😜 后续会以CIFAR10数据集作为案例,关于CIFAR10数据集在上篇中有详细的介绍,可以跳转👉Pytorch公共数据集、tensorboard、DataLoader使用。

基本骨架–nn.Module的使用

torch.nn模块包含着torch已经准备好的层,方便使用者调用构建网络,一下内容包括nnModule而极少、卷积操作的简单操作、卷积层、池化层、激活函数、全连接层以及其他层的相关使用方法

neural network

在这里插入图片描述

torch.nn模块包含着torch已经准备好的层,方便使用者调用构建网络。后文将介绍卷积层、池化层、激活函数层、循环层、全连接层的相关使用方法。

Module:位于containers容器中

在这里插入图片描述

'''神经网络模板'''
#https://beishan.blog.csdn.net/
import torch.nn as nn
import torch.nn.functional as F


class Model(nn.Module):  # nn.Module为其父类,Model继承它

    def __init__(self):
        super().__init__()  #调用父类的初始化函数
        self.conv1 = nn.Conv2d(1, 20, 5)
        self.conv2 = nn.Conv2d(20, 20, 5)

    def forward(self, x):  #用于定义神经网络的前向传播过程
        x = F.relu(self.conv1(x))  #卷积->非线性处理
        return F.relu(self.conv2(x))  #卷积->非线性处理->return

代码解释如下:

forward 函数是深度学习框架中常见的一个函数,用于定义神经网络的前向传播过程。

forward 函数的作用是将输入数据经过网络中各个层的计算和变换后,得到输出结果。

在这里插入图片描述

在这里插入图片描述

在上述代码中,forward函数:对输入的x进行第一次卷积,再进行第一次非线性操作;再第二次进行卷积,然后第二次非线性操作。最后返回结果。

搭建自己的网络

import torch.nn as nn
import torch
class Beishan(nn.Module):

    def __init__(self):
        super().__init__()

    def forward(self, input):
        output = input * 2
        return output


bs = Beishan()
x = torch.tensor(1.0)
print(bs(x))
tensor(2.)

卷积操作

卷积可以看作输入和卷积核之间的内积运算,是两个实值函数之间的一种数学运算

在Pytorch中针对卷积操作的对象和使用场景的不同,有一维卷积、二维卷积、三位卷积与转置卷积(可以简单理解为卷积操作的逆操作),但他们的使用方法类似,都可以从torch.nn模块中调用

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

接下来将以torch.nn.functional.conv2d()为例进行讲解,后续的层的讲解,将以torch.nn作为案例

torch.nn.functional.conv2d(input,
                           weight, 
                           bias=None,
                           stride=1,
                           padding=0,
                           dilation=1, 
                           groups=1) 

在这里插入图片描述

参数解释
input输入图像的通道数
weight卷积核的大小
bias可选的偏置张量的形状(输出通道)(输出通道),默认值:无
stride卷积的步长,默认为1
padding在输入两边进行0填充的数量,默认为0
dilation控制卷积核之间的间距

需要注意的是:在这里插入图片描述

input中的shape:

  • minibatch:batch中的样例个数,
  • in_channels:每个样例数据的通道数,
  • iH:每个样例的高(行数),
  • iW:每个样例的宽(列数)

weight中的shape:

  • out_channels:卷积核的个数
  • in_channels/groups:每个卷积核的通道数
  • kH:每个卷积核的高(行数)
  • kW:每个卷积核的宽(列数)
  1. padding
    就是填充的意思,将图像数据的边缘部分填充的大小,通过padding可以使得卷积过程中提取到图像边缘部分的信息
  2. stride
    卷积核移动的步长,即卷积核完成局部的一次卷积后向右移动的步数,步长增大可以减小特征图的尺寸计算速度提升。适用于高分辨率的图像

在这里插入图片描述

接下来将以下图的卷积操作,其中padding和stride都是默认值。即padding=0,stride=1,利用Pytorch进行验证运算

在这里插入图片描述

import torch.nn.functional as F
import torch

# input
input_ = torch.tensor([[3, 3, 2, 1, 0], 
                       [0, 0, 1, 3, 1], 
                       [3, 1, 2, 2, 3],
                       [2, 0, 0, 2, 2], 
                       [2, 0, 0, 0, 1]])
# 卷积核
kernel = torch.tensor([[0, 1, 2], 
                       [2, 2, 0],
                       [0, 1, 2]])

# print,input_.shape,kernel.shape
print(input_.shape)
print(kernel.shape)
# 由上面可以知道.shape不满足需求,而是只有h和w的2个数据,利用reshape进行变换

input_ = torch.reshape(input_, (1, 1, 5, 5))  # 表示样例个数1,每一个样例数据的通道数1,高5,宽5
kernel = torch.reshape(kernel, (1, 1, 3, 3))

# 进行conv2d卷积运算
output = F.conv2d(input_, kernel, stride=1)  # stride=1即每一次只进行一步移动操作
print(output)
torch.Size([5, 5])
torch.Size([3, 3])
tensor([[[[12, 12, 17],
          [10, 17, 19],
          [ 9,  6, 14]]]])

在后续的层的讲解中,将以torch.nn作为案例。后续会更新

在这里插入图片描述

卷积层

这里主要介绍代码部分,对于相关原理,可以查看 https://beishan.blog.csdn.net/article/details/128058839

import torch.nn as nn
#其中in_channels,ut_channels,kernel_size需要进行设置,其他均有默认值
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_channelsout_channelskernel_sizestridepadding

Conv2d参数说明
in_channels表示输入的图片通道数目。
out_channels表示输出的图片通道数目。
kernel_size表示卷积核的大小,当卷积是正方形的时候,只需要一个整数边长即可,卷积不是正方形,要输入一个元组表示高和宽。
stride表示每次卷积核移动的步长值。
padding表示是否添加边界,一旦设置就是四周都添加。在原始的行列基础上,行增加2行,列增加2列。
dilation表示控制卷积核之间的间距。
groups表示控制输入和输出之间的连接。
bias表示是否将一个 bias 增加到输出。
padding_mode表示接收’zeros’, ‘reflect’, ‘replicate’ or ‘circular’. Default: ‘zeros’,默认是’zeros’,即默认在padding操作时,在外一圈是填充的0。

卷积层操作实战
下面代码以CIFAR10数据集为例进行实践

关于CIFAR10数据集在上篇中有详细的介绍,可以跳转☞Pytorch公共数据集、tensorboard、DataLoader使用。后续的操作也是以CIFAR10数据集为案例

import torch
import torchvision
import torch.nn as nn
from torch.utils.data import DataLoader
dataset = torchvision.datasets.CIFAR10("dataset",train=False,transform=torchvision.transforms.ToTensor(),download=True)
dataloader = DataLoader(dataset,batch_size=64)
Files already downloaded and verified
class BS(torch.nn.Module):
    def __init__(self):
        super().__init__()
        # 即输入通道设定为RGB3层,输出通道设定为6,卷积核大小为3,步长设定1,不进行填充
        self.conv1 = nn.Conv2d(in_channels=3,
                               out_channels=6,
                               kernel_size=3,
                               stride=1,
                               padding=0)

    def forward(self,x):
        return self.conv2(x)
bs = BS()
print(bs)  # 打印创建的卷积参数
BS(
  (conv1): Conv2d(3, 6, kernel_size=(3, 3), stride=(1, 1))
)
#input:torch.Size([64, 3, 32, 32])
#output:torch.Size([64, 6, 32, 32])

从输出结果可知,输入通道为3,输出通道为6,卷积核结构为3×3,步长为1

在这里插入图片描述

按计算可得,输出特征图的尺寸:

( 32 − 3 + 2 ∗ 0 ) 1 (32 - 3 + 2*0)\over1 1323+20) + 1 = 30

完整代码如下:

import torch
import torchvision
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

dataset = torchvision.datasets.CIFAR10(
    "dataset",
    train=False,
    transform=torchvision.transforms.ToTensor(),
    download=True)
# 加载数据集,每次从数据集中取64
dataloader = DataLoader(dataset, batch_size=64)


class BS(torch.nn.Module):

    def __init__(self):
        super().__init__()
        # 即输入通道设定为RGB3层,输出通道设定为6,卷积核大小为3,步长设定1,不进行填充
        self.conv2 = torch.nn.Conv2d(in_channels=3,
                                     out_channels=6,
                                     kernel_size=3,
                                     stride=1,
                                     padding=0)

    def forward(self, x):
        return self.conv2(x)
step = 0
writer = SummaryWriter('logs')
for data in dataloader:
    img, target = data
    # 卷积前
    print(img.shape)
    # 卷积后
    output = BS().conv2(img)
    #print(output.shape)
    #input:torch.Size([64, 3, 32, 32])
    #output:torch.Size([64, 6, 32, 32])
    output=output.reshape(-1,3,30,30) #output的channel为6,此时在Tensorboard可视化中无法显示通道为6的图片,所以需要进行reshape进行重新设定。
    print(output.shape)
    writer.add_images('input',img,step)
    writer.add_images('output',output,step)
    step += 1
writer.close()
Files already downloaded and verified
torch.Size([64, 3, 32, 32])
torch.Size([128, 3, 30, 30])
torch.Size([64, 3, 32, 32])
torch.Size([128, 3, 30, 30])
.......

tensorboard显示如下
在这里插入图片描述

池化层

池化操作主要用于减小特征图的尺寸,并提取出最重要的特征

它通过在特定区域内进行汇总或聚合来实现这一目标。

在这里插入图片描述

池化层的常见操作包含以下几种:最大值池化均值池化随机池化中值池化组合池化等。后续以torch.nn.MaxPool2d为例,进行介绍

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

在这里插入图片描述

在这里插入图片描述

其他参数与池化层中相似,有些默认参数不同而已,这次讲解dilationceil_mode

dilation:表示设置核的膨胀率,默认 dilation=1,即如果kernel_size =3,那么核的大小就是3×3。如果dilation = 2,kernel_size =3×3,那么每列数据与每列数据,每行数据与每行数据中间都再加一行或列数据,数据都用0填充,那么核的大小就变成5×5。
在这里插入图片描述

ceil_mode:floor or ceiling,表示计算输出结果形状的时候,是使用向上取整还是向下取整。即要不要舍弃无法覆盖核的大小的数值。True为保留,False为舍弃
在这里插入图片描述

下图为max_pooling的动态演示图

在这里插入图片描述

利用pytorch演算结果

import torch
from torch import nn

input = torch.tensor(
    [[3, 0, 1, 5, 1, 3], [5, 7, 3, 4, 4, 6], [7, 7, 1, 8, 3, 5],
     [6, 1, 7, 0, 0, 5], [0, 4, 5, 5, 7, 2], [3, 2, 0, 2, 0, 2]],
    dtype=float)  # 使用dtype将此矩阵的数字变为浮点型
# 准备的参数情况
print(input.shape)
# 进行reshape
input = torch.reshape(input, (1,1,6,6))  # input:(N,C,H,W)or(C,H,W)
print(input.shape)


# 搭建神经网络并进行池化操作
class BS(nn.Module):

    def __init__(self):
        super().__init__()
        self.maxpool2 = nn.MaxPool2d(kernel_size=2, ceil_mode=True)

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


# 实例化
bs = BS()
output = bs(input)
print(output)
torch.Size([6, 6])
torch.Size([1, 1, 6, 6])
tensor([[[[7., 5., 6.],
          [7., 8., 5.],
          [4., 5., 7.]]]], dtype=torch.float64)

利用最大池化处理CIFAR10数据集图片,并利用tensorboard可视化

#https://beishan.blog.csdn.net/
import torch
import torch.nn as nn
import torchvision
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
dataset = torchvision.datasets.CIFAR10(
    "dataset",
    train=False,
    transform=torchvision.transforms.ToTensor(),
    download=True)
# 加载数据集,每次从数据集中取64
dataloader = DataLoader(dataset, batch_size=64)


class BS(nn.Module):

    def __init__(self):
        super().__init__()
        self.maxpool1 = nn.MaxPool2d(kernel_size=2, ceil_mode=True)

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


step = 0
bs = BS()
writer = SummaryWriter('logs')
for data in dataloader:
    img, target = data
    output = bs(img)
    writer.add_images('input_maxpool', img, step)
    writer.add_images('output_maxpool', output, step)
    step += 1
writer.close()
Files already downloaded and verified

tensorboard显示如下
在这里插入图片描述

非线性激活

激活函数的作用在于提供网络的非线性建模能力,如果不用激励函数,每一层输出都是上层输入的线性函数,无论神经网络有多少层,输出都是输入的线性组合,这种情况就是最原始的感知机。

激活函数给神经元引入了非线性因素,使得神经网络可以任意逼近任何非线性函数,这样神经网络就可以应用到众多的非线性模型中。

常见的包括:sigmoid、relu和tanh,后续将以relu进行介绍
在这里插入图片描述

在这里插入图片描述

使用relu处理矩阵

import torch

# 准备数据
input = torch.tensor([[1, -1, 0], [-2, 3, -6]])


# 搭建自己的一个神经网络
class BS(torch.nn.Module):

    def __init__(self):
        super().__init__()
        # 默认inplace参数为False
        self.relu1 = torch.nn.ReLU(inplace=False) #inplace保留原始数据

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


# 实例化
l = BS()
output = l(input)
print('转换前:', input)
print('relu转换后:', output)
转换前: tensor([[ 1, -1,  0],
        [-2,  3, -6]])
relu转换后: tensor([[1, 0, 0],
        [0, 3, 0]])

利用Sigmoid来处理CIFAR10数据集

在这里插入图片描述

import torch
import torch.nn as nn
import torchvision
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
dataset = torchvision.datasets.CIFAR10(
    "dataset",
    train=False,
    transform=torchvision.transforms.ToTensor(),
    download=True)
# 加载数据集,每次从数据集中取64
dataloader = DataLoader(dataset, batch_size=64)


class BS(nn.Module):

    def __init__(self):
        super().__init__()
        self.sigmoid1 = nn.Sigmoid()

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


step = 0
bs = BS()
writer = SummaryWriter('logs')
for data in dataloader:
    img, target = data
    output = bs(img)
    writer.add_images('input_sigmoid', img, step)
    writer.add_images('output_sigmoid', output, step)
    step += 1
writer.close()
Files already downloaded and verified

tensorboard显示如下
在这里插入图片描述

全连接层

在这里插入图片描述

线性层它也被称为全连接层,通常所说的全连接层是指一个由多个神经元所组成的层,其所有的输出和该层的所有输入都有连接,即每个输入都会影响所有神经元的输出,在Pytorch中nn.Linear()表示线性变换

全连接层可以看作是nn.Linear()表示线性层再加上一个激活函数所构成的结构。

全连接层的应用范围非常广泛,只有全连接层组成的网络是全连接神经网络,可以用于数据的分类或回归任务,卷积神经网络和循环神经网络的末端通常会由多个全连接层组成

在这里插入图片描述

torch.nn.Linear(in_features,
				out_features, 
				bias=True, 
 			    device=None, 
				dtype=None)

其中最重要的三个参数为in_features, out_features, bias

  • in_features:表示输入的特征值大小,即输入的神经元个数
  • out_features:表示输出的特征值大小,即经过线性变换后输出的神经元个数
  • bias:表示是否添加偏置

以VGG16网络结构为例进行介绍
在这里插入图片描述

in_features为1,1,x形式,out_features为1,1,y的形式

import torch
import torchvision
from torch.utils.data import DataLoader

# 准备数据
test_set = torchvision.datasets.CIFAR10("dataset",
                                        train=False,
                                        transform=torchvision.transforms.ToTensor(),
                                        download=True)
# 加载数据集
dataloader = DataLoader(test_set,batch_size=64)

# 查看输入的通道数
# for data in dataloader:
#     imgs, target = data
#     print(imgs.shape)  # torch.Size([64, 3, 32, 32])
#     # 将img进行reshape成1,1,x的形式
#     input = torch.reshape(imgs,(1,1,1,-1)) # 每次一张图,1通道,1*自动计算x
#     print(input.shape) # torch.Size([1, 1, 1, 196608])

# 搭建神经网络,设置预定的输出特征值为10
class BS(torch.nn.Module):
    def __init__(self):
        super().__init__()
        self.linear1 = torch.nn.Linear(196608,10)  # 输入数据的特征值196608,输出特征值10
    def forward(self, input):
        output = self.linear1(input)
        return output

l = BS()
for data in dataloader:
    imgs, target = data
    print(f"原先的图片shape:{imgs.shape}")  # torch.Size([64, 3, 32, 32])
    # 将img进行reshape成1,1,x的形式
    input = torch.flatten(imgs) # 每次一张图,1通道,1*自动计算x
    print(f"flatten后的图片shape:{input.shape}")
    output = l(input)
    print(f"经过线性后的图片shape:{output.shape}") # torch.Size([1, 1, 1, 10])
Files already downloaded and verified
原先的图片shape:torch.Size([64, 3, 32, 32])
flatten后的图片shape:torch.Size([196608])
经过线性后的图片shape:torch.Size([10])
原先的图片shape:torch.Size([64, 3, 32, 32])
flatten后的图片shape:torch.Size([19660

关于神经网络的层结构远不止这些,例如dropout layers、transformer layers、recurrent layers等,大家可以去官网自行学习

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1136764.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2023.10.26 关于 CAS 和 ABA 问题

目录 CAS 操作 执行过程 CAS 应用场景 实现原子类 实现自旋锁 ABA 问题 CAS 操作 全称 Compare and swap ,译为 比较并交换 执行过程 我们假设内存中的原始数据 V,旧的预期值 A,需要修改的新值 B 比较 A 与 V 是否相等如果比较相等&…

SpringBoot日志+SpringMVC+UUID重命名文件+Idea热部署

目录 【SpringBoot日志】 什么是日志,日志的作用 关于日志的基本信息,又有哪些呢? 关于日志的级别 Springboot内置SLF4J【门面模式】 和 logback【日志框架】 在配置文件中可以设置日志级别【以.yml为例】 SpringBoot 持久化的保存日…

QT图形视图框架绘制曲线图和Smith图

QT图形视图框架绘制曲线图和Smith图 QGraphicsView是Qt框架中的一个图形视图部件,用于显示和处理2D图形元素。它提供了强大的工具来创建交互式和自定义的图形应用程序。在绘制折线图和Smith图时,使用QGraphicsView有以下一些优点: 交互性&am…

二叉树题目:最大二叉树 II

文章目录 题目标题和出处难度题目描述要求示例数据范围 解法一思路和算法代码复杂度分析 解法二思路和算法代码复杂度分析 题目 标题和出处 标题:最大二叉树 II 出处:998. 最大二叉树 II 难度 5 级 题目描述 要求 如果一个树满足其中每个结点的值…

【Python学习】—Python基础语法(六)

一、数据容器 Python中的数据容器:一种可以容纳多份数据的数据类型,容纳的每一个元素,可以是任意类型的数据,如字符串、数字、布尔等。 二、list列表 列表的下标索引 嵌套列表的下标 my_list[aaa,1,True] print(my_list[0]) p…

电压检测芯片如何发挥作用,保护电路?纳米软件为您介绍工作原理

电压检测芯片是一种常见的集成电路芯片,用来监测电路中的电压变化,防止电路受到过电压和欠电压的损坏。电源电压检测芯片被广泛应用于各种电子设备中,比如手机、电脑、家电等,在电压监测、电源管理、电池电量检测、温度检测、电压…

3D模型怎么贴法线贴图?

1、法线贴图的原理? 法线贴图(normal mapping)是一种计算机图形技术,用于在低多边形模型上模拟高多边形模型的细节效果。它通过在纹理坐标上存储和应用法线向量的信息来实现。 法线贴图的原理基于光照模型。在渲染过程中&#x…

云表低代码:数字化转型的新风口,你了解多少?

自2019年起,低代码开发平台骤然引发热议,成为了科技领域的新宠。关于其定义和影响力,众说纷纭。有人将它誉为第四代编程语言,有人视它为开发模式的颠覆者,更有人认为它引领了企业管理模式的变革。这股热潮在社区内引发…

BIOS MBR UEFI GPT详解

先来看下名词 启动方式: Legacy:传统的。指的就是BIOS。 BIOS:Basic Input Output System,中文名称"基本输入输出系统"。 UEFI:Unified Extensible Firmware Interface,中文名称"统一的…

获取IEEE会议论文的标题和摘要

获取IEEE会议论文的标题和摘要 – 潘登同学的爬虫笔记 文章目录 获取IEEE会议论文的标题和摘要 -- 潘登同学的爬虫笔记 打开IEEE的高级搜索环境准备完整爬虫过程获取文章地址翻译函数获取文章标题和摘要 前几天接到导师的一个任务,要我去找找IEEE Transactions on K…

用低代码平台代替Excel搭建进销存管理系统

目录 一、用低代码平台搭建系统 1.需求调研 2.基于痛点梳理业务流程 3.低代码实现 (1)基础资料模块 (2)采购管理模块 (3)销售管理模块 (4)库存管理模块 (5&…

快手联合阿里云构建容器混合云架构,轻松应对百万级秒杀

云布道师 摘要:快手电商在 2023 年某大 V 大促直播活动中,首次采用混合云弹性调度架构,应对大 V 百万级别秒杀峰值的计算资源需求。此次为【快手容器云 阿里云】的深度技术结合,在【快手电商直播秒杀】场景下的大规模首次应用。既…

Calcite 解析层详解

1、概述 用户的操作请求经过服务层的接收和封装被传递给calcite-core模块。 其中第一站就是解析层,它的作用主要是对SQL语句进行语法解析。 在这个过程中,初始的SQL字符串会被转化为Calcite内部的语法解析节点,为进一步的语法校验和优化做…

建筑木模板厂家直销 915*1830*15mm酚醛面板规格

建筑木模板在建筑施工中扮演着重要的角色,它是支撑混凝土浇筑和保证建筑结构稳定性的关键材料。作为一家专业的建筑木模板厂家直销商,我们引以为傲地推出了915*1830*15mm酚醛面板规格的产品。 我们的建筑木模板采用高质量的酚醛树脂胶粘剂和优质桉木木材…

低代码平台是什么意思?低代码平台如何设计与实现?

低代码这个词,也许许多人都相当陌生。低代码的正式提出可以追溯到2014年,当时全球最具影响力的独立研究咨询公司Forrester,正式界定了低代码的概念。低代码指可通过最少的手工编程就能快速交付应用程序,并能快速设置和部署用于参与…

centos启动tomcat 并指定jdk 版本

在tomcat的catalina.sh文件手动设置JAVA_HOME变量即可 例如: 前提是文件存在 保存配置重新启动tomcat

短说通用版V4.1.0测试版发布|新增全新马甲模块等新功能

大家好, 我是给你们带来惊喜的运营小番茄。 本期更新为短说通用版 4.1.0测试版。 本次V4.1.0版本新增功能有: ①学院免费课程支持发布评价 ②商城子系统商品支持使用积分抵扣 ③新增管理后台查看和导出评论功能 ④支持设置积分类型展示排序功能 …

记录一次时序数据库的实战测试

0x1.前言 ​ 本文章仅用于信息安全防御技术分享,因用于其他用途而产生不良后果,作者不承担任何法律责任,请严格遵循中华人民共和国相关法律法规,禁止做一切违法犯罪行为。文中涉及漏洞均以提交至教育漏洞平台。 0x2.背景 ​ 在某…

99%的时间里使用的14个git命令

学习14个Git命令,因为你将会在99%的时间里使用它们 必须了解的命令整理 1,git init 初始化一个新的Git仓库。 这将在当前目录中创建一个名为".git"的子目录,Git会将所有仓库的元数据存储在其中。 2,git clone 克隆…

【unity3D】Rect Transform组件

💗 未来的游戏开发程序媛,现在的努力学习菜鸡 💦本专栏是我关于游戏开发的学习笔记 🈶本篇是unity的Rect Transform组件 Rect Transform组件 基础知识详细介绍补充 基础知识 Rect Transform是Unity中的一个UI组件,用于…