很奇怪 - 代码(随机)的作品不同,当我使用断点 [英] Very weird - code (with Random) works different when I use breakpoint
问题描述
我工作的一个神经网络的项目,我有2个班是这样的:
公共类网
{
// .NET对象是由神经元
公开名单<的;神经元与GT;神经元=新的List<&神经GT;();
//神经元的净类的构造函数
公网创建(INT neuronCount,诠释neuronInputs)
{
为(INT N = 0; N< neuronCount ; N ++)
{
Neurons.Add(新神经元(N,neuronInputs));
}
}
}
公共类神经元
{
公众诠释指数; //神经元有指数
公开名单<双>权重=新的List<双>(); //和权重
//神经元构造的名单应该是随机权增加新的神经元
公众神经元(INT neuronIndex,诠释neuronInputs)
{
随机RND =新的随机();
的for(int i = 0; I< neuronInputs;我++)
{
this.index = neuronIndex;
this.weights.Add(rnd.NextDouble());
}
}
当我尝试创建网络并显示它的内容
Neuro.Net网络=新Neuro.Net(4,4); //创建网络4神经元4的权重各
// DGV是权重预览
dgv.Rows.Clear一个DataGridView();
dgv.Columns.Clear();
//创建列
的foreach(Neuro.Neuron在Network.Neurons神经元)
{
dgv.Columns.Add(科隆+ neuron.index, N+ neuron.index);
}
dgv.Rows.Add(Network.Neurons [0] .weights.Count());
为(INT N = 0; N< Network.Neurons.Count(); N ++)
{
为(INT W = 0; W< Network.Neurons [N] .weights.Count(); W-- ++)
{
dgv.Rows [W] .Cells [N]。价值= Network.Neurons [N] .weights [W]
}
}
当我运行的代码 - 我m到处是这样的(所有的重量是相同的):
当我看到它 - 我试着调试和找到我的错误。然而,当我把断点在神经元中构造 - 我的网络初始化,因为我想(权重是不同的):
我试图用调试和发布配置 - 同结果。
有人能解释这是怎么回事吗?
魔术
然而,当我把断点神经构造 - 我网络
初始化,因为我想(神经元是不同势):
块引用>
据推测,断点引入足够的延迟为
随机()
用不同数量的种子。延迟可以由您的代码(明显)暂停或者甚至条件断点的非匹配评价(其减慢执行略)而引起。
这将是最好有:
私有静态只读随机_random =新的随机();
和调用
_random.Next()
无创建一个新的实例,如:公众神经元(INT neuronIndex,诠释neuronInputs)
{
的for(int i = 0; I< neuronInputs;我++)
{
this.index = neuronIndex;
this.weights.Add(_random.NextDouble());
}
}
随机使用
Environment.TickCount
(因此当引入的延迟的差异)。你也可以提供自己的种子,如果你必须每次创建新实例。
这行为被记录在案的这里,具体为:
。 ..because时钟具有有限的分辨率,采用了无参数
构造函数来创建紧密相继
不同的随机对象创建产生
随机数相同序列的随机数发生器。 [...]这个问题可以通过创建一个单一
随机对象,而不是多个可以避免的。
块引用>
另外,你可以使用
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屋!