PyTorch是一个基于Python的深度学习框架,它提供了一种灵活、高效、易于学习的方式来实现深度学习模型。PyTorch最初由Facebook开发,被广泛应用于计算机视觉、自然语言处理、语音识别等领域。
PyTorch使用张量(tensor)来表示数据,可以轻松地处理大规模数据集,且可以在GPU上加速。
PyTorch提供了许多高级功能,如自动微分(automatic differentiation)、自动求导(automatic gradients)等,这些功能可以帮助我们更好地理解模型的训练过程,并提高模型训练效率。
CUDA:
CUDA(Compute Unified Device Architecture),统一计算设备架构,是由 NVIDIA 提供的并行计算平台和编程模型。它允许开发者利用 NVIDIA GPU 的强大计算能力进行通用计算,包括科学计算、机器学习、图像处理和视频处理等。CUDA提供了GPU并行计算的底层基础,使GPU能够解决复杂的计算问题。
CUDNN:
cuDNN是基于CUDA的深度神经网络加速库,提供了针对深度学习常见操作(如卷积、池化、归一化、激活函数等)的高度优化实现。
-
性能优化:cuDNN 为卷积神经网络等深度学习模型的训练和推理提供了极高的性能优化。它利用 CUDA 在 GPU 上进行加速计算,充分发挥了 GPU 的并行计算能力。
-
易用性:cuDNN 被集成在主流的深度学习框架(如 TensorFlow、PyTorch、MXNet 等)中,用户直接通过框架调用 cuDNN 的功能,无需关心底层实现细节
安装:
pip install torch==1.13.1+cu116 torchvision==0.14.1+cu116 torchaudio==0.13.1 --extra-index-url https://download.pytorch.org/whl/cu116
Tensor:
PyTorch会将数据封装成张量(Tensor)进行计算,所谓张量就是元素为相同类型的多维矩阵。
张量可以在 GPU 上加速运行。
张量是一个多维数组,通俗来说可以看作是扩展了标量、向量、矩阵的更高维度的数组。张量的维度决定了它的形状(Shape),例如:
-
标量 是 0 阶张量,只有大小没有方向(温度,高度),如
a = torch.tensor(5)
-
向量 是 1 阶张量,具有大小和方向(加速度,力),如
b = torch.tensor([1, 2, 3])
-
2维矩阵 是 2 阶张量,线性变换(旋转矩阵,位移矩阵),,如
c = torch.tensor([[1, 2], [3, 4]])
-
更高维度的张量,如3维、4维等,通常用于表示图像、视频数据等复杂结构。
特点:
-
动态计算图:PyTorch 支持动态计算图,这意味着在每一次前向传播时,计算图是即时创建的。
-
GPU 支持:PyTorch 张量可以通过
.to('cuda')
移动到 GPU 上进行加速计算。 -
自动微分:通过
autograd
模块,PyTorch 可以自动计算张量运算的梯度,这对深度学习中的反向传播算法非常重要。
Tensor的创建:
创建tensor的函数中有两个有默认值的参数dtype和device, 分别代表数据类型和计算设备,可以通过属性dtype和device获取
torch.tensor:
import torch
import numpy as np
def test001():
# 1. 用标量创建张量
shape0 = torch.tensor(5)
print(shape0, shape0.shape)
# 2. 使用numpy随机一个数组创建张量
data = np.random.randn(3, 4)
data = torch.tensor(data)
print(data, data.shape, data.device)
# 3. 根据list创建tensor
data = [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]
data = torch.tensor(data)
print(data, data.shape, data.dtype)
pass
if __name__ == "__main__":
test001()
torch.Tensor:
注意这里的Tensor是大写,该API根据形状创建张量,其也可用来创建指定数据的张量。
import torch
import numpy as np
def test002():
# 1. 根据形状创建张量
tensor1 = torch.Tensor(2, 3)
print(tensor1)
# 2. 也可以是具体的值
tensor2 = torch.Tensor([[1, 2, 3], [4, 5, 6]])
print(tensor2, tensor2.shape, tensor2.dtype)
tensor3 = torch.Tensor([10])
print(tensor3, tensor3.shape, tensor3.dtype)
if __name__ == "__main__":
test002()
torch.IntTensor:
用于创建指定类型的张量,还有诸如Torch.FloatTensor、 torch.DoubleTensor,torch.LongTensor......等。
import torch
def test003():
# 1. 创建指定类型的张量
tt1 = torch.IntTensor(2, 3)
print(tt1)
tt2 = torch.FloatTensor(3, 3)
print(tt2, tt2.dtype)
tt3 = torch.DoubleTensor(3, 3)
print(tt3, tt3.dtype)
tt4 = torch.LongTensor(3, 3)
print(tt4, tt4.dtype)
tt5 = torch.ShortTensor(3, 3)
print(tt5, tt5.dtype)
if __name__ == "__main__":
test003()
创建线性张量:
import torch
import numpy as np
# 不用科学计数法打印
torch.set_printoptions(sci_mode=False)
def test004():
# 1. 创建线性张量
r1 = torch.arange(0, 10, 2)
print(r1)
# 2. 在指定空间按照元素个数生成张量:等差
r2 = torch.linspace(3, 10, 10)
print(r2)
# 3. 在指定空间按照元素个数生成张量:等比
r3 = torch.logspace(3, 10, 5, base=2)#在2^3到2^10之间均匀生成5个数 base默认为10
print(r3)
if __name__ == "__main__":
test004()
创建随机张量:
import torch
def test001():
# 1. 设置随机数种子
torch.manual_seed(123)
# 2. 获取随机数种子
print(torch.initial_seed())
# 3. 生成随机张量
print(torch.rand(2, 3))
# 4. 生成随机张量:标准正态分布
print(torch.randn(2, 3))
# 5. 原生服从正态分布:均值为2, 方差为3,形状为1*4的正态分布
print(torch.normal(mean=2, std=3, size=(1, 4))
if __name__ == "__main__":
test001()
创建0张量:
import torch
import numpy as np
def test001():
# 创建全0张量
data = torch.zeros(2, 3)
print(data, data.dtype)
mask = np.ones((3, 4))
print(mask)
data = torch.zeros_like(torch.tensor(mask))
print(data)
if __name__ == "__main__":
test001()
创建1张量:
import torch
import numpy as np
def test001():
# 创建全1张量
data = torch.ones(2, 3)
print(data, data.dtype)
mask = np.zeros((3, 4))
print(mask)
data = torch.ones_like(torch.tensor(mask))
print(data)
if __name__ == "__main__":
test001()
创建指定值张量:
import torch
import numpy as np
def test001():
# 创建指定值的张量
data = torch.full((2, 3), 666.0)
print(data, data.dtype)
mask = np.zeros((3, 4))
data = torch.full_like(torch.tensor(mask), 999)
print(data)
if __name__ == "__main__":
test001()
创建单位矩阵张量:
import torch
import numpy as np
def test002():
data = torch.eye(4)
print(data)
if __name__ == "__main__":
test002()
切换设备:
默认在cpu上运行,可以显式的切换到GPU:不同设备上的数据是不能相互运算的。
import torch
def test001():
data = torch.tensor([1, 2, 3])
print(data.dtype, data.device, data.shape)
# 把数据切换到GPU进行运算
device = "cuda" if torch.cuda.is_available() else "cpu"
data = data.to(device)
print(data.device)
if __name__ == "__main__":
test001()
类型转换:
import torch
def test001():
data = torch.tensor([1, 2, 3])
print(data.dtype) # torch.int64
# 1. 使用type进行类型转换
data = data.type(torch.float32)
print(data.dtype) # float32
data = data.type(torch.float16)
print(data.dtype) # float16
# 2. 使用类型方法
data = data.float()
print(data.dtype) # float32
data = data.half()
print(data.dtype) # float16
data = data.double()
print(data.dtype) # float64
data = data.long()
print(data.dtype) # int64
if __name__ == "__main__":
test001()
Tensor数据转换:
Numpy转张量:
调用numpy()方法可以把Tensor转换为Numpy,此时内存是共享的
import torch
def test003():
# 1. 张量转numpy
data_tensor = torch.tensor([[1, 2, 3], [4, 5, 6]])
data_numpy = data_tensor.numpy()
print(type(data_tensor), type(data_numpy))
# 2. 他们内存是共享的
data_numpy[0, 0] = 100
print(data_tensor, data_numpy)
if __name__ == "__main__":
test003()
使用copy()方法可以避免内存共享
import torch
def test003():
# 1. 张量转numpy
data_tensor = torch.tensor([[1, 2, 3], [4, 5, 6]])
# 2. 使用copy()避免内存共享
data_numpy = data_tensor.numpy().copy()
print(type(data_tensor), type(data_numpy))
# 3. 此时他们内存是不共享的
data_numpy[0, 0] = 100
print(data_tensor, data_numpy)
if __name__ == "__main__":
test003()
张量转Numpy:
from_numpy方法转Tensor默认是内存共享的
import numpy as np
import torch
def test006():
# 1. numpy转张量
data_numpy = np.array([[1, 2, 3], [4, 5, 6]])
data_tensor = torch.from_numpy(data_numpy)
print(type(data_tensor), type(data_numpy))
# 2. 他们内存是共享的
data_tensor[0, 0] = 100
print(data_tensor, data_numpy)
if __name__ == "__main__":
test006()
使用传统的torch.tensor()则内存是不共享的
import numpy as np
import torch
def test006():
# 1. numpy转张量
data_numpy = np.array([[1, 2, 3], [4, 5, 6]])
data_tensor = torch.tensor(data_numpy)
print(type(data_tensor), type(data_numpy))
# 2. 内存是不共享的
data_tensor[0, 0] = 100
print(data_tensor, data_numpy)
if __name__ == "__main__":
test006()
图像转Tensor:
import torch
from PIL import Image
from torchvision import transforms
def test001():
imgpath = r"./105429.jpg"
# 1. 读取图片
img = Image.open(imgpath)
# 使用transforms.ToTensor()将图片转换为张量
transform = transforms.ToTensor()
img_tensor = transform(img)
print(img_tensor)
if __name__ == "__main__":
test001()
Tensor转图像:
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()