Python Keras-如何获得非标准化的Logit而不是概率

Python Keras-如何获得非标准化的Logit而不是概率,python,machine-learning,keras,neural-network,nlp,Python,Machine Learning,Keras,Neural Network,Nlp,我正在Keras中创建一个模型,并希望计算我自己的度量(困惑)。这需要使用非标准化概率/逻辑。但是,keras模型仅返回softmax概率: model = Sequential() model.add(embedding_layer) model.add(LSTM(n_hidden, return_sequences=False)) model.add(Dropout(dropout_keep_prob)) model.add(Dense(vocab_size)) model.add(Acti

我正在Keras中创建一个模型,并希望计算我自己的度量(困惑)。这需要使用非标准化概率/逻辑。但是,keras模型仅返回softmax概率:

model = Sequential()
model.add(embedding_layer)
model.add(LSTM(n_hidden, return_sequences=False))
model.add(Dropout(dropout_keep_prob))
model.add(Dense(vocab_size))
model.add(Activation('softmax'))
optimizer = RMSprop(lr=self.lr)

model.compile(optimizer=optimizer, 
loss='sparse_categorical_crossentropy')
Keras FAQ有一个解决方案,可以获得中间层的输出。给出了另一种解决方案。但是,这些答案将中间输出存储在不同的模型中,这不是我需要的。 我想对我的自定义指标使用logits。自定义度量应该包含在
model.compile()
函数中,以便在培训期间对其进行评估和显示。因此,我不需要在不同的模型中分离的
稠密
层的输出,而是作为原始模型的一部分

简言之,我的问题是:

  • 使用
    def custom_metric(y_true,y_pred)
    定义自定义度量时,
    y_pred
    是否包含logit或标准化概率

  • 如果它包含规范化概率,我如何获得非规范化概率,即
    Dense
    层输出的logits


尝试将上次激活从softmax更改为线性

model = Sequential()
model.add(embedding_layer)
model.add(LSTM(n_hidden, return_sequences=False))
model.add(Dropout(dropout_keep_prob))
model.add(Dense(vocab_size))
model.add(Activation('linear'))
optimizer = RMSprop(lr=self.lr)

model.compile(optimizer=optimizer, loss='sparse_categorical_crossentropy')

您可以创建一个用于训练的模型,另一个用于预测

对于培训,您可以使用功能性API模型,只需获取现有模型的一部分,将激活放在一边:

model = yourExistingModelWithSoftmax 
modelForTraining = Model(model.input,model.layers[-2].output)

#use your loss function in this model:
modelForTraining.compile(optimizer=optimizer,loss=my_sparse_categorical_crossentropy, metrics=[my_custom_metric])
由于您将一个模型作为另一个模型的一部分,因此它们将共享相同的权重

  • 当您想要训练时,请使用
    modelForTraining.fit()
  • 要预测概率,请使用
    model.predict()

      我想我已经找到了解决办法

      首先,我将激活层更改为线性,以便接收@loannis Nasios概述的登录

      其次,为了仍然将稀疏分类交叉熵作为损失函数,我定义了自己的损失函数,将from\u logits参数设置为true

      model.add(embedding_layer)
      model.add(LSTM(n_hidden, return_sequences=False))
      model.add(Dropout(dropout_keep_prob))
      model.add(Dense(vocab_size))
      model.add(Activation('linear'))
      optimizer = RMSprop(lr=self.lr)
      
      
      def my_sparse_categorical_crossentropy(y_true, y_pred):
          return K.sparse_categorical_crossentropy(y_true, y_pred, from_logits=True)
      
      model.compile(optimizer=optimizer,loss=my_sparse_categorical_crossentropy)
      

      那么你想保留这个模型还是可以改变它?你想把稀疏的、分类的、交叉熵作为损失吗?有什么办法可以产生相同的最终结果?但我最终需要softmax概率,因此,最终的模型输出必须是概率为什么将激活更改为线性会得到logits而不是概率?@Goldname,因为线性激活意味着只传递值而不应用任何激活。ML中的Logits只是指未规范化的日志概率。如果您将激活更改为softmax,它将接受登录并通过softmax函数传递它们,该函数返回标准化概率。[更多信息]()我认为这行不通。优化器不会自动发现激活是线性的,而不是softmax。我认为我在上面找到的解决方案更容易。但是,在创建自定义构建度量时,我仍然不知道Keras中的y_pred是什么。它总是最后一个网络层的输出吗?是的,
      y\u pred
      是模型的输出,而
      y\u true
      是传递给
      fit
      的真实数据--我的解决方案认为您以后将需要softmax概率。只要我始终添加一个softmax,我以后就不能继续使用softmax概率吗?例如,当调用model.predict(输入)时,输出将是非标准化概率(=logits)。当添加probs=K.nn.softmax(model.predict(input))时,我将获得所需的softmax概率。正确吗?关于你的答案:我必须在训练期间使用稀疏的分类交叉熵作为损失函数。当只训练模型的第一部分时,它使用未规范化的概率作为损失函数的输入,这将产生错误的结果。您只能从输出中获得度量,因此需要非规范化的输出。如果需要,可以在自定义损失函数中对其进行规格化。在所有情况下,您稍后会发现需要一个模型来执行softmax。你最终会得到这个答案加上你的答案的一个变体。因此,你明确承认了一个有用的答案,但甚至不想对它进行投票??不知道你为什么错误地指责另一个用户。我立刻把洛恩尼斯·纳奥斯的答案投了赞成票。但是,一定是其他人投了反对票,所以我的赞成票不显示。那么最后如何获得softmax概率?