我有以下功能
let private sigmoid (z:float) =
1.0 / (1.0 + exp(-z))
let private sigmoidM (z : Matrix<float>) : Matrix<float> =
z.Map (fun x -> sigmoid(x))
let private sigmoidV (z:Vector<float>) =
z.Map(fun x -> sigmoid(x))
我想只有sigmoid并根据输入执行标量,向量或矩阵。
也就是说,这个函数需要非常高效,因为它在循环的最关键部分。有关如何做到这一点的任何见解?如果它很慢,请随意发布如何缓慢。
答案 0 :(得分:5)
您可以使用标准.NET重载:
open MathNet.Numerics.LinearAlgebra
type Sigmoid() = class end with
static member sigmoid (z:float) = 1.0 / (1.0 + exp(-z))
static member sigmoid (z:Matrix<float>) = z.Map (fun x -> Sigmoid.sigmoid(x))
static member sigmoid (z:Vector<float>) = z.Map (fun x -> Sigmoid.sigmoid(x))
// Usage
let x = Sigmoid.sigmoid 4.3
let y = Sigmoid.sigmoid (matrix [[1.0; 2.0]; [3.0; 4.0]])
let z = Sigmoid.sigmoid (vector [1.0; 2.0])
// Results
val x : float = 0.9866130822
val y : Matrix<float> =
DenseMatrix 2x2-Double
0.731059 0.880797
0.952574 0.982014
val z : Vector<float> = seq [0.7310585786; 0.880797078]
这不会影响性能,因为重载解析是在编译时完成的。
对标准.NET重载不满意吗?不想将该功能编码为成员?你想让它更通用(也接受float32)并可扩展到其他类型吗?
使用静态类型约束:
type Sigmoid() = class end with
static member Sigmoid (_:Sigmoid, z:float ) = 1.0 / (1.0 + exp(-z))
static member Sigmoid (_:Sigmoid, z:float32) = 1.0f / (1.0f + exp(-z))
let inline _sigmoid (s:'Sigmoid) (x:'T) :'T =
((^T or ^Sigmoid) : (static member Sigmoid : 'Sigmoid * 'T -> 'T) (s, x))
let inline sigmoid x = _sigmoid (Sigmoid()) x
type Sigmoid with
static member inline Sigmoid (_:Sigmoid, z:Matrix<'T>) = z.Map (fun x -> sigmoid x)
static member inline Sigmoid (_:Sigmoid, z:Vector<'T>) = z.Map (fun x -> sigmoid x)
// Usage
let x = sigmoid 4.3
let y = sigmoid (matrix [[ 1.0; 2.0 ];[ 3.0; 4.0 ]])
let z = sigmoid (vector [ 1.0; 2.0 ])
let x' = sigmoid 4.3f
let y' = sigmoid (matrix [[1.0f; 2.0f];[ 3.0f; 4.0f]])
let z' = sigmoid (vector [ 1.0f; 2.0f])
<强>更新强>
请注意@TheInnerLight在评论中指出您还可以编写特定sigmoid
函数:
let inline sigmoid z =
LanguagePrimitives.GenericOne / (LanguagePrimitives.GenericOne + exp(-z))
这适用于float
和float32
这最终也适用于矢量和矩阵,具体取决于它们的实现。
如果所有操作都否定,除法和exp已经是这些类型的通用,并且它们都支持GenericOne,那对于您的特定情况来说这将是更好的解决方案。
不幸的是,截至今天,MathNet没有以这种方式为Matrix和Vector实现GenericOne
和exp
。