softmax

Softmax函數(shù)

概念

在數(shù)學(xué),尤其是概率論和相關(guān)領(lǐng)域中,Softmax函數(shù),或稱歸一化指數(shù)函數(shù)是[邏輯斯諦函數(shù)]的一種推廣。它能將一個含任意實(shí)數(shù)的K維向量 之間,并且所有元素的和為1(也可視為一個 (k-1)維的hyperplane或subspace)。該函數(shù)的形式通常按下面的式子給出
f(x_i) = \frac{e^{x_i}}{\sum{e^{x_k}}} ( 0 =< k < n, 0 =< i < n)

實(shí)際實(shí)現(xiàn)的時候,為了防止溢出,會先把每個元素減去原先的最大值
f(x_i) = \frac{e^{x_i}}{\sum{e^{x_k}}} = \frac{e^{-m}}{e^{-m}} \frac{e^{x_i}}{\sum{e^{x_k}}} = \frac{e^{x_i - m}}{\sum{e^{x_k - m}}} ( 0 =< k < n, 0 =< i < n)

實(shí)現(xiàn)

python實(shí)現(xiàn)

import numpy as np

def softmax(x):
   e_x = np.exp(x - np.max(x)) # 避免指數(shù)溢出
   return e_x / np.sum(e_x, axis=0)

cuda實(shí)現(xiàn)

__global__ void softmax(float *predict, int length, int *max_index) 
{
    extern __shared__ float shared_data[];
    float *shared_max_vals = shared_data;
    int *shared_max_indices = (int*)&shared_max_vals[blockDim.x];
    
    int tid = threadIdx.x;

    // 1. 找到最大值和最大值的下標(biāo),存儲在共享內(nèi)存中
    float max_val = -FLT_MAX;
    int max_idx = -1;
    for (int i = tid; i < length; i += blockDim.x) {
        if (predict[i] > max_val) {
            max_val = predict[i];
            max_idx = i;
        }
    }
    shared_max_vals[tid] = max_val;
    shared_max_indices[tid] = max_idx;
    __syncthreads();

    // 在所有線程間找到全局最大值和對應(yīng)的下標(biāo)
    if (tid == 0) {
        for (int i = 1; i < blockDim.x; i++) {
            if (shared_max_vals[i] > shared_max_vals[0]) {
                shared_max_vals[0] = shared_max_vals[i];
                shared_max_indices[0] = shared_max_indices[i];
            }
        }
        *max_index = shared_max_indices[0];
    }
    __syncthreads();

    max_val = shared_max_vals[0];

    // 2. 計(jì)算指數(shù)并求和
    float sum_exp = 0.0f;
    for (int i = tid; i < length; i += blockDim.x) {
        predict[i] = expf(predict[i] - max_val);
        sum_exp += predict[i];
    }
    shared_max_vals[tid] = sum_exp;
    __syncthreads();

    // 匯總所有線程的指數(shù)和
    if (tid == 0) {
        for (int i = 1; i < blockDim.x; i++) {
            shared_max_vals[0] += shared_max_vals[i];
        }
    }
    __syncthreads();
    float total_sum = shared_max_vals[0];

    // 3. 每個元素除以總和,得到 softmax 值
    for (int i = tid; i < length; i += blockDim.x) {
        predict[i] /= total_sum;
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容