当前位置: 首页 > 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.…...

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站&#xff0c;会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后&#xff0c;网站没有变化的情况。 不熟悉siteground主机的新手&#xff0c;遇到这个问题&#xff0c;就很抓狂&#xff0c;明明是哪都没操作错误&#x…...

【Java学习笔记】Arrays类

Arrays 类 1. 导入包&#xff1a;import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序&#xff08;自然排序和定制排序&#xff09;Arrays.binarySearch()通过二分搜索法进行查找&#xff08;前提&#xff1a;数组是…...

相机从app启动流程

一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比

目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec&#xff1f; IPsec VPN 5.1 IPsec传输模式&#xff08;Transport Mode&#xff09; 5.2 IPsec隧道模式&#xff08;Tunne…...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包

文章目录 现象&#xff1a;mysql已经安装&#xff0c;但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时&#xff0c;可能是因为以下几个原因&#xff1a;1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...

优选算法第十二讲:队列 + 宽搜 优先级队列

优选算法第十二讲&#xff1a;队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

Mac下Android Studio扫描根目录卡死问题记录

环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中&#xff0c;提示一个依赖外部头文件的cpp源文件需要同步&#xff0c;点…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题

在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件&#xff0c;这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下&#xff0c;实现高效测试与快速迭代&#xff1f;这一命题正考验着…...

人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式

今天是关于AI如何在教学中增强学生的学习体验&#xff0c;我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育&#xff0c;这并非炒作&#xff0c;而是已经发生的巨大变革。教育机构和教育者不能忽视它&#xff0c;试图简单地禁止学生使…...