Правило обучения Hebian в TensorFlow

Извините за мое невежество, это моя первая попытка с тензорным потоком. Для k-й входной выборки Правило обучения Hebian в TensorFlow и скорости обучения Правило обучения Hebian в TensorFlow я пытаюсь реализовать правило обучения Hebian, заданное,

Правило обучения Hebian в TensorFlow

где Правило обучения Hebian в TensorFlow с использованием тензорного потока. После некоторого поиска я нашел этот код, который реализует вариант правила обновления градиента. В этом коде правило обновления не зависит от входных данных. Не могли бы вы подсказать, как настроить этот код (возможно, _apply_dense и _create_slots) для реализации вышеуказанного правила обучения?

Спасибо.

Что такое x? Это ввод?

Vlad 07.04.2019 16:06

@Влад спасибо за ответ. Да, ввод, я внес правку в пост.

Thoth 07.04.2019 16:12

Вы смогли понять мой ответ? Обратите внимание, что вам не нужно создавать подклассы от tf.train.Optimizer для его реализации.

Vlad 07.04.2019 18:33

@ Влад, спасибо за ответ, пожалуйста, дайте мне еще немного, чтобы сделать некоторые заметки.

Thoth 07.04.2019 18:43
Udacity Nanodegree Capstone Project: Классификатор пород собак
Udacity Nanodegree Capstone Project: Классификатор пород собак
Вы можете ознакомиться со скриптами проекта и данными на github .
1
4
99
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Пойдем с примером. Предположим, что размер x равен (None, 2), и вы кормите размер партии 4, поэтому размер x будет (4, 2). Предположим также, что форма веса w равна (2, 2).

  1. Сначала мы умножаем y=W^Tx, и нам также придется транспонировать x, чтобы это можно было сделать: y = tf.matmul(tf.transpose(w), tf.transpose(x)). Это приведет к форме (2, 2)x(2, 4)-->(2, 4).
  2. Затем умножаем xy^T. Здесь мы также переместим x: xyT = tf.matmul(tf.tranpose(x), tf.transpose(y)), что приведет к форме (2, 4)x(4, 2)--> (2, 2).
  3. Затем мы оцениваем WW^T, который будет иметь форму (2, 2).
  4. Теперь мы вычитаем alpha*(I-WW^T), который также будет иметь форму (2, 2).
  5. Умножаем то, что получили в (4) на xy^T.
  6. Наконец, мы обновляем веса.

Код:

def hebian_update(x, alpha=0.01):
    with x.graph.as_default():
        weights = tf.trainable_variables()
        # 1
        y = [tf.matmul(tf.transpose(w), tf.transpose(x)) for w in weights] # y = W^Tx
        # 2
        xyT = [tf.matmul(tf.transpose(x), tf.transpose(w)) for w in y] # xy^T
        # 3
        wwT = [tf.matmul(w, tf.transpose(w)) for w in weights] # WW^T

        wwTshapes = [w.get_shape().as_list() for w in wwT] # shapes of WW^T 

        # 4
        diffs = [alpha*(tf.eye(num_rows=s[0], num_columns=s[1]) - w)
                 for w, s in zip(wwT, wwTshapes)] # alpha*(I-WW^T)
        # 5
        diffs = [tf.matmul(d, w) for d, w in zip(diffs, xyT)] # alpha*(I-WW^T)xy^T
        # 6
        update_ops = [tf.assign(w, w + d) for w, d in zip(weights, diffs)]

        return tf.group(update_ops)

Давайте проверим это с помощью небольшой нейронной сети на наборе данных blobs:

# dataset for illustration
from sklearn.datasets import make_blobs
x_train, y_train = make_blobs(n_samples=4,
                              n_features=2,
                              centers=[[1, 1], [-1, -1]],
                              cluster_std=0.5)
x = tf.placeholder(tf.float32, shape=[None, 2])
y = tf.placeholder(tf.int32, shape=[None])

with tf.name_scope('network'):
    fc1 = tf.layers.dense(x, units=2, use_bias=False)
    logits = tf.layers.dense(fc1, units=2, use_bias=False)

hebian_op = hebian_update(x)

with tf.name_scope('loss'):
    xentropy = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=y, logits=logits)
    loss_fn = tf.reduce_mean(xentropy)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(loss_fn.eval({x:x_train, y:y_train})) # 0.14356796
    _ = sess.run(hebian_op, feed_dict = {x:x_train})
    print(loss_fn.eval({x:x_train, y:y_train})) # 0.3619529

Это ваша ответственность теперь, когда все веса в нейронной сети совместимы с вводом x (т.е. делать y = tf.matmul(tf.transpose(w), tf.transpose(x)))!

Спасибо еще раз. Думаю, у меня есть несколько вопросов. 1) Почему вы используете итеративные вычисления для основных вычислений? Можно подробнее в этой части? 2) На этапе тестирования, почему вы используете в два раза больше tf.layer.dense

Thoth 07.04.2019 19:15

(1, 2) Я дважды использовал tf.layers.dense(), чтобы показать вам пример сети с более чем одним слоем. Я никогда не слышал об обновлении Hebian и не знаю, используется ли оно для оптимизации нейронных сетей, поэтому я показал вам общий случай, когда нейронная сеть может содержать более одной весовой матрицы (в частности, в моем примере определяется как это w2^T(w1^Tx )). Если бы у вас была одна, две или более весовых матриц, функция, которую я предоставил, все равно будет работать.

Vlad 07.04.2019 19:30

В случае w2^T(w1^Tx) я обновляю w1 и w2 независимо, поэтому у меня есть обновления как понимание списка - потому что сначала я обновляю w1, а потом w2.

Vlad 07.04.2019 19:34

Если у вас есть один слой (одна весовая матрица), код все равно будет работать.

Vlad 07.04.2019 19:34

Итак, в данном примере есть серия из одной скрытой единицы активации? Я прав?

Thoth 07.04.2019 19:38

Вы можете сказать это. matmul операция w1^Tx приводит к скрытым единицам (в моем случае без активации), которые являются входными данными для второго слоя. Вывод второго и последнего слоя w2^T(w1^Tx) не считается содержащим «скрытые» единицы. В тензорном потоке последний слой называется логитом.

Vlad 07.04.2019 19:45

Другие вопросы по теме