gpt4 book ai didi

c++ - 神经网络的输出每次都保持相同的值

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:49:56 24 4
gpt4 key购买 nike

我正在开发一个非常简单的前馈神经网络来练习我的编程技能。有 3 个类:

  • 神经网络::网络;构建网络,前馈输入值(暂时没有反向传播)
  • 神经网络::神经元;具有神经元的特征(索引、输出、权重等)
  • 神经网络::连接;一个类似结构的类,它随机化权重并保存输出、增量权重等。

该程序非常基础:我构建了具有 2 个隐藏层和随机权重的网络,然后要求它前馈相同的输入值。

我的问题是:预计每次运行后程序都会以不同的输出值结束,但输出始终相同。我尝试在各处放置标记以了解为什么它一遍又一遍地计算相同的东西,但我无法指出错误。

代码如下:

#include <iostream>
#include <cassert>
#include <cstdlib>
#include <vector>
#include "ConsoleColor.hpp"

using namespace std;

namespace Neural {
class Neuron;
typedef vector<Neuron> Layer;

// ******************** Class: Connection ******************** //
class Connection {
public:
Connection();
void setOutput(const double& outputVal) { myOutputVal = outputVal; }
void setWeight(const double& weight) { myDeltaWeight = myWeight - weight; myWeight = weight; }
double getOutput(void) const { return myOutputVal; }
double getWeight(void) const { return myWeight; }
private:
static double randomizeWeight(void) { return rand() / double(RAND_MAX); }
double myOutputVal;
double myWeight;
double myDeltaWeight;
};

Connection::Connection() {
myOutputVal = 0;
myWeight = Connection::randomizeWeight();
myDeltaWeight = myWeight;
cout << "Weight: " << myWeight << endl;
}

// ******************** Class: Neuron ************************ //
class Neuron {
public:
Neuron();
void setIndex(const unsigned int& index) { myIndex = index; }
void setOutput(const double& output) { myConnection.setOutput(output); }
unsigned int getIndex(void) const { return myIndex; }
double getOutput(void) const { return myConnection.getOutput(); }
void feedForward(const Layer& prevLayer);
void printOutput(void) const;

private:
inline static double transfer(const double& weightedSum);
Connection myConnection;
unsigned int myIndex;
};

Neuron::Neuron() : myIndex(0), myConnection() { }
double Neuron::transfer(const double& weightedSum) { return 1 / double((1 + exp(-weightedSum))); }
void Neuron::printOutput(void) const { cout << "Neuron " << myIndex << ':' << myConnection.getOutput() << endl; }
void Neuron::feedForward(const Layer& prevLayer) {
// Weight sum of the previous layer's output values
double weightedSum = 0;
for (unsigned int i = 0; i < prevLayer.size(); ++i) {
weightedSum += prevLayer[i].getOutput()*myConnection.getWeight();
cout << "Neuron " << i << " from prevLayer has output: " << prevLayer[i].getOutput() << endl;
cout << "Weighted sum: " << weightedSum << endl;
}
// Transfer function
myConnection.setOutput(Neuron::transfer(weightedSum));
cout << "Transfer: " << myConnection.getOutput() << endl;
}

// ******************** Class: Net *************************** //
class Net {
public:
Net(const vector<unsigned int>& topology);
void setTarget(const vector<double>& targetVals);
void feedForward(const vector<double>& inputVals);
void backPropagate(void);
void printOutput(void) const;
private:
vector<Layer> myLayers;
vector<double> myTargetVals;

};
Net::Net(const vector<unsigned int>& topology) : myTargetVals() {
assert(topology.size() > 0);
for (unsigned int i = 0; i < topology.size(); ++i) { // Creating the layers
myLayers.push_back(Layer(((i + 1) == topology.size()) ? topology[i] : topology[i] + 1)); // +1 is for bias neuron
// Setting each neurons index inside layer
for (unsigned int j = 0; j < myLayers[i].size(); ++j) {
myLayers[i][j].setIndex(j);
}
// Console log
cout << red;
if (i == 0) {
cout << "Input layer (" << myLayers[i].size() << " neurons including bias neuron) created." << endl;
myLayers[i].back().setOutput(1);
}
else if (i < topology.size() - 1) {
cout << "Hidden layer " << i << " (" << myLayers[i].size() << " neurons including bias neuron) created." << endl;
myLayers[i].back().setOutput(1);
}
else { cout << "Output layer (" << myLayers[i].size() << " neurons) created." << endl; }
cout << white;
}
}
void Net::setTarget(const vector<double>& targetVals) { assert(targetVals.size() == myLayers.back().size()); myTargetVals = targetVals; }
void Net::feedForward(const vector<double>& inputVals) {
assert(myLayers[0].size() - 1 == inputVals.size());
for (unsigned int i = 0; i < inputVals.size(); ++i) { // Setting input vals to input layer
cout << yellow << "Setting input vals...";
myLayers[0][i].setOutput(inputVals[i]); // myLayers[0] is the input layer
cout << "myLayer[0][" << i << "].getOutput()==" << myLayers[0][i].getOutput() << white << endl;
}
for (unsigned int i = 1; i < myLayers.size() - 1; ++i) { // Updating hidden layers
for (unsigned int j = 0; j < myLayers[i].size() - 1; ++j) { // - 1 because bias neurons do not have input
cout << "myLayers[" << i << "].size()==" << myLayers[i].size() << endl;
cout << green << "Updating neuron " << j << " inside layer " << i << white << endl;
myLayers[i][j].feedForward(myLayers[i - 1]); // Updating the neurons output based on the neurons of the previous layer
}
}
for (unsigned int i = 0; i < myLayers.back().size(); ++i) { // Updating output layer
cout << green << "Updating output neuron " << i << ": " << white << endl;
const Layer& prevLayer = myLayers[myLayers.size() - 2];
myLayers.back()[i].feedForward(prevLayer); // Updating the neurons output based on the neurons of the previous layer
}
}
void Net::printOutput(void) const {
for (unsigned int i = 0; i < myLayers.back().size(); ++i) {
cout << blue; myLayers.back()[i].printOutput(); cout << white;
}
}
void Net::backPropagate(void) {

}
}

int main(int argc, char* argv[]) {
vector<unsigned int> myTopology;
myTopology.push_back(3);
myTopology.push_back(4);
myTopology.push_back(2);
myTopology.push_back(2);

cout << myTopology.size() << endl << endl; // myTopology == {3, 4, 2 ,1}

vector<double> myTargetVals= {0.5,1};
vector<double> myInputVals= {1, 0.5, 1};

Neural::Net myNet(myTopology);
myNet.feedForward(myInputVals);
myNet.printOutput();

return 0;
}

编辑:我认为输入层中的偏置神经元正确设置为输出 1,而隐藏层中的偏置神经元设置为 0,我修复了它。但是每次运行的输出仍然相同。我在一张纸上做了数学运算,结果出来了。这是输出(为清楚起见用颜色编码):

Console log

我原以为这些值就像权重一样是随机的。不应该是这样吗?我很困惑。

最佳答案

我发现了我的错误。我认为 rand() 自动初始化了它的种子。我知道这是一件愚蠢的事情。我在程序的开头添加了 srand(time(NULL));,现在它可以正常工作了。

关于c++ - 神经网络的输出每次都保持相同的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30955408/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com