我的Arduino 101内存不足吗?

时间:2017-05-12 16:04:08

标签: python c++ arduino

编辑:更新了更少的示例

我正在Arduino 101上实现一个人工神经网络,当实例化一个有8个输入节点,7个隐藏节点和4个输出节点(small_network)的网络时,它运行正常并完成~10KB的实例化留下记忆。

同样,当我尝试使用具有20个输入节点,10个隐藏节点和1个输出节点的网络做同样的事情时,它完成实例化,剩下大约8KB的内存。

但是,当我尝试使用具有20个输入节点, 20 隐藏节点和1个输出节点的网络执行相同操作时,它只是在调整矢量大小的中途停止。这看起来我的内存不足,但是101有24KB的SRAM,并且存储那么多浮点数只需要~2KB;使用freeMemory()检查可用内存还确认在调整失败的向量大小之前仍有超过9KB的空闲空间。

以下是Network类的头文件(包含using std::vector的道歉;我会修复它,我保证):

#include <MemoryFree.h>
#include <avr/pgmspace.h>

#ifndef NETWORK_H
#define NETWORK_H

#include <vector>
#include <random>
#include "Arduino.h"

using std::vector;

class Network {
    private:
        const int numInputNodes;                    // AKA 'InputNodes' in the original code
        const int numHiddenNodes;                   // AKA 'HiddenNodes' in the original code
        const int numOutputNodes;                   // AKA 'OutputNodes' in the original code
        float learningRate;                         // AKA 'LearningRate' in the original code
        float momentum;                             // AKA 'Momentum' in the original code
        float initialWeightMax;                     // AKA 'InitialWeightMax' in the original code

        long trainingCycle;                         // AKA 'TrainingCycle' in the original code
        float randomFloat;                          // AKA 'Rando' in the original code
        float errorRate;                            // AKA 'Error' in the original code
        float accumulatedInput;                     // AKA 'Accum' in the original code

        vector<float> hiddenNodes;                  // AKA 'Hidden' in the original code
        vector<float> outputNodes;                  // AKA 'Output' in the original code
        vector<vector<float>> hiddenWeights;        // AKA 'HiddenWeights' in the original code
        vector<vector<float>> outputWeights;        // AKA 'OutputWeights' in the original code
        vector<float> hiddenNodesDeltas;            // AKA 'HiddenDelta' in the original code
        vector<float> outputNodesDeltas;            // AKA 'OutputDelta' in the original code
        vector<vector<float>> hiddenWeightsChanges; // AKA 'ChangeHiddenWeights' in the original code
        vector<vector<float>> outputWeightsChanges; // AKA 'ChangeOutputWeights' in the original code

        void initialiseHiddenWeights();
        void initialiseOutputWeights();
        void computeHiddenLayerActivations(vector<float> inputs);
        void computeOutputLayerActivations();
        void computeErrors(vector<float> targets);
        void backpropagateErrors();
        void updateHiddenWeights(vector<float> inputs);
        void updateOutputWeights();
        void setHiddenWeights(vector<vector<float>> hiddenWeights);
        void setOutputWeights(vector<vector<float>> outputWeights);

    public:
        Network(int numInputNodes,
                int numHiddenNodes,
                int numOutputNodes,
                float learningRate,
                float momentum,
                float initialWeightMax);
        float trainNetwork(vector<float> inputs,
                           vector<float> targets);
        vector<float> classify(vector<float> inputs);
        void loadWeights(vector<vector<float>> hiddenWeights,
                         vector<vector<float>> outputWeights);

        int getNumInputNodes() const;
        int getNumHiddenNodes() const;
        int getNumOutputNodes() const;
        float getLearningRate() const;
        float getMomentum() const;
        float getInitialWeightMax() const;
        long getTrainingCycle() const;
        float getRandomFloat() const;
        float getErrorRate() const;
        float getAccumulatedInput() const;
        const vector<float> getHiddenNodes() const;
        const vector<float> getOutputNodes() const;
        const vector<float> getHiddenNodesDeltas() const;
        const vector<float> getOutputNodesDeltas() const;
        const vector<vector<float>> getHiddenWeights() const;
        const vector<vector<float>> getOutputWeights() const;
        const vector<vector<float>> getHiddenWeightsChanges() const;
        const vector<vector<float>> getOutputWeightsChanges() const;
        void setLearningRate(float learningRate);
        void setMomentum(float momentum);
        void setInitialWeightMax(float initialWeightMax);
};

#endif

以下是Network类的构造函数代码(我省略了其他函数实现):

Network::Network(int numInputNodes,
             int numHiddenNodes,
             int numOutputNodes,
             float learningRate,
             float momentum,
             float initialWeightMax):
             numInputNodes(numInputNodes),
             numHiddenNodes(numHiddenNodes),
             numOutputNodes(numOutputNodes),
             learningRate(learningRate),
             momentum(momentum),
             initialWeightMax(initialWeightMax) {

Serial.println(F("In constructor"));
Serial.print(F("Free memory: "));
Serial.println(freeMemory());


trainingCycle = 0;
randomFloat = 0.0f;
errorRate = 0.0f;
accumulatedInput = 0.0f;

Serial.println(F("Resizing vectors..."));
Serial.print(F("Free memory: "));
Serial.println(freeMemory());

hiddenNodes.resize(numHiddenNodes);
outputNodes.resize(numOutputNodes);

Serial.println(F("Nodes done, Resizing weights..."));
Serial.print(F("Free memory: "));
Serial.println(freeMemory());

hiddenWeights.resize(numInputNodes+1, vector<float>(numHiddenNodes));
outputWeights.resize(numHiddenNodes+1, vector<float>(numOutputNodes));

Serial.println(F("Weights done, Resizing deltas..."));    
Serial.print(F("Free memory: "));
Serial.println(freeMemory());

hiddenNodesDeltas.resize(numHiddenNodes);

Serial.println(F("hiddenNodesDeltas done, Resizing outputNodesDeltas..."));    
Serial.print(F("Free memory: "));
Serial.println(freeMemory());

outputNodesDeltas.resize(numOutputNodes);

Serial.println(F("Deltas done, Resizing changes..."));
Serial.print(F("Free memory: "));
Serial.println(freeMemory());

hiddenWeightsChanges.resize(numInputNodes+1, vector<float>(numHiddenNodes));
outputWeightsChanges.resize(numHiddenNodes+1, vector<float>(numOutputNodes));

Serial.println(F("finished resizing"));
Serial.print(F("Free memory: "));
Serial.println(freeMemory());

initialiseHiddenWeights();
initialiseOutputWeights();

Serial.println(F("Finished constructor"));
Serial.print(F("Free memory: "));
Serial.println(freeMemory());
}

以下是调用它的代码:

#include <ArduinoSTL.h>
#include <avr/pgmspace.h>

#include "network.hpp"

int numInputNodes = 20;
int numHiddenNodes = 10;
int numOutputNodes = 1;
float learningRate = 0.3;
float momentum = 0.9;
float initialWeightMax = 0.5;

Network *network;

void setup() {
  /* Initialise Serial communication */
  Serial.begin(115200);
  while(!Serial) ;

  /* Wait for script to notify readiness */
  while (!Serial.available()) {
    Serial.println(F("Ready"));
  }

  delay(1000);

  Serial.print(F("Free memory before initialisation: "));
  Serial.println(freeMemory());

  /* Init network */
  network = new Network(numInputNodes,
                     numHiddenNodes,
                     numOutputNodes,
                     learningRate,
                     momentum,
                     initialWeightMax);
}

void loop() {
  Serial.println(F("Running..."));
  Serial.print(F("Free memory: "));
  Serial.println(freeMemory());
  delay(1000);
}

这是与Arduino over Serial:

进行通信的Python脚本
#!/usr/bin/python

import serial, time, sys

# Open a Serial connection to the Arduino:
print "Connecting..."
try:
    arduino = serial.Serial('/dev/ttyACM0', 115200, timeout=1)
except:
    print "Failed to connect on /dev/ttyACM0"
    sys.exit(2)

print "success"

msg = ""
while "Ready" not in msg:
    msg = arduino.readline()
    print msg

arduino.write('#')

while True:
    line = arduino.readline()
    print line

具有8/7/4神经元的网络提供以下输出:

user@machine:~/project$ ./monitor.py 
Connecting...
success
Ready

Free memory before initialisation: 14196

In constructor

Free memory: 13252

Resizing vectors...

Free memory: 13252

Nodes done, Resizing weights...

Free memory: 13252

Weights done, Resizing deltas...

Free memory: 12076

hiddenNodesDeltas done, Resizing outputNodesDeltas...

Free memory: 12076

Deltas done, Resizing changes...

Free memory: 12076

finished resizing

Free memory: 10900

Finished constructor

Free memory: 10900

Running...

Free memory: 10968

具有20/10/1神经元的网络也是如此,但完成了7976B的内存

具有20/20/1神经元的网络提供以下内容:

user@machine:~/project$ ./monitor.py 
Connecting...
success
Ready

Ready

Ready

Ready

Ready

Free memory before initialisation: 14196

In constructor

Free memory: 13252

Resizing vectors...

Free memory: 13252

Nodes done, Resizing weights...

Free memory: 13172

Weights done, Resizing deltas...

Free memory: 9140

hiddenNodesDeltas done, Resizing outputNodesDeltas...

Free memory: 9060

Deltas done, Resizing changes...

Free memory: 9060

我已经看到了相关的问题,this one看似相似,但没有得到正确回答,所有其他问题似乎都更加直截了当。

那么,是我的Arduino 101内存不足,如果是这样,为什么memoryFree()认为还剩下很多?如果没有,它在做什么?

(这是我的第一个StackOverflow问题,所以如果我错过任何错误或犯了任何错误,请告诉我,我会尽力纠正。

0 个答案:

没有答案