PyTorch中的模型创建

news2024/11/16 17:44:12

42bb4ba4f4194aaf89e12b99bfdfc9db.png

最全最详细的PyTorch神经网络创建~

话不多说直接开始~

神经网络的创建步骤 

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

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

Module: 神经网络的模板

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,执行的操作是𝑦=𝑥𝐴𝑇+𝑏

torch.nn.Linear(in_features, out_features, bias=True, device=None, dtype=None)
  • in_feature代表输入数
  • out_features代表输出数,即神经元数量
m = nn.Linear(2,3)
input = torch.randn(5, 2)
ouput = m(input)
print(ouput.size())

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

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

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,))

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

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 层之间可以连接起来

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是早期的激活函数

c36b506ddb334b74889281c0c6512ff9.png

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

ReLU 

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

82e4a5a6eda14c75a82bc0002501ef8f.png

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

Softmax 

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

079f16eb70ee4ec0a30cb3f52d156fee.png

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

随机失活方法Dropout

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

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

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

m=nn.Dropout( p=0.5)
input = torch.randn(6,8)
output = m( input)
  • 将一个列表,随机将一些值变为0

全连接网络处理一维信息 

142089ad87d040cd897ff9c8aa92d2f3.png

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

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(-1,1000)# 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)

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]])

卷积层

二维卷积

7c68591700b84e1caf8867f5fa51eedc.png

torch.nn.Conv2d(in_channelsout_channelskernel_sizestride=1padding=0dilation=1groups=1bias=Truepadding_mode=‘zeros’device=Nonedtype=None)  

  • in_channels: 输入通道数
  • out_channels: 输出通道数(卷积核数量)
  • kernel_size: 卷积核大小
  • stride: 卷积步长
  • padding: 边缘补零
  • dilation: 扩散卷积
  • group: 分组卷积
  • bias: 是否带有偏置
import torch
import torch.nn as nn
#使用方形卷积核,以及相同的步长
m = nn.conv2d(16,33,3, stride=2)
#使用非方形的卷积核,以及非对称的步长和补零
m = nn.conv2d(16,33,(3,5),stride=(2,1),padding=(4,2))
#使用非方形的卷积核,以及非对称的步长,补零和膨胀系数
m = nn.Conv2d(16,33,(3,5),stride=(2,1),padding=(4,2),dilation=(3,1))
input = torch.randn(20,16,50,100)
output = m( input)
print(output.shape)

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

torch.nn.ConvTranspose2d(in_channelsout_channelskernel_sizestride=1padding=0output_padding=0groups=1bias=Truedilation=1padding_mode=‘zeros’device=Nonedtype=None)

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

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

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)

搭建全卷积网络结构案例

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))

输出:

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
----------------------------------------------------------------

搭建卷积+全连接的网络结构

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))

输出: 

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_sizestride=Nonepadding=0dilation=1return_indices=Falseceil_mode=False)

316359c12ac244bd9b2f85fde82ade75.png

输入参数 kernel_sizestridepaddingdilation可以是

  • 一个 int :代表长宽使用同样的参数
  • 两个int组成的元组:第一个int用在H维度,第二个int用在W维度
#长宽一致的池化,核尺寸为3x3,池化步长为2
m1 = nn.MaxPool2d( 3,stride=2)
#长宽不一致的池化
m2 = nn.MaxPool2d(( 3,2), stride=(2,1))
input = torch.randn(4,3,24,24)
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_sizestride=Nonepadding=0ceil_mode=Falsecount_include_pad=Truedivisor_override=None)

import torch
import torch.nn as nn
#长宽一致的池化,核尺寸为3x3,池化步长为2
m1 = nn.AvgPool2d( 3, stride=2)
#长宽不一致的池化
m2 = nn.AvgPool2d((3,2), stride=(2,1))
input = torch.randn( 4,3,24,24)
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的数据进行归一化操作,可以使得网络训练更稳定,加速网络的收敛。

a367da9c6a6f437ab1023a6b3c9c2b76.png

#批量归一化层(具有可学习参数)
m_learnable = nn.BatchNorm2d( 100)
#批量归一化层(不具有可学习参数>
m_non_learnable = nn.BatchNorm2d(100,affine=False)
#随机生成输入数据
input = torch.randn(20,100,35,45)
#应用具有可学习参数的批量归一化层
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])

最后,欢迎大家来到知识星球「易编橙·终身成长社群」与业内大佬一起交流学习,定期分析专业资料知识~
「易编橙·终身成长社群」

 

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

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

相关文章

拼多多的一场机试 解题报告 | 珂学家

前言 拼多多的一场机试 解题报告 有需要机试辅导,可以私信我 机试题 D. 任务队列是否会死锁? 一个任务队列,长度为n 可以添加一个任务,长度为a可以获取一个任务,长度为b 如果存在一个状态点,即不能添加…

python 两个表格字段列名称值,对比字段差异

支持xlsx,xls文件,相互对比字段列 输出两个表格文件相同字段,置底色为绿色 存在差异的不同字段,输出两个新的表格文件,差异字段,置底色为红色 import pandas as pd from openpyxl import load_workbook from openpy…

简单易懂的 API 集成测试方法

简介:API 集成测试的重要性 API 集成测试是一类测试活动,用于验证 API 是否满足功能性、可靠性、性能和安全性等方面的预期要求。在多 API 协作的应用程序中,这种测试尤为紧要。 在这一阶段,我们不仅审视单个组件,还…

比例溢流阀的放大器找BEUEC

液压比例放大器的使用范围广泛,包括工业生产线、船舶液压系统等多个领域。BEUEC比例放大器是一种重要的液压系统组件,其作用是将微弱的液压信号放大,以实现对液压系统的精确控制。这种设备在多个行业中都有广泛的应用,特别是在需要…

可视化大屏开发,知道了这些经验以及解决方案,效率至少提升2倍!(完结篇)

大家好,我是日拱一卒的攻城师不浪,专注可视化、数字孪生、前端、nodejs、AI学习、GIS等学习沉淀,这是2024年输出的第16/100篇文章; 前言 之前写了两篇可视化大屏开发的经验总结,小伙伴们反应还不错。 最近&#xff0…

响应式UI组件DevExtreme中文教程 - 工具栏的自适应模式

DevExtreme拥有高性能的HTML5 / JavaScript小部件集合,使您可以利用现代Web开发堆栈(包括React,Angular,ASP.NET Core,jQuery,Knockout等)构建交互式的Web应用程序。从Angular和Reac&#xff0c…

浅谈JMeter环境变量设置

JMeter环境变量设置 确保已安装Java Development Kit (JDK) JMeter需要Java运行环境,因此请先安装JDK,并确认JAVA_HOME环境变量已经设置好。可以通过命令提示符输入java -version和javac -version来验证是否安装成功及其版本信息,若没有出现…

阿里云 EMR Serverless Spark 版开启免费公测

阿里云 EMR Serverless Spark 版是一款云原生,专为大规模数据处理和分析而设计的全托管 Serverless 产品。它为企业提供了一站式的数据平台服务,包括任务开发、调试、调度和运维等,极大地简化了数据处理的全生命周期工作流程。使用 EMR Serve…

气膜建筑:室内滑雪场的理想选择—轻空间

近年来,室内滑雪场成为越来越多投资者关注的热门项目。随着滑雪运动的普及,滑雪场的生意也愈加红火。对于投资者来说,选择一种省钱又实惠的搭建方案至关重要,而气膜建筑无疑是一个理想的选择。以下将详细介绍气膜建筑在室内滑雪场…

文章解读与仿真程序复现思路——电力自动化设备EI\CSCD\北大核心《考虑分布式光伏高效消纳与负荷损失最小的区域配电网应急资源协同配置策略》

本专栏栏目提供文章与程序复现思路,具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

域提权漏洞系列分析-Zerologon漏洞分析

2020年08⽉11⽇,Windows官⽅发布了 NetLogon 特权提升漏洞的⻛险通告,该漏洞编号为CVE-2020-1472,漏 洞等级:严重,漏洞评分:10分,该漏洞也称为“Zerologon”,2020年9⽉11⽇&#xff…

Tomcat源码解析(七):底层如何获取请求url、请求头、json数据?

Tomcat源码系列文章 Tomcat源码解析(一):Tomcat整体架构 Tomcat源码解析(二):Bootstrap和Catalina Tomcat源码解析(三):LifeCycle生命周期管理 Tomcat源码解析(四):StandardServer和StandardService Tomcat源码解析(五)&…

Python使用virtualenv创建虚拟环境

目录 第一步:安装virtualenv 第二步:选择一个文件夹用来放所创建的虚拟环境 第三步:创建虚拟环境 第四步:激活虚拟环境 第五步:退出虚拟环境 第六步:测试安装django 前提:你得有个python环…

价格预言机领导者 Pyth 与 Eclipse 平台集成,为高频 DeFi 应用提供支持

本篇文章将对这一战略合作伙伴关系,以及 Pyth 网络在 Eclipse 生态系统中扮演的关键角色进行深入探讨。 目前,Pyth 价格数据已正式上线于 Eclipse 测试网。Eclipse 是首个结合了以太坊安全性、Solana 性能和 Celestia DA 的 Solana虚拟机(SVM) Layer2 方…

喜讯!宝兰德斩获2024数字中国创新大赛·信创赛道全国总决赛三等奖

5月24日,由国家发展和改革委员会、国家数据局、国家互联网信息办公室、科学技术部、国务院国有资产监督管理委员会和福建省人民政府共同主办的2024数字中国创新大赛信创赛道全国总决赛颁奖典礼暨闭幕式大会在福州海峡国际会展中心圆满落幕。依托专业技术研发能力及丰…

【网络安全】勒索软件ShrinkLocker使用 windows系统安全工具BitLocker实施攻击

文章目录 威胁无不不在BitLocker 概述如何利用BitLocker进行攻击如何降低影响Win11 24H2 装机默认开启 BitLocker推荐阅读 威胁无不不在 网络攻击的形式不断发展,即便是合法的 Windows 安全功能也会成为黑客的攻击工具。 卡巴斯基实验室专家 发现 使用BitLocker的…

路径规划 | 图解粒子群(PSO)算法(附ROS C++仿真)

目录 0 专栏介绍1 从鸟群迁徙说起2 粒子群算法基本概念3 粒子群算法流程4 粒子群算法ROS实现 0 专栏介绍 🔥附C/Python/Matlab全套代码🔥课程设计、毕业设计、创新竞赛必备!详细介绍全局规划(图搜索、采样法、智能算法等);局部规…

使用 Ollama框架 下载和使用 Llama3 AI大模型的完整指南

🏡作者主页:点击! 🤖AI大模型部署与应用专栏:点击! ⏰️创作时间:2024年5月24日20点59分 🀄️文章质量:96分 目录 💥Ollama介绍 主要特点 主要优点 应…

Android14之Binder调试(二百一十一)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒…

【论文笔记】advPattern

【论文题目】 advPattern: Physical-World Attacks on Deep Person Re-Identification via Adversarially Transformable Patterns Abstract 本文首次尝试对深度reID实施鲁棒的物理世界攻击。提出了一种新颖的攻击算法,称为advPattern,用于在衣服上生成…