让我们考虑一个包含6列和10行的示例数据集。
在这3列中是数字,其余3列是分类变量。
分类列被转换成大小为10x3的多个热编码数组。
我有我想要预测的目标列也是可以再次获取3个可能值的分类变量。此列是一个热编码列。
现在我想使用这个多热编码数组作为嵌入层的输入。嵌入层应该输出2个单位。
然后我想使用数据集的3个数字列和嵌入层的2个输出单元,总共5个单元作为隐藏层的输入。
这就是我被卡住的地方。我不知道如何使用tensorflow keras桥接嵌入层和其他特性列,也不知道如何传递嵌入层和其他2个单元的输入。
我已经用谷歌搜索过了我尝试了下面的代码,但仍然得到了错误。
我想tf.keras包中没有合并层。
在此方面的任何帮助都将不胜感激。
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
最佳答案
这种“合并”模式与序列模型不兼容我认为使用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])
在连接嵌入层之前,应该先将其输出展平,或者数字数据应该具有兼容的形状和至少三维。
在层之后定义功能模型。输入和输出可以是单层的,也可以是多层的
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