当我尝试在Tensorflow中使用Sequential API和Functional API来应用相同的简单嵌入函数时,我看到了不同的结果。
结果如下:
import numpy as np
import tensorflow as tf
from tensorflow import keras
from keras import layers
inputs = np.random.randint(0, 99, [32, 100, 1])
myLayer = layers.Embedding(input_dim = 100, output_dim = 8)
# Sequential API
sm = keras.Sequential()
sm.add(myLayer)
sm_out = sm(inputs)
sm_out.shape # Shape of sm_out is: TensorShape([32, 100, 8])
# Functional API
fm_out = myLayer(inputs)
fm_out.shape # Shape of fm_out is: TensorShape([32, 100, 1, 8])
它是有意的还是一个错误?
1条答案
按热度按时间kx7yvsdv1#
首先,你的第二个调用不是函数API调用,你需要把你的层输出(用
tf.keras.layers.Input
) Package 在tf.keras.models.Model
中,这样才是函数API调用。其次,当您调用顺序模型时,它足够智能地检测到最后一个维度是1,并在查找嵌入时忽略它(我不确定具体是在哪里处理的,也许其他人可以指出)。因此,当你传入一个
[32, 100, 1]
的Tensor时,嵌入层真正看到的是一个[32, 100]
大小的数组。在查找之后,被转换成[32, 100, 8]
大小的Tensor。在第二次调用中,当直接调用模型时,它不会这样做,所以它只是将
[32, 100, 1]
大小的输入转换为[32, 100, 1, 8]
大小的输入。如果将
inputs
形状设置为[32, 100]
或[32, 100, 2]
(最后一个维度!= 1),则可以从这两种方法中获得相同的结果。我想这里的教训是总是使用
input_shape
参数(到Sequential
模型的第一层)来防止这种意外的行为。