- Tensor的副本
view只会改变数据的表面形状,共享data,但是view后的Tensor和之前的Tensor不是一个id,因为还有一些其他属性。
推荐先用clone创造一个副本再使用view;
使用clone还有一个好处是会被记录在计算图中,即梯度回传到副本时也会传到源Tensor
参考此处
x_cp = x.clone().view(15)
- 常用函数item()
将一个标量Tensor转换成一个Python number
x = torch.randn(1) print(x) print(x.item())
tensor([2.3466]) 2.3466382026672363
- 索引操作不会开辟新内存-----用作数据迭代是等内存替换
y = y + x是新开内存,再用y指向新内存;
以下四种是写入y对应的内存
y[:] = y + x
torch.add(x, y, out=y)
y += x
y.add_(x)
- Tensor和NumPy相互转换
共享相同的内存(所以他们之间的转换很快),改变其中一个时另一个也会改变!!!
共享内存的方式:a.numpy()转numpy、torch.from_numpy(a)转Tensor
不共享内存:torch.tensor(a)转Tensor
- GPU上的Tensor和to()同时可以更改数据类型
# 以下代码只有在PyTorch GPU版本上才会执行
if torch.cuda.is_available():
device = torch.device("cuda") # GPU
y = torch.ones_like(x, device=device) # 直接创建一个在GPU上的Tensor
x = x.to(device) # 等价于 .to("cuda")
z = x + y
print(z)
print(z.to("cpu", torch.double)) # to()还可以同时更改数据类型
TORCH.TENSOR官方文档
loss.item()大坑跑神经网络时遇到的大坑:代码中所有的loss都直接用loss表示的,结果就是每次迭代,空间占用就会增加,直到cpu或者gup爆炸。
解决办法:把除了loss.backward()之外的loss调用都改成loss.item(),就可以解决。
accuracy也是一样,也得用item()的形式。
原理可以见这里:https://www.zhihu.com/question/67209417/answer/344752405
# Example of target with class indices loss = nn.CrossEntropyLoss() input = torch.randn(3, 5, requires_grad=True) target = torch.empty(3, dtype=torch.long).random_(5) output = loss(input, target) output.backward() # Example of target with class probabilities input = torch.randn(3, 5, requires_grad=True) target = torch.randn(3, 5).softmax(dim=1) output = loss(input, target) output.backward()
第一种是0,1,0,1的类
第二种是每一种类的概率值。
李宏毅2021的self attention
模型的验证及保存# Do validation
if (step + 1) % valid_steps == 0:
pbar.close()
valid_accuracy = valid(valid_loader, model, criterion, device)
# keep the best model
if valid_accuracy > best_accuracy:
best_accuracy = valid_accuracy
best_state_dict = model.state_dict()
pbar = tqdm(total=valid_steps, ncols=0, desc="Train", unit=" step")
# Save the best model so far.
if (step + 1) % save_steps == 0 and best_state_dict is not None:
torch.save(best_state_dict, save_path)
pbar.write(f"Step {step + 1}, best model saved. (accuracy={best_accuracy:.4f})")
推理阶段的模型导入
model = Classifier(n_spks=speaker_num).to(device) model.load_state_dict(torch.load(model_path)) model.eval() # 并且需要在这个里面with torch.no_grad():
这种方式只是保存了当时的参数,并没有保存计算图。



