當前位置:
首頁 > 新聞 > 【乾貨】深度學習實驗流程及 PyTorch 提供的解決方案

【乾貨】深度學習實驗流程及 PyTorch 提供的解決方案

【乾貨】深度學習實驗流程及 PyTorch 提供的解決方案



新智元推薦

來源:專知

【新智元導讀】在研究深度學習的過程中,當你腦中突然迸發出一個靈感,你是否發現沒有趁手的工具可以快速實現你的想法?看完本文之後,你可能會多出一個選擇。本文簡要分析了研究深度學習問題時常見的工作流, 並介紹了怎麼使用 PyTorch 來快速構建你的實驗。

【乾貨】深度學習實驗流程及 PyTorch 提供的解決方案

常見的 Research workflow

某一天, 你坐在實驗室的椅子上, 突然:

  • 你腦子裡迸發出一個idea

  • 你看了關於某一theory 的文章, 想試試: 要是把 xx 也加進去會怎麼樣

  • 你老闆突然給你一張紙, 然後說: 那個誰, 來把這個東西實現一下

於是, 你設計實驗流程, 並為這一 idea 挑選了合適的數據集和運行環境, 然後你廢寢忘食的實現模型, 經過長時間的訓練和測試, 你發現:

  • 這 idea 不 work --> 那算了 or 再調調

  • 這 idea 很 work --> 可以 paper 了

我們可以把上述流程用下圖表示:

【乾貨】深度學習實驗流程及 PyTorch 提供的解決方案

實際上, 常見的流程由下面幾項組成起來:

  1. 一旦選定了數據集, 你就要寫一些函數去 load 數據集, 然後 pre-process 數據集, normalize 數據集, 可以說這是一個實驗中佔比重最多的部分, 因為:

  1. 每個數據集的格式都不太一樣

  2. 預處理和正則化的方式也不盡相同

  3. 需要一個快速的 dataloader 來 feed data, 越快越好

  1. 然後, 你就要實現自己的模型, 如果你是 CV 方向的你可能想實現一個 ResNet, 如果你是 NLP 相關的你可能想實現一個 Seq2Seq

  2. 接下來, 你需要實現訓練步驟, 分 batch, 循環 epoch

  3. 在若干輪的訓練後, 總要 checkpoint 一下, 才是最安全的

  4. 你還需要構建一些 baseline, 以驗證自己 idea 的有效性

  5. 如果你實現的是神經網路模型, 當然離不開 GPU 的支持

  6. 很多深度學習框架提供了常見的損失函數, 但大部分時間, 損失函數都要和具體任務結合起來, 然後重新實現

  7. 使用優化方法, 優化構建的模型, 動態調整學習率

Pytorch 給出的解決方案

對於載入數據, Pytorch 提出了多種解決辦法

  • Pytorch 是一個 Python 包, 而不是某些大型 C++ 庫的 Python 介面, 所以, 對於數據集本身提供 Python API 的, Pytorch 可以直接調用, 不必特殊處理.

  • Pytorch 集成了常用數據集的 data loader

  • 雖然以上措施已經能涵蓋大部分數據集了, 但 Pytorch 還開展了兩個項目: vision, 和 text, 見下圖灰色背景部分. 這兩個項目, 採用眾包機制, 收集了大量的 dataloader, pre-process 以及 normalize, 分別對應於圖像和文本信息.

【乾貨】深度學習實驗流程及 PyTorch 提供的解決方案

  • 如果你要自定義數據集,也只需要繼承 torch.utils.data.dataset

對於構建模型, Pytorch 也提供了三種方案

  • 眾包的模型: torch.utils.model_zoo , 你可以使用這個工具, 載入大家共享出來的模型

  • 使用 torch.nn.Sequential 模塊快速構建

net = torch.nn.Sequential(
torch.nn.Linear(1, 10),
torch.nn.ReLU(),
torch.nn.Linear(10, 1)
)
print(net)
"""
Sequential (
(0): Linear (1 -> 10)
(1): ReLU ()
(2): Linear (10 -> 1)
)
"""

  • 集成 torch.nn.Module 深度定製

class Net(torch.nn.Module):
def __init__(self, n_feature, n_hidden, n_output):
super(Net, self).__init__()
self.hidden = torch.nn.Linear(n_feature, n_hidden)
self.predict = torch.nn.Linear(n_hidden, n_output)
def forward(self, x):
x = F.relu(self.hidden(x))
x = self.predict(x)
return x
net = Net(1, 10, 1)
print(net)
"""
Net (
(hidden): Linear (1 -> 10)
(predict): Linear (10 -> 1)
)
"""

對於訓練過程的 Pytorch 實現

你當然可以自己實現數據的 batch, shuffer 等, 但 Pytorch 建議用類 torch.utils.data.DataLoader 載入數據,並對數據進行採樣,生成batch迭代器。

# 創建數據載入器
loader = Data.DataLoader(
dataset=torch_dataset, # TensorDataset類型數據集
batch_size=BATCH_SIZE, # mini batch size
shuffle=True, # 設置隨機洗牌
num_workers=2, # 載入數據的進程個數
)
for epoch in range(3): # 訓練3輪
for step, (batch_x, batch_y) in enumerate(loader): # 每一步
# 在這裡寫訓練代碼...
print("Epoch: ", epoch)

對於保存和載入模型 Pytorch 提供兩種方案

  • 保存和載入整個網路

# 保存和載入整個模型, 包括: 網路結構, 模型參數等
torch.save(resnet, "model.pkl")
model = torch.load("model.pkl")

  • 保存和載入網路中的參數

torch.save(resnet.state_dict(), "params.pkl")
resnet.load_state_dict(torch.load("params.pkl"))

對於 GPU 支持

你可以直接調用 Tensor 的. cuda() 直接將 Tensor 的數據遷移到 GPU 的顯存上, 當然, 你也可以用. cpu() 隨時將數據移回內存

if torch.cuda.is_available():
linear = linear.cuda() # 將網路中的參數和緩存移到GPU顯存中

對於 Loss 函數, 以及自定義 Loss

在 Pytorch 的包 torch.nn 里, 不僅包含常用且經典的 Loss 函數, 還會實時跟進新的 Loss 包括: CosineEmbeddingLoss, TripletMarginLoss 等.

如果你的 idea 非常新穎, Pytorch 提供了三種自定義 Loss 的方式

  • 繼承 torch.nn.module

import torch
import torch.nn as nn
import torch.nn.functional as func
class MyLoss(nn.Module):
# 設置超參
def __init__(self, a, b, c):
super(TripletLossFunc, self).__init__()
self.a = a
self.b = b
self.c = c
return
def forward(self, a, b, c):
# 具體實現
loss = a + b + c
return loss

然後

loss_instance = MyLoss(...)
loss = loss_instance(a, b, c)

這樣做, 你能夠用 torch.nn.functional 里優化過的各種函數來組成你的 Loss

  • 繼承 torch.autograd.Function

import torch
from torch.autograd import Function
from torch.autograd import Variable
class MyLoss(Function):
def forward(input_tensor):
# 具體實現
result = ......
return torch.Tensor(result)
def backward(grad_output):
# 如果你只是需要在loss中應用這個操作的時候,這裡直接return輸入就可以了
# 如果你需要在nn中用到這個,需要寫明具體的反向傳播操作
return grad_output

這樣做,你能夠用常用的 numpy 和 scipy 函數來組成你的 Loss

  • 寫一個 Pytorch 的 C 擴展

這裡就不細講了,未來會有內容專門介紹這一部分。

對於優化演算法以及調節學習率

Pytorch 集成了常見的優化演算法, 包括 SGD, Adam, SparseAdam, AdagradRMSprop, Rprop 等等.

torch.optim.lr_scheduler 提供了多種方式來基於 epoch 迭代次數調節學習率 torch.optim.lr_scheduler.ReduceLROnPlateau 還能夠基於實時的學習結果, 動態調整學習率.

希望第一篇《深度學習實驗流程及 PyTorch 提供的解決方案》,大家會喜歡,後續會推出系列實戰教程,敬請期待。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 新智元 的精彩文章:

《集異璧》作者侯世達瘋狂吐槽谷歌翻譯:AI替代人類譯者為時尚早
「2018清博盛典暨新媒體大數據峰會」產學創跨界年度觀察

TAG:新智元 |