Tensor
Warm-up:numpy
|
|
PyTorch:Tensor
|
|
Autograd
PyTorch:Variables and autograd
PyTorch中所有的神经网络都来自于autograd包
在上面的例子中,我们必须手动实现神经网络的向前和向后遍。手动实施后向传递对于小型双层网络来说不是一件大事,但是对于大型复杂网络来说,可以很快地得到很多毛病。
幸运的是,我们可以使用自动区分 来自动计算神经网络中的向后遍。PyTorch中的 autograd包提供了这个功能。使用自动格式时,网络的正向传递将定义一个 计算图 ; 图中的节点将是Tensors,边缘将是从输入Tensors生成输出Tensors的函数。通过此图反向传播,您可以轻松地计算渐变。
这听起来很复杂,在实践中使用起来很简单。我们将PyTorch Tensors包装在可变对象中; 变量表示计算图中的节点。如果x是变量,则x.data是Tensor,并且x.grad是另一个变量,x其相对于某个标量值保存渐变 。
PyTorch变量与PyTorch Tensors具有相同的API(几乎)您可以在Tensor上执行的任何操作也适用于变量; 区别在于使用变量定义计算图,允许您自动计算渐变。
这里我们使用PyTorch变量和自动调整来实现我们的两层网络; 现在我们不再需要手动实现向后通过网络:
PyTorch:Defining new autograd functions
在PyTorch中,我们可以通过定义一个子类torch.autograd.Function并实现forward 和backward函数来轻松地定义自己的autograd运算符。然后,我们可以通过构造一个实例并将其称为函数,传递包含输入数据的变量来使用我们的新的自动格式运算符。
在这个例子中,我们定义了我们自己的自定义自整定函数来执行ReLU非线性,并用它来实现我们的两层网络:
TensorFlow: Static Graphs
PyTorch autograd看起来很像TensorFlow:在两个框架中我们定义一个计算图,并使用自动差分来计算梯度。两者之间的最大区别在于TensorFlow的计算图是静态的,PyTorch使用 动态计算图。
在TensorFlow中,我们定义了一次计算图,然后一遍又一遍地执行相同的图,可能会将不同的输入数据提供给图形。在PyTorch中,每个前进传递定义了一个新的计算图。
静态图是很好的,因为你可以优化前面的图形; 例如,框架可能决定融合一些图形操作以获得效率,或者提出一种将图形分布在多个GPU或许多机器上的策略。如果您一遍又一遍地重复使用相同的图表,那么这个潜在的昂贵的前期优化可以被分摊,因为同一个图表一遍又一遍地重新运行。
静态和动态图不同的一个方面是控制流程。对于某些型号,我们可能希望对每个数据点执行不同的计算; 例如,对于每个数据点,可以展开不同数量的时间步长的循环网络; 这个展开可以被实现为循环。使用静态图形,循环构造需要是图形的一部分; 由于这个原因,TensorFlow提供了诸如tf.scan将循环嵌入图中的操作符。使用动态图表,情况更简单:由于我们为每个示例动态构建图表,因此我们可以使用正常的命令式流程控制来执行每个输入不同的计算。
为了与上面的PyTorch autograd示例进行对比,我们使用TensorFlow来简化两层网络:
nn module
PyTorch: nn
|
|
PyTorch: optim
|
|
PyTorch: Custom nn Modules
|
|
PyTorch: Control Flow + Weight Sharing
|
|