این پیاده سازی PyTorch تابع Softmax است:
def softmax(x):
"""این تابع به یک تنسور ورودی n بعدی تابع Softmax را اعمال می کند."""
max_x = torch.max(x, dim=-1, keepdim=True)
exp_x = torch.exp(x - max_x)
sum_exp_x = torch.sum(exp_x, dim=-1, keepdim=True)
probs = exp_x / sum_exp_x
return probs
تابع Softmax یک تنسور ورودی n بعدی را می گیرد و فرمول زیر را برای هر عنصر اعمال می کند:
prob = exp(x - max(x)) / sum(exp(x - max(x)))
این فرمول تضمین می کند که خروجی تابع Softmax یک توزیع احتمال است که مجموع همه احتمالات 1 است.
عبارت های
max_x
و
sum_exp_x
برای جلوگیری از خطاهای سرریز استفاده می شوند که می توانند رخ دهند زمانی که تنسور ورودی حاوی مقادیر بسیار بزرگ است. پرچم
keepdim=True
تضمین می کند که تنسور خروجی دارای همان شکل تنسور ورودی است.
در ضمن شما به تابع argmax هم نیاز دارید.در زیر پیاده سازی هر دو تابع را به صورت جنریک قرار دادم.
#include <algorithm>
#include <vector>
// Function to compute the argmax of a given input vector
template <typename T>
size_t argmax(const std::vector<T>& input) {
return std::distance(input.begin(), std::max_element(input.begin(), input.end()));
}
// Function to compute the softmax of a given input vector
template <typename T>
void softmax(std::vector<T>& input) {
T rowmax = *std::max_element(input.begin(), input.end());
T sum = 0;
for (auto& val : input) {
val = std::exp(val - rowmax);
sum += val;
}
for (auto& val : input) {
val /= sum;
}
}