大佬教程收集整理的这篇文章主要介绍了c – 我的神经网络导致堆栈溢出,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我@L_616_4@了一些我认为对问题不重要的课程等.
神经元
template<std::size_t NumInputs> class Neuron { public: Neuron() { for(auto& i : m_inputValues) i = 0; for(auto& e : m_eligibilityTraces) e = 0; for(auto& w : m_weights) w = 0; m_biasWeight = 0; m_biasEligibilityTrace = 0; m_outputValue = 0; } void SeTinputValue(const std::size_t index,const double value) { m_inputValues[index] = value; } void SetWeight(const std::size_t index,const double weight) { if(std::isnan(weight)) throw std::runtime_error("Shit! this is a nan bread"); m_weights[index] = weight; } void SetBiasWeight(const double weight) { m_biasWeight = weight; } double GeTinputValue(const std::size_t indeX) const { return m_inputValues[index]; } double GetWeight(const std::size_t indeX) const { return m_weights[index]; } double GetBiasWeight() const { return m_biasWeight; } double CalculateOutput() { double m_outputValue = 0; for(std::size_t i = 0; i < NumInputs; ++i) { m_outputValue += m_inputValues[i] * m_weights[i]; } m_outputValue += 1.0 * m_biasWeight; m_outputValue = sigmoid(m_outputvalue); return m_outputValue; } double GetOutput() const { return m_outputValue; } double GetEligibilityTrace(const std::size_t indeX) const { return m_eligibilityTraces[index]; } void SetEligibilityTrace(const std::size_t index,const double eligibility) { m_eligibilityTraces[index] = eligibility; } void SetBiasEligibility(const double eligibility) { m_biasEligibilityTrace = eligibility; } double GetBiasEligibility() const { return m_biasEligibilityTrace; } private: std::array<double,NumInputs> m_inputValues; std::array<double,NumInputs> m_weights; std::array<double,NumInputs> m_eligibilityTraces; double m_biasWeight; double m_biasEligibilityTrace; double m_outputValue; };
神经网络
template<std::size_t NumInputs,std::size_t NumHidden,std::size_t NumOutputs> class NeuralNetwork { public: ... std::array<double,NumOutputs> FeedForWARD(const std::array<double,NumInputs>& inputValues) { for(auto& hiddenNeuron : m_hiddenNeurons) { for(std::size_t i = 0; i < NumInputs; ++i) hiddenNeuron.SeTinputValue(i,inputValues[i]); hiddenNeuron.CalculateOutput(); } std::array<double,NumOutputs> returnValue; for(std::size_t h = 0; h < NumHidden; ++h) { auto hiddenOutput = m_hiddenNeurons[h].GetOutput(); for(std::size_t o = 0; o < NumOutputs; ++o) m_outputNeurons[o].SeTinputValue(h,hiddenOutput); } for(std::size_t o = 0; o < NumOutputs; ++o) { returnValue[o] = m_outputNeurons[o].CalculateOutput(); } return returnValue; } private: std::array<Neuron<NumInputs>,NumHidden> m_hiddenNeurons; std::array<Neuron<NumHidden>,NumOutputs> m_outputNeurons; };
一切都适用于NeuralNetwork< 86,86,2>但在考虑到我需要更多输入变量之后,即NeuralNetwork< 170,170,2>当我启用-O2编译器标志时,FeedForWARD方法会产生堆栈溢出.使用-g标志设置不会产生此问题.
如果我@L_616_4@FeedForWARD方法的这一部分,我不会得到堆栈溢出:
for(std::size_t h = 0; h < NumHidden; ++h) { auto hiddenOutput = m_hiddenNeurons[h].GetOutput(); for(std::size_t o = 0; o < NumOutputs; ++o) m_outputNeurons[o].SeTinputValue(h,hiddenOutput); }
我无法理解为什么会产生堆栈溢出.隐藏单位数为170,输出单位数为2;当然这还不足以导致溢出,特别是考虑到上面我通过170输入循环到170个隐藏单位.
正如您在Neuron类中看到的,GetOutput()方法不涉及任何其他函数调用,SeTinputValue()也不会执行任何类似的操作.没有递归.
@L_616_4@的部分没有内循环工作正常.但是下面的循环会导致堆栈溢出.
即这会导致堆栈溢出:
for(std::size_t h = 0; h < NumHidden; ++h) { auto hiddenOutput = m_hiddenNeurons[h].GetOutput(); // for(std::size_t o = 0; o < NumOutputs; ++o) // m_outputNeurons[o].SeTinputValue(h,hiddenOutput); } for(std::size_t o = 0; o < NumOutputs; ++o) { returnValue[o] = m_outputNeurons[o].CalculateOutput(); }
然而,这不是:
for(std::size_t h = 0; h < NumHidden; ++h) { auto hiddenOutput = m_hiddenNeurons[h].GetOutput(); // for(std::size_t o = 0; o < NumOutputs; ++o) // m_outputNeurons[o].SeTinputValue(h,hiddenOutput); } for(std::size_t o = 0; o < NumOutputs; ++o) { //returnValue[o] = m_outputNeurons[o].CalculateOutput(); }
这没有任何意义,因为循环不是嵌套的……
一旦将第一个非空字节写入保护页面,它就会触发页面错误(如果写入该地址是合法的,则共享空页将被RAM中的实际页面替换).结果,然后检测到堆栈溢出,因为不应该写入该地址.
在你的情况下,你实际上已经离开了堆栈,并且分配后的所有内容都已经与堆发生冲突.你只是没注意到,因为后卫没有触发并完全被跳过.
将空页面映射到有效堆栈区域下方,而不是保留读取保护的保护页面或将其完全取消映射,这是特定于环境的.
堆栈和堆堆叠在一起,实际上你可以完全跳过防护页面,并且配置足够大,也是特定于环境的.根据您使用的编译器,您可以通过一个选项来捕获此错误,该选项强制堆栈分配以增量方式发生,一次最多一页. (例如 – 海湾合作委员会的检查 – )
使用像Valgrind这样的工具,它可以设置一个更加防御的环境来更容易地捕获这样的错误.然后,这将在创建数组时触发,而不是仅在第一次非零写入时触发.
以上是大佬教程为你收集整理的c – 我的神经网络导致堆栈溢出全部内容,希望文章能够帮你解决c – 我的神经网络导致堆栈溢出所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。