diff --git a/m.test.js b/m.test.js index 3183373..c58cfd4 100644 --- a/m.test.js +++ b/m.test.js @@ -11,10 +11,10 @@ Deno.test("Iterate.Loop", ()=> assertEquals(cloud[0][0], 0); assertEquals(cloud[3][2], 5, "correct output"); }); -Deno.test("Iterate.Edit", ()=> +Deno.test("Iterate.Copy", ()=> { const c = [[1, 2], [3, 4]] - const t = M.Iterate.Edit(c, (i)=>i); + const t = M.Iterate.Copy(c, (i)=>i); assertEquals(t.length, c.length, "correct count"); assertEquals(t[0][0], c[0][0], "correct dimensions"); assertEquals(t[1][1], c[1][1], "correct placement"); @@ -146,20 +146,39 @@ Deno.test("Batch.Subtract", ()=> assertEquals(t[0].length, 2, "correct dimensions"); assertEquals(t[1][0], 2.5, "correct placement"); }); -Deno.test("Batch.Sigmoid", ()=> +Deno.test("Batch.Sig", ()=> { const m = [[-1000, 1000]]; - const t = M.Batch.Sigmoid(m); + const t = M.Batch.Sig(m); assertEquals(t.length, 1, "correct count"); assertEquals(t[0].length, 2, "correct dimensions"); assert(t[0][0]>=0 && t[0][0]<0.5); assert(t[0][1]<=1 && t[0][1]>0.5, "correct placement"); + }); -Deno.test("Batch.Derivative", ()=> +Deno.test("Batch.SigDeriv", ()=> { const m = [[-1000, 0, 1000]]; - const t = M.Batch.Derivative(M.Batch.Sigmoid(m)); + const t = M.Batch.SigDeriv(M.Batch.Sig(m)); assertEquals(t.length, 1, "correct count"); assertEquals(t[0].length, 3, "correct dimensions"); assert(t[0][0]t[0][2]); +}); + +Deno.test("Batch.Rec", ()=> +{ + const m = [[-1, 1, 10]]; + const t = M.Batch.Rec(m); + assert(t[0][0] == 0); + assert(t[0][1] == 1); + assert(t[0][2] == 10); +}); +Deno.test("Batch.RecDeriv", ()=> +{ + const m = [[-1, 1, 10]]; + const t = M.Batch.RecDeriv(m); + + assert(t[0][0] == 0); + assert(t[0][1] == 1); + assert(t[0][2] == 1); }); \ No newline at end of file diff --git a/m.ts b/m.ts index 82ce151..54477e7 100644 --- a/m.ts +++ b/m.ts @@ -16,22 +16,20 @@ const Methods = { for(i=0; i inCloud.map((row:Cloud.V):Cloud.V=>row.map(inFunction)) + Copy: (inCloud:Cloud.M, inFunction:Cloud.HandleEdit):Cloud.M=> inCloud.map((row:Cloud.V):Cloud.V=> row.map(inFunction)), + Edit: (inCloud:Cloud.M, inFunction:Cloud.HandleEdit):void => inCloud.forEach((row:Cloud.V):void=>row.forEach(inFunction)) }, Create: { Box: (inV1:Cloud.V, inV2:Cloud.V, inCount:number):Cloud.M=> Methods.Iterate.Loop(inV1.length, inCount, i=> inV1[i]+(inV2[i]-inV1[i])*Math.random()), Transpose: (inCloud:Cloud.M):Cloud.M=> Methods.Iterate.Loop(inCloud.length, inCloud[0].length, (i, row)=> inCloud[i][row]), Outer: (inV1:Cloud.V, inV2:Cloud.V):Cloud.M=> Methods.Iterate.Loop(inV1.length, inV2.length, (i, row)=> inV1[i]*inV2[row]), - Clone: (inCloud:Cloud.M):Cloud.M=> Methods.Iterate.Edit(inCloud, i=> i), + Clone: (inCloud:Cloud.M):Cloud.M=> Methods.Iterate.Copy(inCloud, i=> i), Padded: (inCloud:Cloud.M):Cloud.M=> inCloud.map((row:Cloud.V)=> [...row, 1]) }, Mutate: @@ -39,13 +37,6 @@ const Methods = { Pad: (inCloud:Cloud.M):Cloud.M=> {inCloud.forEach((row:Cloud.V)=> row.push(1)); return inCloud; }, Unpad: (inCloud:Cloud.M):Cloud.M=> {inCloud.forEach((row:Cloud.V)=> row.pop()); return inCloud; } }, - Test: - { - Dot:(v1:Cloud.V, v2:Cloud.V):number=> - { - return v1.reduce((sum, current, index)=> sum + current*v2[index]); - } - }, Single: { Subtract: (inV1:Cloud.V, inV2:Cloud.V):Cloud.V=> inV1.map((component, i)=> component-inV2[i]), @@ -57,9 +48,11 @@ const Methods = { Subtract: (inCloud1:Cloud.M, inCloud2:Cloud.M):Cloud.M=> inCloud1.map((row:Cloud.V, rowIndex:number)=> Methods.Single.Subtract(row, inCloud2[rowIndex])), Multiply: (inCloud1:Cloud.M, inCloud2:Cloud.M):Cloud.M=> inCloud1.map((row:Cloud.V, rowIndex:number)=> Methods.Single.Multiply(row, inCloud2[rowIndex])), Affine: (inCloud1:Cloud.M, inCloud2:Cloud.M):Cloud.M=> inCloud1.map((row:Cloud.V)=> Methods.Single.Affine(row, inCloud2)), - Sigmoid: (inCloud:Cloud.M):Cloud.M=> Methods.Iterate.Edit(inCloud, i=>1/(1+Math.pow(Math.E, -i))), - Derivative: (inCloud:Cloud.M):Cloud.M=> Methods.Iterate.Edit(inCloud, i=>i*(1-i)), - Scale: (inCloud:Cloud.M, inScalar:number):Cloud.M=> Methods.Iterate.Edit(inCloud, i=>i*inScalar) + Sig: (inCloud:Cloud.M):Cloud.M=> Methods.Iterate.Copy(inCloud, i=>1/(1+Math.pow(Math.E, -i))), + SigDeriv: (inCloud:Cloud.M):Cloud.M=> Methods.Iterate.Copy(inCloud, i=>i*(1-i)), + Rec: (inCloud:Cloud.M):Cloud.M=> Methods.Iterate.Copy(inCloud, i=> i<=0 ? 0 : i), + RecDeriv: (inCloud:Cloud.M):Cloud.M=> Methods.Iterate.Copy(inCloud, i=> i<=0 ? 0 : 1), + Scale: (inCloud:Cloud.M, inScalar:number):Cloud.M=> Methods.Iterate.Copy(inCloud, i=>i*inScalar) } }; diff --git a/nn.ts b/nn.ts index 351d44b..c2e8ff7 100644 --- a/nn.ts +++ b/nn.ts @@ -5,7 +5,7 @@ const Forward = (inData:Cloud.M, inLayers:N):N => { let i:number; let stages:N = [inData]; - let process = (index:number):Cloud.M => M.Batch.Sigmoid(M.Batch.Affine(stages[index], inLayers[index])); + let process = (index:number):Cloud.M => M.Batch.Sig(M.Batch.Affine(stages[index], inLayers[index])); for(i=0; i for(i=inLayers.length-1; i>=0; i--) { - let errorScaled:Cloud.M = M.Batch.Multiply(errorBack, M.Batch.Derivative(inStages[i+1])); + let errorScaled:Cloud.M = M.Batch.Multiply(errorBack, M.Batch.SigDeriv(inStages[i+1])); errorBack = M.Batch.Affine(errorScaled, M.Create.Transpose(inLayers[i])); errorScaled.forEach((inScaledError:Cloud.V, inIndex:number)=> {