自学内容网 自学内容网

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函数来处理一个简单的输入数组,并输出归一化后的概率分布。


原文地址:https://blog.csdn.net/caridle/article/details/143650152

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!