如何获取图像分类模型最后一层的Softmax输出与原始输出?
获取最后一层Dense层的原始输出(Logits)方法
你需要的「最后一层原始输出」是指softmax激活前的logits值,它能直接反映模型对各类别的置信度强度,正好匹配你判断图像是否包含目标对象的需求:无目标时所有logits值极低,有目标时对应类别logits显著偏高。以下是几种可行的实现方式:
方法1:拆分最后一层,同时输出Logits与分类概率
直接修改原模型结构,将softmax激活从Dense层中分离,让模型同时输出原始logits和归一化后的分类概率:
import tensorflow as tf # 重构模型 model = tf.keras.models.Sequential() model.add(tf.keras.layers.Conv2D(16, (3, 3), activation='relu', input_shape=(80, 80, 3))) model.add(tf.keras.layers.MaxPooling2D((2, 2))) model.add(tf.keras.layers.Dropout(0.3)) model.add(tf.keras.layers.Conv2D(16, (3, 3), activation='relu')) model.add(tf.keras.layers.MaxPooling2D((2, 2))) model.add(tf.keras.layers.Dropout(0.3)) model.add(tf.keras.layers.Conv2D(16, (3, 3), activation='relu')) model.add(tf.keras.layers.MaxPooling2D((2, 2))) model.add(tf.keras.layers.Flatten()) # 新增不带激活的Dense层输出原始logits model.add(tf.keras.layers.Dense(4, name='logits')) # 单独添加softmax层输出分类概率 model.add(tf.keras.layers.Activation('softmax', name='probabilities')) # 推理时同时获取两个输出 input_image = tf.random.normal((1, 80, 80, 3)) # 示例输入 logits, probs = model.predict(input_image) class_pred = tf.argmax(probs, axis=1).numpy() # 获取分类结果 print("原始logits输出:", logits) print("分类概率:", probs) print("预测类别:", class_pred)
方法2:基于原模型构建新模型,提取Logits
如果不想改动原模型的训练结构,可以直接构建一个新模型,输出原模型最后一层Dense的输入(即softmax激活前的原始值):
import tensorflow as tf # 假设你已经有训练好的原模型 # 构建logits输出模型 logits_model = tf.keras.Model(inputs=model.input, outputs=model.layers[-1].input) # 推理时分别获取概率和logits input_image = tf.random.normal((1, 80, 80, 3)) probs = model.predict(input_image) logits = logits_model.predict(input_image) class_pred = tf.argmax(probs, axis=1).numpy() print("原始logits输出:", logits) print("分类概率:", probs)
方法3:构建多输出模型(训练阶段适用)
如果需要在训练过程中同时输出logits和分类结果,用函数式API构建多输出模型会更灵活:
import tensorflow as tf # 用函数式API构建多输出模型 inputs = tf.keras.Input(shape=(80, 80, 3)) x = tf.keras.layers.Conv2D(16, (3, 3), activation='relu')(inputs) x = tf.keras.layers.MaxPooling2D((2, 2))(x) x = tf.keras.layers.Dropout(0.3)(x) x = tf.keras.layers.Conv2D(16, (3, 3), activation='relu')(x) x = tf.keras.layers.MaxPooling2D((2, 2))(x) x = tf.keras.layers.Dropout(0.3)(x) x = tf.keras.layers.Conv2D(16, (3, 3), activation='relu')(x) x = tf.keras.layers.MaxPooling2D((2, 2))(x) x = tf.keras.layers.Flatten()(x) # 输出原始logits logits = tf.keras.layers.Dense(4, name='logits')(x) # 输出分类概率 probs = tf.keras.layers.Activation('softmax', name='probabilities')(logits) model = tf.keras.Model(inputs=inputs, outputs=[logits, probs]) # 编译模型时可指定对应损失(示例) model.compile( optimizer='adam', loss={ 'logits': tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), 'probabilities': tf.keras.losses.SparseCategoricalCrossentropy() }, metrics=['accuracy'] )
补充说明
训练时直接基于logits用from_logits=True的损失函数,会比用softmax输出计算损失更稳定,数值精度更高。
内容的提问来源于stack exchange,提问作者abcdefghi999955
相关产品推荐
相关产品推荐

