由浅入深,走进深度学习(补充篇:转置卷积和FCN)

本期内容是针对神经网络层结构的一个补充,主要内容是:转置卷积和全连接卷积网络

相关内容:

由浅入深,走进深度学习(2)_卷积层-CSDN博客

由浅入深,走进深度学习(补充篇:神经网络结构层基础)-CSDN博客

由浅入深,走进深度学习(补充篇:神经网络基础)-CSDN博客

目录

转置卷积

填充、步幅和多通道

全连接卷积神经网络

正片开始!!!!

转置卷积


卷积不会增大输入的高宽  通常要么不变  要么减半
转置卷积则可以用来增大输入高宽

import torch
from torch import nn
from d2l import torch as d2l# 实现基本的转置卷积运算
# 定义转置卷积运算
def trans_conv(X, K):# 获取卷积核的宽度和高度h, w = K.shape # 卷积核的宽、高# 创建一个新的张量Y  其尺寸为输入X的尺寸加上卷积核K的尺寸减去1  在常规卷积中  输出尺寸通常是输入尺寸减去卷积核尺寸加1Y = torch.zeros((X.shape[0] + h -1, X.shape[1] + w - 1)) # 正常的卷积后尺寸为(X.shape[0] - h + 1, X.shape[1] - w + 1)       # 遍历输入张量X的每一行for i in range(X.shape[0]):# 遍历输入张量X的每一列for j in range(X.shape[1]):# 对于输入X的每一个元素  我们将其与卷积核K进行元素级别的乘法  然后将结果加到输出张量Y的相应位置上Y[i:i + h, j:j + w] += X[i, j] * K # 按元素乘法  加回到自己矩阵# 返回转置卷积的结果return Y# 验证上述实现输出
# 定义输入张量X  这是一个2x2的矩阵
X = torch.tensor([[0.0, 1.0],[2.0, 3.0]])
# 定义卷积核K  也是一个2x2的矩阵
K = torch.tensor([[0.0, 1.0],[2.0, 3.0]])
# 调用上面定义的trans_conv函数  对输入张量X和卷积核K进行转置卷积操作  并打印结果
trans_conv(X, K)# 使用高级API获得相同的结果
# 将输入张量X和卷积核K进行形状变换  原来是2x2的二维张量  现在变成了1x1x2x2的四维张量
# 第一个1表示批量大小  第二个1表示通道数  2x2是卷积核的高和宽
X, K = X.reshape(1, 1, 2, 2), K.reshape(1, 1, 2, 2)
# 创建一个转置卷积层对象tconv  其中输入通道数为1   输出通道数为1  卷积核的大小为2  没有偏置项
tconv = nn.ConvTranspose2d(1, 1, kernel_size = 2, bias = False) # 输入通道数为1  输出通道数为1   
# 将创建的转置卷积层对象tconv的权重设置为我们的卷积核K
tconv.weight.data = K
# 使用创建的转置卷积层tconv对输入张量X进行转置卷积操作  并返回结果
tconv(X)

填充、步幅和多通道

填充在输出上  padding=1  之前输出3x3  现在上下左右都填充了1  那就剩下中心那个元素了
填充为1  就是把输出最外面的一圈当作填充
创建一个转置卷积层对象tconv  其中输入通道数为1  输出通道数为1  卷积核的大小为2  没有偏置项  同时设置填充大小为1  
填充(padding)操作在输出上执行  原本输出为3x3  由于填充了大小为1的边框  结果就只剩下中心的元素   
所以填充大小为1就相当于将输出矩阵最外面的一圈当作填充并剔除

tconv = nn.ConvTranspose2d(1, 1, kernel_size = 2, padding = 1, bias = False) 
# 将创建的转置卷积层对象tconv的权重设置为我们的卷积核K
tconv.weight.data = K
# 使用创建的转置卷积层tconv对输入张量X进行转置卷积操作  并返回结果
tconv(X)# 创建一个转置卷积层对象tconv  其中输入通道数为1  输出通道数为1  卷积核的大小为2  步幅(stride)为2  没有偏置项
# 步幅为2表示在进行卷积时  每次移动2个单位  相较于步幅为1  这样会使得输出尺寸增大
tconv = nn.ConvTranspose2d(1, 1, kernel_size = 2, stride = 2, bias = False)
# 将创建的转置卷积层对象tconv的权重设置为我们的卷积核K
tconv.weight.data = K
# 使用创建的转置卷积层tconv对输入张量X进行转置卷积操作 并返回结果
tconv(X)# 多通道
# 创建一个四维张量X  批量大小为1  通道数为10  高和宽都为16
X = torch.rand(size = (1, 10, 16, 16))
# 创建一个二维卷积层对象conv  其中输入通道数为10  输出通道数为20  卷积核大小为5  填充为2  步幅为3
# 这会将输入的10个通道的图像转换为20个通道的特征图
conv = nn.Conv2d(10, 20, kernel_size = 5, padding = 2, stride = 3)
# 创建一个转置卷积层对象tconv  其中输入通道数为20  输出通道数为10  卷积核大小为5  填充为2  步幅为3
# 这会将输入的20个通道的特征图转换回10个通道的图像
tconv = nn.ConvTranspose2d(20, 10, kernel_size = 5, padding = 2, stride = 3)
# 首先对输入张量X进行卷积操作   然后再对卷积的结果进行转置卷积操作
# 然后检查这个结果的形状是否和原始输入张量X的形状相同
# 如果相同  说明转置卷积操作成功地还原了原始输入的形状
tconv(conv(X)).shape == X.shape# 与矩阵变换的联系
# 创建一个一维张量  其中包含从0.0到8.0的连续数字
# 然后将这个一维张量重塑为3x3的二维张量
X = torch.arange(9.0).reshape(3, 3)
# 创建一个2x2的卷积核K  其中包含四个元素:1.0,2.0,3.0,4.0
K = torch.tensor([[1.0, 2.0],[3.0, 4.0]])
# 使用自定义的二维卷积函数corr2d对输入张量X和卷积核K进行卷积操作
# corr2d函数需要在引入d2l(深度学习库)之后才能使用
Y = d2l.corr2d(X, K) # 卷积
# 打印卷积操作的结果
Y# 定义一个函数kernel2matrix  用于将给定的卷积核K转换为一个稀疏矩阵W
def kernel2matrix(K):# 创建长度为5的零向量k和4x9的零矩阵Wk, W = torch.zeros(5), torch.zeros((4,9))# 打印初始状态的kprint(k) # 打印初始状态的Wprint(W)# 打印输入的卷积核Kprint(K)# 将卷积核K的元素填充到向量k中的适当位置  形成一个稀疏向量k[:2], k[3:5] = K[0, :], K[1,:]# 打印填充后的向量kprint(k)# 将稀疏向量k填充到矩阵W中的适当位置  形成一个稀疏矩阵W[0, :5], W[1, 1:6], W[2, 3:8], W[3, 4:] = k, k, k, k# 返回转换后的稀疏矩阵Wreturn W# 每一行向量表示在一个位置的卷积操作  0填充表示卷积核未覆盖到的区域。
# 输入大小为 3 * 3 的图片  拉长一维向量后变成 1 * 9 的向量
# 输入大小为 3 * 3 的图片  卷积核为 2 * 2  则输出图片为 2 * 2  拉长后变为 4 * 1 的向量
# kernel2matrix函数将卷积核改为稀疏矩阵C后矩阵情况# 使用kernel2matrix函数将卷积核K转换为一个稀疏矩阵W
# 这个矩阵的每一行表示在一个特定位置进行的卷积操作  其中的0表示卷积核没有覆盖的区域
# 如果输入是一个3x3的图像  并被拉平为一个1x9的向量
# 而卷积核是2x2的  那么输出图像的大小为2x2  拉平后变为一个4x1的向量
# kernel2matrix函数实际上就是在构建这种转换关系
W = kernel2matrix(K) 
W
# 打印输入张量X的内容
print(X)
# 使用reshape函数将输入张量X拉平为一个一维向量   并打印结果
# 这是为了将X与稀疏矩阵W进行矩阵乘法操作
print(X.reshape(-1))
# 判断卷积操作的结果Y是否等于稀疏矩阵W与拉平的输入张量X的矩阵乘法的结果   并将结果重塑为2x2的形状
# 这是一种检查卷积操作是否等价于某种矩阵变换的方式
Y == torch.matmul(W, X.reshape(-1)).reshape(2, 2)# 使用自定义的转置卷积函数trans_conv对卷积操作的结果Y和卷积核K进行转置卷积操作
Z = trans_conv(Y, K)
# 判断转置卷积操作的结果Z是否等于稀疏矩阵W的转置与拉平的卷积结果Y的矩阵乘法的结果   并将结果重塑为3x3的形状
# 这是一种检查转置卷积操作是否等价于某种特定的矩阵变换的方式
# 注意这里得到的结果并不是原图像   尽管它们的尺寸是一样的
Z == torch.matmul(W.T, Y.reshape(-1)).reshape(3, 3) # 由卷积后的图像乘以转置卷积后  得到的并不是原图像  而是尺寸一样    

全连接卷积神经网络


1 * 1 卷积层来降低维度
转置卷积层把图片扩大,k是通道有多少类,通道数为类别数,则导致可以对每一个像素分类

FCN是用深度神经网络来做语义分割的奠基性工作
其用转置卷积层来替换CNN最后的全连接层  从而可以实现每个像素的预测

# 全连接卷积神经网络
import torch
import torchvision
from torch import nn
from torch.nn import functional as F
from d2l import torch as d2l# 使用在ImageNet数据集上预训练的ResNet18模型来提取图像特征
pretrained_net = torchvision.models.resnet18(pretrained=True)
# 使用list函数和children方法列出预训练模型的所有子层(这些子层通常是神经网络的层)
# 然后使用Python的切片语法来取出最后三层
# 这可以帮助我们理解模型的结构  特别是在我们打算对模型进行微调或者使用模型的某些层来提取特征时
list(pretrained_net.children())[-3:] # 查看最后三层长什么样子# 创建一个全卷积网络实例net
# 使用预训练的ResNet18模型创建一个新的神经网络
# 其中  "*list(pretrained_net.children())[:-2]"这段代码将ResNet18模型的所有子层(除了最后两层)作为新网络的层    
# 这样  新网络实际上是ResNet18模型去掉最后两层后的版本
# 这种方法常常用于迁移学习  即利用一个在大型数据集上训练过的模型的特征提取部分  来帮助我们处理新的任务
net = nn.Sequential(*list(pretrained_net.children())[:-2]) # 去掉ResNet18最后两层
# 创建一个形状为(1, 3, 320, 480)的随机张量  这可以看作是一张形状为(320, 480)  有三个颜色通道的图片
# 这里的3代表图片的颜色通道数量(红、绿、蓝)  320和480分别代表图片的高度和宽度
# 随机张量的所有元素都是在[0, 1)之间随机生成的  可以看作是随机图片的像素值
X = torch.rand(size=(1,3,320,480)) # 卷积核与输入大小无关  全连接层与输入大小有关
# 将随机生成的图片输入到网络中  通过调用net(X)  进行前向传播
# 打印输出张量的形状  输出的形状通常可以用于检查网络的结构是否正确
# 对于全卷积网络  输出的宽度和高度通常会比输入的小  这是由于卷积和池化操作造成的
# 在这个例子中  输出的宽度和高度应该是输入的1/32  这是由ResNet18的结构决定的
net(X).shape  # 缩小32倍# 使用1X1卷积层将输出通道数转换为Pascal VOC2012数据集的类数(21类)
# 将要素地图的高度和宽度增加32倍
# 定义目标数据集中的类别数量  这里的21表示Pascal VOC2012数据集中有21个类别  包括20个物体类别和一个背景类别
num_classes = 21
# 在网络末尾添加一个新的卷积层  这是一个1x1的卷积层  输入通道数为512(这是由前面的ResNet18模型决定的)
# 输出通道数为我们定义的类别数量,即21
# 1x1卷积层常用于改变通道数  即可以将前一层的特征图投影到一个新的空间  这个新的空间的维度即为卷积层的输出通道数
net.add_module('final_conv',nn.Conv2d(512,num_classes,kernel_size=1))  
# 图片放大32倍  所以stride为32
# padding根据kernel要保证高宽不变的最小值  16 * 2 = 32  图片左右各padding
# kernel为64  原本取图片32大小的一半  再加上padding的32  就相当于整个图片
# 再添加一个转置卷积层  转置卷积也被称为反卷积  通常用于将小尺寸的特征图放大到原来的大小
# 这里的输入和输出通道数都是num_classes  表示我们希望在放大的过程中保持通道数不变
# kernel_size是64  stride是32  这意味着这一层将特征图的宽度和高度放大了32倍
# padding是16  它用于在特征图的边缘添加额外的区域  使得输出的大小正好是输入的32倍
net.add_module('transpose_conv', nn.ConvTranspose2d(num_classes,num_classes,kernel_size=64,padding=16,stride=32)) 
# 初始化转置卷积层# 双线性插值核的实现
# 定义一个函数  用于初始化双线性插值核
# 这个函数接受三个参数:输入通道数、输出通道数和核大小
def bilinear_kernel(in_channels, out_channels, kernel_size):# 计算双线性插值核中心点位置# 计算双线性插值核的尺寸的一半  由于我们希望中心点位于核的中心  所以需要先计算核的一半大小# 我们使用 // 运算符进行整数除法  确保结果为整数factor = (kernel_size + 1) // 2# 根据核的大小是奇数还是偶数  确定中心点的位置# 如果核的大小是奇数  则中心点位于尺寸的一半减去1的位置  因为Python的索引从0开始  所以减去1# 例如  如果核的大小是3  那么中心点应该位于1的位置  (3+1)//2 - 1 = 1if kernel_size % 2 == 1:center = factor - 1# 如果核的大小是偶数  则中心点位于尺寸的一半减去0.5的位置# 这是因为偶数大小的核没有明确的中心点  所以我们取中间两个元素的平均位置作为中心点# 例如  如果核的大小是4   那么中心点应该位于1.5的位置  (4+1)//2 - 0.5 = 1.5else:center = factor - 0.5# 创建一个矩阵  其元素的值等于其与中心点的距离og = (torch.arange(kernel_size).reshape(-1,1),torch.arange(kernel_size).reshape(1,-1))# 计算双线性插值核  其值由中心点出发  向外线性衰减filt = (1 - torch.abs(og[0] - center) / factor) * (1 - torch.abs(og[1] - center) / factor)    # 初始化一个权重矩阵  大小为 (输入通道数, 输出通道数, 核大小, 核大小)weight = torch.zeros((in_channels, out_channels, kernel_size, kernel_size))  # 将双线性插值核的值赋给对应位置的权重weight[range(in_channels),range(out_channels),:,:] = filt# 返回初始化的权重矩阵  这个权重矩阵可以直接用于初始化转置卷积层的权重return weight# 双线性插值的上采样实验
# 创建一个转置卷积层  输入和输出通道数都是3  这是因为我们处理的是RGB图片  每个颜色通道都需要进行处理
# 核大小是4  步长是2  这意味着这个层将输入的宽度和高度放大了2倍
# 设置bias为False  因为我们不需要偏置项
conv_trans = nn.ConvTranspose2d(3,3,kernel_size=4,padding=1,stride=2,bias=False)  
# 使用双线性插值核初始化转置卷积层的权重
# 这里我们使用了copy_方法  这是一种就地操作  直接修改了原始张量的值
conv_trans.weight.data.copy_(bilinear_kernel(3,3,4)) # 双线性核初始化权重
# 使用torchvision.transforms.ToTensor()将一张JPEG格式的图片转换为张量
img = torchvision.transforms.ToTensor()(d2l.Image.open('01_Data/03_catdog.jpg'))
# 增加一个批次维度
X = img.unsqueeze(0)
# 将图片张量输入到转置卷积层中  得到上采样的结果
Y = conv_trans(X)
# 将输出结果转换为可以展示的格式   即(高度, 宽度, 颜色通道)的格式  并从计算图中分离出来  这样就可以转换为NumPy数组
out_img = Y[0].permute(1,2,0).detach()
# 设置展示图片的大小
d2l.set_figsize()
# 打印输入图片的形状
print('input image shape:', img.permute(1,2,0).shape)
# 展示图片
d2l.plt.imshow(img.permute(1,2,0))
# 打印输出图片的形状并展示图片
# 可以看到  输出图片的宽度和高度都是输入的2倍  这正是我们设置的步长
print('output image shape:',out_img.shape) # 输出被拉大了2倍
# 并展示图片
d2l.plt.imshow(out_img)# 用双线性插值的上采样初始化转置卷积层
# 对于1X1卷积层   我们使用Xavier初始化参数
# 使用双线性插值核初始化转置卷积层的权重
# num_classes是目标数据集中的类别数量   这里使用双线性插值核的尺寸为64
W = bilinear_kernel(num_classes, num_classes, 64)
# 将初始化的权重W复制给转置卷积层的权重
# 使用copy_方法进行就地操作  直接修改原始张量的值
net.transpose_conv.weight.data.copy_(W)

注:上述内容参考b站up主“我是土堆”的视频,参考吴恩达深度学习,机器学习内容,参考李沐动手学深度学习!!!

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

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

相关文章

7月开始,考研数学0️⃣基础线代30天满分规划

线代零基础? 那千万不要去跟李永乐老师的线代课程,因为李永乐老师的线代课程比较进阶,适合有一定基础的同学去听,下面这两位才是零基础线代的神! 一个是喻老,另外一个是汤家凤! 这两个老师的…

阎石《数字电子技术》面试建议

参考书:《数字电子技术基础》 阎石 高教出版社 整体来说数电要比模电简单,能问的地方也不多,但是一定要注意犄角嘎拉里的东西 , 比如去年就有老师问 sram 是什么的缩写,很简单,但平时不注意就会回答不上来。…

UE4_材质_水涟漪、水深制作_Ben教程

学习笔记,不喜勿喷!侵权立删,祝愿生活越来越好! 效果图如下: 创建水材质的教程,首先需要外出收集一些参考,看一看你将要做的事情很重要,确定将要模仿物体的关键属性,从这…

华为面试题及答案——机器学习(二)

21. 如何评价分类模型的优劣? (1)模型性能指标 准确率(Accuracy): 定义:正确分类的样本数与总样本数之比。适用:当各类样本的数量相对均衡时。精确率(Precision): 定义:预测为正类的样本中实际为正类的比例。适用:当关注假阳性错误的成本较高时(例如垃圾邮件检测…

小山菌_代码随想录算法训练营第三十五天| 509. 斐波那契数 、70. 爬楼梯、746. 使用最小花费爬楼梯

509. 斐波那契数 文档讲解&#xff1a;代码随想录.斐波那契数 视频讲解&#xff1a;手把手带你入门动态规划 | LeetCode&#xff1a;509.斐波那契数 状态&#xff1a;已完成 代码实现 class Solution { public:int fib(int n) {if (n < 1)return n;vector<int> dep(n…

基于SOAR模型的面部情绪识别

摘要 情绪表达在日常交流中起着特殊的作用&#xff0c;而检测情绪最重要的方法之一就是识别面部情绪状态。因此&#xff0c;自然人机交互的关键点是识别面部表情并根据感知到的情绪提供反馈。模型的实现涉及两个主要步骤。第一步是读取视频并将其转换为图像&#xff0c;然后对…

iOS包ShaderVariantCollection预热慢问题

1&#xff09;iOS包ShaderVariantCollection预热慢问题 2&#xff09;使用SBP打Bundle如何读取AssetBundleManifest 3&#xff09;如何将一张贴图经过Shader处理后的结果输出给另外一个Shader使用 4&#xff09;为什么我的水这么干净&#xff0c;和UE教程里的有差别 这是第392篇…

Pandas 学习笔记(一)

一、pandas简介 Pandas 是 Python 语言的一个扩展程序库&#xff0c;用于数据分析。 Pandas 名字衍生自术语 "panel data"&#xff08;面板数据&#xff09;和 "Python data analysis"&#xff08;Python 数据分析&#xff09;。 Pandas 是一个开放源码…

ubuntu 18.04 server源码编译安装freeswitch 1.10.11——筑梦之路

前言 这里主要编译支持语音通话、视频通话、短信、webrtc功能的PBX。 安装编译工具包和依赖包 sudo apt-get updatesudo apt-get install -y autoconf git libtool g zlib1g-dev libjpeg-dev libcurl4-openssl-dev libspeex-dev libldns-dev libedit-dev libssl-dev pkg-con…

百问网全志D1h开发板投屏功能实现

投屏功能实现 D1系列号称点屏神器&#xff0c;不仅能点屏&#xff0c;还能用于投屏。 源码准备 百问网为 【百问网D1h开发板】提供了投屏功能需要使用的源码&#xff0c;直接git下载即可&#xff1a; git clone https://github.com/DongshanPI/DongshannezhaSTU_DLNA_Scree…

平板WPS转换的PDF文件保存位置解析

在日常工作和生活中&#xff0c;我们经常需要将文档转换成PDF格式进行分享&#xff0c;以确保接收者能够无障碍地查看文件内容&#xff0c;不受软件版本或操作系统的限制。WPS作为一款功能强大的办公软件&#xff0c;也提供了文档转换为PDF的功能。然而&#xff0c;有时在转换并…

基于振弦采集仪的工程安全监测技术研究与应用

基于振弦采集仪的工程安全监测技术研究与应用 随着工程规模的不断扩大和复杂性的增加&#xff0c;工程安全监测变得越来越重要。工程安全监测的目的是保证工程的安全运行&#xff0c;预防事故的发生&#xff0c;保护人们的生命财产安全。其中&#xff0c;振弦采集仪作为一种重…

【Vite】控制打包结构

配置 vite.config.json 文件&#xff1a; import { defineConfig } from "vite";export default defineConfig({// ...build: {rollupOptions: {output: {entryFileNames: "js/[name]-[hash].js",chunkFileNames: "js/[name]-[hash].js",assetF…

【Android八股文】如何对ListView RecycleView进行局部刷新的?

文章目录 一、如何对ListView进行局部刷新的?1.1 方法一:更新对应view的内容1.2 方法二:通过ViewHolder去设置值1.3 方法三:调用一次getView()方法1.4 封装在万能适配器当中1.5 总结二、如何对RecyclerView 进行局部刷新的?2.0 为什么会有DiffUtil?2.1 讲解一下DiffUtil2…

JOSEF约瑟 JOLP(ROS-2D)型两级跑偏开关 精度高,耐振动

​ 品牌 :JOSEF约瑟 型号名称 :JOLP(ROS-2D)型两级跑偏开关 触点容量 :AC380V 10A 触点数量 :常开:2常闭:2 极限角度 :70 复位方式 :自动 动作力 :3kg 防护等级 :IP66 结构特点 1.通用的安装设计可使跑偏检测装置随意安装在输送机纵梁顶!顶部或底部位置 2.封闭、防腐、坚固的铸…

3D数字人视频合成用户指南

数字人开放平台3D互动数字人如何接入_虚拟数字人(DVH)-阿里云帮助中心3D互动数字人&#xff08;对应开放平台的“智能客服”场景&#xff09;是虚拟数字人开放平台提供能够支持用户与3D数字人进行实时语音交互的数字人产品能力&#xff0c;需要配合智能对话机器人产品使用。本篇…

安装appnium

官网&#xff1a; https://appium.io/docs/en/latest/quickstart/uiauto2-driver/ 安装Node.js 首先&#xff0c;确保安装了Node.js&#xff0c;因为Appium是基于Node.js的。可以从Node.js官网下载并安装最新稳定版。安装Appium Server 你可以通过npm&#xff08;Node.js的包管…

徐徐拉开的帷幕:拜登与特朗普的辩论大戏 日元跌破160大关!创1986年以来最低纪录

北京时间6月27日&#xff08;本周五&#xff09;上午9:00&#xff0c;拜登和特朗普将参加2024年总统候选人电视辩论。作为参考&#xff0c;2016年大选辩论期间&#xff0c;美元汇率对辩论结果的反应相对温和&#xff0c;希拉里胜选预期增强在一定程度上支撑了美元。 时间逐渐临…

Java - 程序员面试笔记记录 实现 - Part1

社招又来学习 Java 啦&#xff0c;这次选了何昊老师的程序员面试笔记作为主要资料&#xff0c;记录一下一些学习过程。 1.1 Java 程序初始化 Java 程序初始化遵循规则&#xff1a;静态变量优于动态变量&#xff1b;父类优于子类&#xff1b;成员变量的定义顺序&#xff1b; …

python运行相关

一、check python是否仍然在运行 Windows 操作系统下用任务管理器查看 打开任务管理器&#xff1a;Ctrl Shift Esc 查看进程列表&#xff1a; 在“进程”选项卡中&#xff0c;找到与 Python 相关的进程。 检查CPU和内存使用情况&#xff1a; 如果数值在不断变化&#xf…