首页 文章

如何在优化器中获得偏差和神经元权重?

提问于
浏览
4

在TensorFlow优化器(python)中,方法 apply_dense 确实被调用神经元权重(层连接)和偏置权重,但我想在此方法中使用两者 .

def _apply_dense(self, grad, weight):
    ...

例如:一个完全连接的神经网络,其中两个隐藏层有两个神经元,每个神经网络都有偏差 .

Neural network example

如果我们看一下第2层,我们会在 apply_dense 中调用神经元权重:

neuron weights

并呼吁偏差权重:

bias weights

但是我要么在 apply_dense 的一次调用中需要两个矩阵,要么像这样需要一个权重矩阵:

all weights from one layer

X_2X_4,B_1X_4,......只是两个神经元之间连接权重的表示法 . 因此B_1X_4只是B_1和X_4之间权重的占位符 .

这该怎么做?

MWE

对于这里的最小工作示例,具有动量的随机梯度下降优化器实现 . 对于每一层,来自其他神经元的所有传入连接的动量都减少到平均值(参见ndims == 2) . 我需要的不仅是来自神经元连接的动量值的平均值,还来自输入偏置连接的平均值(如上所述) .

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

import tensorflow as tf
from tensorflow.python.training import optimizer


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

        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, weight):
        learning_rate_t = tf.cast(self._lr_t, weight.dtype.base_dtype)
        mu_t = tf.cast(self._mu_t, weight.dtype.base_dtype)
        momentum = self.get_slot(weight, "a")

        if momentum.get_shape().ndims == 2:  # neuron weights
            momentum_mean = tf.reduce_mean(momentum, axis=1, keep_dims=True)
        elif momentum.get_shape().ndims == 1:  # bias weights
            momentum_mean = momentum
        else:
            momentum_mean = momentum

        momentum_update = grad + (mu_t * momentum_mean)
        momentum_t = tf.assign(momentum, momentum_update, use_locking=self._use_locking)

        weight_update = learning_rate_t * momentum_t
        weight_t = tf.assign_sub(weight, weight_update, use_locking=self._use_locking)

        return tf.group(*[weight_t, momentum_t])

    def _prepare(self):
        self._lr_t = tf.convert_to_tensor(self._lr, name="learning_rate")
        self._mu_t = tf.convert_to_tensor(self._mu, name="momentum_term")

对于简单的神经网络:https://raw.githubusercontent.com/aymericdamien/TensorFlow-Examples/master/examples/3_NeuralNetworks/multilayer_perceptron.py(仅将优化器更改为自定义SGDmomentum优化器)

1 回答

  • 1

    更新:我现在尝试给出一个更好的答案(或至少一些想法),因为我对你的目标有一些了解,但是,正如你在评论中所建议的那样,在TensorFlow中可能没有绝对可行的方法 .

    由于TF是一般计算框架,因此没有好的方法来确定模型中存在哪些权重和偏差对(或者它是否完全是神经网络) . 以下是我能想到的问题的一些可能方法:

    • 注释张量 . 这可能不实用,因为您已经说过您无法控制模型,但一个简单的选择是为张量添加额外的属性以表示权重/偏差关系 . 例如,您可以执行类似 W.bias = BB.weight = W 的操作,然后在 _apply_dense 中检查 hasattr(weight, "bias")hasattr(weight, "weight") (在这个意义上可能会有一些更好的设计) .

    • 您可以查看构建在TensorFlow之上的一些框架,您可以在其中获得有关模型结构的更好信息 . 例如,Keras是一个基于层的框架,它实现了自己的optimizer classes(基于TensorFlow或Theano) . 我不太熟悉代码或它的可扩展性,但可能你有更多的工具可供使用 .

    • 自己从优化器中检测网络结构 . 这很复杂,但理论上可行 . 从丢失张量传递给优化器,应该可以在模型图中"climb up"到达其所有节点(取张量的 .op 和操作的 .inputs ) . 您可以使用变量检测张量乘法和加法,并跳过其他所有内容(激活,损失计算等)来确定网络的结构;如果模型与您的期望不符(例如,没有乘法或没有后续添加的乘法),则可以引发异常,指示您的优化器不能用于该模型 .


    Old answer, kept for the sake of keeping.

    我'm not 100% clear on what you are trying to do, so I'我不确定这是否真的能回答你的问题 .

    假设您有一个密集层将大小为M的输入转换为大小为N的输出 . 根据您所显示的惯例,您将拥有N×M权重矩阵W和N大小的偏向量B.然后,大小为M的输入向量X(或一组大小为M×K的输入)将由层处理为W·XB,然后应用激活函数(在批处理的情况下,添加将是"broadcasted"操作) . 在TensorFlow中:

    X = ...  # Input batch of size M x K
    W = ...  # Weights of size N x M
    B = ...  # Biases of size N
    
    Y = tf.matmul(W, X) + B[:, tf.newaxis]  # Output of size N x K
    # Activation...
    

    如果你愿意,你总是可以将W和B放在一个扩展权重矩阵W *中,基本上将B作为W中的新行添加,因此W *将是(N 1)×M . 那么你只需要添加一个包含常量1的输入向量X的新元素(如果是批处理,则为新行),因此您将获得大小为N 1的X *(或批次的(N 1)×K) . 产品W *·X *将为您提供与以前相同的结果 . 在TensorFlow中:

    X = ...  # Input batch of size M x K
    W_star = ...  # Extended weights of size (N + 1) x M
    # You can still have a "view" of the original W and B if you need it
    W = W_star[:N]
    B = W_star[-1]
    
    X_star = tf.concat([X, tf.ones_like(X[:1])], axis=0)
    Y = tf.matmul(W_star, X_star)  # Output of size N x K
    # Activation...
    

    现在,您可以一起计算权重和偏差的渐变和更新 . 这种方法的一个缺点是,如果你想应用正则化,那么你应该小心只将它应用于矩阵的权重部分,而不是在偏见上 .

相关问题