I have this simple method for a neural network in 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
}
How do I do this in F#? I was thinking it could be simpler. Perhaps something like this?
namespace NeuralNetwork
type NeuralNetworkF(layers : int[]) =
member this.Layers = layers
member this.Neurons : float[][] = [| for layer in layers do new float[]|]
This causes a compiler error in F#. I want to take the size of the int array "_layers" and for each value iterate over and add that value to the Neurons member in F#.
The way you're trying to create an array new float[]
is not valid syntax in F#. The correct syntax for an array is [| 1; 2; 3 |]
, or for empty array it would be just [| |]
. The type of elements does not need to be specified, the compiler will infer it from the context. But if you really want to be explicit, you can still specify the type via a colon, like you can with any expression: [| |] : float[]
.
However, that is all useless to you anyway, because what you're trying to do is not create an array with known elements, but create an array of a known length. For that, there are a few functions, and the one that would be useful to you here is Array.create
. It takes two arguments - the size and the value, - and it returns an array of that size, where every element is that value.
type NeuralNetworkF(layers : int[]) =
member this.Layers = layers
member this.Neurons : float[][] = [| for layer in layers -> Array.create layer 0.0 |]
Note that in the code above I've also replaced do
with ->
. This is the second problem you had. You see, do
performs an "action", which does not necessarily result in an item, e.g.:
let xs = [ for n in 1..10 do
if n > 5 then yield n ]
This will produce a list of numbers 6
to 10
- not 1
to 10
- because it only produces an element when n > 5
. The yield
keyword is what produces an element. So, if you wanted to produce an array for every layer in your code, you'd have to yield
that array:
[| for layer in layers do yield Array.create layer 0.0 |]
This works, but there is a shortcut: the arrow ->
stands for do yield
, so you can use it instead.
[| for layer in layers -> Array.create layer 0.0 |]
Finally, a question to you: do you really need a class? Classes are wibbly-wobbly-timey-whimey, so unless you have a good reason, I recommend going with a record.
Nice explanation there, @FyodorSoikin, but the following is probably even nicer:
let newNeuralNetwork (layers : _ []) =
fun i -> Array.zeroCreate<float> layers.[i]
|> Array.init layers.Length
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With