如何用TensorFlow Estimator提取MNIST CNN模型首个FC层特征?
提取Estimator中首个全连接层的特征值
没问题!当然可以通过Estimator提取你模型里第一个全连接层(就是那个1024单元的dense层)的特征值。只需要在你的模型函数里做几处简单修改,就能让Estimator在预测时返回这些特征。下面是具体的实现步骤和修改后的代码:
1. 修改模型函数,将全连接层特征加入输出
在你的cnn_model_fn中,我们需要把dense层的输出添加到predictions字典里——这样当你调用Estimator的predict方法时,就能拿到这些特征值。同时,如果你希望在评估阶段也能获取特征,也可以在EVAL模式下的返回中加入,但通常用PREDICT模式更直接。
修改后的cnn_model_fn关键部分如下:
def cnn_model_fn(features, labels, mode): # ... 原有的层定义保持不变 ... # Dense Layer pool2_flat = tf.reshape(pool2, [-1, 7 * 7 * 64]) dense = tf.layers.dense(inputs=pool2_flat, units=1024, activation=tf.nn.relu) dropout = tf.layers.dropout(inputs=dense, rate=0.4, training=mode == tf.estimator.ModeKeys.TRAIN) # Logits Layer logits = tf.layers.dense(inputs=dropout, units=10) predictions = { # 原有的预测结果保留 "classes": tf.argmax(input=logits, axis=1), "probabilities": tf.nn.softmax(logits, name="softmax_tensor"), # 新增:加入首个全连接层的特征 "fc1_features": dense # 这里就是你要的特征! } # ... 原有的mode判断逻辑保持不变 ... if mode == tf.estimator.ModeKeys.PREDICT: return tf.estimator.EstimatorSpec(mode=mode, predictions=predictions) # ... 其余TRAIN和EVAL的代码不变 ...
2. 编写特征提取的逻辑
在主函数中,你可以创建一个输入函数,加载需要提取特征的数据(比如测试集),然后调用mnist_classifier.predict()来获取包含特征的结果。
修改后的主函数部分示例:
if __name__ == "__main__": # ... 原有的数据加载和Estimator创建代码不变 ... # 提取特征的输入函数(用测试集为例) feature_input_fn = tf.estimator.inputs.numpy_input_fn( x={"x": eval_data}, num_epochs=1, shuffle=False ) # 获取特征:遍历predict的结果,收集fc1_features fc1_features_list = [] for result in mnist_classifier.predict(input_fn=feature_input_fn): fc1_features_list.append(result["fc1_features"]) # 转成numpy数组方便后续使用 fc1_features_np = np.array(fc1_features_list) print("首个全连接层特征形状:", fc1_features_np.shape) # 应该是(10000, 1024),对应MNIST测试集的10000个样本
关键点说明
- 我们提取的是
dense层的输出,而不是dropout层的——因为dropout只在训练时生效,预测时会自动关闭dropout,不过如果你确实需要dropout后的特征,也可以把dropout加入predictions,但通常我们要的是原始的全连接层特征。 - 确保你已经训练过模型(或者加载了预训练的模型参数),否则提取的特征是随机初始化的,没有意义。如果之前已经训练过,
model_dir="mnist_convnet"会自动加载已保存的参数。
这样你就能轻松获取到每个样本的首个全连接层特征值啦!
内容的提问来源于stack exchange,提问作者caleale90
相关产品推荐
相关产品推荐

