C# 到 F#:在 F# 中创建和使用 float[][]

Chr*_*ans 4 c# arrays f# machine-learning neural-network

我有一个简单的 C# 神经网络方法:

  private void InitNeurons()
    {
        //Neuron Initilization
        List<float[]> neuronsList = new List<float[]>();

        for (int i = 0; i < _layers.Length; i++) //run through all layers
        {
            neuronsList.Add(new float[_layers[i]]); //add layer to neuron list
        }

        _neurons = neuronsList.ToArray(); //convert list to array
    }
Run Code Online (Sandbox Code Playgroud)

我如何在 F# 中做到这一点?我在想它可以更简单。也许像这样?

namespace NeuralNetwork

type NeuralNetworkF(layers : int[]) = 
    member this.Layers = layers
    member this.Neurons : float[][] = [| for layer in layers do new float[]|]
Run Code Online (Sandbox Code Playgroud)

这会导致 F# 中的编译器错误。我想获取 int 数组“_layers”的大小,并对每个值进行迭代并将该值添加到 F# 中的 Neurons 成员中。

Fyo*_*kin 5

您尝试创建数组的new float[]方式在 F# 中是无效的语法。数组的正确语法是[| 1; 2; 3 |],或者对于空数组,它只是[| |]. 元素的类型不需要指定,编译器会从上下文中推断出来。但是,如果您真的想明确表示,您仍然可以通过冒号指定类型,就像您可以使用任何表达式一样:[| |] : float[]

但是,无论如何,这对您来说都是无用的,因为您要做的不是创建一个具有已知元素的数组,而是创建一个已知长度的数组。为此,有一些函数,这里对您有用的函数是Array.create. 它接受两个参数 - 大小和值, - 并返回一个具有该大小的数组,其中每个元素都是该值。

type NeuralNetworkF(layers : int[]) = 
    member this.Layers = layers
    member this.Neurons : float[][] = [| for layer in layers -> Array.create layer 0.0 |]
Run Code Online (Sandbox Code Playgroud)

请注意,在上面的代码我也更换do->。这是你遇到的第二个问题。你看,do执行一个“动作”,这不一定会产生一个项目,例如:

let xs = [ for n in 1..10 do 
             if n > 5 then yield n ]
Run Code Online (Sandbox Code Playgroud)

这将产生一个数字列表6to 10- not 1to 10- 因为它只在 时产生一个元素n > 5。该yield关键字是什么产生的元素。因此,如果您想为代码中的每一层生成一个数组,则必须使用yield该数组:

[| for layer in layers do yield Array.create layer 0.0 |]
Run Code Online (Sandbox Code Playgroud)

这有效,但有一个快捷方式:箭头->代表do yield,因此您可以使用它。

[| for layer in layers -> Array.create layer 0.0 |]
Run Code Online (Sandbox Code Playgroud)

最后,问你一个问题:你真的需要上课吗?课程是 wibbly-wobbly-timey-whimey,所以除非你有充分的理由,否则我建议去记录。