Tensor
Tensor的基本数据类型有五种:
32位浮点型:torch.FloatTensor。 (默认)
64位整型:torch.LongTensor。
32位整型:torch.IntTensor。
16位整型:torch.ShortTensor。
64位浮点型:torch.DoubleTensor。
除以上数字类型外,还有 byte和chart型
基本操作如下:
# torch.Tensor - 多维数组,自动调用 backward()实现支持自动梯度计算
# 生成一个标量
a = torch.tensor(2.342323)
a.item()
# 打印版本
print(torch.__version__)
# 将Tensor转为ndarray
a.numpy()
# numpy转化为Tensor
torch.from_numpy(a)
# torch.view: 可以改变张量的维度和大小,与Numpy的reshape类似
a = torch.rand(2,2)
a.view(1,4)
# 沿着行取最大值
x = torch.randn(3, 3)
max_value, max_idx = torch.max(x, dim=1)
print(max_value, max_idx)
# 每行 x 求和
sum_x = torch.sum(x, dim=1)
print(sum_x)
# 设备间转换
# 1 .cuda方法将tensor移动到gpu
gpu_a=cpu_a.cuda()
# 2 .cpu方法将tensor移动到cpu
cpu_b=gpu_a.cpu()
# 3 多GPU的情况,to方法确定使用那个设备
# 使用torch.cuda.is_available()来确定是否有cuda设备
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(device)
# 将tensor传送到设备
gpu_b=cpu_b.to(device)
autograd
autograd.Variable - 改变Tensor并且记录下来操作的历史记录。和Tensor拥有相同的API,以及backward()的一些API。同时包含着和张量相关的梯度。
autograd.Function - 实现了使用自动求导方法的前馈和后馈的定义。每个Variable的操作都会生成至少一个独立的Function节点,与生成了Variable的函数相连之后记录下操作历史。
.requires_grad_(True) 可以改变现有张量的 requires_grad属性
如果.requires_grad=True但是你又不希望进行autograd的计算, 那么可以将变量包裹在 with torch.no_grad()中:
with torch.no_grad():
print((x ** 2).requires_grad)
nn
nn.Module - 神经网络模块。便捷的数据封装,能够将运算移往GPU,还包括一些输入输出的东西。封装参数、移动到GPU上运行、导出、加载等。
nn.Parameter - 一种变量,当将任何值赋予Module时自动注册为一个参数。
数据加载
文本的数据处理(使用原生Python或者Cython以及NLTK和SpaCy)转换为numpy中的数组,之后再转换为torch.*Tensor
GPU
在GPU上进行训练:inputs, labels = Variable(inputs.cuda()), Variable(labels.cuda())
# 在GPU上训练
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
# 确认我们的电脑支持CUDA,然后显示CUDA信息:
print(device)
inputs, labels = inputs.to(device), labels.to(device)
# 数据并行,多个GPU
model = Model(input_size, output_size)
if torch.cuda.device_count() > 1:
print("Let's use", torch.cuda.device_count(), "GPUs!")
model = nn.DataParallel(model)
model.to(device)
可视化
tensorboard_logger库
模型参数配置
训练细节
net.zero_grad() 将所有参数的梯度缓存清零
优化器: torch.optim
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)
optimizer.zero_grad() # 梯度置0
optimizer.step()
损失函数:nn的loss函数
调用loss.backward()获得反向传播的误差。但是在调用前需要清除已存在的梯度,否则梯度将被累加到已存在的梯度。loss.backward()
criterion = nn.CrossEntropyLoss()
loss = criterion(outputs, labels)
loss.backward()
训练模型时:
# 训练模型
for epoch in range(2): # 多批次循环
running_loss = 0.0
for i, data in enumerate(trainloader, 0):
# 获取输入
inputs, labels = data
# 梯度置0
optimizer.zero_grad()
# 正向传播,反向传播,优化
# 正向传播:x传入网络,经过隐含层最后得到损失
outputs = net(inputs)
loss = criterion(outputs, labels)
# 反向传播:对w和b求梯度,更新参数
loss.backward()
# 优化
optimizer.step()
# 打印状态信息
running_loss += loss.item()
if i % 2000 == 1999: # 每2000批次打印一次
print('[%d, %5d] loss: %.3f' %
(epoch + 1, i + 1, running_loss / 2000))
running_loss = 0.0
print('Finished Training')
测试模型时:
# 测试集
correct = 0
total = 0
with torch.no_grad():
for data in testloader:
x, y = data
outputs = net(x)
_, predicted = torch.max(outputs.data, 1)
total += y.size(0)
correct += (predicted == y).sum().item()
print('Accuracy : %d %%' % (100 * correct / total))