调用numpy()方法可以把Tensor转换为Numpy,此时内存是共享的。
使用copy()方法可以避免内存共享:
import torch
from PIL import Image
from torchvision import transforms
import os
def test001():
dir_path = os.path.dirname(__file__)
file_path = os.path.join(dir_path,'img', '1.jpg')
file_path = os.path.relpath(file_path)
print(file_path)
# 1. 读取图片
img = Image.open(file_path)
# transforms.ToTensor()用于将 PIL 图像或 NumPy 数组转换为 PyTorch 张量,并自动进行数值归一化和维度调整
# 将像素值从 [0, 255] 缩放到 [0.0, 1.0](浮点数)
# 自动将图像格式从 (H, W, C)(高度、宽度、通道)转换为 PyTorch 标准的 (C, H, W)
transform = transforms.ToTensor()
img_tensor = transform(img)
print(img_tensor)
if __name__ == "__main__":
test001()
import torch
from PIL import Image
from torchvision import transforms
def test002():
# 1. 随机一个数据表示图片
img_tensor = torch.randn(3, 224, 224)
# 2. 创建一个transforms
transform = transforms.ToPILImage()
# 3. 转换为图片
img = transform(img_tensor)
img.show()
# 4. 保存图片
img.save("./test.jpg")
if __name__ == "__main__":
test002()
import torch
from PIL import Image
from torchvision import transforms
import os
def test003():
# 获取文件的相对路径
dir_path = os.path.dirname(__file__)
file_path = os.path.relpath(os.path.join(dir_path, 'dog.jpg'))
# 加载图片
img = Image.open(file_path)
# 转换图片为tensor
transform = transforms.ToTensor()
t_img = transform(img)
print(t_img.shape)
# 获取GPU资源,将图片处理移交给CUDA
device = 'cuda' if torch.cuda.is_available() else 'cpu'
t_img = t_img.to(device)
t_img += 0.3
# 将图片移交给CPU进行图片保存处理,一般IO操作是基于CPU的
t_img = t_img.cpu()
transform = transforms.ToPILImage()
img = transform(t_img)
img.show()
if __name__ == "__main__":
test003()
阿达玛积是指两个形状相同的矩阵或张量对应位置的元素相乘。它与矩阵乘法不同,矩阵乘法是线性代数中的标准乘法,而阿达玛积是逐元素操作。假设有两个形状相同的矩阵 A和 B,它们的阿达玛积 C=A∘B定义为:
$$
C_{ij}=A_{ij}×B_{ij}
$$
其中:
Cij 是结果矩阵 C的第 i行第 j列的元素。
Aij和 Bij分别是矩阵 A和 B的第 i行第 j 列的元素。
在 PyTorch 中,可以使用mul函数或者*来实现;
torch.squeeze(input, dim=None)
参数
input: 输入的张量。
dim (可选): 指定要移除的维度。如果指定了 dim,则只移除该维度(前提是该维度大小为 1);如果不指定,则移除所有大小为 1 的维度。
torch.unsqueeze(input, dim)
参数
input: 输入的张量。
dim: 指定要增加维度的位置(从 0 开始索引)。
在 PyTorch 中,你可以查看和设置用于 CPU 运算的线程数。PyTorch 使用多线程来加速 CPU 运算,但有时你可能需要调整线程数来优化性能。
使用 torch.get_num_threads() 来查看当前 PyTorch 使用的线程数:
import torch def get_threads(): # 获取pytorch运行的线程数 print(torch.get_num_threads()) pass if __name__ == "__main__": get_threads()
使用 torch.set_num_threads() 设置 PyTorch 使用的线程数:
import torch def set_get_threads(): # 设置pytorch运行的线程数 torch.set_num_threads(4) print(torch.get_num_threads()) if __name__ == "__main__": set_get_threads()
设置线程数时,确保考虑到你的 CPU 核心数和其他进程的资源需求,以获得最佳性能。
---------自动微分模块torch.autograd负责自动计算张量操作的梯度,具有自动求导功能。自动微分模块是构成神经网络训练的必要模块,可以实现网络权重参数的更新,使得反向传播算法的实现变得简单而高效。
Torch中一切皆为张量,属性requires_grad决定是否对其进行梯度计算。默认是 False,如需计算梯度则设置为True。
torch.autograd通过创建一个动态计算图来跟踪张量的操作,每个张量是计算图中的一个节点,节点之间的操作构成图的边。
在 PyTorch 中,当张量的 requires_grad=True 时,PyTorch 会自动跟踪与该张量相关的所有操作,并构建计算图。每个操作都会生成一个新的张量,并记录其依赖关系。当设置为 True
时,表示该张量在计算图中需要参与梯度计算,即在反向传播(Backpropagation)过程中会自动计算其梯度;当设置为 False
时,不会计算梯度。如:
z = x * y loss = z.sum()
在上述代码中,x 和 y 是输入张量,即叶子节点,z 是中间结果,loss 是最终输出。每一步操作都会记录依赖关系:
z = x * y:z 依赖于 x 和 y。
loss = z.sum():loss 依赖于 z。
叶子节点:
在 PyTorch 的自动微分机制中,叶子节点(leaf node) 是计算图中:
特征
(3)反向传播
使用tensor.backward()方法执行反向传播,从而计算张量的梯度。这个过程会自动计算每个张量对损失函数的梯度。例如:调用 loss.backward() 从输出节点 loss 开始,沿着计算图反向传播,计算每个节点的梯度。
(4)梯度
计算得到的梯度通过tensor.grad访问,这些梯度用于优化模型参数,以最小化损失函数。
(5)梯度清零
x.grad.zero_()