P-NET 所需要的基础数值算子
TensorOps
00 Remarks
这里的所有热路径算子都直接操作 Tensor.Data 所暴露的底层 Double 数组, 目的是规避 Tensor 默认索引器与 Tensor.MatMul 带来的额外开销 (Tensor.MatMul 为 O(n^3) 的三重循环且逐元素走属性索引器)。
张量本身仍然统一使用 Tensor 类型,本模块只是为其补充了若干运算工具。
01 Syntax
02 Methods
| Name | Overloads | Summary |
|---|---|---|
| RandomNormal | 1 | 生成服从正态分布的张量(Double 精度) |
| XavierInit | 1 | Xavier 初始化,适用于 sigmoid / tanh 这类对称有界激活函数 |
| Sigmoid | 1 | 数值稳定的 sigmoid 函数 |
| Tanh | 1 | 双曲正切函数,对应论文中隐藏层所使用的 f(x) = (e^2x - 1) / (e^2x + 1) |
| TanhActivate | 1 | 对矩阵逐元素施加 tanh 激活函数 |
| TanhDerivative | 1 | tanh 激活函数关于前一层激活值的导数,由激活值直接计算得到 1 - a^2 |
| AddBiasInPlace | 1 | 把偏置向量按列加到矩阵的每一行上 |
| FillBias | 1 | 用偏置向量填充矩阵(先把矩阵按行填为偏置的复制,再加上原有内容) |
| ColumnSum | 1 | 计算矩阵沿行方向(即按列)的累加和 |
| AccumulateColumnSum | 1 | 把矩阵沿行方向(即按列)累加到目标数组之上 |
| WeightedBinaryCrossEntropy | 1 | 计算带类别权重的二元交叉熵损失 |
| WeightedBCEGradient | 1 | 加权二元交叉熵损失关于预测概率的导数 |
| ClipProbability | 1 | 把概率值裁剪到 [Epsilon, 1 - Epsilon] 区间内,防止对数运算溢出 |
| Mean | 1 | 计算数组的均值 |
| StdDev | 1 | 计算数组的标准差 |
| ArgsortDescending | 1 | 返回按值降序排列的下标序列 |
03 Fields
| Name | Overloads | Summary |
|---|---|---|
| Epsilon | 2 | 数值计算中用于防止除零与对数溢出的极小正数(1e-12) |
04 Members
Int32(), Double, Double, Nullable(Of Int32))生成服从正态分布的张量(Double 精度)
Tensor.RandomNormal() 内部使用 CSng 把结果截断为单精度, 这里直接写 Double 数组,可以获得完整的双精度初始化值。
| Name | Type | Description |
|---|---|---|
shape | Int32() | 张量形状 |
mean | Double | 均值 |
stdDev | Double | 标准差 |
seed | Nullable(Of Int32) | 随机数种子,给出之后结果可复现 |
使用 Box-Muller 变换生成的正态随机张量
Int32, Int32, Nullable(Of Int32))Xavier 初始化,适用于 sigmoid / tanh 这类对称有界激活函数
| Name | Type | Description |
|---|---|---|
fanIn | Int32 | 输入维度 |
fanOut | Int32 | 输出维度 |
seed | Nullable(Of Int32) | 随机数种子 |
形状为 [fanIn, fanOut] 的权重张量
Double)数值稳定的 sigmoid 函数
| Name | Type | Description |
|---|---|---|
x | Double | 输入值 |
位于 (0, 1) 区间内的输出值
Double)双曲正切函数,对应论文中隐藏层所使用的 f(x) = (e^2x - 1) / (e^2x + 1)
| Name | Type | Description |
|---|---|---|
x | Double | 输入值 |
位于 (-1, 1) 区间内的输出值
Tensor)对矩阵逐元素施加 tanh 激活函数
| Name | Type | Description |
|---|---|---|
z | Tensor | 线性变换结果,形状为 [N, D] |
形状相同的激活值矩阵
Double)tanh 激活函数关于前一层激活值的导数,由激活值直接计算得到 1 - a^2
| Name | Type | Description |
|---|---|---|
a | Double | tanh 的输出值 |
导数值
Tensor, Tensor)把偏置向量按列加到矩阵的每一行上
这里不能使用 Tensor 的 + 运算符做广播: 该运算符在遇到 [1, n] + [m, 1] 时会触发"广播加法"特例产生外扩矩阵, 因此偏置相加必须显式写循环完成。
| Name | Type | Description |
|---|---|---|
m | Tensor | 形状为 [N, D] 的矩阵 |
bias | Tensor | 形状为 [1, D] 的偏置行向量 |
Tensor, Tensor)用偏置向量填充矩阵(先把矩阵按行填为偏置的复制,再加上原有内容)
| Name | Type | Description |
|---|---|---|
output | Tensor | 输出矩阵,形状为 [N, D] |
bias | Tensor | 形状为 [1, D] 的偏置行向量 |
Tensor)计算矩阵沿行方向(即按列)的累加和
| Name | Type | Description |
|---|---|---|
m | Tensor | 形状为 [N, D] 的矩阵 |
长度为 D 的列和数组
Tensor, Double())把矩阵沿行方向(即按列)累加到目标数组之上
| Name | Type | Description |
|---|---|---|
m | Tensor | 形状为 [N, D] 的矩阵 |
target | Double() | 长度为 D 的累加目标数组,计算会被原地累加进去 |
Double, Double, Double, Double)计算带类别权重的二元交叉熵损失
论文的数据集存在类别不平衡(333 例 CRPC / 转移性 对比 680 例原发性), 因此按照训练集中的类别比例对损失加权,以抑制模型向多数类偏移。
| Name | Type | Description |
|---|---|---|
p | Double | 预测概率,取值范围为 (0, 1) |
y | Double | 真实标签,取值为 0 或者 1 |
positiveWeight | Double | 正样本的损失权重 |
negativeWeight | Double | 负样本的损失权重 |
单个样本的加权二元交叉熵损失值
Double, Double, Double, Double)加权二元交叉熵损失关于预测概率的导数
| Name | Type | Description |
|---|---|---|
p | Double | 预测概率 |
y | Double | 真实标签 |
positiveWeight | Double | 正样本的损失权重 |
negativeWeight | Double | 负样本的损失权重 |
损失对预测概率的梯度
Double)把概率值裁剪到 [Epsilon, 1 - Epsilon] 区间内,防止对数运算溢出
| Name | Type | Description |
|---|---|---|
p | Double | 原始概率值 |
裁剪之后的概率值
Double())计算数组的均值
| Name | Type | Description |
|---|---|---|
x | Double() | 输入数组 |
算术平均值
Double())计算数组的标准差
| Name | Type | Description |
|---|---|---|
x | Double() | 输入数组 |
总体标准差
Double())返回按值降序排列的下标序列
| Name | Type | Description |
|---|---|---|
x | Double() | 输入数组 |
下标数组,result(0) 对应于原数组中最大值的下标
数值计算中用于防止除零与对数溢出的极小正数(1e-12)