Где в этом примере выполняется обратное распространение - PullRequest
0 голосов
/ 28 сентября 2019

У меня есть пример обучения 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.gradient или Optim.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

1 Ответ

1 голос
/ 28 сентября 2019

Давайте сделаем один шаг за раз.

Шаг 1: Расчет градиентов:

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

Здесь мы вычисляем градиенты потерь по переменным впредоставленный список.Список градиентов индексируется на основе индексов переменных.Это означает, что Grads[0] будет градиентами по отношению к W1 и т. Д.

Шаг 2: Далее мы выполняем обновление.Это делается следующим образом:

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

Здесь Grads[0] используются для обновления W1, Grads[1] для обновления B1 и т. Д.

Обратите внимание, что расчет градиента ишаги обновления выполняются отдельно.Поэтому, пока переменные отображаются в одном и том же порядке в обоих списках, проблем не должно быть.

Кроме того, GradientTape должен использоваться с Eager Execution.

...