0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

PyTorch教程-12.6. 势头

jf_pJlTbmA9 来源:PyTorch 作者:PyTorch 2023-06-05 15:44 次阅读

在第 12.4 节中,我们回顾了在执行随机梯度下降时会发生什么,即,在只有梯度的噪声变体可用的情况下执行优化时。特别是,我们注意到对于噪声梯度,我们在选择面对噪声的学习率时需要格外谨慎。如果我们将它降低得太快,收敛就会停滞。如果我们过于宽容,我们将无法收敛到一个足够好的解决方案,因为噪声会不断驱使我们远离最优解。

12.6.1。基本

在本节中,我们将探索更有效的优化算法,尤其是针对实践中常见的某些类型的优化问题。

12.6.1.1。漏平均值

在上一节中,我们讨论了小批量 SGD 作为加速计算的一种方法。它还有一个很好的副作用,即平均梯度减少了方差量。小批量随机梯度下降可以通过以下方式计算:

(12.6.1)gt,t−1=∂w1|Bt|∑i∈Btf(xi,wt−1)=1|Bt|∑i∈Bthi,t−1.

为了保持符号简单,我们在这里使用 hi,t−1=∂wf(xi,wt−1) 作为样本的随机梯度下降i使用及时更新的权重t−1. 如果我们能够从方差减少的效果中受益,甚至超越小批量的平均梯度,那就太好了。完成此任务的一个选择是用“leaky average”代替梯度计算:

(12.6.2)vt=βvt−1+gt,t−1

对于一些β∈(0,1). 这有效地将瞬时梯度替换为对多个过去梯度进行平均的梯度 。v称为速度。它积累了过去的梯度,类似于一个重球从目标函数景观上滚下来如何对过去的力进行积分。为了更详细地了解发生了什么,让我们展开vt递归地进入

(12.6.3)vt=β2vt−2+βgt−1,t−2+gt,t−1=…,=∑τ=0t−1βτgt−τ,t−τ−1.

大的β相当于长期平均水平,而小 β仅相当于相对于梯度法的轻微修正。新的梯度替换不再指向特定实例上最速下降的方向,而是指向过去梯度的加权平均值的方向。这使我们能够实现批量平均的大部分好处,而无需实际计算其梯度的成本。稍后我们将更详细地重新讨论这个平均过程。

上述推理构成了现在所谓的 加速梯度方法的基础,例如动量梯度。他们享有额外的好处,即在优化问题是病态的情况下更有效(即,在某些方向上进展比其他方向慢得多,类似于狭窄的峡谷)。此外,它们允许我们对后续梯度进行平均以获得更稳定的下降方向。事实上,即使对于无噪声凸问题,加速方面也是动量起作用的关键原因之一。

正如人们所预料的那样,由于其功效,势头是深度学习及其他领域优化的一个深入研究的课题。例如,请参阅Goh(2017 年)撰写的 精美说明文章,以获取深入分析和交互式动画。它是由Polyak ( 1964 )提出的。Nesterov(2018)在凸优化的背景下进行了详细的理论讨论。长期以来,众所周知,深度学习的势头是有益的。参见例如Sutskever等人的讨论 。( 2013 )了解详情。

12.6.1.2。病态问题

为了更好地理解动量法的几何特性,我们重新审视了梯度下降法,尽管它的目标函数明显不太令人满意。回想一下我们在12.3 节中使用的f(x)=x12+2x22,即适度扭曲的椭球物镜。我们通过在x1方向通过

(12.6.4)f(x)=0.1x12+2x22.

像之前一样f有它的最小值(0,0). 这个函数 在方向上非常平坦x1. 让我们看看当我们像以前一样对这个新函数执行梯度下降时会发生什么。我们选择一个学习率0.4.

%matplotlib inline
import torch
from d2l import torch as d2l

eta = 0.4
def f_2d(x1, x2):
  return 0.1 * x1 ** 2 + 2 * x2 ** 2
def gd_2d(x1, x2, s1, s2):
  return (x1 - eta * 0.2 * x1, x2 - eta * 4 * x2, 0, 0)

d2l.show_trace_2d(f_2d, d2l.train_2d(gd_2d))

epoch 20, x1: -0.943467, x2: -0.000073

poYBAGR9OX-AKB36AACuJIQS7k4965.svg

%matplotlib inline
from mxnet import np, npx
from d2l import mxnet as d2l

npx.set_np()

eta = 0.4
def f_2d(x1, x2):
  return 0.1 * x1 ** 2 + 2 * x2 ** 2
def gd_2d(x1, x2, s1, s2):
  return (x1 - eta * 0.2 * x1, x2 - eta * 4 * x2, 0, 0)

d2l.show_trace_2d(f_2d, d2l.train_2d(gd_2d))

epoch 20, x1: -0.943467, x2: -0.000073

pYYBAGR9OYGAHC7FAACu4DhNFcs464.svg

%matplotlib inline
import tensorflow as tf
from d2l import tensorflow as d2l

eta = 0.4
def f_2d(x1, x2):
  return 0.1 * x1 ** 2 + 2 * x2 ** 2
def gd_2d(x1, x2, s1, s2):
  return (x1 - eta * 0.2 * x1, x2 - eta * 4 * x2, 0, 0)

d2l.show_trace_2d(f_2d, d2l.train_2d(gd_2d))

epoch 20, x1: -0.943467, x2: -0.000073

pYYBAGR9OYSAHb4AAACt8pawNu8524.svg

通过构造,梯度在x2方向比水平方向高得多 ,变化也快得多x1 方向。因此,我们陷入了两个不受欢迎的选择之间:如果我们选择一个小的学习率,我们确保解决方案不会在x2方向,但我们背负着缓慢收敛x1方向。相反,随着学习率的提高,我们在x1方向但分歧 x2. 下面的例子说明了即使在学习率略有增加之后会发生什么0.4到0.6. 趋同于x1方向有所改善,但整体解决方案质量更差。

eta = 0.6
d2l.show_trace_2d(f_2d, d2l.train_2d(gd_2d))

epoch 20, x1: -0.387814, x2: -1673.365109

poYBAGR9OYaAL1u4AACZkZpMDjg700.svg

eta = 0.6
d2l.show_trace_2d(f_2d, d2l.train_2d(gd_2d))

epoch 20, x1: -0.387814, x2: -1673.365109

pYYBAGR9OYuAOnI8AACadiWOA18802.svg

eta = 0.6
d2l.show_trace_2d(f_2d, d2l.train_2d(gd_2d))

epoch 20, x1: -0.387814, x2: -1673.365109

poYBAGR9OY6AZUNGAACYwvCS4-c528.svg

12.6.1.3。动量法

动量法使我们能够解决上述梯度下降问题。看看上面的优化轨迹,我们可能会凭直觉认为对过去的梯度进行平均会很有效。毕竟,在x1direction 这将聚合良好对齐的梯度,从而增加我们每一步覆盖的距离。相反,在x2梯度振荡的方向,聚合梯度将由于相互抵消的振荡而减小步长。使用vt而不是渐变 gt产生以下更新方程:

(12.6.5)vt←βvt−1+gt,t−1,xt←xt−1−ηtvt.

请注意,对于β=0我们恢复常规梯度下降。在深入研究数学属性之前,让我们快速了解一下该算法在实践中的表现。

def momentum_2d(x1, x2, v1, v2):
  v1 = beta * v1 + 0.2 * x1
  v2 = beta * v2 + 4 * x2
  return x1 - eta * v1, x2 - eta * v2, v1, v2

eta, beta = 0.6, 0.5
d2l.show_trace_2d(f_2d, d2l.train_2d(momentum_2d))

epoch 20, x1: 0.007188, x2: 0.002553

poYBAGR9OZCAYFcyAACmFpc5vvY213.svg

def momentum_2d(x1, x2, v1, v2):
  v1 = beta * v1 + 0.2 * x1
  v2 = beta * v2 + 4 * x2
  return x1 - eta * v1, x2 - eta * v2, v1, v2

eta, beta = 0.6, 0.5
d2l.show_trace_2d(f_2d, d2l.train_2d(momentum_2d))

epoch 20, x1: 0.007188, x2: 0.002553

pYYBAGR9OZOAb3_OAACmYPm7_AI155.svg

def momentum_2d(x1, x2, v1, v2):
  v1 = beta * v1 + 0.2 * x1
  v2 = beta * v2 + 4 * x2
  return x1 - eta * v1, x2 - eta * v2, v1, v2

eta, beta = 0.6, 0.5
d2l.show_trace_2d(f_2d, d2l.train_2d(momentum_2d))

epoch 20, x1: 0.007188, x2: 0.002553

poYBAGR9OZWATOJ5AACltJBLQUI056.svg

正如我们所看到的,即使使用我们之前使用的相同学习率,动量仍然收敛得很好。让我们看看当我们减少动量参数时会发生什么。减半到β=0.25导致几乎不收敛的轨迹。尽管如此,它比没有动量(当解决方案发散时)要好得多。

eta, beta = 0.6, 0.25
d2l.show_trace_2d(f_2d, d2l.train_2d(momentum_2d))

epoch 20, x1: -0.126340, x2: -0.186632

poYBAGR9OZiAOEXIAACmFYZtz7U083.svg

eta, beta = 0.6, 0.25
d2l.show_trace_2d(f_2d, d2l.train_2d(momentum_2d))

epoch 20, x1: -0.126340, x2: -0.186632

pYYBAGR9OZuAMleVAACmiRZJAjY082.svg

eta, beta = 0.6, 0.25
d2l.show_trace_2d(f_2d, d2l.train_2d(momentum_2d))

epoch 20, x1: -0.126340, x2: -0.186632

poYBAGR9OZ2ALvCLAAClw8XpirU268.svg

请注意,我们可以将动量与随机梯度下降结合起来,特别是小批量随机梯度下降。唯一的变化是在那种情况下我们替换梯度gt,t−1 和gt. 最后,为了方便我们初始化 v0=0在时间t=0. 让我们看看泄漏平均实际上对更新做了什么。

12.6.1.4。有效样品重量

回想起那个 vt=∑τ=0t−1βτgt−τ,t−τ−1. 在极限条件下,项加起来为 ∑τ=0∞βτ=11−β. 换句话说,而不是迈出一大步η在梯度下降或随机梯度下降中,我们采取一个大小的步骤 η1−β同时,处理可能表现更好的下降方向。这是二合一的好处。为了说明加权如何针对不同的选择β考虑下图。

d2l.set_figsize()
betas = [0.95, 0.9, 0.6, 0]
for beta in betas:
  x = torch.arange(40).detach().numpy()
  d2l.plt.plot(x, beta ** x, label=f'beta = {beta:.2f}')
d2l.plt.xlabel('time')
d2l.plt.legend();

poYBAGR9OaGAXFqQAAEknE0zr00608.svg

d2l.set_figsize()
betas = [0.95, 0.9, 0.6, 0]
for beta in betas:
  x = np.arange(40).asnumpy()
  d2l.plt.plot(x, beta ** x, label=f'beta = {beta:.2f}')
d2l.plt.xlabel('time')
d2l.plt.legend();

poYBAGR9OaGAXFqQAAEknE0zr00608.svg

d2l.set_figsize()
betas = [0.95, 0.9, 0.6, 0]
for beta in betas:
  x = tf.range(40).numpy()
  d2l.plt.plot(x, beta ** x, label=f'beta = {beta:.2f}')
d2l.plt.xlabel('time')
d2l.plt.legend();

poYBAGR9OaGAXFqQAAEknE0zr00608.svg

12.6.2。实践实验

让我们看看动量在实践中是如何工作的,即,当在适当的优化器的上下文中使用时。为此,我们需要一个更具可扩展性的实现。

12.6.2.1。从零开始实施

与(minibatch)随机梯度下降相比,动量法需要维护一组辅助变量,即速度。它与梯度(和优化问题的变量)具有相同的形状。在下面的实现中,我们称这些变量为states。

def init_momentum_states(feature_dim):
  v_w = torch.zeros((feature_dim, 1))
  v_b = torch.zeros(1)
  return (v_w, v_b)

def sgd_momentum(params, states, hyperparams):
  for p, v in zip(params, states):
    with torch.no_grad():
      v[:] = hyperparams['momentum'] * v + p.grad
      p[:] -= hyperparams['lr'] * v
    p.grad.data.zero_()

def init_momentum_states(feature_dim):
  v_w = np.zeros((feature_dim, 1))
  v_b = np.zeros(1)
  return (v_w, v_b)

def sgd_momentum(params, states, hyperparams):
  for p, v in zip(params, states):
    v[:] = hyperparams['momentum'] * v + p.grad
    p[:] -= hyperparams['lr'] * v

def init_momentum_states(features_dim):
  v_w = tf.Variable(tf.zeros((features_dim, 1)))
  v_b = tf.Variable(tf.zeros(1))
  return (v_w, v_b)

def sgd_momentum(params, grads, states, hyperparams):
  for p, v, g in zip(params, states, grads):
      v[:].assign(hyperparams['momentum'] * v + g)
      p[:].assign(p - hyperparams['lr'] * v)

让我们看看这在实践中是如何工作的。

def train_momentum(lr, momentum, num_epochs=2):
  d2l.train_ch11(sgd_momentum, init_momentum_states(feature_dim),
          {'lr': lr, 'momentum': momentum}, data_iter,
          feature_dim, num_epochs)

data_iter, feature_dim = d2l.get_data_ch11(batch_size=10)
train_momentum(0.02, 0.5)

loss: 0.248, 0.133 sec/epoch

pYYBAGR9OamAW01UAADyZR3bcs0823.svg

def train_momentum(lr, momentum, num_epochs=2):
  d2l.train_ch11(sgd_momentum, init_momentum_states(feature_dim),
          {'lr': lr, 'momentum': momentum}, data_iter,
          feature_dim, num_epochs)

data_iter, feature_dim = d2l.get_data_ch11(batch_size=10)
train_momentum(0.02, 0.5)

loss: 0.243, 29.702 sec/epoch

poYBAGR9Oa2AP7dFAADyd5nBQrE057.svg

def train_momentum(lr, momentum, num_epochs=2):
  d2l.train_ch11(sgd_momentum, init_momentum_states(feature_dim),
          {'lr': lr, 'momentum': momentum}, data_iter,
          feature_dim, num_epochs)

data_iter, feature_dim = d2l.get_data_ch11(batch_size=10)
train_momentum(0.02, 0.5)

loss: 0.243, 1.087 sec/epoch

pYYBAGR9Oa-ABziAAADycuYHUrI903.svg

当我们将动量超参数增加到momentum0.9 时,它相当于一个显着更大的有效样本量 11−0.9=10. 我们稍微降低学习率 0.01以控制事情。

train_momentum(0.01, 0.9)

loss: 0.259, 0.156 sec/epoch

poYBAGR9ObKAfC1oAADya3SrF2w584.svg

train_momentum(0.01, 0.9)

loss: 0.245, 28.885 sec/epoch

pYYBAGR9ObSAJ6EqAADydoktmRQ920.svg

train_momentum(0.01, 0.9)

loss: 0.253, 1.084 sec/epoch

poYBAGR9ObiAcQ8qAADyaEVhoBY962.svg

降低学习率进一步解决了非平滑优化问题的任何问题。将其设置为0.005产生良好的收敛特性。

train_momentum(0.005, 0.9)

loss: 0.243, 0.141 sec/epoch

poYBAGR9ObqAf9y7AADyds5MOfc310.svg

train_momentum(0.005, 0.9)

loss: 0.248, 22.937 sec/epoch

pYYBAGR9Ob2AUCgKAADyepkCiR4630.svg

train_momentum(0.005, 0.9)

loss: 0.243, 1.088 sec/epoch

poYBAGR9Ob-AAe7jAADydBZtyIM197.svg

12.6.2.2。简洁的实现

在 Gluon 中几乎不需要做任何事情,因为标准sgd求解器已经内置了动量。设置匹配参数会产生非常相似的轨迹。

trainer = torch.optim.SGD
d2l.train_concise_ch11(trainer, {'lr': 0.005, 'momentum': 0.9}, data_iter)

loss: 0.250, 0.141 sec/epoch

pYYBAGR9OcOAFOoFAADcBP5DgHk640.svg

d2l.train_concise_ch11('sgd', {'learning_rate': 0.005, 'momentum': 0.9},
            data_iter)

loss: 0.245, 21.439 sec/epoch

poYBAGR9OceATjVbAADyZ9V1daQ470.svg

trainer = tf.keras.optimizers.SGD
d2l.train_concise_ch11(trainer, {'learning_rate': 0.005, 'momentum': 0.9},
            data_iter)

loss: 0.259, 1.141 sec/epoch

poYBAGR9OcqAGJTsAADyb_qG9D8296.svg

12.6.3。理论分析

到目前为止的二维示例f(x)=0.1x12+2x22似乎很做作。我们现在将看到,这实际上非常具有代表性,至少在最小化凸二次目标函数的情况下可能遇到的问题类型。

12.6.3.1。二次凸函数

考虑函数

(12.6.6)h(x)=12x⊤Qx+x⊤c+b.

这是一个一般的二次函数。对于正定矩阵 Q≻0,即,对于具有正特征值的矩阵,它有一个最小值 x∗=−Q−1c最小值 b−12c⊤Q−1c. 因此我们可以重写h作为

(12.6.7)h(x)=12(x−Q−1c)⊤Q(x−Q−1c)+b−12c⊤Q−1c.

梯度由下式给出 ∂xh(x)=Q(x−Q−1c). 也就是说,它由之间的距离给出x和最小化器,乘以Q. 因此,速度也是项的线性组合 Q(xt−Q−1c).

自从Q是正定的,它可以分解成它的特征系统通过 Q=O⊤ΛO对于正交(旋转)矩阵O和一个对角矩阵 Λ正特征值。这允许我们执行变量的更改x到 z=defO(x−Q−1c) 获得一个更简化的表达式:

(12.6.8)h(z)=12z⊤Λz+b′.

这里 b′=b−12c⊤Q−1c. 自从O只是一个正交矩阵,它不会以有意义的方式扰乱梯度。表示为 z梯度下降变成

(12.6.9)zt=zt−1−Λzt−1=(I−Λ)zt−1.

这个表达式中的重要事实是梯度下降不会在不同的特征空间之间混合。也就是说,当用以下的特征系统表示时Q优化问题以坐标方式进行。这也适用于

(12.6.10)vt=βvt−1+Λzt−1zt=zt−1−η(βvt−1+Λzt−1)=(I−ηΛ)zt−1−ηβvt−1.

在这样做时,我们只是证明了以下定理:凸二次函数有和没有动量的梯度下降分解为二次矩阵特征向量方向上的坐标优化。

12.6.3.2。标量函数

鉴于上述结果,让我们看看当我们最小化函数时会发生什么f(x)=λ2x2. 对于梯度下降,我们有

(12.6.11)xt+1=xt−ηλxt=(1−ηλ)xt.

每当|1−ηλ|<1这种优化以指数速率收敛,因为之后t我们的步骤 xt=(1−ηλ)tx0. 这显示了收敛速度最初是如何随着我们增加学习率而提高的 η直到ηλ=1. 除此之外,事情有所不同ηλ>2优化问题发散。

lambdas = [0.1, 1, 10, 19]
eta = 0.1
d2l.set_figsize((6, 4))
for lam in lambdas:
  t = torch.arange(20).detach().numpy()
  d2l.plt.plot(t, (1 - eta * lam) ** t, label=f'lambda = {lam:.2f}')
d2l.plt.xlabel('time')
d2l.plt.legend();

pYYBAGR9Oc2ABTV3AAGuOA1lotY614.svg

lambdas = [0.1, 1, 10, 19]
eta = 0.1
d2l.set_figsize((6, 4))
for lam in lambdas:
  t = np.arange(20).asnumpy()
  d2l.plt.plot(t, (1 - eta * lam) ** t, label=f'lambda = {lam:.2f}')
d2l.plt.xlabel('time')
d2l.plt.legend();

pYYBAGR9OdOALRdOAAGuN24rxN8874.svg

lambdas = [0.1, 1, 10, 19]
eta = 0.1
d2l.set_figsize((6, 4))
for lam in lambdas:
  t = tf.range(20).numpy()
  d2l.plt.plot(t, (1 - eta * lam) ** t, label=f'lambda = {lam:.2f}')
d2l.plt.xlabel('time')
d2l.plt.legend();

pYYBAGR9Oc2ABTV3AAGuOA1lotY614.svg

为了分析动量情况下的收敛性,我们首先根据两个标量重写更新方程:一个用于x和一个速度v. 这产生:

(12.6.12)[vt+1xt+1]=[βλ−ηβ(1−ηλ)][vtxt]=R(β,η,λ)[vtxt].

我们用了R表示2×2治理收敛行为。后t步骤初始选择 [v0,x0]成为 R(β,η,λ)t[v0,x0]. 因此,这取决于特征值R来确定收敛速度。有关精彩动画,请参阅Goh ( 2017 )的Distill 帖子,以及有关详细分析的Flammarion 和 Bach ( 2015 ) 。可以证明0<ηλ<2+2β 速度收敛。与相比,这是更大范围的可行参数0<ηλ<2用于梯度下降。它还表明,一般来说,大值β是可取的。进一步的细节需要相当多的技术细节,我们建议有兴趣的读者查阅原始出版物。

12.6.4。概括

动量用过去梯度的泄漏平均值代替梯度。这显着加快了收敛速度。

无噪声梯度下降和(噪声)随机梯度下降都是可取的。

动量可防止优化过程停滞,而随机梯度下降更可能发生这种情况。

梯度的有效数量由下式给出 11−β由于过去数据的指数下降。

在凸二次问题的情况下,这可以明确地详细分析。

实现非常简单,但它需要我们存储一个额外的状态向量(速度v).

12.6.5。练习

使用动量超参数和学习率的其他组合,观察和分析不同的实验结果。

对具有多个特征值的二次问题尝试梯度下降和动量,即 f(x)=12∑iλixi2,例如, λi=2−i. 绘制值如何x减少初始化xi=1.

导出最小值和最小值 h(x)=12x⊤Qx+x⊤c+b.

当我们使用动量执行随机梯度下降时会发生什么变化?当我们使用带动量的小批量随机梯度下降时会发生什么?试验参数?

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • pytorch
    +关注

    关注

    2

    文章

    798

    浏览量

    13104
收藏 人收藏

    评论

    相关推荐

    Pytorch模型训练实用PDF教程【中文】

    ?模型部分?还是优化器?只有这样不断的通过可视化诊断你的模型,不断的对症下药,才能训练出一个较满意的模型。本教程内容及结构:本教程内容主要为在 PyTorch 中训练一个模型所可能涉及到的方法及函数,并且
    发表于 12-21 09:18

    Pytorch自动求导示例

    Pytorch自动微分的几个例子
    发表于 08-09 11:56

    Pytorch入门之的基本操作

    Pytorch入门之基本操作
    发表于 05-22 17:15

    PyTorch如何入门

    PyTorch 入门实战(一)——Tensor
    发表于 06-01 09:58

    PyTorch10的基础教程

    PyTorch 10 基础教程(4):训练分类器
    发表于 06-05 17:42

    Pytorch AI语音助手

    想做一个Pytorch AI语音助手,有没有好的思路呀?
    发表于 03-06 13:00

    如何安装TensorFlow2 Pytorch

    如何安装TensorFlow2 Pytorch
    发表于 03-07 07:32

    pytorch模型转化为onxx模型的步骤有哪些

    首先pytorch模型要先转化为onxx模型,然后从onxx模型转化为rknn模型直接转化会出现如下问题,环境都是正确的,论坛询问后也没给出准确答案说是版本问题--&gt
    发表于 05-09 16:36

    如何往星光2板子里装pytorch

    如题,想先gpu版本的pytorch只安装cpu版本的pytorch,pytorch官网提供了基于conda和pip两种安装方式。因为咱是risc架构没对应的conda,而使用pip安装提示也没有
    发表于 09-12 06:30

    pytorch模型转换需要注意的事项有哪些?

    什么是JIT(torch.jit)? 答:JIT(Just-In-Time)是一组编译工具,用于弥合PyTorch研究与生产之间的差距。它允许创建可以在不依赖Python解释器的情况下运行的模型
    发表于 09-18 08:05

    基于PyTorch的深度学习入门教程之PyTorch简单知识

    本文参考PyTorch官网的教程,分为五个基本模块来介绍PyTorch。为了避免文章过长,这五个模块分别在五篇博文中介绍。 Part1:PyTorch简单知识 Part2:PyTorch
    的头像 发表于 02-16 15:20 2200次阅读

    基于PyTorch的深度学习入门教程之PyTorch的自动梯度计算

    本文参考PyTorch官网的教程,分为五个基本模块来介绍PyTorch。为了避免文章过长,这五个模块分别在五篇博文中介绍。 Part1:PyTorch简单知识 Part2:PyTorch
    的头像 发表于 02-16 15:26 1984次阅读

    PyTorch教程12.6势头

    电子发烧友网站提供《PyTorch教程12.6势头.pdf》资料免费下载
    发表于 06-05 14:53 0次下载
    <b class='flag-5'>PyTorch</b>教程<b class='flag-5'>12.6</b>之<b class='flag-5'>势头</b>

    tensorflow和pytorch哪个更简单?

    PyTorch更简单。选择TensorFlow还是PyTorch取决于您的具体需求和偏好。如果您需要一个易于使用、灵活且具有强大社区支持的框架,PyTorch可能是一个更好的选择。如果您需要一个在
    的头像 发表于 07-05 09:45 681次阅读

    pytorch怎么在pycharm中运行

    第一部分:PyTorch和PyCharm的安装 1.1 安装PyTorch PyTorch是一个开源的机器学习库,用于构建和训练神经网络。要在PyCharm中使用PyTorch,首先需
    的头像 发表于 08-01 16:22 1072次阅读