做外贸上哪些网站找客户,简单 手机 网站 源码,h5培训,企业软件开发公司softmax 函数的多种实现方式 包括纯C语言、C版本、Eigen版本等
flyfish
先看这里Softmax函数介绍
版本1 规矩的写法
#include iostream
#include vector
#include algorithm
#include numeric
#include cmath// 计算 softmax 的函…softmax 函数的多种实现方式 包括纯C语言、C版本、Eigen版本等
flyfish
先看这里Softmax函数介绍
版本1 规矩的写法
#include iostream
#include vector
#include algorithm
#include numeric
#include cmath// 计算 softmax 的函数
std::vectordouble softmax(const std::vectordouble input) {// 找到最大元素以防止 exp 计算时溢出double maxProb *std::max_element(input.begin(), input.end());// 计算指数并求和std::vectordouble 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::vectordouble softmaxProb;softmaxProb.reserve(input.size());for (double val : expVals) {softmaxProb.push_back(val / sumExp); // 每个指数值除以总和得到 softmax 概率}return softmaxProb;
}// 示例用法
int main() {std::vectordouble input {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0}; // 示例输入std::vectordouble 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::vectordouble softmax(const std::vectordouble input) {// 找到最大元素以防止 exp 计算时溢出double maxProb *std::max_element(input.begin(), input.end());// 计算指数和求和std::vectordouble 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::vectordouble input {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0}; // 示例输入std::vectordouble 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 C17 使用并行执行策略
std::transform用于计算每个元素的指数值并存储在 expVals 中。使用并行执行策略可以提升计算效率。 std::reduce用于并行求和替代 std::accumulate。
#include iostream
#include vector
#include algorithm
#include numeric
#include cmath
#include execution// 计算 softmax 的函数
std::vectordouble softmax(const std::vectordouble input) {// 找到最大元素以防止 exp 计算时溢出double maxProb *std::max_element(input.begin(), input.end());// 计算指数和求和同时避免重复遍历std::vectordouble 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::vectordouble 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::vectordouble input {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0}; // 示例输入std::vectordouble 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::vectordouble softmax(const std::vectordouble input) {// 将输入向量转换为 Eigen 向量Eigen::VectorXd vec Eigen::Mapconst Eigen::VectorXd(input.data(), input.size());// 找到最大元素以防止 exp 计算时溢出double maxProb vec.maxCoeff();// 计算指数和求和Eigen::VectorXd expVals (vec.array() - maxProb).exp();double sumExp expVals.sum();// 归一化指数值以得到 softmax 概率std::vectordouble softmaxProb(input.size());Eigen::VectorXd result expVals / sumExp;Eigen::VectorXd::Map(softmaxProb[0], result.size()) result;return softmaxProb;
}// 示例用法
int main() {std::vectordouble input {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0}; // 示例输入std::vectordouble 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;
}