Open
Description
The biases are never updated in the backprop algorithm as it currently stands.
Biases can be included in the array of weights which would simplify things a bit (or keep treating separately but need to update them). Then, each input to the network will need to have a 1 as an extra, last, value. First we can update the code like so:
diff --git a/Tinn.c b/Tinn.c
index 74eb573..9a6fe8b 100644
--- a/Tinn.c
+++ b/Tinn.c
@@ -74,7 +74,7 @@ static void fprop(const Tinn t, const float* const in)
float sum = 0.0f;
for(int j = 0; j < t.nips; j++)
sum += in[j] * t.w[i * t.nips + j];
- t.h[i] = act(sum + t.b[0]);
+ t.h[i] = act(sum);
}
// Calculate output layer neuron values.
for(int i = 0; i < t.nops; i++)
@@ -82,11 +82,11 @@ static void fprop(const Tinn t, const float* const in)
float sum = 0.0f;
for(int j = 0; j < t.nhid; j++)
sum += t.h[j] * t.x[i * t.nhid + j];
- t.o[i] = act(sum + t.b[1]);
+ t.o[i] = act(sum);
}
}
-// Randomizes tinn weights and biases.
+// Randomizes tinn weights.
static void wbrand(const Tinn t)
{
for(int i = 0; i < t.nw; i++) t.w[i] = frand() - 0.5f;
@@ -113,8 +113,7 @@ Tinn xtbuild(const int nips, const int nhid, const int nops)
{
Tinn t;
// Tinn only supports one hidden layer so there are two biases.
- t.nb = 2;
- t.nw = nhid * (nips + nops);
+ t.nw = nhid * (nips + nops + 2);
t.w = (float*) calloc(t.nw, sizeof(*t.w));
t.x = t.w + nhid * nips;
t.b = (float*) calloc(t.nb, sizeof(*t.b));
Then the training part needs to be adjusted so that each input row contains an extra column with 1.
Example (for xor training - remember, these are the inputs now):
The last column will ensure the bias weight is always included in forward propagation. And backprop will update all weights as usual, including the biases.
Metadata
Assignees
Labels
No labels