如何在 Keras 中更改 softmax 输出的温度

Posted

技术标签:

【中文标题】如何在 Keras 中更改 softmax 输出的温度【英文标题】:How to change the temperature of a softmax output in Keras 【发布时间】:2016-09-11 18:39:21 【问题描述】:

我目前正在尝试重现以下文章的结果。http://karpathy.github.io/2015/05/21/rnn-effectiveness/ 我正在使用带有 theano 后端的 Keras。在文章中,他谈到了控制最终 softmax 层的温度以提供不同的输出。

温度。我们也可以玩一下 Softmax 的温度 在采样期间。将温度从 1 降低到更低 数字(例如 0.5)使 RNN 更加自信,但也更加 在其样本中保守。相反,较高的温度会产生 更多的多样性,但代价是更多的错误(例如拼写错误, 等等)。特别是,将温度设置为非常接近零将使 Paul Graham 最有可能说的话:

我的模型如下。

model = Sequential()
model.add(LSTM(128, batch_input_shape = (batch_size, 1, 256), stateful = True, return_sequences = True))
model.add(LSTM(128, stateful = True))
model.add(Dropout(0.1))
model.add(Dense(256, activation = 'softmax'))

model.compile(optimizer = Adam(),
              loss = 'categorical_crossentropy', 
              metrics = ['accuracy'])

我认为调整最终密集层温度的唯一方法是获取权重矩阵并将其乘以温度。有谁知道更好的方法吗?另外,如果有人发现我设置模型的方式有任何问题,请告诉我,因为我是 RNN 新手。

【问题讨论】:

【参考方案1】:

嗯,看起来温度是你对 softmax 层的输出所做的事情。我找到了这个例子。

https://github.com/fchollet/keras/blob/master/examples/lstm_text_generation.py

他应用以下函数对 soft-max 输出进行采样。

def sample(a, temperature=1.0):
    # helper function to sample an index from a probability array
    a = np.log(a) / temperature
    a = np.exp(a) / np.sum(np.exp(a))
    return np.argmax(np.random.multinomial(1, a, 1))

【讨论】:

最后一个和np.random.choice(len(a), p=a)有什么不同吗? 这不是标准的softmax,这里定义了温度:en.wikipedia.org/wiki/Softmax_function(在强化学习部分)。为什么在除以温度之前要应用对数? @A.D 参数a 实际上是网络的softmax 输出。所以我们使用 log 来反转 softmax 操作,得到类似 logit 的值。这些是可以应用温度的值的类型。这与wikipedia一致。【参考方案2】:

@chasep255 的答案可以正常工作,但您会因为 log(0) 而收到警告。可以简化操作e^log(a)/T = a^(1/T),去掉log

def sample(a, temperature=1.0):
  a = np.array(a)**(1/temperature)
  p_sum = a.sum()
  sample_temp = a/p_sum 
  return np.argmax(np.random.multinomial(1, sample_temp, 1))

希望对你有帮助!

【讨论】:

我认为你的意思是 e^(log(a)/T) = a^(1/T)【参考方案3】:

您可以在 keras 中构建您的自定义层来制作温度。

keras 中的代码将是这样的,并将该层用作 keras 中的任何层,例如(Dense)

class Temperature(keras.layers.Layer):
  def __init__(self):
    super(Temperature, self).__init__()
    self.temperature = torch.nn.Parameter(torch.ones(1))
    
  def call(self, final_output):
    return final_output/ self.temperature

【讨论】:

以上是关于如何在 Keras 中更改 softmax 输出的温度的主要内容,如果未能解决你的问题,请参考以下文章

如何在Keras的每个输出中应用sigmoid函数?

如何在 Keras 的顺序模型中更改输入形状

在 tensorflow 2.4 中使用 sampled_softmax 时无法将符号 Keras 输入/输出转换为 numpy 数组 TypeError

如何在 Keras 模型中使用 TensorFlow 的采样 softmax 损失函数?

Keras softmax 激活,category_crossentropy 损失。但输出不是 0, 1

在 tf.keras 中使用 softmax 作为顺序层和使用 softmax 作为密集层的激活函数有啥区别?