1.Anaconda配置pytorch环境

1.创建环境
在Anaconda Prompt工具中输入conda create -n pyTorch,报如下错误。
image.png
  1. 解决方法:为 Anaconda 配置国内镜像源。
1. 方式1:使用conda命令在AnacondaPrompt命令行窗口添加
conda config --add channels http://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
conda config --add channels http://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/
conda config --add channels http://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch/
conda config --add channels http://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/
conda config --set show_channel_urls yes
2. 方式2:在C:\Users\用户名\.condarc文件中修改
3. 方式3:打开Anaconda Navigator进行add channels
2.激活创建的环境
conda activate pyTorch 
3.安装pytorch
  • 安装之前,在cmd窗口下输入NVIDIA-smi查看安装的cuda的版本,然后根据不同的cuda版本安装合适的pytorch版本
  • 方式1 在AnacondaPrompt命令行窗口中输入复制的命令安装pytorch.
    image.png 检验是否安装成功
    image.png 方式2:使用pip下载 方式1:依次安装torch,torchversion,torchaudio 上官网查看上面三个包对应要求的版本,然后在上面下载。下载成功后是一些后缀名为whl的文件
    image.png
  • 使用pip install xxx命令依次安装torch、torchvison、torchaudio。
  • 方式2:复制上图中的命令直接安装,记得关闭代理
  • 4.在当前pytorch环境下配置Jupyter
    # 安装Jupter
    conda install nb_conda
    # 启动Jupter,打开指定的目录
    jupyter notebook 项目目录
    

    2.两个重要的函数

    1. dir()
    dir(torch)
    
    1. help()
    help(torch.cuda.is_available)
    

    3.pytorch中加载数据

    1.Dataset类
    1. 在Jupter中查看类的实用信息
    from torch.utils.data import Dataset
    1. 方式1:
    help(Dataset) #按shift + enter
    2. 方式2:
    Dataset?? #按shift + enter
    

    4.数据操作

    1. 张量(tensor):类似于计算机中的数组,这个数组可能有多个维度。
      1. torch.tensor()函数等用于创建张量。
      # 导入pytorch
      import torch
      # x是一个一维数组
      x = torch.arange(5)
      x #tensor([0, 1, 2, 3, 4])
      
      # 0维的标量
      a = torch.tensor(10)
      print(a) #tensor(10)
      print(a.dim()) #0
      print(a.type())#torch.LongTensor
      print(a.dtype) #torch.int64
      print(a.device)#cpu
      print(a.shape)#torch.Size([])
      print(a.size())#torch.Size([])
      print(isinstance(a, torch.LongTensor))#True
      print(len(a.shape)) #0
      
      1. 通过Tensor类创建张量
      x = torch.Tensor(3, 2, 2)
      print(x)
      print(x.dtype) #torch.float32
      x = torch.IntTensor(3, 2, 2)
      print(x)
      print(x.dtype) #torch.int32
      
    2. 通过张量的shape属性和numel()方法分别来访问张量的形状和张量中元素的总数
    import torch
    x = torch.arange(1, 9,2)
    x         # tensor([1, 3, 5, 7])
    x.shape   # torch.Size([4])
    x.numel() # 4,4为元素总数
    
    1. reshape函数:改变一个张量的形状而不改变元素数量和元素值
    import torch
    x = torch.arange(12)
    X = x.reshape(3,4)
    # tensor([[ 0,  1,  2,  3],
    #        [ 4,  5,  6,  7],
    #        [ 8,  9, 10, 11]])
    X
    
    1. 使用全0、全1、其他常量或者从特定分布中随机采样的数字
      1. zeros函数
      torch.zeros(2,3,4)
      
      1. ones函数
      torch.ones(2,3,4)
      
      1. randn函数:均值为0方差为1的标准正态分布
      torch.randn(2,3,4)
      
      1. linspace函数:产生一个一维张量,第三个参数指定等分的份数
      x = torch.linspace(0, 12, 5) # tensor([ 0.,  3.,  6.,  9., 12.])
      
      1. randperm函数:产生随机的0~n-1的n个数
      x = torch.randperm(10) # tensor([9, 7, 3, 6, 2, 5, 4, 8, 1, 0])
      
      1. randint函数:产生指定形状的张量
      # tensor([[[8, 3],
      #          [3, 8]],
      
      #         [[5, 8],
      #          [2, 5]],
      
      #         [[1, 7],
      #          [9, 8]]])
      y = torch.randint(1, 10, (3, 2, 2))
      
      1. rand函数:产生指定形状,元素范围在[0,1)的张量
      x = torch.rand(3, 2, 2)
      
    2. 通过提供包含数值的Python列表(或嵌套列表)来为所需张量中的每个元素赋予确定值
    x = torch.tensor([1, 2, 3, 4]) # tensor([1, 2, 3, 4])
    
    1. 常见的标准运算
    x = torch.tensor([1.0, 2, 4, 8])
    y = torch.tensor([2, 2, 2, 2])
    z = torch.exp(x) # e^x
    x + y, x - y, x * y, x / y, x**y, z
    
    1. cat函数:将多个张量 连结(concatenate) 在一起
    X = torch.arange(12, dtype=torch.float32).reshape((3, 4))
    Y = torch.tensor([[2.0, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]])
    # dim指定张量按照行还是列维度来连接
    torch.cat((X, Y), dim=0), torch.cat((X, Y), dim=1)
    
    1. 通过逻辑运算符构建二元张量
    X = torch.arange(12, dtype=torch.float32).reshape((3, 4))
    Y = torch.tensor([[2.0, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]])
    # tensor([[False,  True, False,  True],
    #         [False, False, False, False],
    #         [False, False, False, False]])
    X == Y
    
    1. 对张量中的所有元素进行求和会产生一个只有一个元素的张量(标量)
    X = torch.arange(4, dtype=torch.float32)
    X.sum() # tensor(6.)
    
    1. 切片
    x = torch.arange(12).reshape(3,4)
    print(x) 
    a = x[-1] # 最后一行元素
    b = x[1:3] # 第二行元素和第三行元素
    x[1,2] = 9 # 改变指定元素的值
    a,b,x
    
    1. 运行一些操作可能会导致为新结果分配内存
    # 会分配内存
    import torch
    Y = torch.arange(5)
    X = torch.arange(5)
    before = id(Y)
    Y = Y + X
    id(Y) == before # False
    
    # 执行原地操作
    1. 使用Y += X
    Y = torch.arange(5)
    X = torch.arange(5)
    before = id(Y)
    Y  +=  X
    id(Y) == before # True
    
    2. 使用Y[:] = X + Y
    Y = torch.arange(5)
    X = torch.arange(5)
    before = id(Y)
    Y[:]=  X + Y
    id(Y) == before # True
    
    1. numpy和torch中张量的互相转化
    x = torch.tensor([3])
    print(type(x)) #<class 'torch.Tensor'>
    # torch转numpy
    y = x.numpy()
    print(type(y)) #<class 'numpy.ndarray'>
    # numpy转torch
    x = torch.tensor(y)
    print(type(x)) #<class 'torch.Tensor'>
    

    5.数据预处理

    1. 创建一个人工数据集,并存储在csv(逗号分隔值)文件
    import torch
    import os
    import pandas as pd
    import warnings
    # 去除一些warning
    warnings.filterwarnings("ignore")
    # 在上一级目录下创建data目录
    os.makedirs(os.path.join('..', 'data'), exist_ok=True)
    data_file = os.path.join('..', 'data', 'house_tiny.csv')
    with open(data_file, 'w') as f:
        f.write('NumRooms,Alley,Price\n')
        f.write('NA,Pave,127500\n')
        f.write('2,NA,106000\n')
        f.write('4,NA,178100\n')
        f.write('NA,NA,140000\n')
    data = pd.read_csv(data_file)
    print(data)
    
    # 使用插值处理缺失的数据(前两个特征的数据)
    inputs, outputs = data.iloc[:, 0:2], data.iloc[:, 2]
    
    # 使用均值填充
    inputs = inputs.fillna(inputs.mean())
    print(inputs)
    
    # 对于inputs中的类别值或离散值,我们将“NaN”视为一个类别
    # dummy variable是用0或1表示某个类别是否出现,dummy_na值为真表示不忽略NaN,且增加一列数据表示NaN
    inputs = pd.get_dummies(inputs, dummy_na=True)
    print(inputs)
    
    # inputs和outputs中的所有条目都是数值类型,可以转换为张量格式
    X, y = torch.tensor(inputs.values), torch.tensor(outputs.values)
    X, y
    
    

    基本运算和统计

    1. 标量:由只有一个元素的张量表示
    x = torch.tensor([3.0])
    y = torch.tensor([2.0])
    x + y, x * y, x / y, x ** y # (tensor([5.]), tensor([6.]), tensor([1.5000]), tensor([9.]))
    
    1. 向量:由标量值组成的列表
    import torch
    x = torch.arange(5)
    # 通过张量的索引来访问任一元素
    x[0] # tensor(0)
    # len函数获取张量的长度
    len(x) # 5
    # shape属性获取张量的形状
    x.shape # torch.Size([5])
    
    1. 创建一个形状为m * n的矩阵
    # 创建一个2行3列的矩阵
    x = torch.Tensor(2,3)
    
    1. 矩阵的转置:使用属性T或者使用t()方法
    x = torch.Tensor(2,3)
    x.T
    
    1. 计算元素的和,结果为一个0维标量
    x = torch.tensor([2, 3])
    x, x.sum() # tensor([2, 3]), tensor(5)
    
    1. 指定张量沿哪一个轴来通过求和降低维度
    A = torch.arange(20, dtype=torch.float32).reshape(2,2,5)
    print(A)
    # axis参数为0表示消去第一维
    A_sum_axis0 = A.sum(axis=0)
    print(A_sum_axis0), print(A_sum_axis0.shape) # torch.Size([2, 5])
    # axis参数为1表示消去第二维
    A_sum_axis1 = A.sum(axis=1)
    print(A_sum_axis1), print(A_sum_axis1.shape) # torch.Size([2, 5])
    A_sum_axis0 = A.sum(axis=[0, 1])
    print(A_sum_axis0), print(A_sum_axis0.shape) # torch.Size([5])
    
    1. 均值
    A = torch.arange(20, dtype=torch.float32).reshape(5, 4)
    print(A)
    A.mean(axis=0), A.sum(axis=0) / A.shape[0]
    
    1. 计算总和或均值时保持轴数不变
    A = torch.arange(20, dtype=torch.float32).reshape(5, 4)
    print(A)
    # keepdim 参数表示保持维度,不消去
    sum_A = A.sum(axis=1, keepdims=True)
    print(sum_A)
    # 通过广播将A除以sum_A
    A / sum_A
    
    1. 按照某个轴计算A元素的累积总和
    A = torch.arange(20).reshape(5, 4)
    print(A)
    A.cumsum(axis=0)
    


    10. 矩阵的乘法:使用mm函数或者@运算符

    A = torch.arange(20, dtype=torch.float32).reshape(5, 4)
    print(A)
    B = torch.ones(4, 3)
    print(B)
    torch.mm(A, B) # 等价于A @ B
    
    1. 范数
      1. L2范数是向量元素平方和的平方根:
      u = torch.tensor([3.0, -4.0])
      torch.norm(u) # tensor(5.)
      
      1. L1 范数,它表示为向量元素的绝对值之和:
      u = torch.tensor([3.0, -4.0])
      torch.abs(u).sum() # tensor(7.)
      
      1. 矩阵 的弗罗贝尼乌斯范数(Frobenius norm)是矩阵元素平方和的平方根:
      A = torch.arange(4, dtype=torch.float32).reshape(2, 2)
      torch.norm(A) #tensor(3.7417)
      
    2. 数学运算中的加减乘除、平方、平方根等
      1. add
      2. sub
      3. mul
      4. div
      5. pow或者**
      6. sqrt:平方根
      7. rsqrt:平方根的倒数
      8. floor:向下取整
      9. ceil:向上取整
      10. round:四舍五入
      11. trunc:裁剪整数部分
      12. frac:裁剪小数部分
    3. 张量相乘:使用bmm函数或者matmul函数

    pytorch中的常用函数或者方法

    1.索引相关
    1. torch.index_select函数:从指定的维度对张量进行索引(根据整形张量或者长整型张量)
    # 创建一个一维张量
    a = torch.linspace(1, 12, 12)
    a = a.view(3, 4)
    # 从第一个维度对a张量进行索引
    b = torch.index_select(a, 0, torch.tensor([0, 2]))
    # tensor([[ 1.,  2.,  3.,  4.],
    #         [ 9., 10., 11., 12.]])
    b
    
    1. torch.masked_select函数:根据布尔张量对张量进行索引,索引对角线上的元素。

      1. torch.eye函数:生成对角线全1,其余部分全0的二维数组
    2. torch.take函数:根据长整型张量对张量进行索引

    2.维度变换相关
    1. view方法:根据数据返回指定形状的张量

    2. torch.reshape函数:上同

    3. unsqueeze方法或者函数:升维

    4. squeeze方法或者函数:维度压缩,其中输入的张量中,大小为1的维度将删除。

    5. expand方法:扩张张量

    6. repeate方法:扩张张量。和expand方法的区别:expand是在原地操作,类似于浅拷贝;而repeat类似于深拷贝。

    7. transpose函数或者方法:对输入的张量在给定的维度上进行变换

    8. permute函数或者方法:根据指定的维度次序对输入张量进行排列

    3.合并与拆分
    1. cat:在给定的维度上对给定的张量进行拼接,除了拼接的那个维度,其他维度必须相等。

    2. stack:沿着一个新的维度将张量序列连接起来

    3. split:在指定的维度上根据大小对张量进行分割

    4. chunk:在指定的维度上根据数量对张量进行分割

    broadcast机制

    1.broadcast机制的特点

    broadcast是一种在不同size的张量之间进行运算会自动进行的一种机制,它的特点有:

    1. 能够进行维度的扩展,相当于expand。broadcast机制会自动扩展。
    2. 扩展的时候在原地扩展,不需要拷贝数据。
    2.主要思想:
    1. 依次从最后一个维度开始匹配,若前面没有维度则插入一个新的维度,size为1。
    2. 自动调用expand方法使得维度size相同。
    3.引入broadcast机制的原因
    1. 真实需求:例如将一个三维的张量和一个1维的标量进行相加运算,因为广播机制的存在代码编写简洁。
    a = torch.tensor([1])
    b = torch.Tensor(2,2,3)
    # 因为广播机制的存在,运行成功
    print(a + b)
    
    # 使用unsqueeze方法和expand方法手动实现
    a = torch.tensor([1])
    b = torch.Tensor(2,2,3)
    a = a.unsqueeze(0)
    a = a.unsqueeze(0)
    a = a.expand(2,2,3)
    print(a.shape) # torch.Size([2, 2, 3])
    print(a + b)
    
    1. 节约内存:broadcast核心利用expand,在原地上操作,不进行拷贝。

    pytorch中的Hub模块

    提供了很多预训练好的网络,例如VGG19等

    pytorch中的torchvision模块

    该模块提供了著名的数据集、经典网络架构的实现、图像预处理操作、

    神经网络包

    torch.nn是pytorch专门为神经网络设计的模块化接口。