张量(tensor)是机器学习的基础,类似于numpy的数组。NVIDIA的显卡有张量加速功能,可以提升计算速度,因此张量可以说是深度学习的基础。
函数 | 作用 |
---|---|
Tensor(size) | 基础构造函数 |
tensor(data) | 类似于np.array,可以将ndarray转换为tensor |
ones(size) | 全为1 |
zeros(size) | 全为0 |
eye(size) | 对角阵,对角线全为1,其余为0 |
arange(s,e,step) | 从s到e,步长为step |
linspace(s,e,step) | 从s到e,均匀分成step份 |
rand(size) | 生成服从[0, 1]上均匀分布的随机数 |
randn(size) | 生成服从标准正态分布 N ( 0 , 1 ) N(0,1) N(0,1)的随机数 |
normal(mean, std) | 生成服从正态分布 N ( m e a n , s t d ) N(mean, std) N(mean,std)的随机数 |
randperm(m) | 生成最大数为m的随机排列,个数为m |
randint(low, high, size) | 生成[low, high]范围内的随机整数,size为tuple,如(10,1) |
举个栗子:
In:
import torch
x1 = torch.ones(5)
print(x1)
x2 = torch.randint(0,10,(5,1)) #生成5行1列的范围在[0,10]的随机整数
print(x2)
Out:
tensor([1., 1., 1., 1., 1.])
tensor([[9],
[1],
[9],
[1],
[3]])
tensor的切片、加减乘除操作同numpy的数组,这里不再赘述。
注意切片出来的结果与原数据共享内存,修改一个另一个也会跟着修改。如果不想修改原数据,可以先克隆clone()在运算。
举个栗子:
In:
x = torch.ones(2, 5)
print(x)
print('\n先克隆在运算,不改变原数据x:')
y = x[0, :].clone()
y += 1
print(x)
print(y)
print('\n直接索引,会改变原数据x:')
y2 = x[0, :]
y2 += 1
print(x)
print(y2)
Out:
tensor([[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.]])
先克隆在运算,不改变原数据x:
tensor([[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.]])
tensor([2., 2., 2., 2., 2.])
直接索引,会改变原数据x:
tensor([[2., 2., 2., 2., 2.],
[1., 1., 1., 1., 1.]])
tensor([2., 2., 2., 2., 2.])
重点说一下改变数组形状的view()。
In:
x = torch.randn(4, 3)
y = x.view(12)
z = x.view(-1, 2) # -1是指这一维的维数由其他维度决定
print(x.size(), y.size(), z.size())
Out:
torch.Size([4, 3]) torch.Size([12]) torch.Size([6, 2])
注意 view() 返回的新tensor与源tensor共享内存(其实是同一个tensor),也即更改其中的一个,另 外一个也会跟着改变。(顾名思义,view仅仅是改变了对这个张量的观察⻆度)
自动求导帮助我们解决了神经网络中最难的部分。一般我们只需要定义好神经网络的前向传播过程,利用自动求导Pytorch可以自动帮我们计算反向传播过程,优化网络参数,寻找是目标函数最小的最优解。因此,自动求导(autograd包)是神经网络的核心。
在模型训练时,我们需要计算变量的梯度并追踪其计算历史,方便更新参数,此时我们可以这么写:
x = torch.ones(3,1, requires_grad=True)
或者:
x.requires_grad_(True)
.
输出梯度:x.grad
。
反向传播:loss.backward()
。
如果要组织一个张量被跟踪历史,可以调用.detach()
方法将其与计算历史分离,并阻止它未来的计算记录被跟踪。
在评估模型时,我们不需要对张量进行求导,只需要正向传播即可,此时可以把代码块包装在with torch.no_grad():
中。
当数据量比较大或模型比较复杂时,使用GPU可以显著提高计算速度(当然数据量小且操作简单时,用CPU更快,因为CPU和GPU之间传递数据比较耗时)。
定义使用的计算设备:
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print(device)
如果有多块NVIDIA显卡:
# 方式一:设置在文件最开始部分
import os
os.environ["CUDA_VISIBLE_DEVICE"] = "2" # 设置默认的显卡
# 方式二:
CUDA_VISBLE_DEVICE=0,1 python train.py # 使用0,1两块GPU
将数据和模型放到GPU上:
#方式一:.to(deivice)
model = model.to(device)
for data in dataloader:
x, y = data
x = x.to(deivice)
y = y.to(device)
#方式二:.cuda()
if torch.cuda.is_available():
model = Model()
model = model.cuda()
for data in dataloader:
x, y = data
x = x.cuda()
y = y.cuda()
参考资料:
[1] Datawhale_深入浅出pytorch
[2] https://blog.csdn.net/weixin_45468845/article/details/122971688