【问题标题】:How to use embedding layer and other feature columns together in a network using tensorflow keras如何使用 tensorflow keras 在网络中一起使用嵌入层和其他特征列
【发布时间】:2019-02-28 07:32:22
【问题描述】:

让我们考虑一个包含 6 列和 10 行的示例数据集。

在这 3 列中是数字,其余 3 列是分类变量。

分类列被转换为大小为 10x3 的多热编码数组。

我有我想要预测的目标列也是分类变量,它可以再次取 3 个可能的值。此列是一个热编码。

现在我想使用这个多热编码数组作为嵌入层的输入。嵌入层应输出 2 个单元。

然后我想使用数据集中的 3 个数字列和嵌入层的 2 个输出单元,总共 5 个单元作为隐藏层的输入。

这是我被困住的地方。我不知道如何使用 tensorflow keras 桥接嵌入层和我的其他特征列,也不知道如何为嵌入层和其他 2 个单元传递输入。

我已经用谷歌搜索过了。我尝试了以下代码,但仍然出现错误。 我猜 tf.keras 包中没有 Merge 层

对此的任何帮助将不胜感激。

        import tensorflow as tf
        from tensorflow import keras
        import numpy as np

        num_data = np.random.random(size=(10,3))
        multi_hot_encode_data = np.random.randint(0,2, 30).reshape(10,3)
        target =  np.eye(3)[np.random.randint(0,3, 10)]

        model = keras.Sequential()
        model.add(keras.layers.Embedding(input_dim=multi_hot_encode_data.shape[1], output_dim=2))
        model.add(keras.layers.Dense(3, activation=tf.nn.relu, input_shape=(num_data.shape[1],)))
        model.add(keras.layers.Dense(3, activation=tf.nn.softmax)

        model.compile(optimizer=tf.train.RMSPropOptimizer(0.01),
                      loss=keras.losses.categorical_crossentropy,
                      metrics=[keras.metrics.categorical_accuracy])

        #model.fit([multi_hot_encode_data, num_data], target)   # I get error here 

我的网络结构将是

    multi-hot-encode-input  num_data_input 
            |                   |
            |                   |
            |                   |
        embedding_layer         |
            |                   |
            |                   | 
             \                 /        
               \              / 
              dense_hidden_layer
                     | 
                     | 
                  output_layer 

【问题讨论】:

  • 您尝试将它们连接起来吗?
  • @PMende 嗨.. 不确定连接是如何工作的。但我试过了,我又遇到了无效的语法错误。请在这里举个例子。
  • 有谁知道上面的代码如何使用 tf.keras.Concatenate。

标签: python tensorflow keras


【解决方案1】:

这种“合并”模式与顺序模型不兼容。我认为使用带有keras.Model 而不是keras.Sequential (short explanation of main differences) 的功能性keras API 更容易:

import tensorflow as tf
from tensorflow import keras
import numpy as np

num_data = np.random.random(size=(10,3))
multi_hot_encode_data = np.random.randint(0,2, 30).reshape(10,3)
target =  np.eye(3)[np.random.randint(0,3, 10)]

# Use Input layers, specify input shape (dimensions except first)
inp_multi_hot = keras.layers.Input(shape=(multi_hot_encode_data.shape[1],))
inp_num_data = keras.layers.Input(shape=(num_data.shape[1],))
# Bind nulti_hot to embedding layer
emb = keras.layers.Embedding(input_dim=multi_hot_encode_data.shape[1], output_dim=2)(inp_multi_hot)  
# Also you need flatten embedded output of shape (?,3,2) to (?, 6) -
# otherwise it's not possible to concatenate it with inp_num_data
flatten = keras.layers.Flatten()(emb)
# Concatenate two layers
conc = keras.layers.Concatenate()([flatten, inp_num_data])
dense1 = keras.layers.Dense(3, activation=tf.nn.relu, )(conc)
# Creating output layer
out = keras.layers.Dense(3, activation=tf.nn.softmax)(dense1)
model = keras.Model(inputs=[inp_multi_hot, inp_num_data], outputs=out)

model.compile(optimizer=tf.train.RMSPropOptimizer(0.01),
              loss=keras.losses.categorical_crossentropy,
              metrics=[keras.metrics.categorical_accuracy])
  • 您可以在连接之前将嵌入层的输出展平,或者 numeric_data 应该具有兼容的形状和至少三个维度
  • 在层之后定义功能模型。输入和输出可以是单层或可迭代的层

model.summary 的输出:

__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
input_5 (InputLayer)            (None, 3)            0                                            
__________________________________________________________________________________________________
embedding_2 (Embedding)         (None, 3, 2)         6           input_5[0][0]                    
__________________________________________________________________________________________________
flatten (Flatten)               (None, 6)            0           embedding_2[0][0]                
__________________________________________________________________________________________________
input_6 (InputLayer)            (None, 3)            0                                            
__________________________________________________________________________________________________
concatenate_2 (Concatenate)     (None, 9)            0           flatten[0][0]                    
                                                                 input_6[0][0]                    
__________________________________________________________________________________________________
dense (Dense)                   (None, 3)            30          concatenate_2[0][0]              
__________________________________________________________________________________________________
dense_1 (Dense)                 (None, 3)            12          dense[0][0]                      
==================================================================================================
Total params: 48
Trainable params: 48
Non-trainable params: 0
__________________________________________________________________________________________________

另外,它很适合:

model.fit([multi_hot_encode_data, num_data], target)
Epoch 1/1
10/10 [==============================] - 0s 34ms/step - loss: 1.0623 - categorical_accuracy: 0.3000

【讨论】:

  • 我认为“inp_num_data = keras.layers.Input(shape=(multi_hot_encode_data.shape[1],))”这一行应该写成“inp_num_data = keras.layers.Input(shape=( num_data.shape[1],))" 如果我​​错了,请纠正我。
  • @shakthydoss 完全是,我的错。固定!
  • 我的嵌入层正在使用 mask_zero ,但是我不能在带有掩码的嵌入层上使用 Flatten 层
猜你喜欢
  • 2018-10-31
  • 1970-01-01
  • 2016-05-07
  • 1970-01-01
  • 2020-10-27
  • 2017-12-12
  • 1970-01-01
  • 2018-04-28
相关资源
最近更新 更多