I Failed To Train Neural Network On JS - javascript

I am newbie in machine learning, but decided to make own js library for neural networks, everything went perfect until i tryed to train my NN. In My Mini Library i created some functions...
1) A Function That Creates My Neuron-Object:
this.Node = function (conns) {
var output = {};
output.b = hyth.Random({type: "TanH"});
output.w = [];
for (var a = 0; a < conns; a++){
output.w[a] = hyth.Random({type: "TanH"});
}
output.Value = function (i) {
if (i.length == conns) {
var sum = 0;
for (var a = 0; a < conns; a++){
sum += i[a] * output.w[a];
}
sum += output.b;
return myMath.Activate(sum, {type: "Sigmoid"});
}
}
return output;
}
This function has one argument , which is the amount of wanted weights from neuron, and it returns an object with two properties - "b" the float (bias), and "w" the 1D Array which contains floats, and one method - which calculates the activation of neuron-object.
2) A Function That Creates My Neural Net
this.Network = function () {
var p = arguments;
var arr = [];
for (var a = 0; a < p.length-1; a++){
arr[a] = [];
for (var b = 0; b < p[a+1]; b++){
arr[a][b] = this.Node(p[a]);
}
}
return arr;
}
This Function Returns A 2D Array with Neuron-Object as It's final value, using argument array as settings for layer count and node count for each layer.
3) A Function That Feeds Forward The NN
this.Forward = function (network, input) {
if (network[0][0].w.length == input.length) {
var activations = [];
for (var a = 0; a < network.length; a++){
activations[a] = [];
for (var c = 0; c < network[a].length; c++){
if (a == 0){
activations[0][c] = network[0][c].Value(input);
continue;
}
activations[a][c] = network[a][c].Value(activations[a-1]);
}
}
return activations;
}
}
This Function Returns 2D array with an activation float for every neuron as it's final value. It uses 2 agruments - the output of 2nd function, input array.
4) And Final Function That Backpropagates
this.Backward = function (network, input, target) {
if (network[0][0].w.length == input.length && network[network.length-1].length == target.length) {
var activations = this.Forward(network, input, true);
var predictions = activations[activations.length-1];
var errors = [];
for (var v = 0; v < network.length; v++) {
errors[v] = [];
}
for (var a = network.length-1; a > -1; a--){
for (var x = 0; x < network[a].length; x++) {
var deract = hyth.Deractivate(activations[a][x]);
if (a == network.length-1) {
errors[a][x] = (predictions[x] - target[x]) * deract;
} else {
errors[a][x] = 0;
for (var y = 0; y < network[a+1].length; y++) {
errors[a][x] += network[a+1][y].w[x] * errors[a+1][y];
}
errors[a][x] *= deract;
}
}
}
return errors;
}
}
This Function Returns 2D array with the rror float for every neuron as it's final value. Arguments are 3 - the nnet , input and wanted output.
So I can make a neural network, feed forward and and backpropagate, receive activations and errors, but i always fail to train my net with my errors and activations to work perfect , last time it was outputing same result for every type of input. I want to understand training algorithm from zero , so i need someone's help.
P.S. - i dont want someone say that i need to use famous libraries , i want to understand and make it myself.

Related

How to display output of one function after another

I have written a Javascript file of two algorithms. As shown in the code below, I am using a for loop to generate random values which are used by both algorithms as input.
At present, I am displaying output of the binarySearch and SearchSorted alternatively.
The problem I am facing is I have to pass the same array values generated by randomlyGenerateArray in the main program to both the algorithms for a meaningful comparison. But I don't know how to change the output format.
I have thought of adding them in different loops, but as I have explained above i need to use the same randomArray values for both the algorithms.
i.e., The below code produces output as shown below -
Binary Search Successful 1
Search Sorted Successful 5
Binary Search Successful 3
Search Sorted Successful 10
How do I display the output of Binary Search First and then display output of Search Sorted? it's something like this. Any help will be greatly appreciated.
Binary Search Successful 1
Binary Search Successful 3
Search Sorted Successful 5
Search Sorted Successful 10
// Binary Search Algorithm
function binarySearch(A,K)
{
var l = 0; // min
var r = A.length - 1; //max
var n = A.length;
var operations = 0;
while(l <= r)
{
var m = Math.floor((l + r)/2);
operations++;
if(K == A[m])
{
console.log('Binary Search Successful %d',operations);
return m;
}
else if(K < A[m])
{
r = m - 1;
}
else
{
l = m + 1;
}
}
operations++;
console.log('Binary Search Unsuccessful %d',operations);
return -1;
}
// Search Sorted Algorithm
function searchSorted(A, K)
{
var n = A.length;
var i = 0;
var operations = 0;
while (i < n)
{
operations++;
if (K < A[i])
{
return -1;
}
else if (K == A[i])
{
console.log('Search Sorted Successful %d', operations);
return i;
}
else
{
i = i + 1;
}
}
operations++;
console.log('Search Sorted Unsuccessful %d', operations);
return -1;
}
// Random Array generator
var randomlyGenerateArray = function(size)
{
var array = [];
for (var i = 0; i < size; i++)
{
var temp = Math.floor(Math.random() * maxArrayValue);
var final = array.splice(5, 0, 30);
array.push(final);
}
return array;
}
//Sort the Array
var sortNumber = function(a, b)
{
return a - b;
}
// Main Program
var program = function()
{
var incrementSize = largestArray / numberOfArrays;
for (var i = smallestArray; i <= largestArray; i += incrementSize)
{
var randomArray = randomlyGenerateArray(i);
var sort = randomArray.sort(sortNumber);
var randomKey = 30;
binarySearch(sort, randomKey);
searchSorted(sort, randomKey);
}
}
var smallestArray = 10;
var largestArray = 10000;
var numberOfArrays = 1000;
var minArrayValue = 1;
var maxArrayValue = 1000;
program();
You could store the sorted randomArrays in an array (which I've called sortedRandomArrays), then run a for loop for each search.
The Main Program would then look like:
// Main Program
var program = function()
{
var incrementSize = largestArray / numberOfArrays;
var sortedRandomArrays = [];
for (var i = smallestArray; i <= largestArray; i += incrementSize)
{
var randomArray = randomlyGenerateArray(i));
var sort = randomArray.sort(sortNumber);
sortedRandomArrays.push(sort);
var randomKey = 30;
}
for (var i = 0; i < sortedRandomArrays.length; i++)
{
binarySearch(sortedRandomArrays[i], randomKey);
}
for (var i = 0; i < sortedRandomArrays.length; i++)
{
searchSorted(sortedRandomArrays[i], randomKey);
}
}
Solution is simple: store the results and print with 2 separate loops (take out the printing from within the functions).
var program = function()
{
var binarySearchResults = [];
var sortedSearchResults = [];
var incrementSize = largestArray / numberOfArrays;
for (var i = smallestArray; i <= largestArray; i += incrementSize)
{
var randomArray = randomlyGenerateArray(i);
var sort = randomArray.sort(sortNumber);
var randomKey = 30;
binarySearchResults[i] = binarySearch(sort, randomKey);
sortedSearchResults[i] = searchSorted(sort, randomKey);
}
for (var i = smallestArray; i <= largestArray; i += incrementSize)
{
//print binary results
}
for (var i = smallestArray; i <= largestArray; i += incrementSize)
{
//print sorted results
}
}

Array equals itself plus number = NaN

I must be doing something stupid. The array newArea needs to add up data from all regions, i.e. be global. Regions are represented by variable p. But when I try to get newArea array to add to itself, e.g. newArea[p] += otherArray, it outputs NaNs. Even newArea[p] += 1 outputs NaNs.
Can anyone spot what I'm doing wrong? It's driving me mad and I'm working to a deadline.
mm=0
var maxVolume = 0;
var tempCAGR = 0;
var maxCAGR = 0;
var newArray = [];
var newRegions = [];
var newConsValues = [];
var newArea = [];
for (var p=0; p<arrayRef[mm].length; p++) {//9 regions
newArray[p] = [];
for (var q=0; q<arrayRef[mm][p].length; q++) {//4 scenarios
newArea[q] = [];
if (q==0) {
newRegions.push(arrayRef[mm][p][q][0]);
newConsValues.push(arrayRef[mm][p][q][1]);
}
for (var r=0; r<dates.length; r++) {//time
//console.log('p: '+p+', q: '+q+', r: '+r);
if (p==0) {
newArea[q][r] = 1;
} else {
newArea[q][r] += 1;
}
}
arrayRef[mm][p][q].shift();
tempCAGR = Math.pow(( arrayRef[mm][p][q][len] / arrayRef[mm][p][q][1] ),(1/len))-1;
//console.log(newRegions[p]+', num: '+arrayRef[mm][p][q][len-1]+', denom: '+arrayRef[mm][p][q][0]+', len: '+len+', cagr: '+tempCAGR);
newArray[p][q] = tempCAGR;
maxCAGR = Math.max(maxCAGR,tempCAGR);
}
}
console.log(newArea);
You are cleaning the array in newArea everytime you loop through it:
...loop q ...
newArea[q] = []; // <-- resets the array at q pos
... loop r ...
if (p==0) {
newArea[q][r] = 1;
} else {
newArea[q][r] += 1;
}
So when p === 0 it will fill an array at q pos of your newArea array. However, next iteration of p will clear them out, so there's nothing there to sum.
You probably want to keep the old array or create a new one if there isn't one.
newArea[q] = newArea[q] || [];
It looks like you do not have the variable initialised. With adding something to undefined, you get NaN.
You can change the art of incrementing with a default value:
if (p == 0) {
newArea[q][r] = 1;
} else {
newArea[q][r] = (newArea[q][r] || 0) + 1;
}

JavaScript program crashes page

I made a simple program in JavaScript to find a matrix of the cofactors of a 3X3 matrix. However, the program is crashing my page repeatedly, and I cannot find any logical error in the program. Here's my code :
var matrixA = {
a11:"",
a12:"",
a13:"",
a21:"",
a22:"",
a23:"",
a31:"",
a32:"",
a33:""
};
function determinant (given,order) {
if(order==3){
var det = (given.a11*((given.a22*given.a33)-(given.a23*given.a32)))-
(given.a21*((given.a12*given.a33)-(given.a13*given.a32)))+
(given.a31*((given.a12*given.a23)-(given.a13*given.a22)));
}
else if(order==2){
var det = (given.a11*given.a22)-(given.a21*given.a12);
}
return det;
}
function cofactors(given){
var multiplier;
var temp = {
a11:"",
a12:"",
a21:"",
a22:""
};
var found_cofactor_matrix = {};
for (var i = 1; i <4; i++) {
for (var j = 1; i < 4; j++) {
if(((i+j)%2)==0){
multiplier = 1;
}
else if(((i+j)%2)==1){
multiplier = -1;
}
//Check whether row or column number is the same to make a 2X2 matrix
for(var a = 1; a < 4; a++){
for (var b = 0; b < 4; b++) {
if((a==i)||(b==j)){
} //do nothing
else{
if(temp.a11==""){
temp.a11 = given["a"+a+b];
}
else if(temp.a12 == ""){
temp.a12 = given["a"+a+b];
}
else if(temp.a21 == ""){
temp.a21 = given["a"+a+b];
}
else if(temp.a22 == ""){
temp.a22 = given["a"+a+b];
}
}
};
};
found_cofactor_matrix["a"+i+j] = multiplier*determinant(temp,2);
};
};
return found_cofactor_matrix;
}
Here, the parameter "given" is an object sent to it from the place where the function is called, and is the original matrix (matrixA) whose cofactors have to be found. I basically create a 2X2 matrix first, find its determinant and multiply it with 1 or -1 as required. I then write this value into the appropriate position in the matrix.
for (var j = 1; i < 4; j++) { should be for (var j = 1; j < 4; j++) {.
Remove semicolons at the end of for loop. And add your determinant function.
Did you open your console? Running this code in Chrome's console yields Uncaught ReferenceError: found_cofactor is not defined. You are trying to define the ["a"+i+j] property of an undefined object. It should be found_cofactor_matrix.
Besides, the determinant() function may be undefined (it does not appear in your piece of code)

Variable scope within methods

I was teaching myself how to make a binary genetic algorithm the other day. The goal was to make it so that it would match a randomly generated 35 length binary string. I ran into a problem where methods were editing variables that I did not think were in its scope. This caused my solution to slowly degrade in fitness instead of increase! After I found out where this was happening I fixed it by newP[0].join('').split('') so that newP[0] itself would not be edited. For convenience I've marked where the problem was happening below in comments.
While I have fixed this problem I'd like to hopefully get an understanding as to why this happens and also prevent without doing the join/split silliness.
Here is the code:
var GeneticAlgorithm = function () {};
GeneticAlgorithm.prototype.mutate = function(chromosome, p) {
for(var i = 0; i < chromosome.length; i++) {
if(Math.random() < p) {
chromosome[i] = (chromosome[i] == 0) ? 1 : 0;
}
}
return chromosome;
};
GeneticAlgorithm.prototype.crossover = function(chromosome1, chromosome2) {
var split = Math.round(Math.random() * chromosome1.length);
var c1 = chromosome1;
var c2 = chromosome2;
for(var i = 0; i < split; i++) {
c1[i] = chromosome2[i];
c2[i] = chromosome1[i];
}
return [c1, c2];
};
// fitness = function for finding fitness score of an individual/chromosome (0-1)
// length = length of string (35)
// p_c = percentage chance of crossover (0.6)
// p_m = percentage change of mutation (0.002)
GeneticAlgorithm.prototype.run = function(fitness, length, p_c, p_m, iterations) {
var iterations = 100;
var size = 100;
// p = population, f = fitnesses
var p = [];
var f = [];
for(var i = 0; i < size; i++) {
p.push(this.generate(length));
f.push(fitness(p[i].join('')));
}
while( iterations > 0 && Math.max.apply(Math, f) < 0.999 ) {
var mates = [];
var newP = [];
var newF = [];
mates = this.select(p, f);
newP.push(mates[0], mates[1]);
while(newP.length < size) {
/*-------------------> Problem! <-------------------*/
mates = [newP[0].join('').split(''), newP[1].join('').split('')];
/*
* If I passed newP[0] when mates[0] changed newP[0] would also change
*/
if(Math.random() < p_c) {
mates = this.crossover(mates[0], mates[1]);
}
mates[0] = this.mutate(mates[0], p_m);
mates[1] = this.mutate(mates[1], p_m);
newP.push(mates[0], mates[1]);
}
for(var i = 0; i < size; i++) {
newF.push(fitness(newP[i].join('')));
}
p = newP;
f = newF;
iterations--;
}
return p[f.indexOf(Math.max.apply(Math, f))].join('');
};

Creating A Randomised Array with a Single Pre-defined Choice in JavaScript

I'm creating a program that will ask a question and give 5 choices for answers.
One is pre-defined and is correct, the others I want to be random selections from a bank of answers and the entire array is to be shuffled too.
I've written something, but it has some inconsistencies.
For one, sometimes the pre-defined choice appears twice in the list (it appears to skip over my if check).
Another is that sometimes, the editor crashes when I run it.
I use for in loops and I'm worried the crash is caused by a never-ending loop.
Here's my code:
private var numberOfComponents:int;
private var maxComponents:int = 5;
//numberOfComponents returns the length property of my 'components' answer bank
componentsSelection = buildComponentSelectionList(0); //0 is the index of my correct answer
function buildComponentSelectionList(correctItemIndex){
var theArray:Array = new Array();
var indicesOfSelection:Array = getIndicesByIncluding(correctItemIndex);
Debug.Log(indicesOfSelection);
for (var i=0;i<indicesOfSelection.length;i++)
theArray.Push(components[indicesOfSelection[i]]);
return theArray;
}
function getIndicesByIncluding(correctItem){
var indicesArray:Array = new Array();
var numberOfChoices = maxComponents-1;
for(var i=0;i<numberOfChoices;i++){
var number = Mathf.Round(Random.value*(numberOfComponents-1));
addToRandomNumberSelection(indicesArray, number,correctItem);
}
indicesArray.Push(correctItem);
RandomizeArray(indicesArray);
return indicesArray;
}
function addToRandomNumberSelection(indicesArray:Array,number,correctItem){
if(indicesArray.length == 0){
indicesArray.Push(number);
} else {
var doesntExist = true;
for(var i=0;i<indicesArray.length;i++){
if(indicesArray[i] == correctItem)
doesntExist = false;
if (indicesArray[i] == number)
doesntExist = false;
}
if(doesntExist) {
indicesArray.Push(number);
} else {
addToRandomNumberSelection(indicesArray, Mathf.Round(Random.value*(numberOfComponents-1)),correctItem);
}
}
}
function RandomizeArray(arr : Array)
{
for (var i = arr.length - 1; i > 0; i--) {
var r = Random.Range(0,i);
var tmp = arr[i];
arr[i] = arr[r];
arr[r] = tmp;
}
}
The editor is Unity3D, and the code is a version of JavaScript; I think my error is a logic one, rather than a syntactical one.
I feel I've been staring at this code for too long now and I'm missing something obvious.
Can anybody help me?
You can loop through the options and determine the probability that it should be included, then shuffle the included options:
function getRandomOptions(allOptions, correctIndex, count){
var result = [allOptions[correctIndex]];
count--;
var left = allOptions.length;
for (var i = 0; count > 0; i++) {
if (i != correctIndex && Math.floor(Math.random() * left) < count) {
result.push(allOptions[i]);
count--;
}
left--;
}
shuffleArray(result);
return result;
}
function shuffleArray(arr) {
for (var i = arr.length - 1; i > 0; i--) {
var r = Math.floor(Math.random() * i);
var tmp = arr[i];
arr[i] = arr[r];
arr[r] = tmp;
}
}
Demo: http://jsfiddle.net/Guffa/wXsjz/

Categories