2.1.6 多输入单一输出TensorFlow编译方法(选学)
在前面内容的学习中,我们采用的是标准化的深度学习流程,即数据的准备、处理,数据的输入与计算,以及最后结果的打印。虽然在真实情况中可能会遇到各种各样的问题,但是基本步骤是不会变的。
这里存在一个非常重要的问题——在模型的计算过程中遇到多个数据输入端应该怎么处理,如图2.8所示。
图2.8 多个数据输入端
以Tensor格式的数据为例,在数据的转化部分就需要将数据进行“打包”处理,即将不同的数据按类型进行打包,例如:
输入1,输入2,输入3,标签 -> (输入1,输入2,输入3),标签
注意小括号的位置,这里将数据分成两个部分,即输入与标签两类。多输入的部分使用小括号打包在一起,形成一个整体。
下面以iris数据集为例讲解多数据输入的问题。
第一步:数据的获取与处理
从前面的介绍可以知道,iris数据集每行是一个由4个特征组合在一起表示的特征集合,此时可以人为地将其切分,即将长度为4的特征转化成一个长度为3和一个长度为1的两个特征集合,代码如下:
打印其中一条数据,一行4列的数据被拆分成2组特征,如下所示。
第二步:模型的建立
这里的数据被人为地拆分成两个部分,因此在模型的输入端也要能够对应处理两组数据的输入。
input_xs_1 = tf.keras.Input(shape=(1,), name='input_xs_1') input_xs_2 = tf.keras.Input(shape=(3,), name='input_xs_2') input_xs = tf.concat([input_xs_1,input_xs_2],axis=-1)
首先建立input_xs_1和input_xs_2作为数据的接收端,接收传递进来的数据,之后通过一个concat重新将数据组合起来,恢复成一条4特征的集合。
out = tf.keras.layers.Dense(32, activation='relu', name='dense_1')(input_xs) out = tf.keras.layers.Dense(64, activation='relu', name='dense_2')(out) logits = tf.keras.layers.Dense(3, activation="softmax",name='predictions')(out) model = tf.keras.Model(inputs=[input_xs_1,input_xs_2], outputs=logits)
对剩余部分的部分数据处理没有变化,按前文程序处理即可。
第三步:数据的组合
切分后的数据需要重新对其进行组合,生成能够符合模型需求的Tensor数据。这里最关键的是在模型中对输入输出格式的定义,把模式的输入输出格式拆分如下:
input = 【输入1,输入2】,outputs = 输出 #注意model中的中括号
因此,在Tensor建立的过程中,也要按模型输入的格式创建对应的数据集。格式如下:
((输入1,输入2),输出)
这里我们采用了2层括号对数据进行包裹,即首先将输入1和输入2包裹成一个输入数据,之后重新打包输出,共同组成一个数据集。转化Tensor数据的代码如下:
train_data = tf.data.Dataset.from_tensor_slices(((iris_data_1, iris_data_2),iris_target)).batch(128)
注意
一定要注意小括号的层数。
完整代码如下所示。
【程序2-6】
最终结果如图2.9所示。
图2.9 打印结果
这里TensorFlow默认输出了每个循环结束后的loss值,并且按compile函数设定的内容输出准确率(accuracy)值。最后的evaluate函数通过对测试集中的数据进行重新计算,获取在测试集中的损失值和准确率。本例使用训练数据代替测试数据。
在程序2-6中数据的准备是使用tf.data API完成的,即通过打包的方式将数据输出,也可以直接将输入的数据输入到模型中进行训练,代码如下:
【程序2-7】
最终打印结果请读者自行验证,需要注意的是其中数据的包裹情况。