Bootstrap

深度学习(1)

一、torch的安装

基于直接设备情况,选择合适的torch版本,有显卡的建议安装GPU版本,可以通过nvidia-smi命令来查看显卡驱动的版本,在官网中根据cuda版本,选择合适的版本号,下面是安装示例代码
GPU:

pip install torch==2.5.0 torchvision==0.20.0 torchaudio==2.5.0 --index-url https://download.pytorch.org/whl/cu124

CPU:

pip install torch==2.5.0 torchvision==0.20.0 torchaudio==2.5.0 --index-url https://download.pytorch.org/whl/cpu

!!!,因为torch包很大,有3个G左右,下载时请选择稳定的网络环境,预防因网络波动导致安装失败。

二、tensor简述

PyTorch会将数据封装成张量(Tensor)进行计算,所谓张量就是元素为相同类型的多维矩阵。张量可以在 GPU 上加速运行。

2.1、概述

张量是一个多维数组,通俗来说可以看作是扩展了标量、向量、矩阵的更高维度的数组。张量的维度决定了它的形状(Shape),常见的张量有:

  • 标量:0阶张量;
  • 向量:1阶张量;
  • 矩阵:2阶张量;
  • 其他:例如高阶张量、图像、视频等复杂数据结构。

2.2、特点

  • 动态计算图
  • GPU支持
  • 自动微分

2.3、数据类型

PyTorch中有3种数据类型:浮点数、整数、布尔。其中,浮点数和整数又分为8位、16位、32位、64位,加起来共9种。

三、tensor创建---- torch.tensor:根据指定的数据创建张量。

3.1、标量

def th_touchs():
    # ? 创建一个一阶张量
    t1 = torch.tensor(5)

    print(t1.shape) # 打印张量的形状
    print(t1.dtype) # 打印张量的数据类型
    print(type(t1)) # 打印张量的类型

3.2、数组

# 数组
data = np.array([1, 2, 3, 4])
x = torch.tensor(data)
print(x)

3.3、列表

# 列表
data = [1,2,3,4]
x = torch.tensor(data)
print(x)

3.4、指定张量的数据类型

data = np.array([1, 2, 3, 4],dtype = int)
x = torch.tensor(data)
print(x)

3.5、指定张量的执行设备

data = np.array([1, 2, 3, 4],divice = "cuda")
x = torch.tensor(data)
print(x)

3.6、其他指定类型张量

"""
创建张量
"""
import torch

# ! 创建线性张量
def test_linear():
    # 左闭右开区间,步长为2
    x = torch.arange(1, 10, 2)
    # print(x)

    #闭区间,自动等差步长
    y = torch.linspace(1, 10, 4)
    # print(y)

    # 等比数列,base表示指数,表示3^1~3^10取5个数
    z = torch.logspace(1, 10, 10,base=2)
    # print(z)


# ! 创建随机张量
def test_tensor():
    # 设置随机数种子
    torch.manual_seed(123)

    # 获取当前随机数种子
    # print(torch.initial_seed())

    # 生成随机张量
    x = torch.rand(10, 5)
    # print(x)

    # 生成正太分布的随机张量
    y = torch.randn(2, 10)
    # print(y)

    # 自定义方差和均值
    z = torch.normal(mean=10, std=2, size=(2, 2))
    print(z)


# ! 创建0/1张量
def test_zeros():
    # 创建指定形状的张量
    x = torch.zeros((4, 4), dtype=torch.int64)
    # print(x)

    # 从数据中构建张量,传入的容器只能是tensor
    x = torch.tensor([[1, 2, 3],
                      [4, 5, 6]])
    
    x = torch.rand(3,3)
    x = torch.zeros_like(x)
    print(x)

def test_ones():
    # 创建指定形状的张量
    x = torch.ones((4, 4), dtype=torch.int64)
    # print(x)

    # 从数据中构建张量,传入的容器只能是tensor
    x = torch.tensor([[1, 2, 3],
                      [4, 5, 6]])
    
    x = torch.rand(3,3)
    x = torch.ones_like(x)
    print(x)

# ! 创建指定值张量
def test_full():
    # 创建指定形状的张量
    x = torch.full((4, 4), fill_value=7)
    # print(x)

        # 从数据中构建张量,传入的容器只能是tensor
    x = torch.tensor([[1, 2, 3],
                      [4, 5, 6]])
    x = torch.full_like(x, 11)
    print(x)


# ! 创建单位矩阵张量
def test_eye():
    # 创建指定形状的张量
    x = torch.eye(4, 4)
    print(x)



if __name__ == '__main__':
    test_linear()
    test_tensor()
    test_zeros()
    test_ones()
    test_full()
    test_eye()

tensor常用属性

"""
常见属性
"""

import torch

def th_tensor():
    x = torch.tensor([1, 2, 3],device='cuda') # 指定创建到cuda/cpu的tensor
    print(x.dtype) # 数据类型
    print(x.device)# tensor所在的设备,默认是cpu
    print(x.shape) # 形状


# 设备切换
def device_change():
    # 方式1
    # 将tensor创建在cuda设备上
    x = torch.tensor([1, 2, 3], device='cuda')
    # print(1,x.device)
    
    # 方式2
    # 先创建一个cpu上的tensor
    x = torch.tensor([1, 2, 3])
    # 将tensor移动到cuda设备上
    x = x.to('cuda:0')
    # print(2,x.device)

    # 通过api获取设备是否有cuda
    # 检查CUDA是否可用
    res = torch.cuda.is_available()
    print(res)

    # 条件判断
    c = 1 if 100>10 else 0
    print(c)
    # 根据CUDA可用性将tensor移动到cuda或cpu设备上
    x.to("cuda" if torch.cuda.is_available() else "cpu")
    print(x.device)

    # 方式3
    # 创建一个cpu上的tensor
    x = torch.tensor([1, 2, 3])
    print(x.device)
    # 把tensor移动到cuda上
    y = x.cuda()  # 把tensor移动到cuda上
    print(y.device)
    # 根据CUDA可用性将tensor移动到cuda或cpu设备上
    x = x.cuda() if torch.cuda.is_available() else x.cpu()


# 类型转换
def type_convert():
    # 直接指定tensor的数据类型
    x = torch.tensor([1, 2, 3], dtype=torch.float64)
    print(x.dtype)

    # 通过type方法转换tensor的数据类型
    x  = x.type(torch.int8)
    print(x.dtype)

    # 通过half方法转换tensor的数据类型
    x = x.half()
    print(x.dtype)

    # 通过double方法转换tensor的数据类型
    x = x.double()
    print(x.dtype)

    # 通过float方法转换tensor的数据类型
    x = x.float()
    print(x.dtype)

    # 通过int方法转换tensor的数据类型
    x = x.int()
    print(x.dtype)

if __name__ == '__main__':
    # print(th_tensor())
    # device_change()
    type_convert()

五、tensor数据类型转换

5.1、常规数据类型转换

import numpy as np
import torch


def th_data_np():
    x = torch.tensor([1, 2, 3])
    print(x)
    # 把Tensor转换为numpy数组
    x1 = x.numpy()
    print(x1)
    print(type(x1))

    # x 和x1 是两个不同的对象,但它们都指向同一个数据存储空间
    x1[0] = 100
    print(x)


def th_data_copy():
    x = torch.tensor([1, 2, 3])
    print(x)
    # 把Tensor转换为numpy数组并copy,copy()不会改变原来的数据
    x1 = x.numpy().copy() # 注意这里是copy(深拷贝),还有一个view(浅拷贝)
    print(x1)
    print(type(x1))

    x1[0] = 100
    print(x)
    print(x1)

def th_data_np_tensor():
    # np转tensor,不共用内存(浅拷贝)
    x = np.array([1, 2, 3])
    print(x)
    # 把numpy数组转换为Tensor
    x1 = torch.tensor(x)
    x[0] = 100
    x1[0] = 200
    print(x)
    print(x1)

    # from_numpy()会和原来的数组共享内存(深拷贝)
    x2 = np.array([1, 2, 3])
    x3 = torch.from_numpy(x2)
    x2[0] = 100
    x3[1] = 200

    print(x2)
    print(x3)

if __name__ == '__main__':
    # th_data_np()
    # th_data_copy()
    th_data_np_tensor()

5.2、图片数据类型转换


from PIL import Image
import torch
from torchvision import transforms


def tensor_to_img():
    pass

# ? 将图像转换为张量
def img_to_tensor():
    path = './data/1.png'
    img = Image.open(path)
    print(img)
    transfer = transforms.ToTensor()
    img_tensor = transfer(img)
    print(img_tensor.shape)

# ? 将张量转换为图像
def test():
    # r = torch.rand(315,315)
    # g = torch.rand(315,315)
    # b = torch.rand(315,315)

    img_tensor = torch.rand(4,315,315)
    # print(img_tensor)
    # print(img_tensor.shape)

    # tensor转PIL对象
    transfer = transforms.ToPILImage()
    img = transfer(img_tensor)
    img.show()


def test2():
    prth = r"./data/1.png"
    img = Image.open(prth)
    print(img)
    transfer = transforms.ToTensor()
    img_tensor = transfer(img)
    img_tensor[0] = 255
    tensor2pil = transforms.ToPILImage()
    img_pil = tensor2pil(img_tensor)
    img_pil.show()
    img_pil.save('./data/2.png')

if __name__ == "__main__":
    # img_to_tensor(
    # test()
    test2()

六、tensor常见操作

6.1、获取元素

"""
从tensor中获取元素
"""

import torch


def th_items():
    # 标量
    x = torch.tensor(1)
    print(x.item())

    # 一阶
    x = torch.tensor([100])
    print(x.item())

    # ! 如果输入的数据大于一个,会报错
    x = torch.tensor([1, 2])
    # print(x.item())


if __name__ == '__main__':
    th_items()

6.2、元素值运算

"""
元素值运算
"""
import torch

def th_cction():
    torch.manual_seed(666)
    x = torch.randint(1, 10, (3, 3))
    print(x)
    
    # ? 加
    x1 = x.add(100)
    print(x1)
    # !带_结尾的函数,基本上都是在原数据进行操作
    x.add_(200)
    print(x)

    # ? 减
    x2 = x.sub(50)
    print(x2)
    x.sub_(40)
    print(x)

    # ? 乘
    x3 = x.mul(2)
    print(x3)
    x.mul_(2)
    print(x)

    # ? 除
    x4 = x.div(2)
    print(x4)
    x.div_(2)
    print(x)

    # ? 幂
    x5 = x.pow(2)
    print(x5)
    x.pow_(2)
    print(x)

    # ?
    x6 = x**2
    print(x6)

if __name__ == '__main__':
    th_cction()

6.3、阿达玛积

"""
计算阿达玛积


"""
import torch

def adama():
    x1 = torch.tensor([[1,2],
                      [3,4]])
    x2 = torch.tensor([[1,2],
                      [3,4]])
    #! Adama积矩阵形状必须相同
    x3 = x1 * x2
    print(x3)



if __name__ == '__main__':
    adama()

6.4、相乘

"""
矩阵相乘
"""

import torch


def dot():
    x1 = torch.tensor([[1,2],
                      [3,4]])
    x2 = torch.tensor([[1,2],
                      [3,4]])
    
    x3 = torch.matmul(x1, x2)
    x3 = x1.matmul(x2)
    x3 = x1 @ x2
    x3 = x1.mm(x2)
    print(x3)

if __name__ == '__main__':
    dot()

6.5、索引

"""
索引
"""

import torch


def index():
    # tensor 的布尔运算
    # torch.manual_seed(66)
    # x = torch.randint(0, 10, (5, 5))
    # print(x)
    # x1 = x > 7
    # print(x1)
    # x3 = x[x1]
    # print(x3)

    # print(x[x % 2 == 0])

    # 创建一个5x5的tensor作为示例数据
    x = torch.tensor([
        [2, 3, 2000, 10, 20],  # 满足条件:偶数,奇数,闰年
        [1, 2, 2001, 30, 40],  # 不满足条件:第一列是奇数
        [4, 5, 2004, 50, 60],  # 满足条件:偶数,奇数,闰年
        [3, 7, 1900, 70, 80],  # 不满足条件:第三列不是闰年(虽然能被4整除,但也能被100整除且不能被400整除)
        [6, 9, 1600, 90, 100]  # 满足条件:偶数,奇数,闰年
    ])

    # 找出第一列是偶数,第二列是奇数,第三列是闰年的行中的第四列和第五列的数据
    print(x[(x[:, 0] % 2 == 0) & (x[:, 1] % 2 != 0) & ((x[:, 2] % 4 == 0) | (x[:, 2] % 400 == 0))][:, [3, 4]])


# ? 索引赋值
def index_ass():
    torch.manual_seed(66)
    x = torch.randint(1,10,(5, 5))
    print(x)
    x1 = x[1,1]
    print(x1)
    x[1,1] = 100
    print(x)
    x[:,3] = 200
    print(x)
    x[:,:] = 300
    print(x)
    x.fill_(400)
    print(x)

if __name__ == "__main__":
    # index()
    index_ass()

6.6、拼接

"""
拼接
"""

import torch
from PIL import Image
from torchvision import transforms

def montage_cat():
    x = torch.randint(1, 10, (3,3))
    y = torch.randint(1, 10, (3,3))

    print(x)
    print(y)

    # cat():不会增加维度
    # 拼接,dim=0:按行拼接,dim=1:按列拼接
    z = torch.cat([x, y], dim=0)
    print(z)


def montage_stack():
    torch.manual_seed(66)
    x = torch.randint(1, 10, (3,3))
    y = torch.randint(1, 10, (3,3))

    # print(x)
    # print(y)

    # ! stack():会增加维度(张量级别)
    # ! 堆叠,dim=0:按行堆叠,dim=1:按列堆叠
    # ! 要堆叠的张量必须具有相同的形状
    z = torch.stack([x, y],dim=1)
    print(z)

def montage_img():
    # 加载本地图像为PIL
    img = Image.open('./data/1.png')
    transfer = transforms.ToTensor()
    img_tensor = transfer(img)
    # print(img_tensor)
    # print(img_tensor.shape)
    res = torch.stack([img_tensor[0], img_tensor[1],img_tensor[2]], dim=0)

if __name__ == '__main__':
    # montage_cat()
    # montage_stack()
    montage_img()

6.7、形状

"""
形状操作
"""

import torch

def th_reshape():
    x = torch.reshape(x, (-1, 5))
    x1 = torch.reshape(x, (2, 6))
    print(x)
    x2 = torch.reshape(x, (2, 3, 2))
    print(x2)



def th_view():
    x = torch.randint(1, 10,(4, 3))
    # print(x)
    # !改变形状,由于没有改变原x中的内存空间,因此改变形状操作比reshape快
    x1 = x.view((2, 6))
    # print(x1)

    # x2 = torch.randit(1, 10,(4, 3))
    # # x3 = torch.reshape(x2, (2, 6))
    # x4 = x2.t() # 转置矩阵
    # print(x4)
    # # !改变形状,在内存中不连续的数据不能通过view转换
    # x5 = x4.view(2,6)
    # print(x5)

    # ! 改变形状后,是否共享数据内存
    x6 = torch.randint(1, 10, (4, 3))
    x7 = x6.view(2, 6)
    x6[1,1] = 999
    print(x6)
    print(x7)


# ? 改变维度0
def rh_transpose():
    x1 = torch.randint(1, 10, (4, 3))
    print(x1,x1.shape)
    # ! transpose(x, dim0, dim1), 交换两个维度
    x2 = torch.transpose(x1, 0, 1)
    print(x2,x2.shape)


# ? 改变维度1
def th_permute():
    x1 = torch.randint(0, 255, (3, 512,360))
    print(x1.shape)
    x2 = x1.permute(1, 2, 0)
    print(x2.shape)


# ? 改变为1维
def th_flatten():
    x1 = torch.randint(0, 255, (4, 3))
    # print(x1)
    x2 = x1.flatten()
    # print(x2)

    x3 = torch.randint(0, 255, (3, 4, 2, 2))
    print(x3)
    x4 = x3.flatten(start_dim=1, end_dim=-1)
    print(x4)


# ? 数据升维
def th_unsqueeze():
    x1 = torch.randint(0, 255, (4, 3))
    print(x1)
    # ! 0,表示在0处插入一个维度
    x2 = x1.unsqueeze(0)
    print(x2.shape)


# ? 数据降维
def th_squeeze():
    x1 = torch.randint(0, 255, (1, 4, 3, 1))
    print(x1)
    x2 = x1.squeeze()
    print(x2)
    x3 = x1.squeeze(0).squeeze(-1)
    print(x3)


# ? 数据分割
def th_split():
    x1 = torch.randint(0, 255, (4, 3))
    print(x1)

    # ! split(),表示每个tensor有2行
    x2, x3 = torch.split(x1, 2)
    # print(x2, x3)

    # ! chunk(),表示将数据分割成多少份
    x4 = torch.chunk(x1, 4)
    print(x4)

# ? 广播
def th_broadcast():
    a = torch.arange(1, 13).reshape(3, 4)
    b = torch.arange(1, 5)
    c = a + b


if __name__ == '__main__':
    # th_reshape()
    # th_view()
    # rh_transpose()
    # th_permute()
    # th_flatten()
    # th_unsqueeze()
    # th_squeeze()
    # th_split()
    th_broadcast()
```

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;