编辑:更新了更少的示例
我正在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问题,所以如果我错过任何错误或犯了任何错误,请告诉我,我会尽力纠正。