Keras Embedding层详解
请注意,以下内容对应 Keras2.0 版本,并且所有内容都可以在这里找到。值得注意的是,Embedding层只能作为模型的第一层。
函数原型
def keras.layers.Embedding(input_dim, output_dim,
embeddings_initializer='uniform',
embeddings_regularizer=None,
activity_regularizer=None,
embeddings_constraint=None,
mask_zero=False,
input_length=None)
各参数解释如下:
- input_dim:大或等于0的整数,字典长度,即输入数据最大下标+1。比如ID类特征取值为0到5,则input_dim应该设为6
- output_dim:大于0的整数,代表全连接嵌入的维度
- embeddings_initializer: 嵌入矩阵的初始化方法,为预定义初始化方法名的字符串,或用于初始化权重的初始化器。其他初始化参考initializers。
- embeddings_regularizer: 嵌入矩阵的正则项,为Regularizer对象
- embeddings_constraint: 嵌入矩阵的约束项,为Constraints对象
- mask_zero:布尔值,确定是否将输入中的‘0’看作是应该被忽略的‘填充’(padding)值,该参数在使用递归层处理变长输入时有用。设置为True的话,模型中后续的层必须都支持masking,否则会抛出异常。如果该值为True,则下标0在字典中不可用,input_dim应设置为|vocabulary| + 1。
- input_length:当输入序列的长度固定时,该值为其长度。如果要在该层后接Flatten层,然后接Dense层,则必须指定该参数,否则Dense层的输出维度无法自动推断。
处理带padding的输入
有时候会遇到不等长样本输入,对其进行padding补零之后作为输入送入Embedding层,这时候就需要活用mask_zero
字段。若令mask_zero=True
,则注意input_dim
应该加一,例如原本ID类取值为0到5,为了实现padding,ID取值范围变成1到6,则此时input_dim=6+1=7
。
下面给出一个例子,我们准备了四个ID列表型样本,经过了padding补零到长度4,为了方便展示,我们让所有非零ID相同。在Embedding层中设置mask_zero=True
,然后调用自定义的MeanPooling层(见这里)。如果masking起作用,则输出的result
应该是一个4x3矩阵,且所有行向量相同。
# 四个ID列表型样本,经过padding
ID_seq0 = [1, 0, 0, 0]
ID_seq1 = [1, 1, 0, 0]
ID_seq2 = [1, 1, 1, 0]
ID_seq3 = [1, 1, 1, 1]
data = np.array([ID_seq0, ID_seq1, ID_seq2, ID_seq3])
model = Sequential()
model.add(Embedding(5, 3, mask_zero=True))
model.add(MyMeanPool())
result = model.predict(data)
print result
输出结果如下,这些数值都是Embedding层随机生成的权值而已。
[[-0.00347356 -0.03284906 -0.03016986]
[-0.00347356 -0.03284906 -0.03016986]
[-0.00347356 -0.03284906 -0.03016986]
[-0.00347356 -0.03284906 -0.03016986]]
那么,如果设置mask_zero=False
,那这四个行向量理论上应该各不相同,因为没有masking的作用,meanpooling是对整个序列做的。
model = Sequential()
model.add(Embedding(5, 3, mask_zero=False))
model.add(MyMeanPool())
result = model.predict(data)
print result
输出结果如下:
[[ 0.03359272 0.03033846 -0.00561328]
[ 0.03674956 0.02729746 -0.0023707 ]
[ 0.03990639 0.02425646 0.00087187]
[ 0.04306323 0.02121546 0.00411445]]