在TensorFlow优化器(python)中,方法apply_dense
会调用神经元权重(图层连接)和偏差权重,但我想在此方法中同时使用它们。
def _apply_dense(self, grad, weight):
...
例如:一个完全连接的神经网络,其中两个隐藏层有两个神经元,每个神经网络都有偏差。
如果我们看一下第2层,我们会在apply_dense
调用神经元权重:
并要求偏见权重:
但我要么在apply_dense
的一次调用中需要两个矩阵,要么像这样需要一个权重矩阵:
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优化器)
答案 0 :(得分:1)
更新:我现在尝试给出一个更好的答案(或者至少是一些想法),因为我对你的目标有一些了解,但正如你在评论中所建议的那样,在TensorFlow中这不是绝对可靠的方式。
由于TF是一般计算框架,因此没有好的方法来确定模型中存在哪些权重和偏差对(或者它是否完全是神经网络)。以下是我能想到的问题的一些可能方法:
W.bias = B
和B.weight = W
之类的操作,然后在_apply_dense
中检查hasattr(weight, "bias")
和hasattr(weight, "weight")
(在这个意义上可能会有一些更好的设计)。.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...
如果需要,您可以随时将 W 和 B 放在一个扩展权重矩阵 W *中,基本上可以添加 B 作为 W 中的新行,因此 W *将是( N + 1)× M 。然后你只需要在包含常量1的输入向量 X 中添加一个新元素(如果是一个批处理,则为新行),这样你就可以得到 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...
现在,您可以一起计算权重和偏差的渐变和更新。这种方法的一个缺点是,如果你想应用正则化,那么你应该小心只将它应用于矩阵的权重部分,而不是偏差。