TensorFlow模型推理返回多值,期望单值输出的问题咨询
问题描述
模型结构摘要
Model: "model" Layer (type) Output Shape Param # input_1 (InputLayer) [(None, 1024, 9)] 0 conv1d (Conv1D) (None, 1024, 1024) 28672 re_lu (ReLU) (None, 1024, 1024) 0 conv1d_1 (Conv1D) (None, 1024, 64) 196672 re_lu_1 (ReLU) (None, 1024, 64) 0 dense (Dense) (None, 1024, 1024) 66560 dense_1 (Dense) (None, 1024, 1) 1025 Total params: 292,929 Trainable params: 292,929 Non-trainable params: 0
输入张量信息
<tf.Tensor: shape=(1, 1024, 9), dtype=float64, numpy= array([[[2.88565600e+04, 2.88415400e+04, 2.88415300e+04, ..., 5.92000000e+02, 2.68717000e+00, 7.75434895e+04], [2.88415300e+04, 2.88391800e+04, 2.88364700e+04, ..., 3.80000000e+02, 8.36111000e+00, 2.41110700e+05], [2.88391900e+04, 2.88597400e+04, 2.88391800e+04, ..., 4.94000000e+02, 1.46990300e+01, 4.23977006e+05], ..., [2.96478600e+04, 2.96478600e+04, 2.96478600e+04, ..., 2.24000000e+02, 3.16775000e+00, 9.39170402e+04], [2.96478700e+04, 2.96456900e+04, 2.96422200e+04, ..., 4.22000000e+02, 3.72039000e+00, 1.10288124e+05], [2.96457000e+04, 2.96389700e+04, 2.96389700e+04, ..., 2.69000000e+02, 1.79933000e+00, 5.33333054e+04]]])>
当前输出结果
调用model.call(inputs, training=False, mask=None)后得到:
<tf.Tensor: shape=(1, 1024, 1), dtype=float32, numpy= array([[[28849.605], [28859.383], [28880.047], ..., [29644.61 ], [29644.61 ], [29667.752]]], dtype=float32)>
核心疑问
模型训练目标是返回单个数值,但当前输入后得到1024个预测值。请问如何正确输入以确保网络正常工作并得到单个预测结果?是否存在输入维度问题?
解决方案
问题不在输入维度,而是模型结构缺少聚合序列维度的层。从模型输出形状可以看到,所有Conv1D和Dense层都保留了1024这个序列长度维度(对应输入的序列步数),最终输出(1,1024,1)意味着每个序列步都生成了一个预测值,而非对整个序列生成单个预测。
要得到单个数值结果,可通过两种方式处理:
1. 修改模型结构添加聚合层(推荐)
在模型最后添加全局池化层或展平+全连接层,将序列维度压缩为单个值:
全局池化方案:
# 在原dense_1层之后添加全局平均池化 global_avg = tf.keras.layers.GlobalAveragePooling1D()(dense_1.output) # 重新构建模型 model = tf.keras.Model(inputs=input_1.input, outputs=global_avg)输出形状会变为
(None,1),对应单样本单个预测值;也可使用GlobalMaxPooling1D()取序列最大值。展平+全连接方案:
# 展平序列维度 flatten = tf.keras.layers.Flatten()(dense_1.output) # 压缩为单个值 final_dense = tf.keras.layers.Dense(1)(flatten) # 重新构建模型 model = tf.keras.Model(inputs=input_1.input, outputs=final_dense)
注意:修改结构后需要重新训练模型(或适配新结构的权重),否则未训练的新层会导致预测结果无意义。
2. 预测后手动聚合(无需修改模型)
如果不想调整模型结构,可在预测后对输出的序列维度做聚合计算:
output = model.call(inputs, training=False, mask=None) # 取序列维度的平均值得到单个预测值,也可使用reduce_max取最大值 single_pred = tf.reduce_mean(output, axis=1)
处理后会得到形状为(1,1)的单个数值结果。
内容的提问来源于stack exchange,提问作者Krzysztof Cichocki
相关产品推荐
相关产品推荐

