C++实现softmax函数的面试经验
作者:concyclics 发布时间:2023-06-16 02:07:47
标签:C++,softmax,函数,面试经验
背景
今天面试字节算法岗时被问到的问题,让我用C++实现一个softmax函数。softmax是逻辑回归在多分类问题上的推广。大概的公式如下:
即判断该变量在总体变量中的占比。
第一次实现
实现
我们用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已经溢出了双精度浮点(double)所能表示的范围,所以变成了NaN(not a number)。
第二次实现(改进)
改进原理
我们注意观察softmax的公式:
如果我们给上下同时乘以一个很小的数,最后答案的值是不变的。
那我们可以给每一个输入 x i 都减去一个值 a ,防止爆精度。
大致表示如下:
实现
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<<' ';
}
}
来源:https://blog.csdn.net/qq_21008741/article/details/124496100


猜你喜欢
- 前言开发中,免不了会用到多边形、多角星等图案,比较常用的多边形比如雷达图、多角星比如评价星级的五角星等,本篇文章就使用Flutter绘制封装
- (注意:本文基于JDK1.8) 前言Vector是线程安全的动态数组类,提供4个创建Vector对象的构造方法,接下来我们逐个分析
- SpringBoot的自动装配是拆箱即用的基础,也是微服务化的前提。这次主要的议题是,来看看它是怎么样实现的,我们透过源代码来把握自动装配的
- 话不多说,直接上实例:一、获取集合内重复值public void GetDuplicateValue(){ List<st
- ubuntu 安装jdk 的两种方法总结:1:通过ppa(源) 方式安装.2:通过官网下载安装包安装.这里推荐第1种,因为可以通过 apt-
- Redisson分布式锁之前的基于注解的锁有一种锁是基本redis的分布式锁,锁的实现我是基于redisson组件提供的RLock,这篇来看
- 数据类型转换就是将数据(变量、表达式的结果)从一种类型转换到另一种类型。例如,为了保存小数你可以将int类型的变量转换为double类型。数
- 一、返回BufferedImage由于spring mvc不支持返回BufferedImage ,所以增加图片转换器@Configurati
- 一般文本文件我们以日志文件.log文件为例:import java.io.BufferedReader; import java.io.Fi
- 本文实例为大家分享了Android实现滚动日期选择器的具体代码,供大家参考,具体内容如下wheelview滚动效果的View这段时间需要用到
- 一、前言最近写了个项目,前端还没写,需要部署到服务器给女朋友实现前端,可是不熟悉Linux的我,蹑手蹑脚,真的是每一步都是bug,可谓是步步
- 下边是一些我们常用的正则表达式。自己写的一些正则表达式,可以先在线测评一下。一、校验数字的表达式 1 数字:^[0-9]*$&nb
- http无状态协议的解决:HTTP 是一种无状态协议。 无状态协议不要求服务器在多次请求期间保留有关每个用户的信息或状态。但是某些 Web
- 使用wait()与notify()实现线程间协作1. wait()与notify()/notifyAll()调用sleep()和yield(
- 接着上篇文章,我们继续来学习 Java 中的字节流操作。装饰者缓冲流 BufferedInput/OutputStream装饰者流其实是基于
- 之前的项目中,在Socket通信的时候需要传int类型的值,不过java中outputsteam貌似不能直接传int类型,只能传byte[]
- 目录aop配合反射统一签名验证接口统一签名校验第一种aop 方式实现第二种 * aop配合反射统一签名验证直接上代码,作为记录。CheckS
- 用DataFormatString格式化GridView在 GridView里面显示数据,要显示的数据有好多位小数,就想让它只显示两位小数,
- 今天在工作中突然遇到这个问题,开始郁闷得不行,查阅了很多资料才解决。话不多少先上图①解决连接超时问题1:在Linux下输入命令ifconfi
- 一、问题Flutter原有的图片缓存机制,是通过PaintingBinding.instance!.imageCache来管理缓存的,这个缓