日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

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

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
兩個框架的故事:pytorch與tensorflow

使用Pytorch 1.x和Tensorflow 2.x比較自動差異和動態(tài)模型子類方法

公司主營業(yè)務:成都網(wǎng)站設計、成都網(wǎng)站制作、外貿(mào)網(wǎng)站建設、移動網(wǎng)站開發(fā)等業(yè)務。幫助企業(yè)客戶真正實現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競爭能力。創(chuàng)新互聯(lián)是一支青春激揚、勤奮敬業(yè)、活力青春激揚、勤奮敬業(yè)、活力澎湃、和諧高效的團隊。公司秉承以“開放、自由、嚴謹、自律”為核心的企業(yè)文化,感謝他們對我們的高要求,感謝他們從不同領域給我們帶來的挑戰(zhàn),讓我們激情的團隊有機會用頭腦與智慧不斷的給客戶帶來驚喜。創(chuàng)新互聯(lián)推出曲沃免費做網(wǎng)站回饋大家。

> Source: Author

數(shù)據(jù)科學界是一種充滿活力和合作的空間。我們從彼此的出版物中學到,辯論關于論壇和在線網(wǎng)點的想法,并分享許多代碼(和許多)代碼。這種合作精神的自然副作用是遇到同事使用的不熟悉工具的高可能性。因為我們不在真空中工作,所以在給定的主題領域中獲得熟悉多種語言和圖書館的熟悉程度往往是有意義的,以便合作和學習最有效。

這并不奇怪,那么,許多數(shù)據(jù)科學家和機器學習工程師在其工具箱中有兩個流行的機器學習框架:Tensorflow和Pytorch。這些框架 - 在Python中 - 分享許多相似之處,也以有意義的方式分歧。這些差異,例如它們?nèi)绾翁幚鞟PI,加載數(shù)據(jù)和支持專業(yè)域,可以在兩個框架繁瑣且效率低下之間交替。這是一個問題,給出了這兩個工具的常見。

因此,本文旨在通過專注于創(chuàng)建和訓練兩個簡單模型的基礎知識來說明Pytorch和Tensorflow之間的差異。特別是,我們將介紹如何使用來自Pytorch 1.x的模塊API和來自Tensorflow 2.x的模塊API使用動態(tài)子類模型。我們將查看這些框架的自動差異如何,以提供非常樸素的梯度下降的實現(xiàn)。

但首先,數(shù)據(jù)

因為我們專注于自動差分/自動求導功能的核心(作為一種進修,是可以自動提取函數(shù)的導數(shù)的容量并在一些參數(shù)上應用梯度,以便使用這些參數(shù)梯度下降)我們可以從最簡單的模型開始,是線性回歸。我們可以使用Numpy庫使用一點隨機噪聲生成一些線性數(shù)據(jù),然后在該虛擬數(shù)據(jù)集上運行我們的模型。

 
 
 
 
  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
  5.   return x.astype(np.float32), y.astype(np.float32)
  6. x, y = generate_data()
  7. plt.figure(figsize = (12,5))
  8. ax = plt.subplot(111)
  9. ax.scatter(x,y, c = "b", label="samples")

模型

一旦我們擁有數(shù)據(jù),我們就可以從Tensorflow和Pytorch中的原始代碼實現(xiàn)回歸模型。為簡單起見,我們不會最初使用任何層或激活器,僅定義兩個張量,W和B,表示線性模型Y = Wx + B的權重和偏置。

正如您所看到的,除了API名稱的幾個差異之外,兩個模型的類定義幾乎相同。最重要的區(qū)別在于,Pytorch需要一個明確的參數(shù)對象來定義由圖捕獲的權重和偏置張量,而TensoRFlow能夠自動捕獲相同的參數(shù)。實際上,Pytorch參數(shù)是與模塊API一起使用時具有特殊屬性的Tensor子類:它們會自動向模塊參數(shù)列表添加SELF,因此SECRES在參數(shù)()迭代器中出現(xiàn)。

這兩個框架都提取了從此類定義和執(zhí)行方法生成圖所需的一切(__call__或轉發(fā)),并且如下,如下所示,計算實現(xiàn)bospropagation所需的漸變。

Tensorflow動態(tài)模型

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

Pytorch動態(tài)模型

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

構建訓練循環(huán),backpropagation和優(yōu)化器

使用這些簡單的Tensorflow和Bytorch模型建立,下一步是實現(xiàn)損失函數(shù),在這種情況下只是意味著平方錯誤。然后,我們可以實例化模型類并運行訓練循環(huán)以實現(xiàn)幾個周期。

同樣,由于我們專注于核心自動差分/自動求導功能,這里的目的是使用TensorFlow和特定于Pytorch特定的自動Diff實現(xiàn)構建自定義訓練循環(huán)。這些實施方式計算簡單的線性函數(shù)的梯度,并用天真梯度下降優(yōu)化器手動優(yōu)化權重和偏置參數(shù),基本上最小化了在每個點處使用可微差函數(shù)之間計算的實際點和預測之間計算的損失。

對于TensorFlow訓練循環(huán),我明確地使用GradientTape API來跟蹤模型的前向執(zhí)行和逐步損耗計算。我使用GradientTape的漸變來優(yōu)化權重和偏置參數(shù)。Pytorch提供了一種更“神奇的”自動求導方法,隱式地捕獲參數(shù)張量的任何操作,并提供用于優(yōu)化權重和偏置參數(shù)的梯度,而無需調用另一API。一旦我具有權重和偏置梯度,在Pytorch和Tensorflow上實現(xiàn)自定義梯度下降方法就像從這些梯度中減去權重和偏置參數(shù)一樣簡單,乘以恒定的學習速率。

請注意,由于Pytorch自動實現(xiàn)自動差分/自動求導,因此在計算后向傳播之后,有必要明確調用no_grad api。這指示Pytorch不計算權重和偏置參數(shù)的更新操作的梯度。我們還需要明確釋放在前向操作中計算的先前自動計算的漸變,以阻止Pytorch自動累積較批次和循環(huán)迭代中的漸變。

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()
  4. [w, b] = tf_model.trainable_variables
  5. for epoch in range(epochs):
  6.   with tf.GradientTape() as tape:
  7.     predictions = tf_model(x)
  8.     loss = squared_error(predictions, y)
  9.         
  10.   w_grad, b_grad = tape.gradient(loss, tf_model.trainable_variables)
  11.   w.assign(w - w_grad * learning_rate)
  12.   b.assign(b - b_grad * learning_rate)
  13.   if epoch % 20 == 0:
  14.     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()
  4. [w, b] = torch_model.parameters()
  5. for epoch in range(epochs):
  6.   y_pred = torch_model(inputs)
  7.   loss = squared_error(y_pred, labels)
  8.   loss.backward()
  9.   
  10.   with torch.no_grad():
  11.     w -= w.grad * learning_rate
  12.     b -= b.grad * learning_rate
  13.     w.grad.zero_()
  14.     b.grad.zero_()
  15.     
  16.   if epoch % 20 == 0:
  17.     print(f"Epoch {epoch} : Loss {loss.data}")

Pytorch和Tensorflow模型重用可用層

既然我展示了如何從Pytorch和Tensorflow中的原始代碼實現(xiàn)線性回歸模型,我們可以查看如何使用密集和線性層,從TensorFlow和Pytorch庫中重新實現(xiàn)相同的型號。

帶現(xiàn)有圖層的TensoRFlow和Pytorch動態(tài)模型

您將在模型初始化方法中注意到,我們正在用TensorFlow中的密集層替換W和B參數(shù)的顯式聲明和Pytorch中的線性層。這兩個層都實現(xiàn)了線性回歸,并且我們將指示它們使用單個權重和偏置參數(shù)來代替以前使用的顯式W和B參數(shù)。密集和線性實現(xiàn)將在內(nèi)部使用我們之前使用的相同的張解聲明(分別為tf.variable和nn.parameter)來分配這些張量并將它們與模型參數(shù)列表相關聯(lián)。

我們還將更新這些新模型類的呼叫/前進方法,以替換具有密度/線性層的手動線性回歸計算。

 
 
 
 
  1. class LinearRegressionKeras(tf.keras.Model):
  2.     def __init__(self):
  3.         super().__init__()
  4.         self.linear = tf.keras.layers.Dense(1, activation=None) # , input_shape=[1]
  5.     def call(self, x): 
  6.         return self.linear(x)
 
 
 
 
  1. class LinearRegressionPyTorch(torch.nn.Module):
  2.     def __init__(self):
  3.         super(LinearRegressionPyTorch, self).__init__()
  4.         self.linear = torch.nn.Linear(1, 1)  
  5.     def forward(self, x):
  6.         return self.linear(x)

具有可用優(yōu)化器和損耗函數(shù)的訓練

既然我們已經(jīng)使用現(xiàn)有圖層重新實現(xiàn)了我們的Tensorflow和Pytorch型號,我們可以專注于如何構建更優(yōu)化的訓練循環(huán)。我們不是使用我們以前的Na?ve實現(xiàn),我們將使用這些庫可用的本機優(yōu)化器和損失函數(shù)。

我們將繼續(xù)使用之前觀察到的自動差分/自動求導功能,但此時具有標準漸變下降(SGD)優(yōu)化實現(xiàn)以及標準損耗功能。

Tensorflow訓練循環(huán),易于擬合方法

在Tensorflow中,F(xiàn)IT()是一種非常強大,高級別的訓練模型方法。它允許我們用單個方法替換手動訓練循環(huán),該方法指定超級調整參數(shù)。在調用fit()之前,我們將使用Compile()方法編譯模型類,然后通過梯度后代優(yōu)化器和用于訓練的損失函數(shù)。

您會注意到在這種情況下,我們將盡可能多地重用來自TensorFlow庫的方法。特別是,我們將通過標準隨機梯度下降(SGD)優(yōu)化器和標準的平均絕對誤差函數(shù)實現(xiàn)(MEAL_ABSOLUTE_ERROR)到編譯方法。一旦模型進行編譯,我們最終可以撥打擬合方法來完全訓練我們的模型。我們將通過數(shù)據(jù)(x和y),epochs的數(shù)量以及每個時代使用的批量大小。

帶有自定義循環(huán)和SGD優(yōu)化器的TensoRFLOF訓練循環(huán)

在以下代碼段中,我們將為我們的模型實施另一個自定義訓練循環(huán),這次盡可能多地重用由Tensorflow庫提供的損失函數(shù)和優(yōu)化器。您會注意到我們的前自定義Python損失函數(shù)替換為tf.losses.mse()方法。我們初始化了TF.keras.optimizers.sgd()優(yōu)化程序而不是用漸變手動更新模型參數(shù)。調用Optimizer.apply_gradient()并傳遞權重和偏置元組列表將使用漸變更新模型參數(shù)。

 
 
 
 
  1. tf_model_train_loop = LinearRegressionKeras()
  2. optimizer = tf.keras.optimizers.SGD(learning_ratelearning_rate=learning_rate)
  3. for epoch in range(epochs * 3):
  4.     x_batch = tf.reshape(x, [200, 1])
  5.     with tf.GradientTape() as tape:
  6.         y_pred = tf_model_train_loop(x_batch)
  7.         y_pred = tf.reshape(y_pred, [200])
  8.         loss = tf.losses.mse(y_pred, y)
  9.     
  10.     grads = tape.gradient(loss, tf_model_train_loop.variables)
  11.     
  12.     optimizer.apply_gradients(grads_and_vars=zip(grads, tf_model_train_loop.variables))
  13.     if epoch % 20 == 0:
  14.         print(f"Epoch {epoch} : Loss {loss.numpy()}")

具有自定義循環(huán)和SGD優(yōu)化器的Pytorch訓練循環(huán)

與上面的上一個Tensorflow代碼段一樣,以下代碼片段通過重用Pytorch庫提供的丟失功能和優(yōu)化器來實現(xiàn)新模型的Pytorch訓練循環(huán)。您會注意到我們將使用NN.Mseloss()方法替換我們以前的自定義Python丟失函數(shù),并初始化標準Optim.sgd()優(yōu)化程序,其中包含模型的學習參數(shù)列表。如前所述,我們將指示Pytorch從丟失向后傳播中獲取每個參數(shù)張量的關聯(lián)梯度(load.backward()),最后,我們可以通過調用來容易地更新新標準優(yōu)化器與與梯度相關聯(lián)的所有參數(shù)更新新的標準優(yōu)化器優(yōu)化器.step()方法。Pytorch使張量和梯度之間自動關聯(lián)的方式允許優(yōu)化器檢索張量和梯度以通過配置的學習速率更新它們。

 
 
 
 
  1. torch_model = LinearRegressionPyTorch()
  2. criterion = torch.nn.MSELoss(reduction='mean')
  3. optimizer = torch.optim.SGD(torch_model.parameters(), lr=learning_rate)
  4. for epoch in range(epochs * 3):
  5.     y_pred = torch_model(inputs)
  6.     loss = criterion(y_pred, labels)
  7.     optimizer.zero_grad()
  8.     loss.backward()
  9.     optimizer.step()
  10.     if epoch % 20 == 0:
  11.       print(f"Epoch {epoch} : Loss {loss.data}")

結果

正如我們所看到的那樣,TensoRFlow和Pytorch自動差分和動態(tài)子類API非常相似,即使它們使用標準SGD和MSE實現(xiàn)方式也是如此。當然,這兩個模型也給了我們非常相似的結果。

在下面的代碼片段中,我們使用Tensorflow的Training_variables和Pytorch的參數(shù)方法來獲得對模型的參數(shù)的訪問,并繪制我們學習的線性函數(shù)的圖表。

 
 
 
 
  1. [w_tf, b_tf] = tf_model_fit.trainable_variables
  2. [w2_tf, b2_tf] = tf_model_train_loop.trainable_variables
  3. [w_torch, b_torch] = torch_model.parameters()
  4. w_tf = tf.reshape(w_tf, [1])
  5. w2_tf = tf.reshape(w2_tf, [1])
  6. with torch.no_grad():
  7.   plt.figure(figsize = (12,5))
  8.   ax = plt.subplot(111)
  9.   ax.scatter(x, y, c = "b", label="samples")
  10.   ax.plot(x, w_tf * x + b_tf, "r", linewidth = 5.0, label = "tensorflow fit")
  11.   ax.plot(x, w2_tf * x + b2_tf, "y", linewidth = 5.0, label = "tensorflow train loop")
  12.   ax.plot(x, w_torch * inputs + b_torch, "c", linewidth = 5.0, label = "pytorch")
  13.   ax.legend()
  14.   plt.xlabel("x1")
  15.   plt.ylabel("y",rotation = 0)

結論

Pytorch和新Tensorflow 2.x都支持動態(tài)圖形和自動差分核心功能,以提取圖表中使用的所有參數(shù)的漸變。您可以輕松地在Python中實現(xiàn)訓練循環(huán),其中包含任何損失函數(shù)和漸變后代優(yōu)化器。為了專注于兩個框架之間的真實核心差異,我們通過實施自己的簡單MSE和Na?veSGD來簡化上面的示例。

但是,我強烈建議您在實現(xiàn)任何Na?ve代碼之前重用這些庫上可用的優(yōu)化和專用代碼。

下表總結了上面示例代碼中所注明的所有差異。我希望它可以作為在這兩個框架之間切換時的有用參考。

> Source: Author


當前名稱:兩個框架的故事:pytorch與tensorflow
網(wǎng)頁鏈接:http://www.5511xx.com/article/cdihdhe.html