函数的特点是复用,可以多次调用,这里的函数式编程,也是一样,一个层定义了一次,可以多次复用,这个很好理解:
# 定义一次 lstm = layers.LSTM(32) left_input = Input(shape=(None, 128)) # 使用 left_output = lstm(left_input) right_input = Input(shape=(None, 128)) # 使用 right_output = lstm(right_input) merged = layers.concatenate([left_output, right_output], axis=-1) predictions = layers.Dense(1, activation='sigmoid')(merged) model = Model([left_input, right_input], predictions)这是层的复用,扩大范围,模型也可以是输出向量,因此模型也是可以当做一个层的,这与前面文章的预定义网络有异曲同工之妙:
# Xception 是一个网络 xception_base = applications.Xception(weights=None, include_top=False) left_input = Input(shape=(250, 250, 3)) right_input = Input(shape=(250, 250, 3)) left_features = xception_base(left_input) right_input = xception_base(right_input) merged_features = layers.concatenate([left_features, right_input], axis=-1) 总结本来我的每篇文章都控制在 1000 字左右,但是本篇文章实在是有点收不住了,他们之间的联系太紧密了,没办法,那就算一篇长文。其中的内容是一脉相承的,主要记住一点:因为这种函数式的 API,所以就可以构建复杂的网络结构,而不仅仅是单纯的网络层的堆叠,基于此,可以构建出多输入、多输出以及各种情况复杂的网络,并且因为这种函数式的特点,因此有各种复用的情况。