C++builder中的人工智能(18):神经网络中的SoftMax函数
在这篇文章中,我们将探讨SoftMax函数在神经网络中的作用,如何在人工神经网络(ANN)中使用SoftMax函数,以及在AI技术中SoftMax的应用场景。让我们来详细解释这些概念。
SoftMax函数是什么?
SoftMax函数是逻辑函数在多维情况下的推广,也被称为软argmax或归一化指数函数。它在多项式逻辑回归中使用,并且常作为神经网络最后一个激活函数,用于将网络的输出归一化为概率分布。换句话说,SoftMax用于将预测输出向量转换为概率分布。SoftMax函数不作为激活函数使用,而是在所有输出从激活函数获得后,用于归一化这个向量(或数组)。换言之,SoftMax从给定的输出向量或数组中给出重要值。
SoftMax对激活输出的每个元素使用标准指数函数,每个值的输出在0和1之间。它通过将所有这些指数的和除以这些值来归一化,确保输出向量的分量之和为1。
SoftMax函数的作用是什么?
在神经网络中,SoftMax函数通常用于基于神经网络的分类器的最后一层。这类网络通常在对数损失或交叉熵方法下进行训练,这些方法是多项式逻辑回归的非线性变体。
对于一个有n个成员的x向量(或数组),每个成员的SoftMax可以写成如下,
这个函数可能会因为无限结果而溢出。为了避免这种情况,我们可以通过减去最大值m来调节x值。
如何在C++中编写SoftMax函数?
SoftMax函数可以在C++中如下编写:
static void softmax(double* input, double* output, unsigned int n) {
double sum = 0;
double m = -INFINITY;
for (long int i = 0; i < n; i++) {
m = std::max(m, input[i]);
}
for (unsigned int j = 0; j < n; j++) {
sum += std::exp(input[j] - m);
}
for (unsigned int i = 0; i < n; i++) {
output[i] = std::exp(input[i] - m) / sum;
}
}
我们还可以使用偏移量来计算softmax,如下:
static void softmax2(double* input, double* output, size_t input_len) {
assert(input);
double m = -INFINITY;
for (long int i = 0; i < input_len; i++) {
if (input[i] > m) {
m = input[i];
}
}
double sum = 0.0;
for (size_t i = 0; i < input_len; i++) {
sum += expf(input[i] - m);
}
double offset = m + logf(sum);
for (size_t i = 0; i < input_len; i++) {
output[i] = expf(input[i] - offset);
}
}
有没有一个简单的C++ SoftMax示例?
以下示例中使用了两个softmax()函数:
#include <iostream>
#include <assert.h>
#include <algorithm>
#include <math.h>
static void softmax(double* input, double* output, unsigned int n) {
double sum = 0;
double m = -INFINITY;
for (long int i = 0; i < n; i++) {
m = std::max(m, input[i]);
}
for (unsigned int j = 0; j < n; j++) {
sum += std::exp(input[j] - m);
}
for (unsigned int i = 0; i < n; i++) {
output[i] = std::exp(input[i] - m) / sum;
}
}
static void softmax2(double* input, double* output, size_t input_len) {
assert(input);
double m = -INFINITY;
for (long int i = 0; i < input_len; i++) {
if (input[i] > m) {
m = input[i];
}
}
double sum = 0.0;
for (size_t i = 0; i < input_len; i++) {
sum += expf(input[i] - m);
}
double offset = m + logf(sum);
for (size_t i = 0; i < input_len; i++) {
output[i] = expf(input[i] - offset);
}
}
#define N 7
int main() {
double inp[] = {1.0, 2.0, 400.0, 4000.0, 1.0, 2.0, 3.0};
double out[N];
std::cout << "Inputs:\n";
for (int i = 0; i < N; i++) {
std::cout << inp[i] << ',';
}
std::cout << '\n';
softmax(inp, out, N);
double tot = 0;
std::cout << "Softmax Output:\n";
for (int i = 0; i < N; i++) {
std::cout << out[i] << ',';
tot += out[i];
}
std::cout << '\n';
std::cout << "total of softmax output:" << tot << '\n';
softmax2(inp, out, N);
tot = 0;
std::cout << "Softmax Output:\n";
for (int i = 0; i < N; i++) {
std::cout << out[i] << ',';
tot += out[i];
}
std::cout << '\n';
std::cout << "total of softmax output:" << tot << '\n';
getchar();
return 0;
}
这个示例展示了如何在C++中使用SoftMax函数来处理一个简单的输入数组,并输出归一化后的概率分布。