当前位置: 首页 > article >正文

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


http://www.kler.cn/a/387192.html

相关文章:

  • STM32问题集
  • 2024年11月12日Github流行趋势
  • 前端垂直居中的多种实现方式及应用分析
  • 实现 MVC 模式
  • 解决Anaconda出现CondaHTTPError: HTTP 000 CONNECTION FAILED for url
  • DevOps工程技术价值流:加速业务价值流的落地实践与深度赋能
  • el-tab使用
  • 新手如何快速搭建一个Springboot项目
  • 代码随想录刷题记录(二十五)——54. 替换数字
  • 【信号处理】绘制IQ信号时域图、星座图、功率谱
  • 吾店云介绍 – 中国人的WordPress独立站和商城系统平台
  • docker进行SRS直播服务器搭建
  • WPS 默认模板修改
  • 关于qiskit版本>1.0.0,execute函数被替换
  • Java基于微信小程序的美食推荐系统(附源码,文档)
  • ONLYOFFICE 办公套件测评:高效办公新选择
  • 「Mac畅玩鸿蒙与硬件32」UI互动应用篇9 - 番茄钟倒计时应用
  • Python自动化运维:配置管理工具到自动化部署与版本控制
  • Flutter错误: uses-sdk:minSdkVersion 16 cannot be smaller than version 21 declared
  • Shortcut Learning in In-Context Learning: A Survey
  • MySQL 权限困境:从权限丢失到权限重生的完整解决方案20241108
  • Android Framework AMS(11)广播组件分析-2(注册/注销流程解读)
  • PDS的主要部件
  • 50个广泛使用的SQL关键字
  • 在 Ubuntu 上安装 Redis 并为其设置登录密码
  • go桌面框架Fyne最全api文档