Pytorch CookBook
生活随笔
收集整理的這篇文章主要介紹了
Pytorch CookBook
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
結合網上收集和個人總結,用于以后背記。
檢查 PyTorch 版本:
torch.__version__ # PyTorch version torch.version.cuda # Corresponding CUDA version torch.backends.cudnn.version() # Corresponding cuDNN version torch.cuda.get_device_name(0) # GPU type固定隨機種子
torch.manual_seed(0) torch.cuda.manual_seed_all(0)GPU和cudnn
os.environ['CUDA_VISIBLE_DEVICES'] = '0,1' #指定GPU torch.cuda.empty_cache() #清空顯存 torch.backends.cudnn.benchmark = True #能夠加快計算速度,但每次前饋結果有波動 torch.backends.cudnn.deterministic = True #加上此句,使每次前饋結果相同torch.Tensor 與 np.ndarray 與PIL.Image的互換
# torch.Tensor <-> np.ndarray ndarray = tensor.cpu().numpy() tensor = torch.from_numpy(ndarray).float() # torch.Tensor -> PIL.Image. image = PIL.Image.fromarray(torch.clamp(tensor * 255, min=0, max=255).byte().permute(1, 2, 0).cpu().numpy()) image = torchvision.transforms.functional.to_pil_image(tensor) # Equivalently way # PIL.Image -> torch.Tensor. tensor = torch.from_numpy(np.asarray(PIL.Image.open(path))).permute(2, 0, 1).float() / 255 tensor = torchvision.transforms.functional.to_tensor(PIL.Image.open(path)) # Equivalently way # np.ndarray <-> PIL.Image. image = PIL.Image.fromarray(ndarray.astypde(np.uint8)) ndarray = np.asarray(PIL.Image.open(path))打亂順序
tensor = tensor[torch.randperm(tensor.size(0))] # Shuffle the first dimension水平翻轉
PyTorch 不支持 tensor[::-1] 這樣的負步長操作,水平翻轉可以用張量索引實現。
復制張量
有三種復制的方式,對應不同的需求。
拼接張量
tensor = torch.cat(list_of_tensors, dim=0) #3個10×5 -> 30x5 tensor = torch.stack(list_of_tensors, dim=0) #3個10×5 -> 3x10x5獨熱編碼
N = tensor.size(0) one_hot = torch.zeros(N, num_classes).long() one_hot.scatter_(dim=1, index=torch.unsqueeze(tensor, dim=1), src=one_hot)計算模型總參數量
num_parameters = sum(torch.numel(parameter) for parameter in model.parameters())以較大學習率微調全連接層,以較小學習率微調卷積層
model = torchvision.models.resnet18(pretrained=True) finetuned_parameters = list(map(id, model.fc.parameters())) conv_parameters = (p for p in model.parameters() if id(p) not in finetuned_parameters) parameters = [{'params': conv_parameters, 'lr': 1e-3}, {'params': model.fc.parameters()}] optimizer = torch.optim.SGD(parameters, lr=1e-2, momentum=0.9, weight_decay=1e-4)標簽平滑
for images, labels in train_loader:images, labels = images.cuda(), labels.cuda()N = labels.size(0)# C is the number of classes.smoothed_labels = torch.full(size=(N, C), fill_value=0.1 / (C - 1)).cuda()smoothed_labels.scatter_(dim=1, index=torch.unsqueeze(labels, dim=1), value=0.9)score = model(images)log_prob = torch.nn.functional.log_softmax(score, dim=1)loss = -torch.sum(log_prob * smoothed_labels) / Noptimizer.zero_grad()loss.backward()optimizer.step()mixup
beta_distribution = torch.distributions.beta.Beta(alpha, alpha) for images, labels in train_loader:images, labels = images.cuda(), labels.cuda()# Mixup images.lambda_ = beta_distribution.sample([]).item()index = torch.randperm(images.size(0)).cuda()mixed_images = lambda_ * images + (1 - lambda_) * images[index, :]# Mixup loss. scores = model(mixed_images)loss = (lambda_ * loss_function(scores, labels) + (1 - lambda_) * loss_function(scores, labels[index]))optimizer.zero_grad()loss.backward()optimizer.step()得到當前學習率
# If there is one global learning rate (which is the common case). lr = next(iter(optimizer.param_groups))['lr']# If there are multiple learning rates for different layers. all_lr = [] for param_group in optimizer.param_groups:all_lr.append(param_group['lr'])注意事項
模型定義
- 建議有參數的層和匯合(pooling)層使用 torch.nn 模塊定義,激活函數直接使用torch.nn.functional。torch.nn 模塊和 torch.nn.functional 的區別在于,torch.nn模塊在計算時底層調用了 torch.nn.functional,但 torch.nn模塊包括該層參數,還可以應對訓練和測試兩種網絡狀態。
- 使用 torch.nn.functional 時要注意網絡狀態,如 model(x)前用 model.train() 和 model.eval() 切換網絡狀態。
- 不需要計算梯度的代碼塊用 with torch.no_grad() 包含起來。model.eval() 和 torch.no_grad()的區別在于,model.eval() 是將網絡切換為測試狀態,例如 BN和隨機失活(dropout)在訓練和測試階段使用不同的計算方法。torch.no_grad() 是關閉 PyTorch張量的自動求導機制,以減少存儲使用和加速計算,得到的結果無法進行 loss.backward()。
- torch.nn.CrossEntropyLoss 的輸入不需要經過 Softmax。torch.nn.CrossEntropyLoss等價于 torch.nn.functional.log_softmax + torch.nn.NLLLoss。
用法: loss = torch.nn.CrossEntropyLoss(); loss(input,target)。
其中 input:(N,C) 類型torch.float(); target:(N) 類型torch.long() 0≤target[i]≤C?1 - loss.backward() 前用 optimizer.zero_grad() 清除累積梯度。如果需要累積梯度以進行batch_size放大或者多個損失函數相加時可以不清除梯度。optimizer.zero_grad()和 model.zero_grad() 效果一樣。
PyTorch 性能與調試
- torch.utils.data.DataLoader 中盡量設置 pin_memory=True,對特別小的數據集如 MNIST 設置pin_memory=False 反而更快一些。num_workers 的設置需要在實驗中找到最快的取值。
- 用 del 及時刪除不用的中間變量,節約 GPU 存儲。
- 使用 inplace 操作可節約 GPU 存儲,如
- 時常使用 assert tensor.size() == (N, D, H, W) 作為調試手段,確保張量維度和你設想中一致。
- 除了標記 y 外,盡量少使用一維張量,使用 n*1 的二維張量代替,可以避免一些意想不到的一維張量計算結果。
- 統計代碼各部分耗時:
總結
以上是生活随笔為你收集整理的Pytorch CookBook的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【论文学习】高频分量有助解释卷积神经网络
- 下一篇: 【论文学习】ICLR2021,鲁棒早期学