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

softmax 函数的多种实现方式 包括纯C语言、C++版本、Eigen版本等

softmax 函数的多种实现方式 包括纯C语言、C++版本、Eigen版本等

flyfish

先看这里Softmax函数介绍

版本1 规矩的写法

#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <cmath>// 计算 softmax 的函数
std::vector<double> softmax(const std::vector<double>& input) {// 找到最大元素以防止 exp 计算时溢出double maxProb = *std::max_element(input.begin(), input.end());// 计算指数并求和std::vector<double> expVals;expVals.reserve(input.size());for (double val : input) {expVals.push_back(std::exp(val - maxProb)); // 计算每个元素的指数}double sumExp = std::accumulate(expVals.begin(), expVals.end(), 0.0); // 求所有指数的和// 归一化指数值以得到 softmax 概率std::vector<double> softmaxProb;softmaxProb.reserve(input.size());for (double val : expVals) {softmaxProb.push_back(val / sumExp); // 每个指数值除以总和得到 softmax 概率}return softmaxProb;
}// 示例用法
int main() {std::vector<double> input = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0}; // 示例输入std::vector<double> probabilities = softmax(input);// 输出 softmax 概率std::cout << "Softmax 概率:" << std::endl;for (double prob : probabilities) {std::cout << prob << " ";}std::cout << std::endl;// 找到具有最高概率的类别auto maxElementIter = std::max_element(probabilities.begin(), probabilities.end());int classId = std::distance(probabilities.begin(), maxElementIter);double confidence = *maxElementIter;std::cout << "预测类别: " << classId << " 置信度: " << confidence << std::endl;return 0;
}

版本2 合并循环,只使用一个 softmaxProb 向量来存储指数值和最终的 softmax 概率

#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <cmath>// 计算 softmax 的函数
std::vector<double> softmax(const std::vector<double>& input) {// 找到最大元素以防止 exp 计算时溢出double maxProb = *std::max_element(input.begin(), input.end());// 计算指数和求和std::vector<double> softmaxProb(input.size());double sumExp = 0.0;for (size_t i = 0; i < input.size(); ++i) {softmaxProb[i] = std::exp(input[i] - maxProb);sumExp += softmaxProb[i];}// 归一化指数值以得到 softmax 概率for (double& val : softmaxProb) {val /= sumExp;}return softmaxProb;
}// 示例用法
int main() {std::vector<double> input = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0}; // 示例输入std::vector<double> probabilities = softmax(input);// 输出 softmax 概率std::cout << "Softmax 概率:" << std::endl;for (double prob : probabilities) {std::cout << prob << " ";}std::cout << std::endl;// 找到具有最高概率的类别auto maxElementIter = std::max_element(probabilities.begin(), probabilities.end());int classId = std::distance(probabilities.begin(), maxElementIter);double confidence = *maxElementIter;std::cout << "预测类别: " << classId << " 置信度: " << confidence << std::endl;return 0;
}

版本3 C++17 使用并行执行策略

std::transform:用于计算每个元素的指数值,并存储在 expVals 中。使用并行执行策略可以提升计算效率。
std::reduce:用于并行求和,替代 std::accumulate。

#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <cmath>
#include <execution>// 计算 softmax 的函数
std::vector<double> softmax(const std::vector<double>& input) {// 找到最大元素以防止 exp 计算时溢出double maxProb = *std::max_element(input.begin(), input.end());// 计算指数和求和,同时避免重复遍历std::vector<double> expVals(input.size());std::transform(std::execution::par, input.begin(), input.end(), expVals.begin(), [maxProb](double val) {return std::exp(val - maxProb);});// 使用 std::reduce 并行求和double sumExp = std::reduce(std::execution::par, expVals.begin(), expVals.end(), 0.0);// 归一化指数值以得到 softmax 概率std::vector<double> softmaxProb(input.size());std::transform(std::execution::par, expVals.begin(), expVals.end(), softmaxProb.begin(), [sumExp](double val) {return val / sumExp;});return softmaxProb;
}// 示例用法
int main() {std::vector<double> input = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0}; // 示例输入std::vector<double> probabilities = softmax(input);// 输出 softmax 概率std::cout << "Softmax 概率:" << std::endl;for (double prob : probabilities) {std::cout << prob << " ";}std::cout << std::endl;// 找到具有最高概率的类别auto maxElementIter = std::max_element(probabilities.begin(), probabilities.end());int classId = std::distance(probabilities.begin(), maxElementIter);double confidence = *maxElementIter;std::cout << "预测类别: " << classId << " 置信度: " << confidence << std::endl;return 0;
}

版本4 Eigen 库实现

利用 Eigen 库可以高效地进行矩阵和向量运算。Eigen 库通过优化内存布局和利用 SIMD 指令集来提升性能。
Eigen::Map 可以将标准库中的容器(如 std::vector)映射为 Eigen 向量,从而直接进行高效的向量运算。
配置 CMakeLists.txt

# 添加 Eigen 目录
set(EIGEN3_INCLUDE_DIR "path/to/eigen") # 将此路径替换为你解压缩 Eigen 的目录
include_directories(${EIGEN3_INCLUDE_DIR})
#include <iostream>
#include <vector>
#include <algorithm>
#include <Eigen/Dense>// 计算 softmax 的函数
std::vector<double> softmax(const std::vector<double>& input) {// 将输入向量转换为 Eigen 向量Eigen::VectorXd vec = Eigen::Map<const Eigen::VectorXd>(input.data(), input.size());// 找到最大元素以防止 exp 计算时溢出double maxProb = vec.maxCoeff();// 计算指数和求和Eigen::VectorXd expVals = (vec.array() - maxProb).exp();double sumExp = expVals.sum();// 归一化指数值以得到 softmax 概率std::vector<double> softmaxProb(input.size());Eigen::VectorXd result = expVals / sumExp;Eigen::VectorXd::Map(&softmaxProb[0], result.size()) = result;return softmaxProb;
}// 示例用法
int main() {std::vector<double> input = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0}; // 示例输入std::vector<double> probabilities = softmax(input);// 输出 softmax 概率std::cout << "Softmax 概率:" << std::endl;for (double prob : probabilities) {std::cout << prob << " ";}std::cout << std::endl;// 找到具有最高概率的类别auto maxElementIter = std::max_element(probabilities.begin(), probabilities.end());int classId = std::distance(probabilities.begin(), maxElementIter);double confidence = *maxElementIter;std::cout << "预测类别: " << classId << " 置信度: " << confidence << std::endl;return 0;
}

版本5 纯C语言方式

#include <stdio.h>
#include <stdlib.h>
#include <math.h>// 计算 softmax 的函数
void softmax(const double* input, double* softmaxProb, int size) {// 找到最大元素以防止 exp 计算时溢出double maxProb = input[0];for (int i = 1; i < size; ++i) {if (input[i] > maxProb) {maxProb = input[i];}}// 计算指数和求和double sumExp = 0.0;for (int i = 0; i < size; ++i) {softmaxProb[i] = exp(input[i] - maxProb);sumExp += softmaxProb[i];}// 归一化指数值以得到 softmax 概率for (int i = 0; i < size; ++i) {softmaxProb[i] /= sumExp;}
}// 示例用法
int main() {double input[] = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0}; // 示例输入int size = sizeof(input) / sizeof(input[0]);double* probabilities = (double*)malloc(size * sizeof(double));if (probabilities == NULL) {fprintf(stderr, "内存分配失败\n");return 1;}softmax(input, probabilities, size);// 输出 softmax 概率printf("Softmax 概率:\n");for (int i = 0; i < size; ++i) {printf("%f ", probabilities[i]);}printf("\n");// 找到具有最高概率的类别double maxProb = probabilities[0];int classId = 0;for (int i = 1; i < size; ++i) {if (probabilities[i] > maxProb) {maxProb = probabilities[i];classId = i;}}double confidence = maxProb;printf("预测类别: %d 置信度: %f\n", classId, confidence);free(probabilities);return 0;
}

相关文章:

softmax 函数的多种实现方式 包括纯C语言、C++版本、Eigen版本等

softmax 函数的多种实现方式 包括纯C语言、C版本、Eigen版本等 flyfish 先看这里Softmax函数介绍 版本1 规矩的写法 #include <iostream> #include <vector> #include <algorithm> #include <numeric> #include <cmath>// 计算 softmax 的函…...

R语言学习笔记11-读取csv-xlsx-txt-json-pdf-lua格式文件

R语言学习笔记11-读取csv-xlsx-txt-json-pdf-lua格式文件 读取csv使用base的 read.csv 函数使用 readr 包的 read_csv 函数 读取xlsx使用 xlsx 包的 read.xlsx 函数使用 readxl 包的 read_excel 函数 读取txt使用base的文件读取函数 readLines使用 readr 包的 read_lines 函数 …...

Vue的计算属性和方法有什么区别

Vue中的计算属性&#xff08;computed&#xff09;和方法&#xff08;methods&#xff09;都是用于处理数据和逻辑的重要特性&#xff0c;但它们之间存在一些关键的区别。以下是两者的主要区别&#xff1a; 1. 缓存性 计算属性&#xff1a;计算属性是基于它们的依赖进行缓存的…...

学生成绩管理系统(C语言)

系统分析 1. 主菜单的实现 2. 增加人员功能的实现 3. 删除数据功能的实现 4. 编辑人员功能的实现 5. 排序功能的实现 6. 输出功能 7. 查找信息功能 具体代码 #include <stdio.h> #include <string.h> #include <stdlib.h> #define SIZE 100000typedef struc…...

C语言 通讯录管理 完整代码

这份代码&#xff0c;是我从网上找的。目前是能运行。我正在读。有些不懂的地方&#xff0c;等下再记录下来。 有些地方的命名&#xff0c;还需要重新写一下。 比如: PersonInfo* info &address_book->all_address[address_book->size]; 应该改为&#xff1a; Perso…...

2024北京国际智能工厂及自动化展览会亮点前瞻

随着“工业创新&#xff0c;智造未来”的浪潮席卷而来&#xff0c;2024年度北京国际智能工厂及自动化与工业装配展览会定于8月1日至3日在中国国际展览中心&#xff08;顺义新馆&#xff09;盛大开幕。本次展会汇聚了智能制造与自动化技术的最新成果&#xff0c;通过三展联动的创…...

《网络安全等级保护制度详解》

网络安全等级保护制度是我国网络安全领域的一项重要制度&#xff0c;旨在保障网络安全&#xff0c;维护国家安全、社会秩序和公共利益。 网络安全等级保护制度主要包含以下几个关键方面&#xff1a; 等级划分 根据信息系统在国家安全、经济建设、社会生活中的重要程度&#xff…...

使用Wanderboat AI 来规划到巴黎的旅行计划

​ Wanderboat AI 平台是一个由 GPT-4 驱动的智能旅行规划工具&#xff0c;旨在通过自然对话和多模式互动&#xff0c;为用户提供个性化的旅行行程。以下是该平台的架构和使用方法&#xff1a; 平台架构 GPT-4 驱动&#xff1a;平台利用 GPT-4 的强大自然语言处理能力&#x…...

基于YOLO8的目标检测系统:开启智能视觉识别之旅

文章目录 在线体验快速开始一、项目介绍篇1.1 YOLO81.2 ultralytics1.3 模块介绍1.3.1 scan_task1.3.2 scan_taskflow.py1.3.3 target_dec_app.py 二、核心代码介绍篇2.1 target_dec_app.py2.2 scan_taskflow.py 三、结语 在线体验 基于YOLO8的目标检测系统 基于opencv的摄像头…...

实验07 接口测试postman

目录 知识点 1 接口测试概念 1.1为什么要做接口测试 1.2接口测试的优点 1.3接口测试概念 1.4接口测试原理和目的 2 接口测试内容 2.1测什么 2.1.1单一接口 2.1.2组合接口 2.1.3结构检查 2.1.4调用方式 2.1.5参数格式校验 2.1.6返回结果 2.2四大块 2.2.1功能逻辑…...

C++常用但难记的语法

模板函数的声明和定义必须在同一个文件中。 C中每一个对象所占用的空间大小&#xff0c;是在编译的时候就确定的&#xff0c;在模板类没有真正的被使用之前&#xff0c;编译器是无法知道&#xff0c;模板类中使用模板类型的对象的所占用的空间的大小的。只有模板被真正使用的时…...

Qt 快速保存配置的方法

Qt 快速保存配置的方法 一、概述二、代码1. QFileHelper.cpp2. QSettingHelper.cpp 三、使用 一、概述 这里分享一下&#xff0c;Qt界面开发时&#xff0c;快速保存界面上一些参数配置的方法。 因为我在做实验的时候&#xff0c;界面上可能涉及到很多参数的配置&#xff0c;我…...

RKE部署k8s

移除docker&#xff08;非必要&#xff09; rm -rf /etc/docker rm -rf /run/docker rm -rf /var/lib/dockershim rm -rf /var/lib/docker yum list installed | grep docker yum remove ***rke部署k8s集群 cat > /etc/sysctl.conf << EFO net.ipv4.ip_forward 1 n…...

从0开始的STM32HAL库学习8

PWM控制舵机 配置环境 1. 选择TIM2时钟 2.选择内部时钟模式&#xff0c;打开通道二 3.分频系数PSC:72-1 自动重装寄存器ARR:20000-1 输出比较寄存器 CCR:500~2500( 后面可调整 ) 脉冲选择500后期可以改 编辑代码 调用启动函数 HAL_TIM_PWM_Start(&htim2,TIM_CHANN…...

微信小程序数组绑定使用案例(一)

微信小程序数组绑定案例&#xff0c;修改数组中的值 1.Wxml 代码 <view class"list"><view class"item {{item.ischeck?active:}}" wx:for"{{list}}"><view class"title">{{item.name}} <text>({{item.id}…...

Kudu节点数规划

作者&#xff1a;南墨 一、概述 由于Kudu是Hadoop生态的一部分&#xff08;虽然它不依赖于Hadoop生态系统&#xff09;&#xff0c;因此大多数实际应用场景需要的不仅仅是Kudu&#xff1b;为了输入数据&#xff0c;可能需要Kafka、StreamSets或Spark Streaming&#xff1b;对…...

flutter 充电气泡

前言&#xff1a; 之前一直看到 有手机充电的时候 有气泡从Type-C 的位置冒泡上来 慢慢上移&#xff0c; 然后和上面的圆圈 会和&#xff0c;感觉还是挺好看的。今天试了下用 Flutter 实现了一版本。大致效果如下&#xff0c;而且气泡 和 气泡直接还可以粘黏 实现原理&#xff…...

【C++】deque以及优先级队列

容器适配器 deque的介绍deque的原理介绍 priority_queue的介绍与使用priority_queue的介绍priority_queue的使用constructor&#xff08;构造函数&#xff09;emptypushpoptopsize priority_queue的模拟实现 仿函数何为适配器容器适配器deque的缺陷选择deque作为适配器的理由ST…...

手机如何播放电脑的声音?

准备工具&#xff1a; 有线耳机&#xff0c;手机&#xff0c;电脑&#xff0c;远控软件 1.有线耳机插电脑上 2.电脑安装pc版远控软件&#xff0c;手机安装手机端控制版远控软件 3.手机控制电脑开启声音控制 用手机控制电脑后&#xff0c;打开声音控制&#xff0c;电脑播放视频…...

系统架构设计师教程 第3章 信息系统基础知识-3.6 办公自动化系统(OAS)-解读

系统架构设计师教程 第3章 信息系统基础知识-3.6 办公自动化系统&#xff08;OAS&#xff09; 3.6.1 办公自动化系统的概念3.6.1.1 办公活动3.6.1.1 办公自动化的概念 3.6.2 办公自动化系统的功能3.6.2.1 事务处理3.6.2.1.1 单机系统3.6.2.1.2 多机系统 3.6.2.2 信息管理3.6.2.…...

第五部分-后期特效与着色器——24. 后期特效基础

24. 后期特效基础 1. 概述 后期特效&#xff08;Post-Processing&#xff09;是在场景渲染完成后&#xff0c;对渲染结果进行额外处理的技术。通过 EffectComposer 合成器&#xff0c;可以叠加多种特效&#xff0c;如泛光、景深、颜色校正等。 ┌───────────────…...

扩散模型噪声补偿:提升图像生成质量的实践方案

1. 项目背景与核心问题在图像生成领域&#xff0c;扩散模型近年来展现出惊人的创造力。但当我们把这类模型部署到真实场景时&#xff0c;经常会遇到一个棘手问题&#xff1a;输入数据中难以避免的高斯噪声会导致生成质量显著下降。我在最近的一个医疗影像生成项目中就深刻体会到…...

农田边缘计算+云端协同:Python实现毫秒级多源时序数据融合(含TensorFlow Lite部署实录)

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;农田边缘计算云端协同的农业物联网数据融合概述 在智慧农业演进过程中&#xff0c;农田边缘计算与云端协同正成为解决实时性、带宽约束与全局决策矛盾的关键范式。边缘设备&#xff08;如土壤传感器、无…...

Git仓库自动化同步工具QtoGitHub的设计与实现

1. 项目概述&#xff1a;从代码仓库到GitHub的自动化同步最近在整理个人项目时&#xff0c;我遇到了一个挺典型的场景&#xff1a;手头有几个长期维护的私有代码仓库&#xff0c;它们分散在不同的托管平台或者本地服务器上。每次想把这些代码备份一份到GitHub&#xff0c;或者同…...

对比在ubuntu上直连厂商与通过taotoken调用大模型的体验差异

在 Ubuntu 上使用 Taotoken 调用大模型的体验观察 1. 多模型可选性的便利体验 在 Ubuntu 开发环境中直接连接单一厂商 API 时&#xff0c;开发者通常需要为每个厂商单独配置 SDK 或 HTTP 客户端&#xff0c;并维护不同的认证机制。例如&#xff0c;切换 Claude 和 GPT 模型需…...

RRT算法避坑指南:MATLAB实现中那些容易出错的细节(附完整可运行代码)

RRT算法避坑指南&#xff1a;MATLAB实现中那些容易出错的细节&#xff08;附完整可运行代码&#xff09; 当你第一次尝试在MATLAB中实现RRT算法时&#xff0c;可能会遇到各种奇怪的问题&#xff1a;路径规划失败、计算效率低下、或者结果看起来完全不合理。这些问题往往源于几个…...

如何3分钟免费安装FigmaCN中文插件:设计师必备的界面翻译工具终极指南

如何3分钟免费安装FigmaCN中文插件&#xff1a;设计师必备的界面翻译工具终极指南 【免费下载链接】figmaCN 中文 Figma 插件&#xff0c;设计师人工翻译校验 项目地址: https://gitcode.com/gh_mirrors/fi/figmaCN 还在为Figma的英文界面感到困扰吗&#xff1f;专业术语…...

FastAPI整洁架构实战:分层设计与依赖注入构建可维护后端

1. 项目概述&#xff1a;为什么我们需要一个“干净”的FastAPI后端架构&#xff1f;如果你和我一样&#xff0c;用FastAPI开发过几个项目&#xff0c;从简单的API服务到稍具规模的后台系统&#xff0c;大概率会经历这样一个过程&#xff1a;一开始&#xff0c;main.py里写几个路…...

PvZ Toolkit终极指南:3分钟成为植物大战僵尸游戏大师

PvZ Toolkit终极指南&#xff1a;3分钟成为植物大战僵尸游戏大师 【免费下载链接】pvztoolkit 植物大战僵尸 PC 版综合修改器 项目地址: https://gitcode.com/gh_mirrors/pv/pvztoolkit 还在为植物大战僵尸无尽模式难度太高而烦恼吗&#xff1f;想要轻松调整游戏参数&am…...

量化感知训练失效?模型编译器加速失败?AI原生应用推理瓶颈诊断清单,含12个关键检查点

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;AI原生应用推理加速的底层认知与瓶颈本质 AI原生应用并非简单地将模型部署上线&#xff0c;而是要求从计算图调度、内存布局、硬件亲和性到服务编排全栈协同优化。其推理加速的本质&#xff0c;是打破…...