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

标签 python tensorflow

在 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优化器)

最佳答案

更新:既然我对您的目标有了一些了解,我会尝试给出更好的答案(或至少一些想法),但是,正如您在评论中建议的那样,可能在 TensorFlow 中执行此操作并非万无一失。

由于 TF 是一个通用的计算框架,因此没有很好的方法来确定模型中有哪些权重和偏差对(或者它是否是一个神经网络)。以下是我能想到的解决该问题的一些可能方法:

  • 注释张量。这可能不切实际,因为您已经说过您无法控制模型,但一个简单的选择是向张量添加额外的属性以表示权重/偏差关系。例如,您可以执行类似 W.bias = BB.weight = W 的操作,然后在 _apply_dense 中检查 hasattr (weight, "bias")hasattr(weight, "weight")(在这个意义上可能会有一些更好的设计)。
  • 您可以研究一些构建在 TensorFlow 之上的框架,您可能会在其中获得有关模型结构的更好信息。例如,Keras是一个基于层的框架,实现了自己的 optimizer classes (基于 TensorFlow 或 Theano)。我不太熟悉代码或其可扩展性,但您可能有更多工具可以使用。
  • 通过优化器自行检测网络结构。这相当复杂,但理论上是可行的。从传递给优化器的损失张量,应该可以在模型图中“向上爬”以到达其所有节点(采用张量的 .op.inputs 操作)。您可以使用变量检测张量乘法和加法,并跳过其他一切(激活、损失计算等)以确定网络的结构;如果模型不符合您的预期(例如,没有乘法或乘法没有后来的加法),您可以引发异常,表明您的优化器不能用于该模型。

旧答案,为了保存而保存。

我不是 100% 清楚你想做什么,所以我不确定这是否真的回答了你的问题。

假设您有一个密集层,将大小为 M 的输入转换为大小为 N 的输出。根据您展示的惯例,您将有一个 N × M 权重矩阵 W 和一个 N-大小的偏置向量 B。然后,大小为 M 的输入向量 X(或大小为 M × K 的一批输入)将被层处理为 W · X + B,然后应用激活函数(在批处理的情况下,相加会是一个“广播”操作)。在 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...

如果你愿意,你总是可以把 WB 放在一个扩展的权重矩阵 W* 中,基本上是添加 B 作为 W 中的新行,因此 W* 将是 (N + 1) × M。然后,您只需向输入向量 X 添加一个新元素,其中包含常量 1(如果是批处理,则添加一个新行),这样您就可以得到 X*大小 N + 1(或 (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...

现在您可以一起计算权重和偏差的梯度和更新。这种方法的一个缺点是,如果您想应用正则化,那么您应该小心地将其仅应用于矩阵的权重部分,而不是偏差。

关于python - 如何在优化器中获得偏差和神经元权重?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45015709/

相关文章:

python - 不能用 mingus 演奏音符

python - 对 im2txt 微调 inception v3 时损失并没有减少

python - 在 tensorflow 中更新张量

python - 如何使用 TensorFlow 中的 Estimator 将模型存储在 `.pb` 文件中?

python - 如何在lightGBM中设置metric输出的频率?

python - 马赫制表符或行首 8 个空格

python - 如何在 tensorflow 中的张量上自定义逐元素函数?

python - Tensorflow 分类示例期间的 tf.train.get.global_step 错误

python.data.ops.dataset_ops.BatchDataset - 如何使用它来创建训练和测试数据集

python - Python中的条件计数