Python Keras-如何获得非标准化的Logit而不是概率
我正在Keras中创建一个模型,并希望计算我自己的度量(困惑)。这需要使用非标准化概率/逻辑。但是,keras模型仅返回softmax概率: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
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)
是否包含logit或标准化概率y_pred
- 如果它包含规范化概率,我如何获得非规范化概率,即
层输出的logitsDense
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
的真实数据--我的解决方案认为您以后将需要softmax概率。只要我始终添加一个softmax,我以后就不能继续使用softmax概率吗?例如,当调用model.predict(输入)时,输出将是非标准化概率(=logits)。当添加probs=K.nn.softmax(model.predict(input))时,我将获得所需的softmax概率。正确吗?关于你的答案:我必须在训练期间使用稀疏的分类交叉熵作为损失函数。当只训练模型的第一部分时,它使用未规范化的概率作为损失函数的输入,这将产生错误的结果。您只能从输出中获得度量,因此需要非规范化的输出。如果需要,可以在自定义损失函数中对其进行规格化。在所有情况下,您稍后会发现需要一个模型来执行softmax。你最终会得到这个答案加上你的答案的一个变体。因此,你明确承认了一个有用的答案,但甚至不想对它进行投票??不知道你为什么错误地指责另一个用户。我立刻把洛恩尼斯·纳奥斯的答案投了赞成票。但是,一定是其他人投了反对票,所以我的赞成票不显示。那么最后如何获得softmax概率?fit