【发布时间】:2019-07-11 10:26:52
【问题描述】:
我正在尝试使用 TensorFlow Keras API 实现多实例学习模型。假设输入张量形状为(None, 18, 10, 300),我需要使用submodel 和axis=1 进行多实例学习。因此,submodel 的输入应该是(None, 10, 300)。假设单个submodel 的输出张量的形状是(None, 100),然后将submodels 的输出连接起来,从而创建输出形状(None, 18, 100)。
我用两种方式实现了这个机制,它们在功能上应该是相等的,但是,在训练模型时,第二个实现的准确率比第一个实现高 20%(尽管两者都不够好)。我想知道这两种实现之间是否存在功能差异?如果这两个实现都不是我的意思,你能给出一个正确的实现吗?
实现1.该实现用kerasLambda层拆分输入张量,执行submodel,在axis=1中扩展结果维度,然后将结果沿axis=1连接起来。
def get_branch_model(input_shape, submodel, args={}):
model_input = tf.keras.Input(input_shape)
sliced_inputs = [tf.keras.layers.Lambda(lambda x: x[:,i])(model_input)
for i in range(input_shape[0])]
sub_instance = submodel(**args)
branch_models = [sub_instance(sliced_inputs[i]) for i in range(input_shape[0])]
expand_layer = tf.keras.layers.Lambda(lambda x: tf.keras.backend.expand_dims(x, axis=1))
expanded_outputs = [expand_layer(branch_models[i]) for i in range(input_shape[0])]
concated_layer = tf.keras.layers.Concatenate(axis=1)(expanded_outputs)
return tf.keras.Model(model_input, concated_layer)
实现2.本实现使用tf.slice分割输入张量,执行submodel,在axis=1中扩展结果的维度,然后将结果沿axis=1连接起来。
def __get_filter_layer(total_dim, target_dim, index):
def tensor_filter(tensor_in):
nonlocal index
begin = [0 if i != target_dim else index for i in range(total_dim)]
size = [-1 if i != target_dim else 1 for i in range(total_dim)]
return tf.squeeze(tf.slice(tensor_in, begin, size), axis=target_dim)
return tf.keras.models.Sequential([
tf.keras.layers.Lambda(tensor_filter)
])
def get_branch_model(input_shape, branch_index, output_shape, submodel, args={}):
model_input = tf.keras.Input(input_shape)
sliced_inputs = [__get_filter_layer(len(input_shape) + 1, branch_index, i)(model_input)
for i in range(input_shape[branch_index - 1])]
sub_instance = submodel(**args)
branch_models = [sub_instance(sliced_inputs[i])
for i in range(input_shape[branch_index - 1])]
expand_layer = tf.keras.layers.Lambda(lambda x: tf.keras.backend.expand_dims(x, axis=1))
expanded_outputs = [expand_layer(branch_models[i]) for i in range(input_shape[0])]
concated_layer = tf.keras.layers.Concatenate(axis=1)(expanded_outputs)
return tf.keras.Model(model_input, concated_layer)
参数
input_shape的输入是(18, 10, 300),branch_index是1。submodel是Sequential模型,如tf.keras.Sequential([tf.keras.layers.Dense(...)])。
【问题讨论】:
标签: python tensorflow keras nlp