在 Tensorflow 2.x 中,双向层默认的 merge_mode 为
concat
,如下所示。
tf.keras.layers.Bidirectional(
layer, merge_mode='concat', weights=None, backward_layer=None, **kwargs
)
但是,为什么
fb_out
不是 f_out
和 b_out
的串联,如下面的测试代码所示?
>>> import copy
>>> inputs = tf.random.normal([1, 5, 10])
>>> forward_layer = LSTM(1, return_sequences=True)
>>>
>>> backward_layer = LSTM(1, return_sequences=True, go_backwards=True)
>>>
>>> f_copy = copy.deepcopy(forward_layer)
>>>
>>> b_copy = copy.deepcopy(backward_layer)
>>>
>>> fb = Bidirectional(forward_layer, backward_layer=backward_layer)
>>>
>>> f_out = f_copy(inputs)
>>> b_out = b_copy(inputs)
>>>
>>> fb_out = fb(inputs)
>>> f_out
<tf.Tensor: shape=(1, 5, 1), dtype=float32, numpy=
array([[[ 0.11658007],
[-0.0704283 ],
[-0.17762654],
[ 0.0304627 ],
[-0.19515464]]], dtype=float32)>
>>> b_out
<tf.Tensor: shape=(1, 5, 1), dtype=float32, numpy=
array([[[-0.18902111],
[-0.00259904],
[ 0.23515013],
[ 0.22268802],
[ 0.4035125 ]]], dtype=float32)>
>>> fb_out
<tf.Tensor: shape=(1, 5, 2), dtype=float32, numpy=
array([[[ 0.21822408, 0.07384206],
[ 0.0036808 , -0.0700341 ],
[-0.11105614, -0.38493848],
[-0.13826807, -0.12408008],
[ 0.05806111, -0.05853282]]], dtype=float32)>
这个回复似乎有点晚了,但我希望它能对其他人有所帮助......
好吧,keras 中的双向层的行为类似于合并(求和/连接等)两个常规 LSTM,但它不会负责初始化权重,这就是为什么你有不同的输出。
例如,您有一个简单的输入,每个步骤有 3 个时间戳和 2 个特征。
import tensorflow as tf
unit = 1
dim = 2
timestamp = 3
inputs = tf.random.normal([1, timestamp, dim])
我们设置三层:前向 LSTM、后向 LSTM 和双向层。
forward_layer = tf.keras.layers.LSTM(unit, return_sequences=True)
backward_layer = tf.keras.layers.LSTM(unit, return_sequences=True,
go_backwards=True)
fb = tf.keras.layers.Bidirectional(forward_layer, backward_layer=backward_layer)
forward_layer.build((None, timestamp, dim))
backward_layer.build((None, timestamp, dim))
fb.build((None, timestamp, dim))
只需检查初始化的权重,您就会看到双向层为前向部分初始化了一组新的权重,但为后向部分使用了相同的权重集。如果相应地重置权重,您最终可以获得相同的结果。
a, b, c = forward_layer.get_weights()
a1, b1, c1 = backward_layer.get_weights()
a2, b2, c2 , a3, b3, c3 = fb.get_weights()
fb.set_weights([a, b, c, a1, b1, c1])
forward_layer(inputs)
array([[[ 0.0342516 ],
[ 0.0213093 ],
[-0.06462004]]], dtype=float32)>
backward_layer(inputs)
array([[[-0.08782256],
[-0.16806953],
[-0.17708375]]], dtype=float32)>
fb(inputs)
array([[[ 0.0342516 , -0.17708375],
[ 0.0213093 , -0.16806953],
[-0.06462004, -0.08782256]]], dtype=float32)>