Pytorch CookBook
生活随笔
收集整理的這篇文章主要介紹了
Pytorch CookBook
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
結(jié)合網(wǎng)上收集和個人總結(jié),用于以后背記。
檢查 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固定隨機(jī)種子
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 #能夠加快計算速度,但每次前饋結(jié)果有波動 torch.backends.cudnn.deterministic = True #加上此句,使每次前饋結(jié)果相同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水平翻轉(zhuǎn)
PyTorch 不支持 tensor[::-1] 這樣的負(fù)步長操作,水平翻轉(zhuǎn)可以用張量索引實(shí)現(xiàn)。
復(fù)制張量
有三種復(fù)制的方式,對應(yīng)不同的需求。
拼接張量
tensor = torch.cat(list_of_tensors, dim=0) #3個10×5 -> 30x5 tensor = torch.stack(list_of_tensors, dim=0) #3個10×5 -> 3x10x5獨(dú)熱編碼
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)計算模型總參數(shù)量
num_parameters = sum(torch.numel(parameter) for parameter in model.parameters())以較大學(xué)習(xí)率微調(diào)全連接層,以較小學(xué)習(xí)率微調(diào)卷積層
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)標(biāo)簽平滑
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()得到當(dāng)前學(xué)習(xí)率
# 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'])注意事項(xiàng)
模型定義
- 建議有參數(shù)的層和匯合(pooling)層使用 torch.nn 模塊定義,激活函數(shù)直接使用torch.nn.functional。torch.nn 模塊和 torch.nn.functional 的區(qū)別在于,torch.nn模塊在計算時底層調(diào)用了 torch.nn.functional,但 torch.nn模塊包括該層參數(shù),還可以應(yīng)對訓(xùn)練和測試兩種網(wǎng)絡(luò)狀態(tài)。
- 使用 torch.nn.functional 時要注意網(wǎng)絡(luò)狀態(tài),如 model(x)前用 model.train() 和 model.eval() 切換網(wǎng)絡(luò)狀態(tài)。
- 不需要計算梯度的代碼塊用 with torch.no_grad() 包含起來。model.eval() 和 torch.no_grad()的區(qū)別在于,model.eval() 是將網(wǎng)絡(luò)切換為測試狀態(tài),例如 BN和隨機(jī)失活(dropout)在訓(xùn)練和測試階段使用不同的計算方法。torch.no_grad() 是關(guān)閉 PyTorch張量的自動求導(dǎo)機(jī)制,以減少存儲使用和加速計算,得到的結(jié)果無法進(jìn)行 loss.backward()。
- torch.nn.CrossEntropyLoss 的輸入不需要經(jīng)過 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() 清除累積梯度。如果需要累積梯度以進(jìn)行batch_size放大或者多個損失函數(shù)相加時可以不清除梯度。optimizer.zero_grad()和 model.zero_grad() 效果一樣。
PyTorch 性能與調(diào)試
- torch.utils.data.DataLoader 中盡量設(shè)置 pin_memory=True,對特別小的數(shù)據(jù)集如 MNIST 設(shè)置pin_memory=False 反而更快一些。num_workers 的設(shè)置需要在實(shí)驗(yàn)中找到最快的取值。
- 用 del 及時刪除不用的中間變量,節(jié)約 GPU 存儲。
- 使用 inplace 操作可節(jié)約 GPU 存儲,如
- 時常使用 assert tensor.size() == (N, D, H, W) 作為調(diào)試手段,確保張量維度和你設(shè)想中一致。
- 除了標(biāo)記 y 外,盡量少使用一維張量,使用 n*1 的二維張量代替,可以避免一些意想不到的一維張量計算結(jié)果。
- 統(tǒng)計代碼各部分耗時:
總結(jié)
以上是生活随笔為你收集整理的Pytorch CookBook的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【论文学习】高频分量有助解释卷积神经网络
- 下一篇: 【论文学习】ICLR2021,鲁棒早期学