You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Keras中编写L2-softmax损失?附TensorFlow实现示例

我来帮你搞定Keras里的L2-softmax实现~其实核心思路和你给出的TensorFlow代码一致,就是先对特征做L2归一化,再缩放,然后接softmax损失。下面分两种常见场景给你方案:

在Keras中实现L2-Softmax损失的两种方案

方案1:自定义归一化层 + 标准Softmax损失

这种方式更直观,把L2归一化和缩放的逻辑封装成一个Keras层,之后直接接常规的交叉熵损失就行,和普通分类流程完全兼容。

代码示例:

import tensorflow as tf
from tensorflow.keras import layers, Model, losses

class L2NormalizeScale(layers.Layer):
    def __init__(self, alpha=30.0, **kwargs):
        super(L2NormalizeScale, self).__init__(**kwargs)
        self.alpha = alpha  # 对应你TensorFlow代码里的缩放系数

    def call(self, inputs):
        # 对输入特征做L2归一化,再乘以alpha
        norm = tf.norm(inputs, ord='euclidean', axis=1, keepdims=True)
        normalized = tf.divide(inputs, norm)
        return self.alpha * normalized

# 构建示例模型
def build_model(num_classes=10):
    inputs = layers.Input(shape=(256,))  # 假设输入是256维特征
    x = layers.Dense(128, activation='relu')(inputs)
    # 插入自定义的L2归一化缩放层
    l2_scaled = L2NormalizeScale(alpha=30.0)(x)
    # 分类头不需要激活函数,因为损失会处理softmax
    outputs = layers.Dense(num_classes)(l2_scaled)
    model = Model(inputs=inputs, outputs=outputs)
    # 使用带from_logits=True的交叉熵,保证数值稳定性
    model.compile(optimizer='adam',
                  loss=losses.SparseCategoricalCrossentropy(from_logits=True),
                  metrics=['accuracy'])
    return model

方案2:自定义损失函数

如果你不想额外添加层,也可以把L2归一化+缩放的逻辑直接嵌入损失函数里,对Dense层的输出做处理。

代码示例:

import tensorflow as tf
from tensorflow.keras import layers, Model, losses

def l2_softmax_loss(y_true, y_pred, alpha=30.0):
    # y_pred是Dense层输出的logits
    # 先对logits做L2归一化和缩放
    norm = tf.norm(y_pred, ord='euclidean', axis=1, keepdims=True)
    scaled_pred = alpha * tf.divide(y_pred, norm)
    # 计算交叉熵损失
    return losses.SparseCategoricalCrossentropy(from_logits=True)(y_true, scaled_pred)

# 构建模型
def build_model(num_classes=10):
    inputs = layers.Input(shape=(256,))
    x = layers.Dense(128, activation='relu')(inputs)
    outputs = layers.Dense(num_classes)(x)  # 直接输出logits
    model = Model(inputs=inputs, outputs=outputs)
    # 传入自定义损失函数
    model.compile(optimizer='adam',
                  loss=l2_softmax_loss,
                  metrics=['accuracy'])
    return model

注意事项

  • 两种方案核心逻辑完全一致,选哪种取决于你的代码结构偏好:第一种更模块化,特征归一化逻辑和损失分离,方便复用;第二种更紧凑,适合快速验证。
  • alpha的取值一般在10-50之间,你可以根据任务调整,比如人脸识别任务常用30左右。
  • 不管用哪种方案,都要确保最后计算损失时是基于归一化缩放后的logits,并且使用from_logits=True的交叉熵,避免数值不稳定的问题。

内容的提问来源于stack exchange,提问作者MC jiang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:40:37