c# - 非常奇怪 - 当我使用断点时,代码(随机)的工作方式不同

标签 c# debugging

我正在做一个神经网络项目,我有 2 个这样的类:

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());
        }
    }

当我尝试创建网络并显示它的“内容”时:

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];
   }
}

当我运行该代码时 - 我得到这样的结果(所有权重都相同):

enter image description here

当我看到它时 - 我试图调试并发现我的错误。但是,当我在神经元构造函数中放置断点时 - 我的网络会按照我的意愿进行初始化(权重不同):

enter image description here

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

谁能解释一下这里发生了什么?

魔法?

最佳答案

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

据推测,断点为 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(因此引入延迟时会有所不同)。如果您每次都必须创建一个新实例,您也可以提供自己的种子。

此行为已记录 here ,特别是:

...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.

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

关于c# - 非常奇怪 - 当我使用断点时,代码(随机)的工作方式不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15162048/

相关文章:

c# - 我可以通过 ClosedXML 将 EXCEL 工作表保存为 CSV 格式吗?

c# - as 关键字可以代替 try/catch block 吗?

javascript - ionic / Cordova : How to debug JavaScript codes that require "cordova.js" library in a web-browser

.net - 在运行时调试.net?

c# - access数据库中如何查看用户名和密码

c# - ASP.NET Core - 无法在 Controller 内使用 C# StreamReader 读取静态 HTML 文件

c# - 具有 IEnumerable<ISomeInterface> 类型属性的 NewtonSoft.Json 序列化和反序列化类

ruby-on-rails - 使用 Rubymine 调试时如何不进入 gems

linux - addr2line如何定位源文件和代码行?

objective-c - 在调试器中观察 NSString 长度