From c2a5dbcfce6b06f17bb8b60811b78572ee2113ff Mon Sep 17 00:00:00 2001 From: Ola Date: Tue, 7 Jan 2025 18:31:14 -0600 Subject: [PATCH 1/6] chore: Add toJSON and fromJSON to AE --- src/autoencoder.test.ts | 20 ++++++++++++++++++++ src/autoencoder.ts | 21 +++++++++++++++------ 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/autoencoder.test.ts b/src/autoencoder.test.ts index 166903b6..ba8bd589 100644 --- a/src/autoencoder.test.ts +++ b/src/autoencoder.test.ts @@ -66,3 +66,23 @@ test('test a data sample for anomalies', async () => { includesAnomalies(1, 0, 1); includesAnomalies(1, 1, 0); }); + +test('restores a net fromJSON', () => { + expect(result.error).toBeLessThanOrEqual(errorThresh); + function xor(net: AE, ...args: number[]) { + return Math.round(net.denoise(args)[2]); + } + + const decoder = xornet.toJSON(); + const restoredDecoder = xornet.fromJSON(decoder); + + const run1 = xor(restoredDecoder, 0, 0, 0); + const run2 = xor(restoredDecoder, 0, 1, 1); + const run3 = xor(restoredDecoder, 1, 0, 1); + const run4 = xor(restoredDecoder, 1, 1, 0); + + expect(run1).toBe(0); + expect(run2).toBe(1); + expect(run3).toBe(1); + expect(run4).toBe(0); +}); diff --git a/src/autoencoder.ts b/src/autoencoder.ts index 357d7fcd..74ffaafd 100644 --- a/src/autoencoder.ts +++ b/src/autoencoder.ts @@ -3,6 +3,7 @@ import { IJSONLayer, INeuralNetworkData, INeuralNetworkDatum, + INeuralNetworkJSON, INeuralNetworkTrainOptions, } from './neural-network'; import { @@ -26,7 +27,7 @@ export class AE< EncodedData extends INeuralNetworkData > { private decoder?: NeuralNetworkGPU; - private readonly denoiser: NeuralNetworkGPU; + private denoiser: NeuralNetworkGPU; constructor(options?: Partial) { // Create default options for the autoencoder. @@ -149,10 +150,9 @@ export class AE< data: DecodedData[], options?: Partial ): INeuralNetworkState { - const preprocessedData: Array, - Partial - >> = []; + const preprocessedData: Array< + INeuralNetworkDatum, Partial> + > = []; for (const datum of data) { preprocessedData.push({ input: datum, output: datum }); @@ -188,7 +188,16 @@ export class AE< const decoder = new NeuralNetworkGPU().fromJSON(json); - return (decoder as unknown) as NeuralNetworkGPU; + return decoder as unknown as NeuralNetworkGPU; + } + + toJSON(): INeuralNetworkJSON { + return this.denoiser.toJSON(); + } + + fromJSON(json: INeuralNetworkJSON): this { + this.denoiser = this.denoiser.fromJSON(json); + return this; } /** From 6d9dcd5998c78d48253972c2af2466fae27ed2cc Mon Sep 17 00:00:00 2001 From: Ola Date: Tue, 7 Jan 2025 18:45:58 -0600 Subject: [PATCH 2/6] chore: naming --- src/autoencoder.test.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/autoencoder.test.ts b/src/autoencoder.test.ts index ba8bd589..7a18d218 100644 --- a/src/autoencoder.test.ts +++ b/src/autoencoder.test.ts @@ -73,13 +73,13 @@ test('restores a net fromJSON', () => { return Math.round(net.denoise(args)[2]); } - const decoder = xornet.toJSON(); - const restoredDecoder = xornet.fromJSON(decoder); + const jsonNet = xornet.toJSON(); + const restoredNet = xornet.fromJSON(jsonNet); - const run1 = xor(restoredDecoder, 0, 0, 0); - const run2 = xor(restoredDecoder, 0, 1, 1); - const run3 = xor(restoredDecoder, 1, 0, 1); - const run4 = xor(restoredDecoder, 1, 1, 0); + const run1 = xor(restoredNet, 0, 0, 0); + const run2 = xor(restoredNet, 0, 1, 1); + const run3 = xor(restoredNet, 1, 0, 1); + const run4 = xor(restoredNet, 1, 1, 0); expect(run1).toBe(0); expect(run2).toBe(1); From ef188cc0a2db457a6a211de4208dcb8b3a7d1e85 Mon Sep 17 00:00:00 2001 From: Ola Date: Tue, 7 Jan 2025 19:12:07 -0600 Subject: [PATCH 3/6] chore: json in options.json --- src/autoencoder.test.ts | 4 +++- src/autoencoder.ts | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/autoencoder.test.ts b/src/autoencoder.test.ts index 7a18d218..0941f289 100644 --- a/src/autoencoder.test.ts +++ b/src/autoencoder.test.ts @@ -74,7 +74,9 @@ test('restores a net fromJSON', () => { } const jsonNet = xornet.toJSON(); - const restoredNet = xornet.fromJSON(jsonNet); + const restoredNet = new AE({ + json: jsonNet, + }); const run1 = xor(restoredNet, 0, 0, 0); const run2 = xor(restoredNet, 0, 1, 1); diff --git a/src/autoencoder.ts b/src/autoencoder.ts index 74ffaafd..54fc1531 100644 --- a/src/autoencoder.ts +++ b/src/autoencoder.ts @@ -17,6 +17,7 @@ export interface IAEOptions { binaryThresh: number; decodedSize: number; hiddenLayers: number[]; + json?: INeuralNetworkJSON; } /** @@ -48,6 +49,10 @@ export class AE< // Create the denoiser subnet of the autoencoder. this.denoiser = new NeuralNetworkGPU(options); + + if (options.json) { + this.denoiser = this.denoiser.fromJSON(options.json); + } } /** From 5b86dc5a29ed6058899daf5f5aac13b00bd71134 Mon Sep 17 00:00:00 2001 From: Ola Date: Tue, 7 Jan 2025 19:15:20 -0600 Subject: [PATCH 4/6] chore: lint --- src/autoencoder.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/autoencoder.ts b/src/autoencoder.ts index 54fc1531..209f3e44 100644 --- a/src/autoencoder.ts +++ b/src/autoencoder.ts @@ -193,7 +193,7 @@ export class AE< const decoder = new NeuralNetworkGPU().fromJSON(json); - return decoder as unknown as NeuralNetworkGPU; + return (decoder as unknown) as NeuralNetworkGPU; } toJSON(): INeuralNetworkJSON { From faf01b01825c06696ad3cc0184bf619cf9fa5a36 Mon Sep 17 00:00:00 2001 From: Ola Date: Tue, 7 Jan 2025 19:16:58 -0600 Subject: [PATCH 5/6] chore: lint --- src/autoencoder.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/autoencoder.ts b/src/autoencoder.ts index 209f3e44..aae06053 100644 --- a/src/autoencoder.ts +++ b/src/autoencoder.ts @@ -155,9 +155,10 @@ export class AE< data: DecodedData[], options?: Partial ): INeuralNetworkState { - const preprocessedData: Array< - INeuralNetworkDatum, Partial> - > = []; + const preprocessedData: Array, + Partial + >> = []; for (const datum of data) { preprocessedData.push({ input: datum, output: datum }); From fccfb8b46064adb2f33c9bd562dcf0016aed7530 Mon Sep 17 00:00:00 2001 From: Ola Date: Tue, 7 Jan 2025 19:44:06 -0600 Subject: [PATCH 6/6] chore: naming --- src/autoencoder.test.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/autoencoder.test.ts b/src/autoencoder.test.ts index 0941f289..b649add4 100644 --- a/src/autoencoder.test.ts +++ b/src/autoencoder.test.ts @@ -73,15 +73,15 @@ test('restores a net fromJSON', () => { return Math.round(net.denoise(args)[2]); } - const jsonNet = xornet.toJSON(); - const restoredNet = new AE({ - json: jsonNet, + const json = xornet.toJSON(); + const net = new AE({ + json, }); - const run1 = xor(restoredNet, 0, 0, 0); - const run2 = xor(restoredNet, 0, 1, 1); - const run3 = xor(restoredNet, 1, 0, 1); - const run4 = xor(restoredNet, 1, 1, 0); + const run1 = xor(net, 0, 0, 0); + const run2 = xor(net, 0, 1, 1); + const run3 = xor(net, 1, 0, 1); + const run4 = xor(net, 1, 1, 0); expect(run1).toBe(0); expect(run2).toBe(1);