日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關咨詢
選擇下列產品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關閉右側工具欄

新聞中心

這里有您想知道的互聯網營銷解決方案
對比PyTorch和TensorFlow的自動差異和動態(tài)模型

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

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

生成噪聲的線性數據

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

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

模型

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

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

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

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

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

TensorFlow動態(tài)模型

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

PyTorch動態(tài)模型

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

訓練循環(huán),反向傳播和優(yōu)化器

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

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

在TensorFlow訓練循環(huán)中,我們將特別明確地使用GradientTape API來記錄模型的正向執(zhí)行和損失計算,然后從該GradientTape中獲得用于優(yōu)化權重和偏差參數的梯度。

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

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

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

TensorFlow訓練循環(huán)

 
 
 
  1. def squared_error(y_pred, y_true): 
  2.   return tf.reduce_mean(tf.square(y_pred - y_true)) 
  3. tf_model = LinearRegressionKeras()[w, b] = tf_model.trainable_variablesfor epoch in range(epochs): 
  4.   with tf.GradientTape() as tape: 
  5.     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: 
  6.     print(f"Epoch {epoch} : Loss {loss.numpy()}") 

PyTorch訓練循環(huán)

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

結論

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

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

繪制結果

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

當前名稱:對比PyTorch和TensorFlow的自動差異和動態(tài)模型
當前網址:http://www.dlmjj.cn/article/codedig.html