【问题标题】:Sampled Softmax in Keras ModelKeras 模型中的采样 Softmax
【发布时间】:2019-11-11 06:47:23
【问题描述】:

我考虑过的一些方法:

从模型类继承 Sampled softmax in tensorflow keras

继承自 Layers 类 How can I use TensorFlow's sampled softmax loss function in a Keras model?

在这两种方法中,模型方法更简洁,因为分层方法有点老套——它将目标作为输入的一部分推入,然后再见多输出模型。

我需要一些帮助来继承 Model 类 - 具体来说: 1)与第一种方法不同 - 我想像我们在指定标准 keras 模型时一样采用任意数量的层。例如,

class LanguageModel(tf.keras.Model):
    def __init__(self, **kwargs)

2)我希望将以下代码合并到模型类中 - 但希望让模型类认识到这一点

def call(self, y_true, input):
        """ reshaping of y_true and input to make them fit each other """
        input = tf.reshape(input, (-1,self.hidden_size))
        y_true = tf.reshape(y_true, (-1,1))
      weights = tf.Variable(tf.float64))
      biases = tf.Variable(tf.float64)
      loss = tf.nn.sampled_softmax_loss(
      weights=weights,
      biases=biases,
      labels=labels,
      inputs=inputs,
      ...,
      partition_strategy="div")
      logits = tf.matmul(inputs, tf.transpose(weights))
      logits = tf.nn.bias_add(logits, biases)
       y_predis = tf.nn.softmax_cross_entropy_with_logits_v2(
                                labels=inputs[1],
                                logits=logits) 




3 我想我需要一些指针来指出我应该在功能 API 中处理模型类的哪些部分 - 知道我必须编写一个像上面这样的自定义损失函数。 我想问题是访问 tf.nn.sampledsoftmax 函数中的权重

【问题讨论】:

    标签: python tensorflow keras sampled-softmax


    【解决方案1】:

    我能想到的最简单的方法是定义一个忽略输出层结果的损失。

    这里是完整的 Colab: https://colab.research.google.com/drive/1Rp3EUWnBE1eCcaisUju9TwSTswQfZOkS

    损失函数。请注意,它假定输出层是 Dense(activation='softmax') 并且它忽略了y_pred。因此,在使用损失的训练/评估期间,密集层的实际输出是 NOP。

    输出层用于预测。

    class SampledSoftmaxLoss(object):
      """ The loss function implements the Dense layer matmul and activation
      when in training mode.
      """
      def __init__(self, model):
        self.model = model
        output_layer = model.layers[-1]
        self.input = output_layer.input
        self.weights = output_layer.weights
    
      def loss(self, y_true, y_pred, **kwargs):
        labels = tf.argmax(y_true, axis=1)
        labels = tf.expand_dims(labels, -1)
        loss = tf.nn.sampled_softmax_loss(
            weights=self.weights[0],
            biases=self.weights[1],
            labels=labels,
            inputs=self.input,
            num_sampled = 3,
            num_classes = 4,
            partition_strategy = "div",
        )
        return loss
    
    

    型号:

    def make_model():
      inp = Input(shape=(10,))
      h1 = Dense(16, activation='relu')(inp)
      h2 = Dense(4, activation='linear')(h1)
      # output layer and last hidden layer must have the same dims
      out = Dense(4, activation='softmax')(h2)
      model = Model(inp, out)
      loss_calculator = SampledSoftmaxLoss(model)
      model.compile('adam', loss_calculator.loss)
      return model
    
    tf.set_random_seed(42)
    model = make_model()
    model.summary()
    

    请注意,SampledSoftmaxLoss 要求最后一个模型层的输入必须具有与类数相同的维度。

    【讨论】:

    • 嗨 Pedro - 感谢您整理这个示例。 2 澄清 -1) nn.sampled softmax 中的权重和偏差会自动更新并分配给最后一层权重 - 对吗? 2)通过创建一个损失对象/损失层,我将无法在拟合期间访问 val_acc 测量值吗?感谢 colab 代码 - 今晚将对其进行测试。
    • 1) 正确:损失函数假设最后一层是输出层并使用其权重/偏差;并忽略其输出,因为 y_pred 不用于损失计算。 2)您可以使用任何对输出层进行操作的指标,例如准确性;输出层仍然存在,如果您将其连接到图节点(例如准确度指标),仍会生成输出。
    • 感谢我的方便。所以我只是创建一个层,从最后一层获取权重并计算预测?例如软最大等?但这不会使它成为 model.compile 对吗?
    • 损失函数不是一层;是控制计算损失并开始背景过程的图形部分;您希望模型定义明确,以便可以将其用于推理。理解这个损失函数的方法是,它忽略了输出层的输出(y_pred)并使用sampled_softmax_loss使用输出层的权重和偏差重新计算它;这最终会导致输出层的梯度更新,但不直接使用输出层的结果。
    • 谢谢_澄清它。这正是我想要的。我不想要一个层作为我的损失函数。您的模型对象从最后一层接收权重 - 使用它通过采样的 sft max 更新权重。但是因为权重仍然链接到模式层,所以模型中的权重正在更新,并且因为你的外层已经是一个 softmax,我可以添加任何适用于分类响应的指标(因为那是你的最后一层)。它对验证集也是如此。整洁!
    猜你喜欢
    • 2018-06-02
    • 2016-11-16
    • 2018-03-20
    • 1970-01-01
    • 2020-02-10
    • 2020-03-19
    • 1970-01-01
    • 2021-07-11
    • 1970-01-01
    相关资源
    最近更新 更多