LeetGPU习题01:Sigmoid手动实现

813 字
4 分钟
LeetGPU习题01:Sigmoid手动实现
2026-04-11

Sigmoid 函数的实现#

知识讲解#

Sigmoid 函数定义为 σ(x)=11+ex\sigma(x)=\frac{1}{1+e^{-x}},它将任意实数压缩至 (0,1)(0,1) 区间。 其导数为 σ(x)=σ(x)(1σ(x))\sigma'(x)=\sigma(x)(1-\sigma(x)),在 x=0x=0 处取得最大值 0.250.25,向两侧迅速衰减至 00

Sigmoid函数
Sigmoid函数

数学特性

  • 单调递增,光滑可导
  • 饱和区:x>5|x|>5 时梯度趋近于 00,导致梯度消失
  • 中心对称:σ(0)=0.5\sigma(0)=0.5,满足 σ(x)=1σ(x)\sigma(-x)=1-\sigma(x)

深度学习应用

  1. 分类输出层:将网络输出转化为正类概率 P(y=1x)=σ(z)P(y=1|x)=\sigma(z),配合交叉熵损失实现稳定训练。
  2. 旧式隐藏层激活:早期全连接网络常用,但因饱和区梯度消失,已被 ReLU 系列取代。

题目描述#

难度:简单 任务:编写一个GPU程序,对一个32位浮点数向量逐元素应用Sigmoid激活函数。 对于输入向量XX中的每一个元素xx,计算

sigmoid(x)=11+ex\mathrm{sigmoid}(x)=\frac{1}{1+e^{-x}}

并将结果存储到输出向量YY当中,Sigmoid函数将任意实数映射至区间(0,1)(0,1)内。

实现要求:

  • 仅允许C/CUDA runtime库
  • 最终结果存储在Y当中

示例输入/输出#

请自行测试:

示例1:

输入 X = [0.0, 1.0, -1.0, 2.0]
输出 Y = [0.5, 0.7311, 0.2689, 0.8808]

示例2:

输入 X = [0.5, -0.5, 3.0, -3.0]
输出 Y = [0.6225, 0.3775, 0.9526, 0.0474]

模板代码#

CUDA版#

你只需要填写sigmoid_kernel。
#include <stdio.h>
#include <cuda_runtime.h>
#include <math.h>
// ========== 请在此处实现 sigmoid_kernel ==========
__global__ void sigmoid_kernel(float* x, float* y, int N) {
// TODO: 计算全局索引,确保不越界,计算 sigmoid
// 提示: 使用 expf 进行指数运算
}
// =================================================
int main() {
// 典型测试值
float typical_vals[] = {-10.0f, -5.0f, -2.0f, -1.0f, -0.5f,
0.0f, 0.5f, 1.0f, 2.0f, 5.0f, 10.0f};
int num_typical = sizeof(typical_vals) / sizeof(float);
int repeat = 100000; // 每个典型值重复次数
int N = num_typical * repeat;
size_t bytes = N * sizeof(float);
// 主机内存分配与初始化
float* hx = (float*)malloc(bytes);
float* hy = (float*)malloc(bytes);
for (int r = 0; r < repeat; r++) {
for (int i = 0; i < num_typical; i++) {
hx[r * num_typical + i] = typical_vals[i];
}
}
// 设备内存分配与数据拷贝
float *dx, *dy;
cudaMalloc(&dx, bytes);
cudaMalloc(&dy, bytes);
cudaMemcpy(dx, hx, bytes, cudaMemcpyHostToDevice);
// 配置内核启动参数
int threads_per_block = 256;
int blocks_per_grid = (N + threads_per_block - 1) / threads_per_block;
// 启动内核
sigmoid_kernel<<<blocks_per_grid, threads_per_block>>>(dx, dy, N);
cudaDeviceSynchronize(); // 等待内核完成
// 结果拷贝回主机
cudaMemcpy(hy, dy, bytes, cudaMemcpyDeviceToHost);
printf(" x -> sigmoid(x)\n");
printf("-----------------------\n");
for (int i = 0; i < num_typical; i++) {
printf("%6.2f -> %8.6f\n", hx[i], hy[i]);
}
// 释放内存
free(hx);
free(hy);
cudaFree(dx);
cudaFree(dy);
cudaDeviceReset();
return 0;
}

Triton版#

import torch
import triton
import triton.language as tl
# ========== 请在此处实现 sigmoid_kernel ==========
@triton.jit
def sigmoid_kernel(x_ptr, y_ptr, N, BLOCK_SIZE: tl.constexpr):
# TODO: 获取当前程序的起始索引
pass
def solve(X):
N = X.numel()
Y = torch.empty_like(X)
# 配置 block 大小和 grid 大小
BLOCK_SIZE = 256
grid = (triton.cdiv(N, BLOCK_SIZE),)
sigmoid_kernel[grid](X, Y, N, BLOCK_SIZE=BLOCK_SIZE)
return Y
def main():
# 典型测试值
typical_vals = torch.tensor([-10.0, -5.0, -2.0, -1.0, -0.5,
0.0, 0.5, 1.0, 2.0, 5.0, 10.0], dtype=torch.float32)
num_typical = typical_vals.numel()
repeat = 100000
N = num_typical * repeat
hx = typical_vals.repeat(repeat).cuda()
# 调用 solve
hy = solve(hx)
# 打印结果
print(" x -> sigmoid(x)")
print("-----------------------")
for i in range(num_typical):
print(f"{hx[i]:6.2f} -> {hy[i]:8.6f}")
if __name__ == "__main__":
main()

Pytorch版#

import torch
# ========== 请在此处实现 sigmoid 函数 ==========
def sigmoid(x):
# 手动实现 sigmoid 函数
return torch.sigmoid(x)
def solve(X):
return sigmoid(X)
def main():
# 典型测试值
typical_vals = torch.tensor([-10.0, -5.0, -2.0, -1.0, -0.5,
0.0, 0.5, 1.0, 2.0, 5.0, 10.0], dtype=torch.float32)
num_typical = typical_vals.numel()
repeat = 100000
N = num_typical * repeat
hx = typical_vals.repeat(repeat).cuda()
hy = solve(hx)
print(" x -> sigmoid(x)")
print("-----------------------")
for i in range(num_typical):
print(f"{hx[i]:6.2f} -> {hy[i]:8.6f}")
if __name__ == "__main__":
main()

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或赞助支持!

赞助
LeetGPU习题01:Sigmoid手动实现
https://dlog.com.cn/posts/leetgpu01/sigmoid/
作者
杜子源
发布于
2026-04-11
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
杜子源
都是风景,幸会
公告
如果需要原图,请私信联系我。
音乐
封面

音乐

暂未播放

0:00 0:00
暂无歌词
分类
标签
站点统计
文章
9
分类
5
标签
6
总字数
15,516
运行时长
0
最后活动
0 天前

目录