非常奇怪 - 当我使用断点时,代码(随机)的作用不同 [英] Very weird - code (with Random) works different when I use breakpoint

查看:107
本文介绍了非常奇怪 - 当我使用断点时,代码(随机)的作用不同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究一个神经网络项目,我有两个这样的课程:

  public class Net 
{
//净对象由神经元
public List&Neoron>神经元=新List< Neuron>();

//神经元在Net类构造函数中创建
public Net(int neuronCount,int neuronInputs)
{
for(int n = 0; n {
Neurons.Add(new Neuron(n,neuronInputs));
}
}
}

public class Neuron
{
public int index; //神经元有索引

public List< double> weight = new List< double>(); //和权重列表

// Neuron构造函数应该为新神经元添加随机权重
public Neuron(int neuronIndex,int neuronInputs)
{
随机rnd = new Random(); (int i = 0; i< neuronInputs; i ++)


{
this.index = neuronIndex;
this.weights.Add(rnd.NextDouble());
}
}

当我尝试创建网络并显示它是内容:

  Neuro.Net Network = new Neuro.Net(4,4); //创建网络与4个神经元与4个权重每个

// dgv是一个DataGridView的权重预览
dgv.Rows.Clear();
dgv.Columns.Clear();

//创建列
foreach(Network.Neurons中的Neuro.Neuron神经元)
{
dgv.Columns.Add(colN+ neuron.index, N+ neuron.index);
}

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

当我运行该代码 - 得到这样的东西(所有权重相同):





当我看到它 - 我试图调试并发现我的错误。然而,当我在神经元构造函数中设置断点时,我的网络按照我的要求初始化(权重不同):





我尝试使用调试和发布配置 - 相同



有人可以解释这里发生了什么吗?



Magic?

解决方案


然而,当我将神经元构造函数中的断点 - 网络
根据需要初始化(神经元不同):


大概,断点引入足够的延迟时间 Random()用不同的数字种子。延迟可能是由于你暂停代码(显然),甚至是条件断点的非匹配评估(这会稍微减慢执行速度)。



更好地拥有:

  private static readonly Random _random = new Random(); 

并调用 _random.Next()创建一个新的实例,例如:

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

Random的无参数构造函数使用 Environment.TickCount (因此引入延迟的差异)。您还可以提供自己的种子,如果您必须每次都创建一个新的实例。



此行为已记录这里,具体来说:


。因为时钟具有有限的分辨率,使用无参数的
构造函数来紧密创建不同的随机对象
创建产生相同序列
随机数的随机数生成器。 [...]可以通过创建单个
随机对象而不是多个对象来避免此问题。


或者,您可以使用 System.Security.Cryptography.RNGCryptoServiceProvider


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):

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):

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

Can someone explain what is going on here?

Magic?

解决方案

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.

这篇关于非常奇怪 - 当我使用断点时,代码(随机)的作用不同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆