自定义权重初始化 tensorflow tf.layers.dense
Posted
技术标签:
【中文标题】自定义权重初始化 tensorflow tf.layers.dense【英文标题】:Custom weight initialization tensorflow tf.layers.dense 【发布时间】:2018-09-05 04:37:32 【问题描述】:我正在尝试将自定义初始化程序设置为 tf.layers.dense
,在此我使用已有的权重矩阵初始化 kernel_initializer
。
u_1 = tf.placeholder(tf.float32, [784, 784])
first_layer_u = tf.layers.dense(X_, n_params, activation=None,
kernel_initializer=u_1,
bias_initializer=tf.keras.initializers.he_normal())
这是抛出错误说ValueError: If initializer is a constant, do not specify shape.
将占位符分配给kernel_initializer
是否有问题,还是我遗漏了什么?
【问题讨论】:
kernel_initializer 是“权重矩阵的初始化函数函数”,所以在里面放一个占位符是没有意义的 @JonathanR 我可以传递一个numpy
数组吗?
【参考方案1】:
至少有两种方法可以做到这一点:
1 创建您自己的图层
W1 = tf.Variable(YOUR_WEIGHT_MATRIX, name='Weights')
b1 = tf.Variable(tf.zeros([YOUR_LAYER_SIZE]), name='Biases') #or pass your own
h1 = tf.add(tf.matmul(X, W1), b1)
2 使用tf.constant_initializer
init = tf.constant_initializer(YOUR_WEIGHT_MATRIX)
l1 = tf.layers.dense(X, o, kernel_initializer=init)
【讨论】:
我明白了,我想用tf.layers.dense
来实现这个功能
我更新了答案,向您展示如何使用密集层实现它
你好。我在密集层上使用 tf.constant_initializer(YOUR_WEIGHT_MATRIX, dtype=tf.float32) 来初始化我的权重,但是,对于 300 万个权重,初始化需要 5 秒。使用您的方法大约需要 4.2 秒。有更快的方法吗?我只需要评估一次训练集并保存错误,而这需要将近 50% 的时间,只是为了构建网络、测试并删除它。
如果你使用方法 2 (constant_initializer) 是否更新了 YOUR_WEIGHT_MATRIX 的权重?【参考方案2】:
我认为您可以定义自己的初始化函数。该函数需要接受 3 个参数:shape
、dtype
和 partition_info
。它应该返回一个tf.Tensor
,它将用于初始化权重。既然你有一个numpy
数组,我认为你可以使用tf.constant
来创建这个张量。例如:
def custom_initializer(shape_list, dtype, partition_info):
# Use np.ones((7, 3)) as an example
return tf.constant(np.ones((7, 3)))
然后您可以将其传递给kernel_initializer
。如果尺寸都匹配,它应该可以工作。我在gist 上放了一个例子,使用Estimator
构建模型并使用LoggingTensorHook
记录dense/kernel
在每个步骤中。您应该能够看到权重已正确启动。
编辑:
我刚刚发现使用tf.constant_initializer
会更好。它用于tensorflow guide。你可以kernel_initializer=tf.constant_initializer(np.ones((7, 3)))
。
【讨论】:
不会让内核成为tf.constant
使其无法学习——总是等于它的初始值吗?我怀疑这是 OP 的意图......
@mikkola 我刚刚发现 TensorFlow 中有一个 tf.constant_initializer
可用(更新了我的答案)。如果我理解正确,它用于初始化内核但不会“锁定”它。我只有间接证据:1)我的要点示例表明内核确实每一步都发生了变化。 2)tf.constant_initializer
在guide 中使用,我认为该示例不打算使bias
保持不变。
是的,使用tf.constant_initializer
是正确的方法。
@mikkola 需要明确的是,tf.constant_initializer
绝对是更好的方法。但是根据source,tf.constant_initializer
返回一个可调用的Constant
类,它实际上返回tf.constant
。如果人们想做的事情超出了tf.constant_initializer
的能力,custom_initializer
是有效的。
我正在使用它,但是,它需要将近 5 秒来初始化一个 300 万个权重网络。有更快的方法吗?顺便说一句:接受的答案需要 4 秒,仍然太多:它消耗了我算法 50% 的时间。【参考方案3】:
乔纳森的回答在 conv 上也对我有用 -
kernel_in = np.random.uniform(100,1000,(filter_width, filter_height, input_channels, output_channels)).astype(np.float32)
init = tf.constant_initializer(kernel_in)
def model(x):
x = tf.layers.conv2d(x, filters=3, kernel_size=1, strides=1, kernel_initializer=init)
【讨论】:
以上是关于自定义权重初始化 tensorflow tf.layers.dense的主要内容,如果未能解决你的问题,请参考以下文章