import tensorflow as tf
print(tf.version.VERSION)
toy_data = {'movie': [[0], [1], [0], [1]], 'user': [[10], [12], [12], [10]]}
dataset = tf.data.Dataset.from_tensor_slices(toy_data).batch(2)
for x in dataset:
print(x)
def make_model():
inp_movie = tf.keras.Input(shape=(1,))
inp_user = tf.keras.Input(shape=(1,))
movie_embedding = tf.keras.layers.Dense(
units=40, activation=tf.keras.layers.Activation("relu"))(inp_movie)
user_embedding = tf.keras.layers.Dense(
units=40, activation=tf.keras.layers.Activation("relu"))(inp_user)
combined = tf.concat([movie_embedding, user_embedding], 1)
output = tf.keras.layers.Dense(
units=1, activation=tf.keras.layers.Activation("sigmoid"))(combined)
model = tf.keras.Model(inputs=[inp_movie, inp_user], outputs=output)
return model
model = make_model()
for x in dataset:
print(model(x))
这行得通。请注意,您传递给tf.keras.Model 调用的inputs 参数的可迭代对象必须按照与您将使用的字典相同的顺序进行排序,字典按其键排序,movie 然后user。所以使用inputs={'a': inp_movie, 'b': inp_user} 或inputs={'movie': inp_movie, 'user': inp_user} 也可以,而inputs=[inp_user, inp_movie] 则不行。
您可以使用此代码来测试这种交互:
def make_test_model():
inp_movie = tf.keras.Input(shape=(1,))
inp_user = tf.keras.Input(shape=(1,))
model = tf.keras.Model(inputs={'a': inp_movie, 'b': inp_user}, outputs=inp_movie)
return model
def make_test_model_2():
inp_movie = tf.keras.Input(shape=(1,))
inp_user = tf.keras.Input(shape=(1,))
model = tf.keras.Model(inputs=[inp_user, inp_movie], outputs=inp_movie)
return model
model_test = make_test_model()
model_test_2 = make_test_model_2()
for x in dataset:
print(model_test(x))
for x in dataset:
print(model_test_2(x))
您还可以使用字典的键命名Input 层,并作为inputs 参数提供按层名称排序的Input 层列表。这允许您在模型中添加或删除输入,而不必担心每次都重写您的 inputs 参数。所以这就是我要做的:
def make_model_2():
input_list = []
inp_movie = tf.keras.Input(shape=(1,), name='movie')
input_list.append(inp_movie)
inp_user = tf.keras.Input(shape=(1,), name='user')
input_list.append(inp_user)
movie_embedding = tf.keras.layers.Dense(
units=40, activation=tf.keras.layers.Activation("relu"))(inp_movie)
user_embedding = tf.keras.layers.Dense(
units=40, activation=tf.keras.layers.Activation("relu"))(inp_user)
combined = tf.concat([movie_embedding, user_embedding], 1)
output = tf.keras.layers.Dense(
units=1, activation=tf.keras.layers.Activation("sigmoid"))(combined)
input_list.sort(key=lambda inp: inp._keras_history.layer.name)
model = tf.keras.Model(inputs=input_list, outputs=output)
return model
这是一种测试它是否有效的方法:
def make_test_model_3(boolean):
input_list = []
inp_movie = tf.keras.Input(shape=(1,), name='movie')
inp_user = tf.keras.Input(shape=(1,), name='user')
if boolean:
input_list.append(inp_movie)
input_list.append(inp_user)
else:
input_list.append(inp_user)
input_list.append(inp_movie)
input_list.sort(key=lambda inp: inp._keras_history.layer.name)
model = tf.keras.Model(inputs=input_list, outputs=inp_movie)
return model
model_test_3_0= make_test_model_3(True)
model_test_3_1= make_test_model_3(False)
for x in dataset:
print(model_test_3_0(x))
for x in dataset:
print(model_test_3_1(x))
编辑 2020-02-20:
make_model 不适用于 tf2.1.0,但 make_model_2 仍然可以。我在 GitHub 上提出了一个关于这种向后不兼容的问题。 Here 是链接,如果您有兴趣。回想一下,如果您打算继续使用 tf2.0.0,这两个函数都可以工作。