下溢(underflow):当接近零的数被四舍五入为零时发生下溢。许多函数在其参数为零而不是一个很小的正数时才会表现出质的不同。例如,我们通常要避免被零除或避免取零的对数。
上溢(overflow):当大量级的数被近似为∞或-∞时发生上溢。进一步的运算通常会导致这些无限值变为非数字。
必须对上溢和下溢进行数值稳定的一个例子是softmax函数(softmax function).softmax函数经常用于预测与Multinoulli分布相关联的概率,定义为:
考虑一下当所有x
i
都等于某个常数c时会发生什么。从理论分析上说,我们可以发现所有的输出都应该为1/n。从数值计算上说,当c量级很大时,这可能不会发生。如果c是很小的负数,exp(c)就会下溢。这意味着softmax函数的分母会变成0,所以最后的结果是未定义的。当c是非常大的正数时,exp(c)的上溢再次导致整个表达式未定义。这两个困难能通过计算softmax(z)同时解决,其中z=x-max
i
x
i
.简单的代数计算表明,softmax解析上的函数值不会因为从输入向量减去或加上标量而改变。减去max
i
x
i
导致exp的最大参数为0,这排除了上溢的可能性。同样地,分母中至少有一个值为1的项,这就排除了因分母下溢而导致被零除的可能性。
还有一个小问题。分子中的下溢仍可以导致整体表达式被计算为零。这意味着,如果我们在计算log(softmax(x))时,先计算softmax再把结果传给log函数,会错误地得到-∞。相反,我们必须实现一个单独的函数,并以数值稳定的方式计算log(softmax)。我们可以使用相同的技巧来稳定log(softmax)函数。
Softmax函数:在数学,尤其是概率论和相关领域中,Softmax函数,或称归一化指数函数,是逻辑函数的一种推广。它能将一个含任意实数的K维的向量z的”压缩”到另一个K维实向量σ(z)中,使得每一个元素的范围都在(0,1)之间,并且所有元素的和为1。该函数的形式通常按下面的式子给出:其中,j=1,…,K.
Softmax函数实际上是有限项离散概率分布的梯度对数归一化。因此,Softmax函数在包括多项逻辑回归,多项线性判别分析,朴素贝叶斯分类器和人工神经网络等的多种基于概率的多分类问题方法中都有着广泛应用。
The softmax function is often used in the final layer of a neural network-based classifier. Such networks are commonly trained under a log loss (or cross-entropy) regime, giving a non-linear variant of multinomial logistic regression.
Softmax可作为神经网络中的输出层,用于多分类(sigmoid只能用于二分类,而softmax可用于多分类。使用Logistic函数来实现二分类问题,对于多分类问题,可以使用多项Logistic回归,该方法也被称之为softmax函数);Softmax还可以解决学习速度衰退的问题;softmax还可作为loss function。
softmax函数的导数如下:
以上内容主要摘自:
《深度学习中文版》
和
维基百科
以下是C++实现的测试code:
#include "funset.hpp"
#include <math.h>
#include <iostream>
#include <string>
#include <vector>
#include <opencv2/opencv.hpp>
#include "common.hpp"
// ========================= Activation Function: softmax =====================
template<typename _Tp>
int activation_function_softmax(const _Tp* src, _Tp* dst, int length)
const _Tp alpha = *std::max_element(src, src + length);
_Tp denominator{ 0 };
for (int i = 0; i < length; ++i) {
dst[i] = std::exp(src[i] - alpha);
denominator += dst[i];
for (int i = 0; i < length; ++i) {
dst[i] /= denominator;
return 0;
template<typename _Tp>
int activation_function_softmax_derivative(const _Tp* src, _Tp* dst, int length)
std::vector<_Tp> y(length, (_Tp)0);
activation_function_softmax(src, y.data(), length);
fprintf(stderr, "Error: activation_function_softmax_derivative to do ...\n");
return -1;
int test_activation_function()
std::vector<float> src{ 1.23f, 4.14f, -3.23f, -1.23f, 5.21f, 0.234f, -0.78f, 6.23f };
int length = src.size();
std::vector<float> dst(length);
fprintf(stderr, "source vector: \n");
fbc::print_matrix(src);
fprintf(stderr, "calculate activation function:\n");
fprintf(stderr, "type: sigmoid result: \n");
fbc::activation_function_sigmoid(src.data(), dst.data(), length);
fbc::print_matrix(dst);
fprintf(stderr, "type: sigmoid derivative result: \n");
fbc::activation_function_sigmoid_derivative(src.data(), dst.data(), length);
fbc::print_matrix(dst);
fprintf(stderr, "type: sigmoid fast result: \n");
fbc::activation_function_sigmoid_fast(src.data(), dst.data(), length);
fbc::print_matrix(dst);
fprintf(stderr, "type: softplus result: \n");
fbc::activation_function_softplus(src.data(), dst.data(), length);
fbc::print_matrix(dst);
fprintf(stderr, "type: softplus derivative result: \n");
fbc::activation_function_softplus_derivative(src.data(), dst.data(), length);
fbc::print_matrix(dst);
fprintf(stderr, "type: ReLU result: \n");
fbc::activation_function_ReLU(src.data(), dst.data(), length);
fbc::print_matrix(dst);
fprintf(stderr, "type: ReLU derivative result: \n");
fbc::activation_function_ReLU_derivative(src.data(), dst.data(), length);
fbc::print_matrix(dst);
fprintf(stderr, "type: Leaky ReLUs result: \n");
fbc::activation_function_Leaky_ReLUs(src.data(), dst.data(), length);
fbc::print_matrix(dst);
fprintf(stderr, "type: Leaky ReLUs derivative result: \n");
fbc::activation_function_Leaky_ReLUs_derivative(src.data(), dst.data(), length);
fbc::print_matrix(dst);
fprintf(stderr, "type: Leaky ELUs result: \n");
fbc::activation_function_ELUs(src.data(), dst.data(), length);
fbc::print_matrix(dst);
fprintf(stderr, "type: softmax result: \n");
fbc::activation_function_softmax(src.data(), dst.data(), length);
fbc::print_matrix(dst);
fprintf(stderr, "type: softmax derivative result: \n");
fbc::activation_function_softmax_derivative(src.data(), dst.data(), length);
fbc::print_matrix(dst);
return 0;
GitHub:
https://github.com/fengbingchun/NN_Test
请注意,与标准 Softmax 类似,如果需要处理多个样本的情况,可以将输入张量的第一维设置为样本数量,然后在 softmax() 函数中指定 dim 参数为 1。这将对每个样本进行独立的 Negative Softmax 转换,并返回一个大小为 (batch_size, n) 的张量,其中每一行都是对应样本的概率分布。接下来,我们使用 PyTorch 中的 torch.nn.functional.softmax() 函数和 - 运算符来将其转换为 Negative Softmax,即 -x/tau。
import numpy as np
# Write a function that takes as input a list of numbers, and returns
# the list of values given by the softmax function.
def softmax(L):
expL = np.exp(L)
sumExpL = sum(expL)
result = []
for i in expL:
result.append(i*1.0/sumExpL)
return result
python编写交叉
获取Fashion-MNIST训练集和读取数据
在介绍softmax回归的实现前我们先引入一个多类图像分类数据集。它将在后面的章节中被多次使用,以方便我们观察比较算法之间在模型精度和计算效率上的区别。图像分类数据集中最常用的是手写数字识别数据集MNIST[1]。但大部分模型在MNIST上的分类精度都超过了95%。为了更直观地观察算法之间的差异,我们将使用一个图像内容更加复杂的数据集Fashion-MNIST[2]。
我这里我们会使用torchvision包,它是服务于PyTorch深度学习框架的,主要用来构建计算机视觉模型。torchvision主要由以下几部分构成:
torchvision.
在softmax回归和具有softmax输出的神经网络中,生成N个输出,并选择一个输出作为预测类别。在这两种情况下,向量{z}\mathbf{z}{z}由应用于softmax函数的线性函数生成。softmax函数将{z}\mathbf{z}{z}转换为如下所述的概率分布。应用softmax后,每个输出将介于0和1之间,并且输出将相加到1,因此它们可以被解释为概率。较大的输入将对应于较大的输出概率。经过使用指数形式的Softmax函数能够将差距大的数值距离拉的更大。aj=e。
今天面试字节算法岗时被问到的问题,让我用C++实现一个softmax函数。softmax是逻辑回归在多分类问题上的推广。大概的公式如下:
input:{x1,x2,⋯ ,xn}softmax(xt)=ext∑i=1nexi
input: \{x_1, x_2,\cdots, x_n\}\\ softmax(x_t)=\frac{e^{x_t}}{\sum_{i=1}^{n}e^{x_i}}
input:{x1,x2,⋯,xn}softmax(xt)=∑i=1nexiext
即判断该变量
目录1 Softmax定义2 为什么使用Softmax3 Pytorch 实现Softmax4 防止数值溢出方法5 参考文献
1 Softmax定义
2 为什么使用Softmax
3 Pytorch 实现Softmax
4 防止数值溢出方法
5 参考文献
[1]一文详解Softmax函数
[2]Pytorch Softmax用法
常常会遇到需要多分类的问题,比如手写体识别,你需要识别手写的数字是几(0~9),比如文本生成,你需要知道生成的是哪个字,都需要进行多分类。那么我们最常用的多分类函数就是softmax了。接下来本文将会实现一个softmax来进行手写体识别。
本次的数据集分为训练集:文件名为”trainingDigits”和测试集:文件名为”testDigits”,每个文件夹里面有txt文件若干...
文章目录激活函数 Activation functionsSigmoidTanhReluLinearSoftmax
激活函数 Activation functions
解决非线性问题。
Sigmoid
Linear
Reference:
常见的激活函数: https://zhuanlan.zhihu.com/p/70810466
Softmax
softmax用于多分类过程中,它将多个神经元的输出,映射到(0,1)区间内,可以看成概率来理解,从而来进行多分类!
对于分类问题,在网络的最后需要输出各个类别的概率,并认为最大概率的类别为最终分类结果,因此在Affine层之后还需要连接一层输出层,把每个类别的输出值转换为0~1之间的概率,转换函数通常使用Softmax函数。既然是窗口滑动,就涉及到滑动步长step的选择,step可以取固定的1,2,3...,但是要求满足条件step+c...