對比PyTorch和TensorFlow的自動差異和動態子類化模型

2020-12-13 deephub

使用自定義模型類從頭開始訓練線性回歸,比較PyTorch 1.x和TensorFlow 2.x之間的自動差異和動態模型子類化方法,

這篇簡短的文章重點介紹如何在PyTorch 1.x和TensorFlow 2.x中分別使用帶有模塊/模型API的動態子類化模型,以及這些框架在訓練循環中如何使用AutoDiff獲得損失的梯度並從頭開始實現 一個非常幼稚的漸變後代實現。

生成噪聲的線性數據

為了專注於自動差異/自動漸變功能的核心,我們將使用最簡單的模型,即線性回歸模型,然後我們將首先使用numpy生成一些線性數據,以添加隨機級別的噪聲。

def generate_data(m=0.1, b=0.3, n=200):x = np.random.uniform(-10, 10, n) noise = np.random.normal(0, 0.15, n) y = (m * x + b ) + noise return x.astype(np.float32), y.astype(np.float32)x, y = generate_data()plt.figure(figsize = (12,5))ax = plt.subplot(111)ax.scatter(x,y, c = "b", label="samples")

模型

然後,我們將在TF和PyTorch中實現從零開始的線性回歸模型,而無需使用任何層或激活器,而只需定義兩個張量w和b,分別代表線性模型的權重和偏差,並簡單地實現線性函數即可:y = wx + b

正如您在下面看到的,我們的模型的TF和PyTorch類定義基本上完全相同,但在一些api名稱上只有很小的差異。

唯一值得注意的區別是,PyTorch明確地使用Parameter對象定義權重和要由圖形「捕獲」的偏置張量,而TF似乎在這裡更「神奇」,而是自動捕獲用於圖形的參數。

確實在PyTorch參數中是Tensor子類,當與Module api一起使用時,它們具有非常特殊的屬性,可以自動將自身添加到Module參數列表中,並會出現在在parameters()迭代器中。

無論如何,兩個框架都能夠從此類定義和執行方法(call或 forward ),參數和圖形定義中提取信息,以便向前執行圖形執行,並且正如我們將看到的那樣,通過自動可微分獲得梯度功能,以便能夠執行反向傳播。

TensorFlow動態模型

class LinearRegressionKeras(tf.keras.Model):def __init__(self): super().__init__() self.w = tf.Variable(tf.random.uniform(shape=[1], -0.1, 0.1)) self.b = tf.Variable(tf.random.uniform(shape=[1], -0.1, 0.1)) def __call__(self,x): return x * self.w + self.b

PyTorch動態模型

class LinearRegressionPyTorch(torch.nn.Module): def __init__(self): super().__init__() self.w = torch.nn.Parameter(torch.Tensor(1, 1).uniform_(-0.1, 0.1)) self.b = torch.nn.Parameter(torch.Tensor(1).uniform_(-0.1, 0.1)) def forward(self, x): return x @ self.w + self.b

訓練循環,反向傳播和優化器

現在我們已經實現了簡單的TensorFlow和PyTorch模型,我們可以定義TF和PyTorch api來實現均方誤差的損失函數,最後實例化我們的模型類並運行訓練循環。

同樣,本著眼於自動差異/自動漸變功能核心的目的,我們將使用TF和PyTorch特定的自動差異實現方式實現自定義訓練循環,以便為我們的簡單線性函數提供漸變並手動優化權重和偏差參數以及臨時和樸素的漸變後代優化器。

在TensorFlow訓練循環中,我們將特別明確地使用GradientTape API來記錄模型的正向執行和損失計算,然後從該GradientTape中獲得用於優化權重和偏差參數的梯度。

相反,在這種情況下,PyTorch提供了一種更「神奇」的自動漸變方法,隱式捕獲了對參數張量的任何操作,並為我們提供了相同的梯度以用於優化權重和偏置參數,而無需使用任何特定的api。

一旦我們有了權重和偏差梯度,就可以在PyTorch和TensorFlow上實現我們的自定義梯度派生方法,就像將權重和偏差參數減去這些梯度乘以恆定的學習率一樣簡單。

此處的最後一個微小區別是,當PyTorch在向後傳播中更新權重和偏差參數時,以更隱蔽和「魔術」的方式實現自動差異/自動graf時,我們需要確保不要繼續讓PyTorch從最後一次更新操作中提取grad,這次明確調用no_grad api,最後將權重和bias參數的梯度歸零。

TensorFlow訓練循環

def squared_error(y_pred, y_true):return tf.reduce_mean(tf.square(y_pred - y_true))tf_model = LinearRegressionKeras()[w, b] = tf_model.trainable_variablesfor epoch in range(epochs): with tf.GradientTape() as tape: predictions = tf_model(x) loss = squared_error(predictions, y) w_grad, b_grad = tape.gradient(loss, tf_model.trainable_variables) w.assign(w - w_grad * learning_rate) b.assign(b - b_grad * learning_rate) if epoch % 20 == 0: print(f"Epoch {epoch} : Loss {loss.numpy()}")

PyTorch訓練循環

def squared_error(y_pred, y_true):return torch.mean(torch.square(y_pred - y_true))torch_model = LinearRegressionPyTorch()[w, b] = torch_model.parameters()for epoch in range(epochs): y_pred = torch_model(inputs) loss = squared_error(y_pred, labels) loss.backward() with torch.no_grad(): w -= w.grad * learning_rate b -= b.grad * learning_rate w.grad.zero_() b.grad.zero_() if epoch % 20 == 0: print(f"Epoch {epoch} : Loss {loss.data}")

結論

正如我們所看到的,TensorFlow和PyTorch自動區分和動態子分類API非常相似,當然,兩種模型的訓練也給我們非常相似的結果。

在下面的代碼片段中,我們將分別使用Tensorflow和PyTorch trainable_variables和parameters方法來訪問模型參數並繪製學習到的線性函數的圖。

繪製結果

[w_tf, b_tf] = tf_model.trainable_variables[w_torch, b_torch] = torch_model.parameters()with torch.no_grad():plt.figure(figsize = (12,5)) ax = plt.subplot(111) ax.scatter(x, y, c = "b", label="samples") ax.plot(x, w_tf * x + b_tf, "r", 5.0, "tensorflow") ax.plot(x, w_torch * inputs + b_torch, "c", 5.0, "pytorch") ax.legend() plt.xlabel("x1") plt.ylabel("y",rotation = 0)

作者:Jacopo Mangiavacchi

本文代碼:github/JacopoMangiavacchi/TF-VS-PyTorch

deephub翻譯組

相關焦點

  • 如何在PyTorch和TensorFlow中訓練圖像分類模型
    它的應用範圍包括從自動駕駛汽車中的物體分類到醫療行業中的血細胞識別,從製造業中的缺陷物品識別到建立可以對戴口罩與否的人進行分類的系統。在所有這些行業中,圖像分類都以一種或另一種方式使用。他們是如何做到的呢?他們使用哪個框架?你必須已閱讀很多有關不同深度學習框架(包括TensorFlow,PyTorch,Keras等)之間差異的信息。
  • TensorFlow與PyTorch之爭,哪個框架最適合深度學習
    PyTorch 和 TensorFlow 對比PyTorch 和 TensorFlow 的優點和缺點PyTorch 和 TensorFlow 安裝、版本、更新TensorFlow 還是 PyTorch?
  • 寫給純小白的深度學習環境搭建寶典:pytorch+tensorflow
    Anaconda+pytorch環境準備如果你的電腦帶有GPU,可以先安裝Nvidia驅動 + cuda + cudnn,然後再搭建環境,這樣可以達到更高的運行速度。如果不想使用GPU,學習階段也可以使用cpu版本,對於簡單的程序用CPU和GPU其實沒差別。
  • PyTorch稱霸頂會:CVPR論文佔比是TensorFlow 4 倍
    圖表的交互版本參見:http://horace.io/pytorch-vs-tensorflow/ICLR 2020 論文 PyTorch/TensorFlow 使用分析首先看下 ICLR 2020 接收論文中,PyTorch 使用數在
  • 一行代碼切換TensorFlow與PyTorch,模型訓練也能用倆框架
    github項目地址:BlackHC/TfPyTh為什麼框架間的交互很重要目前 GitHub 上有很多優質的開源模型,它們大部分都是用 PyTorch 和 TensorFlow 寫的。如果我們想要在自己的項目中調用某個開源模型,那麼它們最好都使用相同的框架,不同框架間的對接會帶來各種問題。當然要是不怕麻煩,也可以用不同的框架重寫一遍。以前 TensorFlow 和 PyTorch 經常會用來對比,討論哪個才是更好的深度學習框架。但是它們之間就不能友好相處麼,模型在兩者之間的相互遷移應該能帶來更多的便利。
  • 模型秒變API只需一行代碼,支持TensorFlow等框架
    其中工作量很大的地方在於將模型打包,預留 API 接口,並和現有的生產系統相結合。近日,GitHub 上有了這樣一個項目,能夠讓用戶一行代碼將任意模型打包為 API。這一工具無疑能夠幫助開發者在實際的生產應用中快速部署模型。
  • tensorflow安裝教程
    tensorflow是谷歌開源的人工智慧庫,有最完善的生態支持。是進行人工智慧領域開發和科研的必備工具。本文在windows10下,藉助anacondaAnaconda安裝和使用,AkShare入門,安裝tensorflow2.0。
  • 機器學習:TensorFlow 2.0中的10個技巧
    用於構建輸入管道的tf.data API從張量構建管道Batch和Shuffle壓縮兩個Datsets映射外部函數1(b). ImageDataGenerator這是tensorflow.keras API的最佳特性之一。
  • TensorFlow極簡教程:創建、保存和恢復機器學習模型
    需求Python3 (https://www.python.org/)TensorFlow (https://www.tensorflow.org/)NumPy (http://www.numpy.org/)TensorFlow:保存/恢復和混合多重模型在第一個模型成功建立並訓練之後,你或許需要了解如何保存與恢復這些模型。
  • TensorFlow驚現大bug?網友:這是逼著我們用PyTorch啊
    issue 詳情:https://github.com/tensorflow/tensorflow/issues/40638這個帖子在 reddit 上引起了熱議,網友紛紛表示:「這是在逼我用 PyTorch!」到底是什麼驚天大 bug?
  • TensorFlow 2.0正式版官宣!深度集成Keras
    這允許用戶使用TensorFlow運行模型,使用TensorFlow服務部署模型,使用TensorFlow Lite在移動和嵌入式系統上使用模型,使用TensorFlow.js在瀏覽器或Node.js上訓練和運行模型。
  • Transformers2.0讓你三行代碼調用語言模型,兼容TF2.0和PyTorch
    近日 HuggingFace 公司開源了最新的 Transformer2.0 模型庫,用戶可非常方便地調用現在非常流行的 8 種語言模型進行微調和應用,且同時兼容 TensorFlow2.0 和 PyTorch 兩大框架,非常方便快捷。
  • 從零開始搭建深度學習伺服器:TensorFlow + PyTorch + Torch
    Source源和Pip源設置:系統安裝完畢後建議設置一下source源和pip源,這樣可以加速安裝相關的工具包。安裝CUDA:因為Tensorflow和Pytorch目前官方提供的PIP版本只支持CUDA8, 所以我選擇了安裝CUDA8.0。
  • 在瀏覽器中使用TensorFlow.js和Python構建機器學習模型
    TensorFlow.js的兩個組件——Core API和Layer API。了解如何構建一個很棒的使用Tensorflow.js對網絡攝像頭中的圖像進行分類的模型。-- load Tensorflow.js --> <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@1.0.0/dist/tf.min.js"></script></head><body> <h1>Tensorflow.js Core API</h1>
  • 一文詳解 TensorFlow 2.0 的符號式 API 和命令式 API
    從一個開發者的角度,它工作的方法就是擴展由框架定義的模型類別,將模型中的層實例化,然後命令式地編寫下模型的正向傳遞(forward pass),而反向傳遞(backward pass)是自動生成的。TensorFlow 2.0 支持使用現成的 Keras 的子類化 API 來創建模型。
  • 初學AI神經網絡應該選擇Keras或是Pytorch框架?
    keras是google的一個大佬開發的一個高度封裝的模型框架,已開源到github上。起初的計算後臺為Theano(和tensorflow差不多的一個框架),後來經過一系列的劇情,現在默認的計算後臺就為tensorflow了。
  • 正確debug的TensorFlow的姿勢
    最主要和最重要的優點是,數據流圖可以很容易地實現並行性和分布式執行,而無需顯式地使用multiprocessing 模塊。在實踐中,編寫良好的tensorflow模型在啟動時立即使用所有核心的資源,而不需要任何額外的配置。然而,這個工作流的一個非常明顯的缺點是,一旦你構建圖的時候,沒有用提供的輸入來運行,你就不能確保它不會崩潰。它肯定會崩潰。
  • 這裡有一份TensorFlow2.0中文教程
    簡單的圖像分類任務探一探此文章中,機器之心為大家推薦一個持續更新的中文教程,方便大家更系統的學習、使用 TensorFlow 2.0 : 知乎專欄地址:https://zhuanlan.zhihu.com/c_1091021863043624960 Github 項目地址:https://github.com/czy36mengfei/tensorflow2
  • 關於TensorFlow 2.0,這裡有你想知道的一切
    最後,可以檢查調諧器的結論,並選擇最佳模型。請注意,訓練日誌和模型檢查點都保存在目錄文件夾(my_logs)中。此外,最小化或最大化目標(驗證精度)的選擇是自動推斷的。5.這裡的模型是一個擴展tf.keras.Model的Python類。模型子類化是由Chainer提出的,與PyTorch如何定義模型有很大關聯。通過模型子類化來定義類構造函數中的模型層。call()負責正推法的定義和執行。
  • tensorflow
    原有的 TensorFlow 運行時最初是為圖形執行和訓練模型的工作負載而構建的。與之相比,新的運行時將急切的執行需求放在第一位,同時特別強調架構的可擴展性和模塊化。  簡介  在過去,我寫的主要都是「傳統類」的機器學習文章,如樸素貝葉斯分類、邏輯回歸和Perceptron算法。在過去的一年中,我一直在研究深度學習技術,因此,我想和大家分享一下如何使用Tensorflow從頭開始構建和訓練卷積神經網絡。這樣,我們以後就可以將這個知識作為一個構建塊來創造有趣的深度學習應用程式了。