文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

对比PyTorch和TensorFlow的自动差异和动态模型

2024-12-03 18:34

关注

这篇简短的文章重点介绍如何在PyTorch 1.x和TensorFlow 2.x中分别使用带有模块/模型API的动态子类化模型,以及这些框架在训练循环中如何使用AutoDiff获得损失的梯度并从头开始实现 一个非常幼稚的渐变后代实现。

生成噪声的线性数据

为了专注于自动差异/自动渐变功能的核心,我们将使用最简单的模型,即线性回归模型,然后我们将首先使用numpy生成一些线性数据,以添加随机级别的噪声。

  1. def generate_data(m=0.1, b=0.3, n=200): 
  2.   x = np.random.uniform(-1010, n) 
  3.   noise = np.random.normal(00.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名称上只有很小的差异。

唯一值得注意的区别是,PyTorch明确地使用Parameter对象定义权重和要由图形"捕获"的偏置张量,而TF似乎在这里更"神奇",而是自动捕获用于图形的参数。

确实在PyTorch参数中是Tensor子类,当与Module api一起使用时,它们具有非常特殊的属性,可以自动将自身添加到Module参数列表中,并会出现在在parameters()迭代器中。

无论如何,两个框架都能够从此类定义和执行方法(call或 forward ),参数和图形定义中提取信息,以便向前执行图形执行,并且正如我们将看到的那样,通过自动可微分获得梯度功能,以便能够执行反向传播。

TensorFlow动态模型

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

PyTorch动态模型

  1. class LinearRegressionPyTorch(torch.nn.Module):  
  2.   def __init__(self):  
  3.     super().__init__()     self.w = torch.nn.Parameter(torch.Tensor(11).uniform_(-0.10.1)) 
  4.     self.b = torch.nn.Parameter(torch.Tensor(1).uniform_(-0.10.1)) 
  5.     def forward(self, x):   
  6.     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训练循环

  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训练循环

  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自动区分和动态子分类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

 

来源:今日头条内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯