【问题标题】:Where is backpropagation performed in this example本例中的反向传播在哪里执行
【发布时间】:2020-01-28 06:42:29
【问题描述】:

我有一个 DNN 学习 XOR 的例子(右键在新标签中打开):https://colab.research.google.com/drive/1M5xFp4gaXPCbnejM8-5_yLp1B6UvwdL8

我对这两行感到困惑(与反向传播有关):

Grads = T.gradient(Loss,[W1,B1,W2,B2]);
Optim.apply_gradients(zip(Grads,[W1,B1,W2,B2]));

我猜反向循环在T.gradient,因为这些是与损失相关的梯度值,但我仍然不清楚。问题是:

  • 问题 1。这两行中是否存在反向传播(反向循环)?
  • 问题 2。如果有反向传播,它在T.gradientOptim.apply_gradients
  • 问题 3。因为反向传播是反向进行的,[W1,B1,W2,B2] 的顺序重要吗?我相信,例如。这个改组的[B1,W2,B2,W1] 不能相同,因为反向传播需要从输出到输入的层顺序。

从我的尝试来看,当改变变量数组中权重和偏差的顺序时,优化过程仍然有效。 但是反向传播需要从输出到输入的层顺序,我不明白

源代码:

#!pip install tensorflow==2.0.0rc2
%tensorflow_version 2.x
%reset -f

#libs
import tensorflow as tf;

#data
X = [[0,0],[0,1],[1,0],[1,1]];
Y = [[0],  [1],  [1],  [0]  ];
X = tf.convert_to_tensor(X,tf.float32);
Y = tf.convert_to_tensor(Y,tf.float32);

#model
W1 = tf.Variable(tf.random.uniform([2,20],-1,1));
B1 = tf.Variable(tf.random.uniform([  20],-1,1));

W2 = tf.Variable(tf.random.uniform([20,1],-1,1));
B2 = tf.Variable(tf.random.uniform([   1],-1,1));

@tf.function
def feedforward(X):
  H1  = tf.nn.leaky_relu(tf.matmul(X,W1) + B1);
  Out = tf.sigmoid(tf.matmul(H1,W2) + B2);
  return Out;
#end def

#train
Optim = tf.keras.optimizers.SGD(1e-1);
Steps = 1000;

for I in range(Steps):
  if I%(Steps/10)==0:
    Out  = feedforward(X);
    Loss = tf.reduce_sum(tf.square(Y-Out));
    print("Loss:",Loss.numpy());
  #end if

  with tf.GradientTape() as T:
    Out  = feedforward(X);
    Loss = tf.reduce_sum(tf.square(Y-Out));
  #end with

  #BACKPROPAGATION HERE?
  Grads = T.gradient(Loss,[W1,B1,W2,B2]);
  Optim.apply_gradients(zip(Grads,[W1,B1,W2,B2]));
#end for

Out  = feedforward(X);
Loss = tf.reduce_sum(tf.square(Y-Out));
print("Loss:",Loss.numpy(),"(Last)");

print("\nDone.");
#eof

【问题讨论】:

    标签: tensorflow gradient data-science gradient-descent backpropagation


    【解决方案1】:

    在默认的 Eager 模式下使用 TensorFlow 2,即使没有 @tf.function 装饰器来制作图形。 TensorFlow 在计算时仍在跟踪张量之间的关系:https://stats.stackexchange.com/a/272000/142160

    TensorFlow 在此处跟踪每个变量:

    with tf.GradientTape() as T:
        Out  = feedforward(X);
        Loss = tf.reduce_sum(tf.square(Y-Out));
    

    它是自动微分(有点像蒙特卡洛方法)而不是数学微分,因此,以下函数获得的所有梯度在反向传播中已经处于适当的深度(就像反向循环到计算所有层的误差):

    Grads = T.gradient(Loss,[W1,B1,W2,B2]);
    

    之后,优化器将应用梯度来改变权重和偏差:

    Optim.apply_gradients(zip(Grads,[W1,B1,W2,B2]));
    

    【讨论】:

      【解决方案2】:

      让我们一步一步来。

      第 1 步:计算梯度:

      Grads = T.gradient(Loss,[W1,B1,W2,B2])
      

      在这里,我们根据提供的列表中的变量计算损失的梯度。梯度列表基于变量的索引进行索引。这意味着Grads[0] 将是相对于W1 的渐变,依此类推。

      第 2 步:接下来,我们执行更新。这是在:

      Optim.apply_gradients(zip(Grads,[W1,B1,W2,B2]))
      

      这里,Grads[0]用来更新W1Grads[1]用来更新B1等等。

      请注意,梯度计算和更新步骤是分开执行的。因此,只要变量在两个列表中以相同的顺序出现,就不会有任何问题。

      另外,GradientTape 必须与 Eager Execution 一起使用。

      【讨论】:

      • 我知道变量列表在这两行中应该是相同的,但主要是执行反向传播的行
      • Backpropagation 是一个涉及多个步骤的算法,从计算损失开始到更新所涉及的变量。问题中提到的两个步骤都是算法的一部分。
      • 好的,所以有反向传播,反向传播的循环在两行中。但是,[w1,b1,w2,b2] 的顺序重要吗?
      • 不,不是。所有梯度都是独立计算的。
      • 哦,依赖,那么反向循环在哪里?
      猜你喜欢
      • 1970-01-01
      • 2020-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-28
      • 2016-10-23
      • 2021-11-24
      • 1970-01-01
      相关资源
      最近更新 更多