1.Anaconda配置pytorch环境
1.创建环境
- 在Anaconda Prompt工具中输入
conda create -n pyTorch
,报如下错误。
- 解决方法:为 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.
- 检验是否安装成功
- 在AnacondaPrompt命令行窗口中输入复制的命令安装pytorch.
- 方式2:使用pip下载
4.在当前pytorch环境下配置Jupyter
# 安装Jupter
conda install nb_conda
# 启动Jupter,打开指定的目录
jupyter notebook 项目目录
2.两个重要的函数
- dir()
dir(torch)
- help()
help(torch.cuda.is_available)
3.pytorch中加载数据
1.Dataset类
- 在Jupter中查看类的实用信息
from torch.utils.data import Dataset
1. 方式1:
help(Dataset) #按shift + enter
2. 方式2:
Dataset?? #按shift + enter
4.数据操作
- 张量(tensor):类似于计算机中的数组,这个数组可能有多个维度。
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
- 通过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
- 通过张量的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为元素总数
- 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
- 使用全0、全1、其他常量或者从特定分布中随机采样的数字
- zeros函数
torch.zeros(2,3,4)
- ones函数
torch.ones(2,3,4)
- randn函数:均值为0方差为1的标准正态分布
torch.randn(2,3,4)
- linspace函数:产生一个一维张量,第三个参数指定等分的份数
x = torch.linspace(0, 12, 5) # tensor([ 0., 3., 6., 9., 12.])
- randperm函数:产生随机的0~n-1的n个数
x = torch.randperm(10) # tensor([9, 7, 3, 6, 2, 5, 4, 8, 1, 0])
- randint函数:产生指定形状的张量
# tensor([[[8, 3], # [3, 8]], # [[5, 8], # [2, 5]], # [[1, 7], # [9, 8]]]) y = torch.randint(1, 10, (3, 2, 2))
- rand函数:产生指定形状,元素范围在[0,1)的张量
x = torch.rand(3, 2, 2)
- 通过提供包含数值的Python列表(或嵌套列表)来为所需张量中的每个元素赋予确定值
x = torch.tensor([1, 2, 3, 4]) # tensor([1, 2, 3, 4])
- 常见的标准运算
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
- 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)
- 通过逻辑运算符构建二元张量
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
- 对张量中的所有元素进行求和会产生一个只有一个元素的张量(标量)
X = torch.arange(4, dtype=torch.float32)
X.sum() # tensor(6.)
- 切片
x = torch.arange(12).reshape(3,4)
print(x)
a = x[-1] # 最后一行元素
b = x[1:3] # 第二行元素和第三行元素
x[1,2] = 9 # 改变指定元素的值
a,b,x
- 运行一些操作可能会导致为新结果分配内存
# 会分配内存
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
- 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.数据预处理
- 创建一个人工数据集,并存储在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
基本运算和统计
- 标量:由只有一个元素的张量表示
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.]))
- 向量:由标量值组成的列表
import torch
x = torch.arange(5)
# 通过张量的索引来访问任一元素
x[0] # tensor(0)
# len函数获取张量的长度
len(x) # 5
# shape属性获取张量的形状
x.shape # torch.Size([5])
- 创建一个形状为m * n的矩阵
# 创建一个2行3列的矩阵
x = torch.Tensor(2,3)
- 矩阵的转置:使用属性T或者使用t()方法
x = torch.Tensor(2,3)
x.T
- 计算元素的和,结果为一个0维标量
x = torch.tensor([2, 3])
x, x.sum() # tensor([2, 3]), tensor(5)
- 指定张量沿哪一个轴来通过求和降低维度
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])
- 均值
A = torch.arange(20, dtype=torch.float32).reshape(5, 4)
print(A)
A.mean(axis=0), A.sum(axis=0) / A.shape[0]
- 计算总和或均值时保持轴数不变
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
- 按照某个轴计算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
- 范数
- L2范数是向量元素平方和的平方根:
u = torch.tensor([3.0, -4.0]) torch.norm(u) # tensor(5.)
- L1 范数,它表示为向量元素的绝对值之和:
u = torch.tensor([3.0, -4.0]) torch.abs(u).sum() # tensor(7.)
- 矩阵 的弗罗贝尼乌斯范数(Frobenius norm)是矩阵元素平方和的平方根:
A = torch.arange(4, dtype=torch.float32).reshape(2, 2) torch.norm(A) #tensor(3.7417)
- 数学运算中的加减乘除、平方、平方根等
- add
- sub
- mul
- div
- pow或者**
- sqrt:平方根
- rsqrt:平方根的倒数
- floor:向下取整
- ceil:向上取整
- round:四舍五入
- trunc:裁剪整数部分
- frac:裁剪小数部分
- 张量相乘:使用bmm函数或者matmul函数
pytorch中的常用函数或者方法
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
-
torch.masked_select函数:根据布尔张量对张量进行索引,索引对角线上的元素。
- torch.eye函数:生成对角线全1,其余部分全0的二维数组
-
torch.take函数:根据长整型张量对张量进行索引
2.维度变换相关
-
view方法:根据数据返回指定形状的张量
-
torch.reshape函数:上同
-
unsqueeze方法或者函数:升维
-
squeeze方法或者函数:维度压缩,其中输入的张量中,大小为1的维度将删除。
-
expand方法:扩张张量
-
repeate方法:扩张张量。和expand方法的区别:expand是在原地操作,类似于浅拷贝;而repeat类似于深拷贝。
-
transpose函数或者方法:对输入的张量在给定的维度上进行变换
-
permute函数或者方法:根据指定的维度次序对输入张量进行排列
3.合并与拆分
-
cat:在给定的维度上对给定的张量进行拼接,除了拼接的那个维度,其他维度必须相等。
-
stack:沿着一个新的维度将张量序列连接起来
-
split:在指定的维度上根据大小对张量进行分割
-
chunk:在指定的维度上根据数量对张量进行分割
broadcast机制
1.broadcast机制的特点
broadcast是一种在不同size的张量之间进行运算会自动进行的一种机制,它的特点有:
- 能够进行维度的扩展,相当于expand。broadcast机制会自动扩展。
- 扩展的时候在原地扩展,不需要拷贝数据。
2.主要思想:
- 依次从最后一个维度开始匹配,若前面没有维度则插入一个新的维度,size为1。
- 自动调用expand方法使得维度size相同。
3.引入broadcast机制的原因
- 真实需求:例如将一个三维的张量和一个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)
- 节约内存:broadcast核心利用expand,在原地上操作,不进行拷贝。
pytorch中的Hub模块
提供了很多预训练好的网络,例如VGG19等
pytorch中的torchvision模块
该模块提供了著名的数据集、经典网络架构的实现、图像预处理操作、
神经网络包
torch.nn是pytorch专门为神经网络设计的模块化接口。