Python 计算连接到优化器中相同神经元的张量值子集的值

Python 计算连接到优化器中相同神经元的张量值子集的值,python,optimization,tensorflow,Python,Optimization,Tensorflow,我正在用python用TensorFlow编写一个优化器 如何计算作为神经元传入连接的张量值子集的值? 例如,我们使用带有动量项的随机梯度下降优化器。分别计算每个连接的动量项。现在我想通过计算连接到同一个神经元的所有连接的动量值的平均值来计算一个连接的动量 在这张图片中,您可以看到两个连接都连接到神经元3作为传入连接。一个连接的重量更新应考虑两个连接。通常连接(1,3)的更新只包括梯度(1,3)和动量(1,3)。对于连接(1,3)的更新,我想使用动量(1,3)和动量(2,3)的平均值 让我们

我正在用python用TensorFlow编写一个优化器

如何计算作为神经元传入连接的张量值子集的值?


例如,我们使用带有动量项的随机梯度下降优化器。分别计算每个连接的动量项。现在我想通过计算连接到同一个神经元的所有连接的动量值的平均值来计算一个连接的动量

在这张图片中,您可以看到两个连接都连接到神经元3作为传入连接。一个连接的重量更新应考虑两个连接。通常连接(1,3)的更新只包括梯度(1,3)和动量(1,3)。对于连接(1,3)的更新,我想使用动量(1,3)和动量(2,3)的平均值

让我们来看一个简单的完全连接的神经网络,它有一个输入神经元、两个隐藏层、每个隐藏层两个神经元和一个输出神经元:

如果我们对神经元2和神经元5之间的连接的权重更新(代码中称为“积累”)的正常计算,我们只考虑最后一次的动量。< /P> 我们可以从下面的python实现中看到正常的“累积”更新计算:

accumulation = self.get_slot(var, "a")
accumulation_update = grad + (mu_t * accumulation)
对于神经元2和神经元5之间的连接,累积如下所示:

这是应该改变的部分。新的动量计算应采用所有连接的平均值,这些连接作为传入连接连接到与计算权重更新的连接相同的神经元。查看示例神经网络,连接(2,5)的“累积”值是连接(2,5)和(3,5)的“累积”值的平均值。这些都是神经元5的传入连接

“累积”更新按以下方式进行更改:

accumulation = self.get_slot(var, "a")
accumulation_means = # Code to calculate all mean values for all neurons
accumulation_update = grad + (mu_t * accumulation_means) # Use the means for the accumulation_update
accumulation_mean = (accumulation(2, 5) + accumulation(3, 5)) / 2
accumulation_update(2, 5) = grad(2, 5) + (mu_t * accumulation_mean)
连接(2,5)的累积更新计算现在按以下方式计算:

accumulation = self.get_slot(var, "a")
accumulation_means = # Code to calculate all mean values for all neurons
accumulation_update = grad + (mu_t * accumulation_means) # Use the means for the accumulation_update
accumulation_mean = (accumulation(2, 5) + accumulation(3, 5)) / 2
accumulation_update(2, 5) = grad(2, 5) + (mu_t * accumulation_mean)
每个连接的计算方法相同:

这里是随机梯度下降的python实现:

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

from tensorflow.python.framework import ops
from tensorflow.python.ops import control_flow_ops
from tensorflow.python.ops import math_ops
from tensorflow.python.ops import state_ops
from tensorflow.python.training import optimizer


class SGDmomentum(optimizer.Optimizer):
    def __init__(self, learning_rate=0.001, momentum_term=0.9, use_locking=False, name="SGDmomentum"):
        super(SGDmomentum, self).__init__(use_locking, name)
        self._lr = learning_rate
        self._mu = momentum_term

        self._lr_t = None
        self._mu_t = None

    def _create_slots(self, var_list):
        for v in var_list:
            self._zeros_slot(v, "a", self._name)

    def _apply_dense(self, grad, var):
        lr_t = math_ops.cast(self._lr_t, var.dtype.base_dtype)
        mu_t = math_ops.cast(self._mu_t, var.dtype.base_dtype)
        accumulation = self.get_slot(var, "a")

        accumulation_update = grad + (mu_t * accumulation)
        accumulation_t = state_ops.assign(accumulation, accumulation_update, use_locking=self._use_locking)

        var_update = lr_t * accumulation_t
        var_t = state_ops.assign_sub(var, var_update, use_locking=self._use_locking)

        return control_flow_ops.group(*[var_t, accumulation_t])

    def _prepare(self):
        self._lr_t = ops.convert_to_tensor(self._lr, name="learning_rate")
        self._mu_t = ops.convert_to_tensor(self._mu, name="momentum_term")
我正在测试的神经网络(MNIST):

如何在现有MWE代码中实现所述“累积”值的平均值?


作为旁注:

MWE不是我的真实生活场景。这只是一个简单的例子来解释和解决我试图解决的问题

我在Python中编写优化器,因为我不能在Windows上构建TyoSoFrand,因此无法编译C++文件。我确实花了很多时间尝试在Windows上构建,我不能再浪费更多的时间了。python中的优化器对我来说已经足够了,因为我目前正在进行原型设计


我不熟悉tensorflow和python。我在文档中找不到有关此主题的任何内容。把我和一个消息来源联系起来会很好。此外,张量的内部结构对我来说是无法理解的,我在尝试时得到的错误信息对我来说是无法理解的。在解释某事时请记住这一点。

我们以神经元2,3,4,5为例来计算新动量。我们忽略偏见,只考虑权重:

我们使用W作为权重矩阵,G作为W的相应梯度,M作为相应动量矩阵,{\bm{M}}是平均矩阵

因此,新动力的更新非常重要

我更改了您提出的SGDmomentum类中的一些代码,并在MNIST示例上无误地运行了它,我认为您已经这样做了

def _apply_dense(self, grad, var):
    lr_t = math_ops.cast(self._lr_t, var.dtype.base_dtype)
    mu_t = math_ops.cast(self._mu_t, var.dtype.base_dtype)
    accumulation = self.get_slot(var, "a")

    param_dims = len(accumulation.get_shape().as_list())
    if param_dims == 2:  # fc layer weights
        accumulation_mean = tf.reduce_mean(accumulation, axis=1, keep_dims=True)
    elif param_dims == 1:  # biases
        accumulation_mean = accumulation
    else:  # cnn? or others
        # TODO: improvement
        accumulation_mean = accumulation

    accumulation_update = grad + (mu_t * accumulation_mean)  # broadcasting is supported by tf.add()
    accumulation_t = state_ops.assign(accumulation, accumulation_update, use_locking=self._use_locking)

    var_update = lr_t * accumulation_t
    var_t = state_ops.assign_sub(var, var_update, use_locking=self._use_locking)

    return control_flow_ops.group(*[var_t, accumulation_t])
培训方面,

with tf.name_scope('train'):
    train_step = SGDmomentum(FLAGS.learning_rate, 0.9).minimize(cross_entropy)
    # train_step = tf.train.AdamOptimizer(FLAGS.learning_rate).minimize(
    #     cross_entropy)
目前,该算法在MNIST上的收敛速度不如传统的动量SGD

至于额外的阅读资料,我不知道斯坦福CS231n是否能帮助你和我。也许你已经知道了

如果你仍然对梯度张量的矩阵结构感到困惑,那么试着接受它,因为这里矩阵和单个标量几乎没有区别


我在这里所做的只是将您问题中每个
累加更新的计算转换为矩阵形式。

不清楚您想要实现什么,总结为1-2句话?不清楚您计划如何使用这些累加值。因此,您的想法是用另一种形式的动力?在新算法中,一个变量
x
的累加(新形式的动量)是与
x
具有相同输出神经元的所有变量累加的平均值。如果我对你的算法的理解是正确的,那么假设我们已经得到了传统的动量(一个与权重矩阵形状相同的矩阵),那么你所期望的
x
的累积就是
x
同一行中所有元素的平均值。是吗?@Seven我不知道你说的“x的同一行”是什么意思?你说台词是什么意思?对不起。。。传统动量矩阵中同一行的
x
中的所有元素。你的答案让我很困惑。对我来说,梯度张量有一个像你展示的矩阵一样的结构,这是新的。您是否有此信息的来源,以及您将如何在实际的tensorflow优化器(我的问题中的MWE)中使用此解决方案?在实现中,梯度张量具有相同的形状,因此可以轻松执行张量加法,并且每个元素对应于权重矩阵中变量的计算梯度。对于MWE,
accumulation=tf.reduce_平均值(accumulation,axis=1,keepdims=True)
accumulation_更新=