Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Very weird - code (with Random) works different when I use breakpoint

Tags:

c#

debugging

I'm working on a neural networks project and I have 2 classes like this:

public class Net
{
    // Net object is made of neurons
    public List<Neuron> Neurons = new List<Neuron>();

    // neurons are created in Net class constructor
    public Net(int neuronCount, int neuronInputs)
    {
        for (int n = 0; n < neuronCount; n++)
        {
            Neurons.Add(new Neuron(n, neuronInputs));
        }
    }
}

public class Neuron
{
    public int index; // neuron has index

    public List<double> weights = new List<double>(); // and list of weights

    // Neuron constructor is supposed to add random weights to new neuron
    public Neuron(int neuronIndex, int neuronInputs)
    {
        Random rnd = new Random();

        for (int i = 0; i < neuronInputs; i++)
        {
            this.index = neuronIndex;
            this.weights.Add(rnd.NextDouble());
        }
    }

When I try to create network and display it's "contents":

Neuro.Net Network = new Neuro.Net(4, 4); // creating network with 4 neurons with 4 weights each

// dgv is a DataGridView for weights preview
dgv.Rows.Clear();
dgv.Columns.Clear();

// creating columns
foreach (Neuro.Neuron neuron in Network.Neurons)
{
    dgv.Columns.Add("colN" + neuron.index, "N" + neuron.index);
}

dgv.Rows.Add(Network.Neurons[0].weights.Count());

for (int n = 0; n < Network.Neurons.Count(); n++)
{
   for (int w = 0; w < Network.Neurons[n].weights.Count(); w++)
   {
       dgv.Rows[w].Cells[n].Value = Network.Neurons[n].weights[w];
   }
}

When I run that code - I'm getting something like this (all weights are identical):

enter image description here

When I saw it - I tried to debug and find my mistake. However, when I put breakpoint in the neuron constructor - my network initializes as I want (weights are different):

enter image description here

I tried to use Debug and Release configurations - same results.

Can someone explain what is going on here?

Magic?

like image 278
Kamil Avatar asked Mar 01 '13 16:03

Kamil


People also ask

Why breakpoint is not hitting with vs code?

If a source file has changed and the source no longer matches the code you're debugging, the debugger won't set breakpoints in the code by default. Normally, this problem happens when a source file is changed, but the source code wasn't rebuilt. To fix this issue, rebuild the project.

Why breakpoint is not working in Visual Studio?

NET Framework 2.0-based application. However, the Devenv.exe configuration files force the application to load as a . NET Framework 4.0-based application. Therefore, Visual Studio debugs the application in the wrong runtime, and this causes the breakpoints not to be hit.

How do you fix the breakpoint will not currently be hit VS 2022?

Right mouse click your project. Select [Properties] Select the [Build] tab. Make sure [Define DEBUG constant] and [Define TRACE constant] are checked.


1 Answers

However, when I put breakpoint in neuron constructor - my network initializes as I want (neurons are diffrent):

Presumably, the breakpoint introduces enough of a delay for Random() to be seeded with a different number. The delay can be caused by you pausing in the code (obviously) or even the non-matching evaluation of a conditional breakpoint (which slows execution slightly).

It would be better to have:

private static readonly Random _random = new Random();

And call _random.Next() without creating a new instance, such as:

public Neuron(int neuronIndex, int neuronInputs)
{
    for (int i = 0; i < neuronInputs; i++)
    {
        this.index = neuronIndex;
        this.weights.Add(_random.NextDouble());
    }
}

The parameterless constructor of Random uses Environment.TickCount (hence the difference when a delay is introduced). You could also provide your own seed if you must create a new instance every time.

This behavior is documented here, specifically:

...because the clock has finite resolution, using the parameterless constructor to create different Random objects in close succession creates random number generators that produce identical sequences of random numbers. [...] This problem can be avoided by creating a single Random object rather than multiple ones.

Alternatively, you could use System.Security.Cryptography.RNGCryptoServiceProvider.

like image 124
Tim M. Avatar answered Oct 25 '22 01:10

Tim M.