入门 PyTorch ,这70个操作技巧就够了

Pytorch 是当下最流行的算法框架,很多大模型都是基于Pytorch 搭建而成,它提供了大量操作用于创建和训练神经网络。

今天给大家分享 Pytorch 的19个方面,涉及到70个细节操作,这部分内容梳理花了我一天的时间,喜欢记得点个赞

本文从 Pytorch 的操作开始分享,

  • 创建张量

  • 张量属性

  • 张量索引、切片与拼接

  • 张量变换

  • 数学运算

  • 汇总统计

  • 梯度相关

  • 数据管理

  • 其他操作基础操作

  • 自动求导

  • 神经网络模块

  • 数据加载与处理

  • 损失函数

  • 优化器

  • 模型训练与验证

  • 模型保存与加载

  • GPU 加速

  • 模型调优

  • 迁移学习

技术交流&资料

技术要学会分享、交流,不建议闭门造车。一个人可以走的很快、一堆人可以走的更远。

成立了 Pytorch 算法面试和技术交流群,相关资料、技术交流&答疑,均可加我们的交流群获取,群友已超过2000人,添加时最好的备注方式为:来源+兴趣方向,方便找到志同道合的朋友。

方式①、微信搜索公众号:机器学习社区,后台回复:加群
方式②、添加微信号:mlc2040,备注:来自CSDN + 技术交流

创建张量

torch.tensor(data): 从数据创建张量

这个函数会根据提供的数据创建一个新的张量。数据可以是列表、数组等。

import torchdata = [1, 2, 3, 4, 5]
tensor_data = torch.tensor(data)
print(tensor_data)

torch.zeros(size): 创建元素全为0的张量

创建一个指定大小的张量,其中所有元素的值都为0。

import torchsize = (2, 3)
zeros_tensor = torch.zeros(size)
print(zeros_tensor)

torch.ones(size): 创建元素全为1的张量

创建一个指定大小的张量,其中所有元素的值都为1。

import torchsize = (2, 3)
ones_tensor = torch.ones(size)
print(ones_tensor)

torch.empty(size): 创建未初始化的张量

创建一个指定大小的未初始化张量,其值取决于内存的状态。

import torchsize = (2, 3)
empty_tensor = torch.empty(size)
print(empty_tensor)

torch.randn(size): 创建服从标准正态分布的张量

创建一个指定大小的张量,其中的元素值是从标准正态分布中随机抽取的。

import torchsize = (2, 3)
randn_tensor = torch.randn(size)
print(randn_tensor)

torch.arange(start, end, step): 创建一个范围内的一维张量

创建一个一维张量,其中的元素值从起始值到结束值,步长为给定的步长。

import torchstart = 0
end = 5
step = 1
arange_tensor = torch.arange(start, end, step)
print(arange_tensor)

torch.linspace(start, end, steps): 创建一个在指定范围内均匀间隔的张量

创建一个一维张量,其中的元素值在指定范围内均匀分布。

import torchstart = 0
end = 5
steps = 5
linspace_tensor = torch.linspace(start, end, steps)
print(linspace_tensor)

张量属性

.dtype: 获取张量的数据类型

返回张量中元素的数据类型。

import torchtensor = torch.tensor([1, 2, 3])
print(tensor.dtype)

.shape: 获取张量的形状

返回一个元组,表示张量的形状。

import torchtensor = torch.tensor([[1, 2, 3], [4, 5, 6]])
print(tensor.shape)

.device: 获取张量所在的设备

返回一个字符串,表示张量所在的设备,如’cpu’或’cuda:0’。

import torchtensor = torch.tensor([1, 2, 3])
print(tensor.device)

张量索引、切片与拼接

tensor[index]: 索引操作

使用索引来访问张量中的元素。

import torchtensor = torch.tensor([[1, 2, 3], [4, 5, 6]])
element = tensor[0, 1]  # Accesses the element at row 0, column 1
print(element)

tensor[start:end]: 切片操作

使用切片来获取张量的子张量。

import torchtensor = torch.tensor([[1, 2, 3], [4, 5, 6]])
sub_tensor = tensor[:, 1:]  # Slices the tensor to get all rows and columns starting from the second column
print(sub_tensor)

torch.cat(tensors, dim): 在给定维度上连接张量

沿着指定维度将多个张量连接在一起。

import torchtensor1 = torch.tensor([[1, 2], [3, 4]])
tensor2 = torch.tensor([[5, 6], [7, 8]])
concatenated_tensor = torch.cat((tensor1, tensor2), dim=0)  # Concatenates along the row dimension
print(concatenated_tensor)

torch.stack(tensors, dim): 在新维度上堆叠张量

在一个新的维度上堆叠多个张量。

import torchtensor1 = torch.tensor([1, 2, 3])
tensor2 = torch.tensor([4, 5, 6])
stacked_tensor = torch.stack((tensor1, tensor2), dim=1)  # Stacks tensors along a new dimension
print(stacked_tensor)

张量变换

tensor.view(shape): 返回给定形状的张量视图

返回一个具有指定形状的新张量,原始张量的形状必须与新形状兼容。

import torchtensor = torch.tensor([[1, 2], [3, 4]])
reshaped_tensor = tensor.view(1, 4)  # Reshapes the tensor to a 1x4 tensor
print(reshaped_tensor)

tensor.reshape(shape): 改变张量的形状

返回一个具有指定形状的新张量,原始张量的元素数量必须与新形状一致。

import torchtensor = torch.tensor([[1, 2], [3, 4]])
reshaped_tensor = tensor.reshape(1, 4)  # Reshapes the tensor to a 1x4 tensor
print(reshaped_tensor)

tensor.transpose(dim0, dim1): 交换两个维度

交换张量中两个维度的位置。

import torchtensor = torch.tensor([[1, 2], [3, 4]])
transposed_tensor = tensor.transpose(0, 1)  # Swaps the first and second dimensions
print(transposed_tensor)

tensor.permute(*dims): 按照指定顺序排列张量的维度

按照给定顺序重新排列张量的维度。

import torchtensor = torch.tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
permuted_tensor = tensor.permute(1, 0, 2)  # Permutes the dimensions to (1, 0, 2)
print(permuted_tensor)

tensor.squeeze(): 删除所有长度为1的维度

删除张量中所有长度为1的维度。

import torchtensor = torch.tensor([[[1, 2], [3, 4]]])
squeezed_tensor = tensor.squeeze()  # Removes the single-dimensional entries
print(squeezed_tensor)

tensor.unsqueeze(dim): 在指定位置增加一个维度

在指定位置增加一个长度为1的新维度。

import torchtensor = torch.tensor([[1, 2], [3, 4]])
unsqueezed_tensor = tensor.unsqueeze(0)  # Adds a dimension at index 0
print(unsqueezed_tensor)

数学运算

torch.add(x, y): 加法

对两个张量进行逐元素加法运算。

import torchx = torch.tensor([1, 2, 3])
y = torch.tensor([4, 5, 6])
result = torch.add(x, y)
print(result)

torch.sub(x, y): 减法

对两个张量进行逐元素减法运算。

import torchx = torch.tensor([1, 2, 3])
y = torch.tensor([4, 5, 6])
result = torch.sub(x, y)
print(result)

torch.mul(x, y): 乘法

对两个张量进行逐元素乘法运算。

import torchx = torch.tensor([1, 2, 3])
y = torch.tensor([4, 5, 6])
result = torch.mul(x, y)
print(result)

torch.div(x, y): 除法

对两个张量进行逐元素除法运算。

import torchx = torch.tensor([1.0, 2.0, 3.0])
y = torch.tensor([4.0, 5.0, 6.0])
result = torch.div(x, y)
print(result)

torch.matmul(x, y): 矩阵乘法

计算两个张量的矩阵乘法。

import torchx = torch.tensor([[1, 2], [3, 4]])
y = torch.tensor([[5, 6], [7, 8]])
result = torch.matmul(x, y)
print(result)

torch.pow(base, exponent): 幂运算

计算张量的幂。

import torchbase = torch.tensor([1, 2, 3])
exponent = 2
result = torch.pow(base, exponent)
print(result)

torch.exp(tensor): 指数运算

计算张量中所有元素的指数。

import torchtensor = torch.tensor([1.0, 2.0, 3.0])
result = torch.exp(tensor)
print(result)

torch.sqrt(tensor): 开方运算

计算张量中所有元素的平方根。

import torchtensor = torch.tensor([1.0, 4.0, 9.0])
result = torch.sqrt(tensor)
print(result)

汇总统计

torch.sum(input): 求和

计算张量中所有元素的和。

import torchtensor = torch.tensor([[1, 2], [3, 4]])
result = torch.sum(tensor)
print(result)

torch.mean(input): 求平均值

计算张量中所有元素的平均值。

import torchtensor = torch.tensor([[1, 2], [3, 4]], dtype=torch.float)
result = torch.mean(tensor)
print(result)

torch.max(input): 求最大值

找出张量中所有元素的最大值。

import torchtensor = torch.tensor([[1, 2], [3, 4]])
result = torch.max(tensor)
print(result)

torch.min(input): 求最小值

找出张量中所有元素的最小值。

import torchtensor = torch.tensor([[1, 2], [3, 4]])
result = torch.min(tensor)
print(result)

torch.std(input): 求标准差

计算张量中所有元素的标准差。

import torchtensor = torch.tensor([[1, 2], [3, 4]], dtype=torch.float)
result = torch.std(tensor)
print(result)

torch.var(input): 求方差

计算张量中所有元素的方差。

import torchtensor = torch.tensor([[1, 2], [3, 4]], dtype=torch.float)
result = torch.var(tensor)
print(result)

梯度相关

tensor.requires_grad_(): 标记张量需要计算梯度

标记张量以便在反向传播中计算梯度。

import torchtensor = torch.tensor([1.0, 2.0, 3.0], requires_grad=True)

tensor.grad: 获取张量的梯度

获取张量的梯度值,前提是该张量需要计算梯度。

import torchtensor = torch.tensor([1.0, 2.0, 3.0], requires_grad=True)
tensor.sum().backward()
print(tensor.grad)

tensor.backward(): 计算梯度

计算张量的梯度值,前提是该张量需要计算梯度。

import torchtensor = torch.tensor([1.0, 2.0, 3.0], requires_grad=True)
tensor.sum().backward()

数据管理

tensor.to(device): 将张量移动到指定的设备上(如GPU)

将张量移动到指定的设备上,例如GPU。

import torchtensor = torch.tensor([1, 2, 3])
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
tensor = tensor.to(device)
print(tensor.device)

torch.save(obj, f): 保存对象到文件

将对象保存到文件中。

import torchtensor = torch.tensor([1, 2, 3])
torch.save(tensor, 'tensor.pt')  # Save tensor to file

torch.load(f): 从文件加载对象

从文件中加载对象。

import torchtensor = torch.load('tensor.pt')  # Load tensor from file
print(tensor)

其他操作基础操作

torch.nn.functional.relu(input): 应用ReLU激活函数

对输入张量应用ReLU激活函数。

import torch.nn.functional as F
import torchinput = torch.tensor([-1, 0, 1], dtype=torch.float)
output = F.relu(input)
print(output)

torch.nn.Conv2d(in_channels, out_channels, kernel_size): 创建二维卷积层

创建一个二维卷积层。

import torch.nn as nn
import torchconv_layer = nn.Conv2d(in_channels=3, out_channels=16, kernel_size=3)
input = torch.randn(1, 3, 64, 64)
output = conv_layer(input)
print(output.shape)

torch.optim.SGD(params, lr): 使用SGD优化器

使用随机梯度下降(SGD)优化器来优化模型参数。

import torch.optim as optim
import torchparams = torch.tensor([1.0, 2.0, 3.0], requires_grad=True)
optimizer = optim.SGD([params], lr=0.1)

自动求导(Autograd)

自动求导是 PyTorch 中一个重要的功能,能够自动计算张量的梯度。

import torchx = torch.tensor([1.0, 2.0, 3.0], requires_grad=True)
y = x ** 2
y.backward(torch.tensor([1.0, 1.0, 1.0]))  # 计算 y 对 x 的梯度
print(x.grad)  # 输出梯度值

神经网络模块(nn.Module)

使用 nn.Module 类来定义神经网络模型,可以方便地管理和组织模型的结构。

import torch.nn as nn
import torchclass Net(nn.Module):def __init__(self):super(Net, self).__init__()self.fc = nn.Linear(10, 1)def forward(self, x):return self.fc(x)model = Net()

数据加载与处理(Data Loading and Processing)

使用 DataLoader 和 Dataset 类来加载和处理数据集。

import torch
from torch.utils.data import DataLoader, Datasetclass CustomDataset(Dataset):def __init__(self, data):self.data = datadef __len__(self):return len(self.data)def __getitem__(self, index):return self.data[index]data = [1, 2, 3, 4, 5]
dataset = CustomDataset(data)
dataloader = DataLoader(dataset, batch_size=2, shuffle=True)

损失函数(Loss Functions)

使用损失函数来衡量模型输出与真实标签之间的差异。

import torch.nn as nn
import torchcriterion = nn.CrossEntropyLoss()
output = torch.tensor([[0.1, 0.2, 0.7], [0.3, 0.6, 0.1]])
target = torch.tensor([2, 1])
loss = criterion(output, target)
print(loss)

优化器(Optimizers)

使用优化器来更新模型的参数,常见的优化器包括 SGD、Adam 等。

import torch.optim as optim
import torchmodel = Net()
optimizer = optim.SGD(model.parameters(), lr=0.01)

模型训练与验证(Model Training and Validation)

使用 PyTorch 来训练和验证神经网络模型。

import torch.nn as nn
import torch.optim as optim
import torchmodel = Net()
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)for epoch in range(10):# 训练模型for data in dataloader:inputs, labels = dataoptimizer.zero_grad()outputs = model(inputs)loss = criterion(outputs, labels)loss.backward()optimizer.step()# 验证模型with torch.no_grad():# 计算准确率等指标

模型保存与加载(Model Saving and Loading)

在训练完成后,将模型保存到文件中以便后续使用。

import torchtorch.save(model.state_dict(), 'model.pth')  # 保存模型参数

GPU 加速(GPU Acceleration)

利用 GPU 加速计算可以显著提高模型训练的速度。

import torchdevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = Net().to(device)  # 将模型移动到 GPU 上

模型调优(Model Tuning)

使用交叉验证和超参数搜索来调优模型,以提高模型性能。

from sklearn.model_selection import GridSearchCV
import torchparameters = {'lr': [0.01, 0.1, 1.0]}
model = Net()
optimizer = optim.SGD(model.parameters(), lr=0.01)
grid_search = GridSearchCV(optimizer, parameters)

迁移学习(Transfer Learning)

迁移学习是一种常见的训练技巧,可以使用预训练的模型来加速模型的训练过程。

import torchvision.models as models
import torchpretrained_model = models.resnet18(pretrained=True)
# 将预训练模型的参数冻结
for param in pretrained_model.parameters():param.requires_grad = False

最后

掌握以上19种操作方法可以让你更好地使用 PyTorch 进行深度学习任务。这些操作方法涵盖了张量的创建、变换、数学运算、梯度计算、模型构建、数据处理等方面,是使用 PyTorch 进行深度学习的基础操作。

用通俗易懂的方式讲解系列

  • 重磅来袭!《大模型面试宝典》(2024版) 发布!

  • 重磅来袭!《大模型实战宝典》(2024版) 发布!

  • 用通俗易懂的方式讲解:不用再找了,这是大模型最全的面试题库

  • 用通俗易懂的方式讲解:这是我见过的最适合大模型小白的 PyTorch 中文课程

  • 用通俗易懂的方式讲解:一文讲透最热的大模型开发框架 LangChain

  • 用通俗易懂的方式讲解:基于 LangChain + ChatGLM搭建知识本地库

  • 用通俗易懂的方式讲解:基于大模型的知识问答系统全面总结

  • 用通俗易懂的方式讲解:ChatGLM3 基础模型多轮对话微调

  • 用通俗易懂的方式讲解:最火的大模型训练框架 DeepSpeed 详解来了

  • 用通俗易懂的方式讲解:这应该是最全的大模型训练与微调关键技术梳理

  • 用通俗易懂的方式讲解:Stable Diffusion 微调及推理优化实践指南

  • 用通俗易懂的方式讲解:大模型训练过程概述

  • 用通俗易懂的方式讲解:专补大模型短板的RAG

  • 用通俗易懂的方式讲解:大模型LLM Agent在 Text2SQL 应用上的实践

  • 用通俗易懂的方式讲解:大模型 LLM RAG在 Text2SQL 上的应用实践

  • 用通俗易懂的方式讲解:大模型微调方法总结

  • 用通俗易懂的方式讲解:涨知识了,这篇大模型 LangChain 框架与使用示例太棒了

  • 用通俗易懂的方式讲解:掌握大模型这些优化技术,优雅地进行大模型的训练和推理!

  • 用通俗易懂的方式讲解:九大最热门的开源大模型 Agent 框架来了

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

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

相关文章

骑马与砍杀战团mod制作-基础-对话制作笔记(四)

骑马与砍杀战团mod制作-基础-对话制作笔记(四) 资料来源 学习的资料来源: b站【三啸解说】手把手教你做【骑砍】MOD,基础篇,链接为: https://www.bilibili.com/video/BV19x411Q7No?p4&vd_sourcea507…

免费领!系统学习上位机编程的流程与基础教程

上位机电气自动化plc编程全套入门教程工具 华山编程导师根据当前招聘需求的关键点,原创录制了一套系统的学习流程和基础教程,帮助你从快速入门到掌握上位机编程的技能。 二. 学习准备 为了更好地学习并实现80%以上的代码运行,建议准备一个工…

Android音频系统

最近在做UAC的项目,大概就是接收内核UAC的事件,也就是声音相关事件。然后就是pcm_read和AudioTrackr->write之间互传。感觉略微有点奇怪,所以简单总结一下。 1 UAC的简要流程 open_netlink_socket 打开内核窗口,类似于ioctl。…

[leetcode]valid-triangle-number. 有效三角形的个数

. - 力扣&#xff08;LeetCode&#xff09; class Solution { public:int triangleNumber(vector<int>& nums) {int n nums.size();sort(nums.begin(), nums.end());int ans 0;for (int i 0; i < n; i) {for (int j i 1; j < n; j) {int left j 1, righ…

大模型RAG技术:构建高效、可信赖的知识检索系统

前言 LLM 问题 幻觉&#xff1a;在没有答案的情况下提供虚假信息。 过时&#xff1a;当用户需要特定的当前响应时&#xff0c;提供过时或通用的信息。 来源&#xff1a;从非权威来源创建响应。由于术语混淆&#xff0c;不同的培训来源使用相同的术语来谈论不同的事情&#…

网络构建和设计方法_1.网络需求分析

1.网络需求分析 网络需求分析是网络构建及开发过程的起始环节&#xff0c;也是极其重要的阶段。在该阶段&#xff0c;可尽早明确客户使用网络的真实用途或痛点&#xff0c;以便为后续能够构建和设计出更贴近客户真实诉求的网络打下坚实基础&#xff0c;前期的网络需求分析至关…

制造业包括哪些?需要堡垒机吗?

制造业-国民经济的主体&#xff0c;是立国之本、兴国之器、强国之基&#xff0c;一个关系着大家吃穿住行的行业&#xff0c;一个与大家息息相关的行业。但大家对于制造业还有很多不了解&#xff0c;有小伙伴在问&#xff0c;制造业包括哪些&#xff1f;需要堡垒机吗&#xff1f…

深入探索npm依赖:掌握查看与管理包依赖的艺术

深入探索npm依赖&#xff1a;掌握查看与管理包依赖的艺术 在JavaScript和Node.js的世界中&#xff0c;npm&#xff08;Node Package Manager&#xff09;不仅是一个包管理器&#xff0c;更是一个强大的工具&#xff0c;用于管理项目依赖。理解并掌握如何查看和管理npm包的依赖…

k8s使用Endpoint将信息存储到集群外部数据库

https://mp.csdn.net/mp_blog/creation/editor/139864305 上一篇文章

引领AI新时代:深度学习与大模型的关键技术

文章目录 &#x1f4d1;前言一、内容概述二、作者简介三、书籍特色四、学习平台与资源 &#x1f4d1;前言 在数字化浪潮席卷全球的今天&#xff0c;人工智能&#xff08;AI&#xff09;和深度学习技术已经渗透到我们生活的方方面面。从智能手机中的智能语音助手&#xff0c;到…

20.流入门

学习知识&#xff1a;输入流和输出流读文件的简单使用 test.txt&#xff1a; iloveu是我爱你的意思。 Main.java import java.io.*;public class Main {public static void main(String[] args) {// 1.利用输入流读文件//读取test.txt并输出文件内容try{FileInputStream in…

分类预测 | Matlab实现GA-XGBoost遗传算法优化XGBoost的多特征分类预测

分类预测 | Matlab实现GA-XGBoost遗传算法优化XGBoost的多特征分类预测 目录 分类预测 | Matlab实现GA-XGBoost遗传算法优化XGBoost的多特征分类预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 Matlab实现GA-XGBoost遗传算法优化XGBoost的多特征分类预测&#xff0c;…

【Hadoop集群搭建】集群崩溃处理及启动时常见报错解决办法

目录 1. 集群崩溃处理 1.1 杀死进程 1.2 删除目录&#xff08;logs/和hadoopdata/&#xff09; 1.3 重新初始化集群 1.4 重新启动集群 2. 启动时常见报错 2.1 报错如下 2.2 在运行程序测试 MapReduce 计算框架时报错如下 2.3 报错如下 1. 集群崩溃处理 1.1 杀死进程 sbin/st…

Clickhouse的基本sql语句

1&#xff0c;建库语句 create database if not exists mytestdb on cluster default_cluster;注意&#xff1a;用户在集群中创建数据库或者表时使用ON CLUSTER语句&#xff0c;保证各个ClickHouse节点上数据库、表的元信息相同。 2&#xff0c;建表 -- 创建复制表 create t…

SpringBoot优点达项目实战:项目基本配置(二)

SpringBoot优点达项目实战&#xff1a;项目基本配置&#xff08;二&#xff09; 文章目录 SpringBoot优点达项目实战&#xff1a;项目基本配置&#xff08;二&#xff09;1、项目初始化配置2、MyBatisPlus配置3、Knife配置4、定义统一返回数据结构 1、项目初始化配置 创建appli…

学习笔记——动态路由——RIP(RIP工作原理/防环机制)

三、RIP工作原理/防环机制 1、工作原理 配置好RIP的路由器会每隔30s,向邻居路由器自动发送RIP路由更新报文。报文里面携带了其所知道的所有路由。 通过发送数据包进行路由信息的交互&#xff0c;路由器启动RIP协议&#xff0c;向周围邻居路由器传递request(请求)response(响…

克隆网站的风险

克隆网站的风险 随着互联网的快速发展&#xff0c;克隆网站也变得越来越常见。克隆网站是指复制原始网站的外观和功能&#xff0c;并伪装成原始网站。虽然克隆网站可以提供与原始网站相似的服务和体验&#xff0c;但它们也带来了一系列风险。本文将探讨克隆网站的风险&#xff…

我的故事与思考

在24年的高考帷幕落下之后&#xff0c;我们站在了一个新的起点&#xff0c;面对着即将开始的大学新生活&#xff0c;我们面临着一道重要的选择题&#xff1a;是选择一个心仪的专业&#xff0c;还是选择一个知名度更高的学校&#xff1f;这是一个困扰了众多考生和家长的长期难题…

Docker 从入门到精通(大全)

一、概述 1.1 基本概念 Docker 是一个开源的应用容器引擎&#xff0c;基于 Go 语言 并遵从 Apache2.0 协议开源。 Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上&#xff0c;也可以实现虚拟化。…

使用QtGui显示QImage的几种方法

问题描述 我是一名刚学习Qt的新手,正在尝试创建一个简单的GUI应用程序。当点击一个按钮时,显示一张图片。我可以使用QImage对象读取图片,但是否有简单的方法调用一个Qt函数,将QImage作为输入并显示它? 方法一:使用QLabel显示QImage 最简单的方式是将QImage添加到QLabe…