-
Naive Softmax
在实际的计算中,指数计算exp存在不稳定性,数值容易溢出,超过一定范围计算精度会下降等问题
1.1 算法伪代码
1.2 算法的实现
std::vector<float> navieSoftmax(std::vector<float> &src) {
std::vector<float> dst(src.size());
float sum = 0.0f;
for (int i = 0; i < src.size(); i++) {
sum += std::expf(src[i]);
}
for (int i = 0; i < src.size(); i++) {
dst[i] = std::expf(src[i])/sum;
}
return dst;
}
2. # Safe Softmax
与Naive版本相比,不会出现数值溢出,但是计算复杂度高了一些。
2.1 算法伪代码
2.2 算法的实现
std::vector<float> safeSoftmax(std::vector<float> &src) {
std::vector<float> dst(src.size());
float max_value = -99999999.f;
for (int i = 0; i < src.size(); i++) {
max_value = std::max(max_value, src[i]);
}
float sum = 0.0f;
for (int i = 0; i < src.size(); i++) {
sum += std::expf(src[i]-max_value);
}
for (int i = 0; i < src.size(); i++) {
dst[i] = std::expf(src[i] - max_value) / sum;
}
return dst;
}
3. # Online Softmax
3.1 算法伪代码
3.2 算法的实现
std::vector<float> onlineSoftmax(std::vector<float> &src) {
std::vector<float> dst(src.size());
float max_value = -99999999.f;
float sum = 0.0f;
float prev_value = 0.0f;
for (int i = 0; i < src.size(); i++) {
max_value = std::max(max_value, src[i]);
sum = sum * std::expf(prev_value - max_value) + std::expf(src[i] - max_value);
prev_value = max_value;
}
for (int i = 0; i < src.size(); i++) {
dst[i] = std::expf(src[i] - max_value) / sum;
}
return dst;
}