我很难给出一个最小的例子,因为我认为它与我的更多代码有关。但是,我相信我已经在下面提供了相关代码。
我删除了我认为对问题不是很重要的类等部分。
我有一个使用神经元的神经网络类:
神经元
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> FeedForward当我启用 -O2 时,方法会产生堆栈溢出编译器标志。 -g 不会产生此问题标志集。
如果我删除 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()也不做那样的事情。没有递归。
删除的部分在没有内部循环的情况下工作正常。但是下面的循环会导致堆栈溢出。
即这会导致堆栈溢出:
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();
}
这没有意义,因为循环没有嵌套...
最佳答案
堆栈溢出仅在第一个实际 写入堆栈边界外时检测到,分别是在实际到达保护页时。由于您正在用 0 初始化 Neuron 类中的所有内容,这使得您的 Neuron 最初都是 Nullbytes。这与您的环境将内存初始化为的内容完全匹配(实际上并未初始化,而是映射到仅包含 Nullbytes 的共享只读页面)。
一旦第一个非空字节被写入保护页面,它就会触发页面错误(如果写入该地址是合法的,则共享空页面将被 RAM 中的真实页面替换)。结果,检测到堆栈溢出,因为不应写入此地址。
在您的情况下,您实际上早已离开堆栈,并且分配后的所有内容都已经与堆发生冲突。您只是没有注意到,因为守卫没有触发并且被完全跳过了。
在有效堆栈区域下方映射一个空页面,而不是留下一个读保护保护页面或让它完全未映射是特定于环境的。
让堆栈和堆靠近在一起,您实际上可以完全跳过保护页面,分配足够大,这也是特定于环境的。根据您使用的编译器,您可以使用一个选项来捕获此错误,该选项强制堆栈分配以增量方式发生,一次最多一页。 (例如 GCC 的 -fstack-check。)
使用像 Valgrind 这样的工具来设置一个更具防御性的环境来更容易地捕获此类错误。这将在创建数组时触发,而不是仅在第一次非零写入时触发。
关于c++ - 我的神经网络导致堆栈溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47567390/
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R
我喜欢使用Textile或Markdown为我的项目编写自述文件,但是当我生成RDoc时,自述文件被解释为RDoc并且看起来非常糟糕。有没有办法让RDoc通过RedCloth或BlueCloth而不是它自己的格式化程序运行文件?它可以配置为自动检测文件后缀的格式吗?(例如README.textile通过RedCloth运行,但README.mdown通过BlueCloth运行) 最佳答案 使用YARD直接代替RDoc将允许您包含Textile或Markdown文件,只要它们的文件后缀是合理的。我经常使用类似于以下Rake任务的东西:
我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b
rails中是否有任何规定允许站点的所有AJAXPOST请求在没有authenticity_token的情况下通过?我有一个调用Controller方法的JqueryPOSTajax调用,但我没有在其中放置任何真实性代码,但调用成功。我的ApplicationController确实有'request_forgery_protection'并且我已经改变了config.action_controller.consider_all_requests_local在我的environments/development.rb中为false我还搜索了我的代码以确保我没有重载ajaxSend来发送
我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
网络编程套接字网络编程基础知识理解源`IP`地址和目的`IP`地址理解源MAC地址和目的MAC地址认识端口号理解端口号和进程ID理解源端口号和目的端口号认识`TCP`协议认识`UDP`协议网络字节序socket编程接口`sockaddr``UDP`网络程序服务器端代码逻辑:需要用到的接口服务器端代码`udp`客户端代码逻辑`udp`客户端代码`TCP`网络程序服务器代码逻辑多个版本服务器单进程版本多进程版本多线程版本线程池版本服务器端代码客户端代码逻辑客户端代码TCP协议通讯流程TCP协议的客户端/服务器程序流程三次握手(建立连接)数据传输四次挥手(断开连接)TCP和UDP对比网络编程基础知识
我正在开发我的第一个Rubygem,并捆绑了cucumber、rspec和shoulda-matches进行测试。当我运行rspec时,出现以下错误:/app/my_gem/spec/spec_helper.rb:6:in`':undefinedmethod`configure'forShoulda::Matchers:Module(NoMethodError)这是我的gem规范:#my_gem.gemspec...Gem::Specification.newdo|spec|......spec.add_development_dependency"activemodel"spec.a
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我