首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Tensorflow - autodiff会让我们重新体验背靠背的实现吗?

Tensorflow - autodiff会让我们重新体验背靠背的实现吗?
EN

Stack Overflow用户
提问于 2021-04-06 07:35:09
回答 2查看 362关注 0票数 2

问题

例如,当使用Tensorflow实现自定义神经网络层时,实现反向传播的标准实践是什么?我们不需要研究自动微分公式吗?

背景

对于numpy,当创建一个层(例如matmul )时,反向传播梯度首先被解析地导出并相应地编码。

代码语言:javascript
复制
def forward(self, X):
    self._X = X
    np.matmul(self.X, self.W.T, out=self._Y)
    return self.Y

def backward(self, dY):
    """dY = dL/dY is a jacobian where L is loss and Y is matmul output"""
    self._dY = dY
    return np.matmul(self.dY, self.W, out=self._dX)

在Tensorflow中,有自差,它似乎负责雅可比计算。这是否意味着我们不必手动导出梯度公式,而是让Tensorflow磁带来处理它?

计算渐变以自动区分,TensorFlow需要记住在前进过程中发生了什么顺序的操作。然后,在向后传递期间,TensorFlow以反向顺序遍历此操作列表,以计算梯度。

EN

回答 2

Stack Overflow用户

发布于 2021-04-06 14:14:52

基本上,Tensorflow是一个基于数据流和可微编程的符号数学库。我们不需要手动处理自动微分公式。所有这些数学运算都会在后面自动完成。您正确引用了官方文档中关于梯度计算的内容。但是,如果您想知道如何使用numpy手动完成,我建议您检查一下神经网络与深度学习的这个奇妙的过程,特别是第4周,或者另一个源这里

FYI,在TF 2中,我们可以通过重写tf.keras.Model类的train_step从零开始进行自定义培训,在那里我们可以使用tf.GradientTape API进行自动区分;也就是说,计算一些输入的计算梯度。同样的官方页面包含了更多有关这方面的信息。另外,必须看到这是一篇在tf.GradientTape上写得很好的文章.例如,使用这个API,我们可以轻松地计算梯度,如下所示:

代码语言:javascript
复制
import tensorflow as tf 

# some input 
x = tf.Variable(3.0, trainable=True)

with tf.GradientTape() as tape:
    # some output 
    y = x**3 + x**2 + x + 5

# compute gradient of y wrt x 
print(tape.gradient(y, x).numpy()) 
# 34

此外,我们还可以计算更高阶的导数,例如

代码语言:javascript
复制
x = tf.Variable(3.0, trainable=True)

with tf.GradientTape() as tape1:

    with tf.GradientTape() as tape2:
        y = x**3 + x**2 + x + 5
    # first derivative 
    order_1 = tape2.gradient(y, x)

# second derivative 
order_2 = tape1.gradient(order_1, x)

print(order_2.numpy()) 
# 20.0

现在,在tf. keras中的自定义模型培训中,我们首先进行forward传递,然后计算模型中有关loss的可训练变量的loss和下一个计算gradients。随后,我们基于这些gradients更新模型的权重。下面是它的代码片段,下面是端到端的详细信息。从头开始写一个训练循环。

代码语言:javascript
复制
# Open a GradientTape to record the operations run
# during the forward pass, which enables auto-differentiation.
with tf.GradientTape() as tape:

    # Run the forward pass of the layer.
    # The operations that the layer applies
    # to its inputs are going to be recorded
    # on the GradientTape.
    logits = model(x_batch_train, training=True)  # Logits for this minibatch

    # Compute the loss value for this minibatch.
    loss_value = loss_fn(y_batch_train, logits)

# Use the gradient tape to automatically retrieve
# the gradients of the trainable variables with respect to the loss.
grads = tape.gradient(loss_value, model.trainable_weights)

# Run one step of gradient descent by updating
# the value of the variables to minimize the loss.
optimizer.apply_gradients(zip(grads, model.trainable_weights))
票数 1
EN

Stack Overflow用户

发布于 2021-04-06 14:15:02

正确,您只需定义前传球,Tensorflow就会生成适当的后传球。来自tf2自差

TensorFlow提供了用于自动区分的tf.GradientTape API;也就是说,根据某些输入(通常是tf.Variables )计算计算的梯度。TensorFlow将在tf.GradientTape上下文中执行的相关操作“记录”到“磁带”上。然后,TensorFlow使用该磁带来使用反向模式微分计算“记录”计算的梯度。

为了做到这一点,Tensorflow给出了向前通过(或损失)和一组tf.Variable变量来计算导数。此过程仅可用于Tensorflow本身定义的一组特定操作。为了创建自定义NN层,您需要使用这些操作(所有这些操作都是TF的一部分或由某个转换器转换到它)来定义它的前向pas。

因为您似乎有一个numpy背景,所以可以使用numpy定义自定义向前传递,然后使用API接口将其转换为Tensorflow。您也可以使用tf.numpy_function。在此之后,TF将为您创建反向传播。

(*)注意一些操作,例如控制语句本身是不可微的,因此它们对基于梯度的优化器是不可见的。关于这些,有一些警告。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66964498

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档