用C++实现softmax函数(面试经验)

2023-11-10

背景

今天面试字节算法岗时被问到的问题,让我用C++实现一个softmax函数。softmax是逻辑回归在多分类问题上的推广。大概的公式如下:
i n p u t : { x 1 , x 2 , ⋯   , x n } s o f t m a x ( x t ) = e x t ∑ i = 1 n e x i input: \{x_1, x_2,\cdots, x_n\}\\ softmax(x_t)=\frac{e^{x_t}}{\sum_{i=1}^{n}e^{x_i}} input:{x1,x2,,xn}softmax(xt)=i=1nexiext
即判断该变量在总体变量中的占比。

第一次实现

实现

我们用vector来封装输入和输出,简单的按公式复现。

vector<double> softmax(vector<double> input)
{
	double total=0;
	for(auto x:input)
	{
		total+=exp(x);
	}
	vector<double> result;
	for(auto x:input)
	{
		result.push_back(exp(x)/total);
	}
	return result;
}

测试

test 1

  • 测试用例1: {1, 2, 3, 4, 5}
  • 测试输出1: {0.0116562, 0.0316849, 0.0861285, 0.234122, 0.636409}

经过简单测试是正常的。
在这里插入图片描述

test 2

但是这时面试官提出了一个问题,即如果有较大输入变量时会怎么样?

  • 测试用例2: {1, 2, 3, 4, 5, 1000}
  • 测试输出2: {0, 0, 0, 0, 0, nan}

由于 e 1000 e^{1000} e1000已经溢出了双精度浮点(double)所能表示的范围,所以变成了NaN(not a number)。
在这里插入图片描述

第二次实现(改进)

改进原理

我们注意观察softmax的公式:
i n p u t : { x 1 , x 2 , ⋯   , x n } s o f t m a x ( x t ) = e x t ∑ i = 1 n e x i input: \{x_1, x_2,\cdots, x_n\}\\ softmax(x_t)=\frac{e^{x_t}}{\sum_{i=1}^{n}e^{x_i}} input:{x1,x2,,xn}softmax(xt)=i=1nexiext
如果我们给上下同时乘以一个很小的数,最后答案的值是不变的。
那我们可以给每一个输入 x i x_i xi都减去一个值 a a a,防止爆精度。
大致表示如下:
e x t ∑ i = 1 n e x i = e x t ⋅ e − a e − a ⋅ ∑ i = 1 n e x i = e x t ⋅ e − a ∑ i = 1 n e x i ⋅ e − a = e x t − a ∑ i = 1 n e x i − a \frac{e^{x_t}}{\sum_{i=1}^{n}e^{x_i}}= \frac{e^{x_t}\cdot e^{-a}}{e^{-a}\cdot \sum_{i=1}^{n}e^{x_i}}= \frac{e^{x_t}\cdot e^{-a}}{ \sum_{i=1}^{n}e^{x_i}\cdot e^{-a}}= \frac{e^{x_t-a}}{ \sum_{i=1}^{n}e^{x_i-a}} i=1nexiext=eai=1nexiextea=i=1nexieaextea=i=1nexiaexta
那我们如何取这个 a a a的值呢?直接取输入中最大的那个即 m a x ( x i ) max(x_i) max(xi)就好啦,这样所有的 e x i − a e^{x_i-a} exia的值都不会超过 e 0 = 1 e^0=1 e0=1,更不可能爆精度了。

实现

vector<double> softmax(vector<double> input)
{
	double total=0;
	double MAX=input[0];
	for(auto x:input)
	{
		MAX=max(x,MAX);
	}
	for(auto x:input)
	{
		total+=exp(x-MAX);
	}
	vector<double> result;
	for(auto x:input)
	{
		result.push_back(exp(x-MAX)/total);
	}
	return result;
}

测试

test 1

  • 测试用例1: {1, 2, 3, 4, 5, 1000}
  • 测试输出1: {0, 0, 0, 0, 0, 1}
    在这里插入图片描述

test 2

  • 测试用例1: {0, 19260817, 19260817}
  • 测试输出1: {0, 0.5, 0.5}

在这里插入图片描述

我们发现结果正常了。

完整代码

#include <iostream>
#include <vector>
#include <math.h>
using namespace std;

vector<double> softmax(vector<double> input)
{
	double total=0;
	double MAX=input[0];
	for(auto x:input)
	{
		MAX=max(x,MAX);
	}
	for(auto x:input)
	{
		total+=exp(x-MAX);
	}
	vector<double> result;
	for(auto x:input)
	{
		result.push_back(exp(x-MAX)/total);
	}
	return result;
}

int main(int argc, char *argv[])
{
	int n;
	cin>>n;
	vector<double> input;
	while(n--)
	{
		double x;
		cin>>x;
		input.push_back(x);
	}
	for(auto y:softmax(input))
	{
		cout<<y<<' ';
	}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

用C++实现softmax函数(面试经验) 的相关文章

  • Qt 图表和数据可视化小部件

    我已经安装了 Qt 5 7 来尝试 Qt 图表和 Qt 数据可视化 但我在 Qt Designer 和 Qt Creator 中都找不到新的小部件 有什么建议我应该做什么才能让新的小部件出现在设计器中 我今天遇到了完全相同的问题 默认情况下
  • 使用 Json.NET 序列化子类

    我正在尝试使用 Json NET 序列化子类 生成的 json 包含超类的序列化属性 但是not子类对象的属性 这似乎与我发现的一个问题有关这里就这样 https stackoverflow com q 5863496 498969 但必须
  • 将字符串作为 PChar 从 CSharp 传递到 Delphi DLL

    我正在尝试将字符串从 C 传递到 Delphi 构建的 DLL Delphi DLL 需要 PChar 这是Delphi导出 procedure DLL Message Location PChar AIntValue integer st
  • 平滑手绘曲线

    我有一个允许用户绘制曲线的程序 但这些曲线看起来不太好 它们看起来摇摇欲坠 而且是手绘的 所以我想要一种能够自动平滑它们的算法 我知道平滑过程中存在固有的模糊性 因此它不会每次都完美 但这种算法似乎确实存在于多个绘图包中 并且它们工作得很好
  • 最新 .Net MongoDb.Driver 的连接问题

    我创建了一个 MongoLab 沙箱数据库 我与 MongoChef 连接 效果很好 我通过 Nuget 安装了 MongoDB Driver 2 2 2 我编写了一些简单的 C 演示代码 但就是无法使其工作 连接字符串是直接从 Mongo
  • ASP.NET - 在 RenderContent 调用中将事件处理程序添加到 Repeater 内的 LinkBut​​ton

    我有一个加载自定义用户控件的 Sharepoint WebPart 用户控件包含一个 Repeater 而 Repeater 又包含多个 LinkBut ton 在 Web 部件的 RenderContent 调用中 我有一些用于添加事件处
  • 如何在C中同时运行两个子进程?

    所以我开始学习并发编程 但由于某种原因我什至无法掌握基础知识 我有一个名为 fork c 的文件 其中包含一个 main 方法 在此方法中 我将 main 分叉两次 分别进入子进程 1 和 2 在孩子 1 中 我打印了字符 A 50 次 在
  • 将 dataGridView 中选定的行作为对象检索

    我有一堂这样的课 public partial class AdressBokPerson public long Session get set public string F rnamn get set public string Ef
  • 组合框下拉位置

    我有一个最大化的表单 其中包含 500px 的组合框控件 停靠在右上角 Width 尝试打开组合框后 列表的一半超出了屏幕 如何强制列表显示在表单中 棘手的问题 我找不到解决这个问题的好办法 只是一个解决方法 添加一个新类并粘贴如下所示的代
  • 无法加载程序集问题

    我收到以下错误 无法加载程序集 错误详细信息 System BadImageFormatException 无法加载文件或程序集 文件 或其依赖项之一 该程序集是由比当前加载的运行时更新的运行时构建的 无法加载 该程序集是使用 Net Fr
  • Linq 合并列表

    我的课 public class Foo public int A get set public List
  • .NET 5 EF Core SaveChangesAsync 因错误而挂起

    尽管这个问题有很多结果 但没有一个真正给我明确的答案 每次我尝试通过 AddAsync 和 SaveChangesAsync 方法插入错误数据 例如重复的主键 时 我都会看到以下日志 执行 DbCommand 失败 15 毫秒 我还在 SQ
  • 在c#中获取没有时间的日期

    我的表上有一列 缺勤日期时间 日期 当我想要获取包含日期的行时 它返回 0 行 这是我的 C 代码 DateTime ClassDate DateTime Parse lblDate Content ToString var Abs dbs
  • 应用程序处于中断模式。您的应用程序已进入中断状态,

    我发现自己遇到了同样的问题here https stackoverflow com questions 36204009 disable break mode page in vs2015 我在 dll 中使用 Windows 窗体 这是针
  • 如何在 C# 中更改公共 IP 地址

    我正在创建一个 C winform 应用程序 我想在其中更改公共 IP 地址 而不是像 Hotspot Shield ZenMate OpenVPN 等那样更改 IPv4 地址 我已经检查了以下链接 但没有找到足够的帮助 所以我发布了这个问
  • 如何检测应用程序正在运行的 .NET 版本?

    我尝试使用Environment Version ToString 确定目标计算机上正在使用什么 NET 框架 但安装了 4 0 版本时 它说我正在使用 NET 2 0 如何检测目标计算机上正在运行的 NET Framework 版本 En
  • 如何将System.Windows dll添加到Visual Studio 2010 Express?

    我正在开发一个小型应用程序C and VS2010 as IDE with NET框架4 我想用CaptureSource类以便从笔记本电脑的网络摄像头捕获视频 为此我需要添加一个命名空间System Windows DependencyO
  • 从脚本启用/禁用 GameObject 组件 [Unity3D]

    我需要获取一个脚本中设置的布尔值 放入名为 bouclier 的变量 以启用或禁用游戏对象 该变量位于游戏对象 Player 中 此处右下角 我需要启用或禁用这个游戏对象 Bouclier01 为此 我将脚本附加到游戏对象 Bouclier
  • 使用 CodeDOM 将程序集添加到 BuildManager 会导致间歇性错误

    我正在使用 CodeDOM 在运行时创建内存中程序集 如下所示 public Assembly Compile CodeCompileUnit targetUnit string path Path GetDirectoryName new
  • 如何使用 C# 为 azure devops 变量赋值

    我有 selenium C 测试脚本 可以从浏览器获取令牌 我有两个 azure devops 任务 一个用于执行 selenium 测试 另一个用于执行 API 测试 我想将 selenium 测试获取的令牌传递给 API 测试执行任务

随机推荐

  • JAVA基础知识点

    一 概述 JAVA语言是美国Sun公司 Stanford University Network 在1995年推出的高级变成语言 2009年Oracle甲骨文公司收购Sun公司 并于2011年发布Java7版本 DOS命令 Win R cmd
  • 2022 年度软件质量保障行业调查报告

    2022 年度软件质量保障行业调查报告 TesterHome https testerhome com topics 35615 覆盖的测试类型 个人提升工作效率的方式 优秀测试人员应该具备的能力 测试同行们的未来计划 阻碍测试进度的因素
  • CMake进阶(一)设置编译选项

    CMake 进阶 一 设置编译选项 CMake设置编译选项 构建Debug版本和Release版本 CMake文件设置 编译过程 CMake设置编译选项 在cmake脚本中 设置编译选项可以通过add compile options命令 也
  • 【超细节】Vue3的属性传递——Props

    目录 前言 一 定义 二 使用 1 在 setup 中 推荐 2 非 setup 中 3 对象写法的校验类型 4 使用ts进行类型约束 5 使用ts时props的默认值 三 注意事项 1 Prop 名字格式 2 对象或数组类型的默认值 3
  • 第十届蓝桥杯 修改数组 (研究生组)

    修改数组 问题描述 给定一个长度为 N 的数组 A A1 A2 AN 数组中有可能有重复出现的整数 现在小明要按以下方法将其修改为没有重复整数的数组 小明会依次修改 A2 A3 AN 当修改 Ai 时 小明会检查 Ai 是否在 A1 Ai
  • hp服务器g5 u盘装系统,hp 440g5怎么装系统

    惠普probook440g5为一款14英寸高性能商务办公本 在升级了英特尔酷睿i7 8代系列处理器后 配合显卡迸发出超凡的性能 很适合外出携带使用 那这款惠普笔记本怎么安装操作系统 今天小编就为大家分享hp 440g5怎么装系统 hp 44
  • PowerMod@快速幂取模

    图片链接 快速幂取模使用心得 看到过于大的数不要害怕 要学会细致分析 想想取模的作用 不就是帮你把大数化小了吗 include
  • 最强自动化测试框架Playwright(25)-浏览器

    Browser Playwright Python 方法 创建page页面 from playwright sync api import sync playwright def run playwright firefox playwri
  • 深度学习正则化

    在设计机器学习算法时不仅要求在训练集上误差 且希望在新样本上 的泛化能 强 许多机器学习算法都采 相关的策略来减 测试误差 这 些策略被统称为正则化 因为神经 络的强 的表示能 经常遇到过拟 合 所以需要使 不同形式的正则化策略 正则化通过
  • JavaWeb-通过表格显示数据库的信息(jsp+mysql)

    login jsp h2 登录 h2 br
  • python+numpy+pandas数据类型+类/对象

    写代码时逻辑明确 但是被各种数据类型以及对象类型搞蒙了 补习并简单记录一下 在进行数据分析之前需要对数据进行数据处理 其中就包含转化数据格式 可以先查看数据信息 再依据分析需求对进行处理 编写python程序时各种数据类型以及对象的类型以及
  • 微信测试账号 (2)-消息验证sha1签名

    在第1篇中实现了收发微信消息 但是没有做验证 本篇将介绍微信如何使用sha签名 对消息进行认证 其中安全相关的概念 如sha1散列值 签名等 可参考web安全 1 验证参数 GetMapping handler public String
  • live555 server 搭建

    一 直接下载live555MediaServer可执行程序 二 Live555在linux平台上编译 下载源码包 http www live555 com liveMedia live555 latest tar gz 1 解压 2 生成M
  • CCPC-南阳比赛总结

    打铁归来 感触好多 记得英语课上 收到晓红老师的消息 说给我们争取下了国赛的名额 我们感觉好幸运 没想到最后打铁了 这个结果也不太意外 下面说下 这几天的行程 反思 下一步的目标 15号 淄博到济南 15 16号 济南 郑州 南阳 17号
  • 如何过滤 map

    获取 EntrySet 然后正常使用 stream 的 filter 过滤 Entry 最后再转为 Map 即可 对 map 过滤 filter Test public void testMapFilter Map
  • OCJP题库1Z0-851(21/30)

    这套题我参考了这篇文章 以及一些百度上找的内容 再加上自己的解释 总结下来的详解 第1题 1 Given a pre generics implementation of a method 11 public static int sum
  • 申请被拒模板 (六)

    这里只是模板 仅供学习 出现任何问题 与博主无关 Hi xxxxx We really appreciate the time and effort you took to connect with us and apply for the
  • nginx配置详解

    一 什么是nginx nginx是一款自由的 开源的 高性能的HTTP服务器和反向代理服务器 同时也是一个IMAP POP3 SMTP代理服务器 Nginx作为一个HTTP服务器进行网络的发布处理 另外Nginx可以作为反向代理进行负载均衡
  • 【数据分析】为什么要学习分析方法?

    为什么要学习分析方法 如果你有以下这些症状 没有数据分析意识 工作由拍脑袋决定 而不是靠数据分析来支持决策 统计时的数据分析 做了很多图表 却发现不了业务中存在的问题 只会使用工具的数据分析 谈起使用工具的技巧头头是道 但是面对问题 还是不
  • 用C++实现softmax函数(面试经验)

    背景 今天面试字节算法岗时被问到的问题 让我用C 实现一个softmax函数 softmax是逻辑回归在多分类问题上的推广 大概的公式如下 i n p u t