/
TNeuron.cpp
77 lines (71 loc) · 2.56 KB
/
TNeuron.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include "TNeuron.h"
#include "compressFunctions.h"
TNeuron::TNeuron(int countOfSynWeights)
{
//double tmp = 1.0 / (100 + countOfSynWeights * countOfSynWeights);
for (int i = 0; i < countOfSynWeights; i++) {
mSynapticWeights << ((qrand()%100+1) - 50) / 10.0;
}
mDetectivity = ((qrand()%100+1) - 50) / 10.0;
Q_ASSERT(mSynapticWeights.size() == countOfSynWeights);
}
TNeuron::TNeuron(const QDomElement &neuron)
{
QDomElement weight = neuron.firstChild().toElement();
while (!weight.isNull()) {
if(weight.tagName() == "detectivity") {
double newDetectivity = weight.attribute("value").toDouble();
mDetectivity = newDetectivity;
}
else if (weight.tagName() == "weight") {
double newWeight = weight.attribute("value").toDouble();
mSynapticWeights << newWeight;
}
else Q_ASSERT(false);
weight = weight.nextSibling().toElement();
}
Q_ASSERT(mSynapticWeights.size() == neuron.attribute("countOfWeights").toDouble());
}
double TNeuron::getResult(const QVector<double> &input
, ExpSigmoidal &activationFunction)
{
Q_ASSERT(input.size() == mSynapticWeights.size());
double sum = 0;
for (int i = 0; i < input.size(); i++) {
sum += input.at(i) * mSynapticWeights.at(i);
}
sum += mDetectivity;
double out = activationFunction.calculate(sum);
Q_ASSERT(out >= -1 && out <= 1);
return out;
}
// обучение методом обратного распространения ошибки: веса корректируются в соответствии с входными данными
// и оценкой ошибки dj для конкретного нейрона
QVector<double> TNeuron::learn(double dj, const QVector<double> &input)
{
QVector<double> correction;
Q_ASSERT(input.size() == mSynapticWeights.size());
for (int i = 0; i < input.size(); i++) {
mSynapticWeights[i] += -dj * nn * input.at(i);
correction << mSynapticWeights.at(i) * dj;
}
mDetectivity += -dj * nn * 1;
correction << mDetectivity * dj;
return correction;
}
QDomElement TNeuron::save(QDomDocument &mlp, int neuronNumber)
{
QDomElement neuron = mlp.createElement("neuron");
neuron.setAttribute("neuronNumber", neuronNumber);
neuron.setAttribute("countOfWeights", mSynapticWeights.size());
QDomElement detectivity = mlp.createElement("detectivity");
detectivity.setAttribute("value", mDetectivity);
neuron.appendChild(detectivity);
for (int i = 0; i < mSynapticWeights.size(); i++) {
QDomElement weight = mlp.createElement("weight");
weight.setAttribute("number", i+1);
weight.setAttribute("value", mSynapticWeights.at(i));
neuron.appendChild(weight);
}
return neuron;
}