C++實(shí)現(xiàn)softmax函數(shù)的面試經(jīng)驗(yàn)
背景
今天面試字節(jié)算法崗時(shí)被問(wèn)到的問(wèn)題,讓我用C++實(shí)現(xiàn)一個(gè)softmax函數(shù)。softmax是邏輯回歸在多分類(lèi)問(wèn)題上的推廣。大概的公式如下:

即判斷該變量在總體變量中的占比。
第一次實(shí)現(xiàn)
實(shí)現(xiàn)
我們用vector來(lái)封裝輸入和輸出,簡(jiǎn)單的按公式復(fù)現(xiàn)。
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;
}
測(cè)試
test 1
- 測(cè)試用例1: {1, 2, 3, 4, 5}
- 測(cè)試輸出1: {0.0116562, 0.0316849, 0.0861285, 0.234122, 0.636409}
經(jīng)過(guò)簡(jiǎn)單測(cè)試是正常的。

test 2
但是這時(shí)面試官提出了一個(gè)問(wèn)題,即如果有較大輸入變量時(shí)會(huì)怎么樣?
- 測(cè)試用例2: {1, 2, 3, 4, 5, 1000}
- 測(cè)試輸出2: {0, 0, 0, 0, 0, nan}
由于 e^1000已經(jīng)溢出了雙精度浮點(diǎn)(double)所能表示的范圍,所以變成了NaN(not a number)。

第二次實(shí)現(xiàn)(改進(jìn))
改進(jìn)原理
我們注意觀察softmax的公式:

如果我們給上下同時(shí)乘以一個(gè)很小的數(shù),最后答案的值是不變的。
那我們可以給每一個(gè)輸入 x i 都減去一個(gè)值 a ,防止爆精度。
大致表示如下:

實(shí)現(xiàn)
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;
}
測(cè)試
test 1
- 測(cè)試用例1: {1, 2, 3, 4, 5, 1000}
- 測(cè)試輸出1: {0, 0, 0, 0, 0, 1}

test 2
- 測(cè)試用例1: {0, 19260817, 19260817}
- 測(cè)試輸出1: {0, 0.5, 0.5}

我們發(fā)現(xiàn)結(jié)果正常了。
完整代碼
#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<<' ';
}
}
以上就是C++實(shí)現(xiàn)softmax函數(shù)的面試經(jīng)驗(yàn)的詳細(xì)內(nèi)容,更多關(guān)于C++ softmax函數(shù)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C++的靜態(tài)成員變量和靜態(tài)成員函數(shù)你了解多少
這篇文章主要為大家詳細(xì)介紹了C++的靜態(tài)成員變量和靜態(tài)成員函數(shù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02
C語(yǔ)言實(shí)現(xiàn)職工工資管理系統(tǒng)的示例代碼
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言如何實(shí)現(xiàn)職工工資管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08
詳解C語(yǔ)言中的fopen()函數(shù)和fdopen()函數(shù)
這篇文章主要介紹了詳解C語(yǔ)言中的fopen()函數(shù)和fdopen()函數(shù),注意其之間指針功能相關(guān)的區(qū)別,需要的朋友可以參考下2015-08-08
C語(yǔ)言實(shí)現(xiàn)學(xué)生成績(jī)管理系統(tǒng)實(shí)戰(zhàn)教學(xué)
在本篇文章里小編給大家分享了關(guān)于C語(yǔ)言實(shí)現(xiàn)學(xué)生成績(jī)管理系統(tǒng)實(shí)戰(zhàn)教學(xué)內(nèi)容,有興趣的朋友們可以跟著學(xué)習(xí)參考下。2019-01-01
在c和c++中實(shí)現(xiàn)函數(shù)回調(diào)
如何在c和c++中實(shí)現(xiàn)函數(shù)回調(diào)呢?現(xiàn)在小編就和大家分享一下在c/c++中實(shí)現(xiàn)函數(shù)回調(diào)的示例代碼,需要的朋友可以參考下2013-07-07
C++通過(guò)循環(huán)實(shí)現(xiàn)猜數(shù)字小游戲
這篇文章主要為大家詳細(xì)介紹了C++通過(guò)循環(huán)實(shí)現(xiàn)猜數(shù)字小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-09-09
dev-c++創(chuàng)建lib(靜態(tài)鏈接庫(kù))文件的實(shí)現(xiàn)步驟
本文主要介紹了dev-c++創(chuàng)建lib(靜態(tài)鏈接庫(kù))文件的實(shí)現(xiàn)步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06
C語(yǔ)言 棧的表示和實(shí)現(xiàn)詳細(xì)介紹
這篇文章主要介紹了C語(yǔ)言 棧的表示和實(shí)現(xiàn)詳細(xì)介紹的相關(guān)資料,需要的朋友可以參考下2016-12-12
詳解dll動(dòng)態(tài)庫(kù)的開(kāi)發(fā)與調(diào)用及文件的讀寫(xiě)小程序
這篇文章主要介紹了詳解dll動(dòng)態(tài)庫(kù)的開(kāi)發(fā)與調(diào)用及文件的讀寫(xiě)小程序的相關(guān)資料,希望通過(guò)本文能幫助到大家,需要的朋友可以參考下2017-09-09

