diff --git a/Cargo.lock b/Cargo.lock index 2a11373..ed7eb7c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -344,7 +344,7 @@ dependencies = [ [[package]] name = "netsaur" -version = "0.3.0" +version = "0.3.1" dependencies = [ "getrandom", "js-sys", @@ -358,7 +358,7 @@ dependencies = [ [[package]] name = "netsaur-gpu" -version = "0.3.0" +version = "0.3.1" dependencies = [ "cudarc", "ndarray", @@ -371,7 +371,7 @@ dependencies = [ [[package]] name = "netsaur-tokenizers" -version = "0.3.0" +version = "0.3.1" dependencies = [ "getrandom", "js-sys", diff --git a/README.md b/README.md index d05a814..7dd215a 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,8 @@ ### QuickStart This example shows how to train a neural network to predict the output of the -XOR function our speedy CPU backend written in [Rust](https://www.rust-lang.org/). +XOR function our speedy CPU backend written in +[Rust](https://www.rust-lang.org/). ```typescript import { @@ -253,7 +254,7 @@ console.log(`1 xor 1 = ${out4[0]} (should be close to 0)`); ### Documentation The full documentation for Netsaur can be found -[here](https://deno.land/x/netsaur@0.3.0/mod.ts). +[here](https://deno.land/x/netsaur@0.3.1/mod.ts). ### License diff --git a/crates/README.md b/crates/README.md index 3f9f399..f140f9e 100644 --- a/crates/README.md +++ b/crates/README.md @@ -4,6 +4,8 @@ This directory contains the source code for the Netsaur Rust crates. ## Crates -* [core](/core) - The main crate for the Netsaur FFI and wasm bindings. -* [core-gpu](/core-gpu) - The main crate for the Netsaur GPU FFI and wasm bindings. -* [tokenizers](/tokenizers) - The main crate for the Netsaur tokenizers wasm bindings. +- [core](/core) - The main crate for the Netsaur FFI and wasm bindings. +- [core-gpu](/core-gpu) - The main crate for the Netsaur GPU FFI and wasm + bindings. +- [tokenizers](/tokenizers) - The main crate for the Netsaur tokenizers wasm + bindings. diff --git a/crates/core-gpu/Cargo.toml b/crates/core-gpu/Cargo.toml index 8ef7999..cfe10e8 100644 --- a/crates/core-gpu/Cargo.toml +++ b/crates/core-gpu/Cargo.toml @@ -1,7 +1,7 @@ [package] edition = "2021" name = "netsaur-gpu" -version = "0.3.0" +version = "0.3.1" [lib] crate-type = ["cdylib"] diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index 3113894..993d025 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -1,7 +1,7 @@ [package] edition = "2021" name = "netsaur" -version = "0.3.0" +version = "0.3.1" [lib] crate-type = ["cdylib"] diff --git a/crates/tokenizers/Cargo.toml b/crates/tokenizers/Cargo.toml index 0303bd2..53f4f10 100644 --- a/crates/tokenizers/Cargo.toml +++ b/crates/tokenizers/Cargo.toml @@ -1,7 +1,7 @@ [package] edition = "2021" name = "netsaur-tokenizers" -version = "0.3.0" +version = "0.3.1" [lib] crate-type = ["cdylib"] diff --git a/data/data.ts b/data/data.ts index 177282d..8d28671 100644 --- a/data/data.ts +++ b/data/data.ts @@ -21,7 +21,7 @@ export class Data { /** * Load data from a CSV file or URL containing CSV data. */ - static async csv(url: string | URL, config?: CsvLoaderConfig) { + static async csv(url: string | URL, config?: CsvLoaderConfig): Promise { return new Data(await loadCsv(url, config)); } } diff --git a/data/datasets/csv.ts b/data/datasets/csv.ts index e66e624..ded3a5b 100644 --- a/data/datasets/csv.ts +++ b/data/datasets/csv.ts @@ -33,7 +33,7 @@ export async function loadCsv( let columnIndices!: Record; for await (const row of data) { if (!columnNames) { - columnNames = row; + columnNames = row as string[]; columnIndices = columnNames.reduce((acc, col, i) => { acc[col] = i; return acc; @@ -45,7 +45,7 @@ export async function loadCsv( for (const col in columnIndices) { const colConfig = config.columns?.[col]; const i = columnIndices[col]; - const value = row[i]; + const value = (row as string[])[i]; if (colConfig?.label) { y.push(Number(value)); } else { diff --git a/data/deps.ts b/data/deps.ts index fa6c523..b236b66 100644 --- a/data/deps.ts +++ b/data/deps.ts @@ -1 +1 @@ -export { CsvParseStream } from "https://deno.land/std@0.214.0/csv/csv_parse_stream.ts"; +export { CsvParseStream } from "jsr:@std/csv@0.214.0"; diff --git a/deno.json b/deno.json index 9d44e2d..f72945b 100644 --- a/deno.json +++ b/deno.json @@ -1,4 +1,11 @@ { + "name": "@denosaurs/netsaur", + "version": "0.3.1", + "exports": { + ".": "./mod.ts", + "./tokenizers": "./tokenizers/mod.ts", + "./data": "./data/mod.ts" + }, "tasks": { "example:xor": "deno run -A --unstable-ffi ./examples/xor_auto.ts", "example:xor-option": "deno run -A --unstable-ffi ./examples/xor_option.ts", diff --git a/deno.lock b/deno.lock index 00ec94a..eda1eac 100644 --- a/deno.lock +++ b/deno.lock @@ -2,10 +2,59 @@ "version": "3", "packages": { "specifiers": { + "jsr:@denosaurs/netsaur": "jsr:@denosaurs/netsaur@0.3.1", + "jsr:@denosaurs/plug@1.0.3": "jsr:@denosaurs/plug@1.0.3", + "jsr:@std/assert@^0.213.1": "jsr:@std/assert@0.213.1", + "jsr:@std/assert@^0.214.0": "jsr:@std/assert@0.214.0", + "jsr:@std/bytes@^0.214.0": "jsr:@std/bytes@0.214.0", + "jsr:@std/csv@0.214.0": "jsr:@std/csv@0.214.0", + "jsr:@std/encoding@0.213.1": "jsr:@std/encoding@0.213.1", + "jsr:@std/fmt@0.213.1": "jsr:@std/fmt@0.213.1", + "jsr:@std/fs@0.213.1": "jsr:@std/fs@0.213.1", + "jsr:@std/path@0.213.1": "jsr:@std/path@0.213.1", + "jsr:@std/path@^0.213.1": "jsr:@std/path@0.213.1", + "jsr:@std/streams@^0.214.0": "jsr:@std/streams@0.214.0", "npm:chartjs-node-canvas": "npm:chartjs-node-canvas@4.1.6_chart.js@3.9.1", "npm:graphviz": "npm:graphviz@0.0.9", "npm:tokenizers": "npm:tokenizers@0.13.1" }, + "jsr": { + "@denosaurs/netsaur@0.3.1": { + "dependencies": [ + "jsr:@denosaurs/plug@1.0.3" + ] + }, + "@denosaurs/plug@1.0.3": { + "dependencies": [ + "jsr:@std/encoding@0.213.1", + "jsr:@std/fmt@0.213.1", + "jsr:@std/fs@0.213.1", + "jsr:@std/path@0.213.1" + ] + }, + "@std/csv@0.214.0": { + "dependencies": [ + "jsr:@std/assert@^0.214.0", + "jsr:@std/streams@^0.214.0" + ] + }, + "@std/fs@0.213.1": { + "dependencies": [ + "jsr:@std/assert@^0.213.1", + "jsr:@std/path@^0.213.1" + ] + }, + "@std/path@0.213.1": { + "dependencies": [ + "jsr:@std/assert@^0.213.1" + ] + }, + "@std/streams@0.214.0": { + "dependencies": [ + "jsr:@std/bytes@^0.214.0" + ] + } + }, "npm": { "@mapbox/node-pre-gyp@1.0.10": { "integrity": "sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA==", @@ -1159,6 +1208,150 @@ "https://deno.land/x/vectorizer@v0.3.7/src/utils/random/rearrange.ts": "1c1571664845896663b563029f3f2572fccd38c6d92ec3fd11dc6d7ea866cb4b", "https://deno.land/x/vectorizer@v0.3.7/src/utils/random/rng.ts": "213dff1b1a39ae4621d35330eb19a3f96170949e8ca429e8028a1fdf86c61f22", "https://deno.land/x/vectorizer@v0.3.7/src/utils/random/shuffle.ts": "66f966851d5b6dd4c81117d32311742c319ea3042aad22a7874d2b10da4e743f", - "https://deno.land/x/vectorizer@v0.3.7/src/utils/random/weighted.ts": "c4eeb309477ecf431a0b9fd1bf0f04540825194c7ed30ba8c71c9e45e14112e6" + "https://deno.land/x/vectorizer@v0.3.7/src/utils/random/weighted.ts": "c4eeb309477ecf431a0b9fd1bf0f04540825194c7ed30ba8c71c9e45e14112e6", + "https://jsr.io/@denosaurs/netsaur/0.3.1/deps.ts": "1d955ea24fd61ec7ebdc27fb2cdde30c37920c0d189a0f699dd1ce4bbc84fc5d", + "https://jsr.io/@denosaurs/netsaur/0.3.1/mod.ts": "d456339b72873919129f1b962678006024780f4b932ed50cf716537a3e37783c", + "https://jsr.io/@denosaurs/netsaur/0.3.1/src/backends/cpu/backend.ts": "48ab2a4e475fd3638066cc1b613e6a42f47b0ba65c13f21fa1efa4521d407b63", + "https://jsr.io/@denosaurs/netsaur/0.3.1/src/backends/cpu/mod.ts": "0751bfd8dfc3618a9de7b0b9f24d9478a1341c5549c6bc5e088081da6602351c", + "https://jsr.io/@denosaurs/netsaur/0.3.1/src/backends/cpu/util.ts": "cd4b1014adf710cdfe072da898aa38e0dfe821b36c61b8ff3ce9a69311aaa51e", + "https://jsr.io/@denosaurs/netsaur/0.3.1/src/backends/gpu/backend.ts": "41284c284d51935545b3bcdd41615e3edabb173a597ceef270fa1f6a60abef8b", + "https://jsr.io/@denosaurs/netsaur/0.3.1/src/backends/gpu/mod.ts": "31e118c0a05306603a669f4350d1a16c07d23254d395dc8319bca6d3d67bde52", + "https://jsr.io/@denosaurs/netsaur/0.3.1/src/backends/gpu/util.ts": "5920cc0191ff129197d5996d5d8460ef37b9b78700c7c0f2d47bba46d28b3a66", + "https://jsr.io/@denosaurs/netsaur/0.3.1/src/backends/wasm/backend.ts": "ca303a0a50aa681027e81034b4ef0ecab1f48e4f509ee99a9dcd031e2cf0fd7c", + "https://jsr.io/@denosaurs/netsaur/0.3.1/src/backends/wasm/lib/netsaur.generated.js": "8049cc4205a407a6f6e1b1a9bc03e3c7224b6f3c57a990cbc1140b7e3929af67", + "https://jsr.io/@denosaurs/netsaur/0.3.1/src/backends/wasm/mod.ts": "6d154145e58e0039f2ae78c01b3562df544b9b27da702cf08ebe23a00bf99ae1", + "https://jsr.io/@denosaurs/netsaur/0.3.1/src/backends/wasm/utils.ts": "485f7e00fc6680001d6bd6dc8083fa3cbac658c6afff6f38373728acefd320b4", + "https://jsr.io/@denosaurs/netsaur/0.3.1/src/core/api/error.ts": "bd7c3916f6da3d4de0023e35b30d8054dc251c65de6f74553f871c063309bf72", + "https://jsr.io/@denosaurs/netsaur/0.3.1/src/core/api/layer.ts": "addb368878bb5dac195c628739ababdf9974ac401d971b03a62fc35a2032c385", + "https://jsr.io/@denosaurs/netsaur/0.3.1/src/core/api/layers.ts": "f29c8c27cdeaf3842552ad8e36e5a18fda47c24a55791c5113aac31cf510f92c", + "https://jsr.io/@denosaurs/netsaur/0.3.1/src/core/api/network.ts": "a79e10fef6000f984b8032acfa5cad05a6def50dd0d75cf87663b0309d1d6dbd", + "https://jsr.io/@denosaurs/netsaur/0.3.1/src/core/api/optimizer.ts": "76653756cf01cc9816c3087b8c59bb265f3887c9e348db2fa1941b3deb55af61", + "https://jsr.io/@denosaurs/netsaur/0.3.1/src/core/api/scheduler.ts": "292c8112c6a213d172b620e42306025e005b69b22e8fbc02e6e44f5805673efd", + "https://jsr.io/@denosaurs/netsaur/0.3.1/src/core/api/shape.ts": "a65b381937751ab5e0016fb5c8afb023aff480f39612f77d200fea85249026d4", + "https://jsr.io/@denosaurs/netsaur/0.3.1/src/core/engine.ts": "1804666283bfa8ff31d1644bcda1fbaba209459d3535e0dc2ab9dfd07d96b7fb", + "https://jsr.io/@denosaurs/netsaur/0.3.1/src/core/mod.ts": "19a0e7372c6de3b627df0b93f1cda98393b6c19dca85cbe82d5994a650330c78", + "https://jsr.io/@denosaurs/netsaur/0.3.1/src/core/tensor/tensor.ts": "2158458cbf6fedb8b64aead6ada40fc4861fbac7468de4ce13fe46bd8c0aa958", + "https://jsr.io/@denosaurs/netsaur/0.3.1/src/core/tensor/util.ts": "a155bc610a9b5464fd97903997bb999ba1b4f0c89250e3a2be1a27c0c56b5ea5", + "https://jsr.io/@denosaurs/netsaur/0.3.1/src/core/types.ts": "e55862b77d0c4881a1540f4901bfa47adce8db1475fe75b89e03a78351bf5887", + "https://jsr.io/@denosaurs/plug/1.0.3/deps.ts": "4518c332757c16e1b10e01f6d7f618053a45c6c467cc4302827cefea7294f00b", + "https://jsr.io/@denosaurs/plug/1.0.3/download.ts": "ada314a1a273c43559acd341155fbfc4aba41247d84361f2db7423d1648bd816", + "https://jsr.io/@denosaurs/plug/1.0.3/mod.ts": "5dec80ee7a3a325be45c03439558531bce7707ac118f4376cebbd6740ff24bfb", + "https://jsr.io/@denosaurs/plug/1.0.3/types.ts": "0490359117c53783138f2b6692a34f85bca9237314ba8cdef8ad682d81218d21", + "https://jsr.io/@denosaurs/plug/1.0.3/util.ts": "aa96bc3cdae1787220bac9d37e90879b3d5deea5b46adebb1ff2fcb3ea84e0e6", + "https://jsr.io/@std/assert/0.213.1/assert.ts": "501b416473ec27c71885aaf819e363c8df617f89ce68ae57fec7acf9d62743b2", + "https://jsr.io/@std/assert/0.213.1/assertion_error.ts": "dd027fb33707dbff22cd2ef9b55fdb70e2095876caf3c68ecfbb811505ecc022", + "https://jsr.io/@std/assert/0.214.0/assert.ts": "501b416473ec27c71885aaf819e363c8df617f89ce68ae57fec7acf9d62743b2", + "https://jsr.io/@std/assert/0.214.0/assertion_error.ts": "dd027fb33707dbff22cd2ef9b55fdb70e2095876caf3c68ecfbb811505ecc022", + "https://jsr.io/@std/bytes/0.214.0/concat.ts": "8142a1734fd445582be0d209d0def43c2a3c27370a0fd4b327187dd34b98d6eb", + "https://jsr.io/@std/csv/0.214.0/_io.ts": "48bba679fe362e7c0b3305f37b6071698f49018c606b55989e40aa1e89ecf410", + "https://jsr.io/@std/csv/0.214.0/csv_parse_stream.ts": "f1ad887290a1cdf7540db445c6083dfc3a79ffeaec1b05b1261506ffe66cf8fa", + "https://jsr.io/@std/csv/0.214.0/csv_stringify_stream.ts": "93cc46f5738d35bc237438a900a7372593102d025353679ffc79327dade1e245", + "https://jsr.io/@std/csv/0.214.0/mod.ts": "289ecf79b3609f63dfc1d39a7c791f8f14b73b29fb65bbb6b3e3e2bd0cddc75d", + "https://jsr.io/@std/csv/0.214.0/parse.ts": "b47645892a67060a4f8ca11538e19ff873a6a0a26f18c070eae5b51761b1a51b", + "https://jsr.io/@std/csv/0.214.0/stringify.ts": "557a3a41068557c262221128be8e4d8b3a32232dde5114cb5f24193e6c28b1cb", + "https://jsr.io/@std/encoding/0.213.1/_util.ts": "beacef316c1255da9bc8e95afb1fa56ed69baef919c88dc06ae6cb7a6103d376", + "https://jsr.io/@std/encoding/0.213.1/hex.ts": "1aecfa504efd0ffcd176037abc7eb7d775a7b38a9e775d9e7260b583ad1301e7", + "https://jsr.io/@std/fmt/0.213.1/colors.ts": "59b5de7c07cdc0322ed61b2d98da1ca4fbc9f576d45c2beee577a27556e52d63", + "https://jsr.io/@std/fs/0.213.1/_create_walk_entry.ts": "b48774274e42cb540eb2aa31ea64e2734ec909900d14bdf9ce73bd0d3ce465e7", + "https://jsr.io/@std/fs/0.213.1/_get_file_info_type.ts": "da7bec18a7661dba360a1db475b826b18977582ce6fc9b25f3d4ee0403fe8cbd", + "https://jsr.io/@std/fs/0.213.1/_is_same_path.ts": "8f3810e02b6018c1c1e1019715b8ff1deb523f03d08ade597ddba2ec96b5e1ab", + "https://jsr.io/@std/fs/0.213.1/_is_subdir.ts": "2310298ba1017545e8b7d121387b0b1e94dd1e2c91c4c9fa28eb249823312647", + "https://jsr.io/@std/fs/0.213.1/_to_path_string.ts": "da4e710ec2f58266a609d4c649d86731129db1bc7c72fa275f6d13e81576ce45", + "https://jsr.io/@std/fs/0.213.1/copy.ts": "4b3673d4dcbf4957422350c7964868a89622ccbd66f15a12ad3d2fe80a792670", + "https://jsr.io/@std/fs/0.213.1/empty_dir.ts": "78456f5aaf04a911cafd2c21b4dd3c0f5c6620b311aa048541c39ab43f858b84", + "https://jsr.io/@std/fs/0.213.1/ensure_dir.ts": "a6c127285f5bdfe10e6ff5b55ff7f9b5c7f67c74d3dcfe66081c5780a5e1ee85", + "https://jsr.io/@std/fs/0.213.1/ensure_file.ts": "1d99467da9aeb55557412f5773dfdbd78b6c2ba38907b4d4108c8f51bab0c0f1", + "https://jsr.io/@std/fs/0.213.1/ensure_link.ts": "e4efe0a0111a6fa8da52309500eaa740864bf33c5957154b3d3cb727e71e340d", + "https://jsr.io/@std/fs/0.213.1/ensure_symlink.ts": "dd656834384e7131c7ddb5307c84370e2927ece924e7f9fc8176537fc67bcb4d", + "https://jsr.io/@std/fs/0.213.1/eol.ts": "d560d5e3cc3a1acff483f1339d7de31ca6025808b2c499a8b246984b84282e0b", + "https://jsr.io/@std/fs/0.213.1/exists.ts": "e636a0e535793d8677095e7a75308eda47cc4c784f83c4e2beaa90825a5b84de", + "https://jsr.io/@std/fs/0.213.1/expand_glob.ts": "180ee5fd8616d6f5be8ee0d98a1766498594b566c44a51710f964121295d1151", + "https://jsr.io/@std/fs/0.213.1/mod.ts": "107f5afa4424c2d3ce2f7e9266173198da30302c69af662c720115fe504dc5ee", + "https://jsr.io/@std/fs/0.213.1/move.ts": "8301ee1883b3d5e0eda7c5b670e7fe5ca9ac98fe74258551ec513d222c1af85f", + "https://jsr.io/@std/fs/0.213.1/walk.ts": "3a0af602e996a11e3e0305548bfa4b60ba1b8e2dfc582da890604217b52732d6", + "https://jsr.io/@std/path/0.213.1/_common/assert_path.ts": "2ca275f36ac1788b2acb60fb2b79cb06027198bc2ba6fb7e163efaedde98c297", + "https://jsr.io/@std/path/0.213.1/_common/basename.ts": "569744855bc8445f3a56087fd2aed56bdad39da971a8d92b138c9913aecc5fa2", + "https://jsr.io/@std/path/0.213.1/_common/common.ts": "6157c7ec1f4db2b4a9a187efd6ce76dcaf1e61cfd49f87e40d4ea102818df031", + "https://jsr.io/@std/path/0.213.1/_common/constants.ts": "dc5f8057159f4b48cd304eb3027e42f1148cf4df1fb4240774d3492b5d12ac0c", + "https://jsr.io/@std/path/0.213.1/_common/dirname.ts": "684df4aa71a04bbcc346c692c8485594fc8a90b9408dfbc26ff32cf3e0c98cc8", + "https://jsr.io/@std/path/0.213.1/_common/format.ts": "92500e91ea5de21c97f5fe91e178bae62af524b72d5fcd246d6d60ae4bcada8b", + "https://jsr.io/@std/path/0.213.1/_common/from_file_url.ts": "d672bdeebc11bf80e99bf266f886c70963107bdd31134c4e249eef51133ceccf", + "https://jsr.io/@std/path/0.213.1/_common/glob_to_reg_exp.ts": "2007aa87bed6eb2c8ae8381adcc3125027543d9ec347713c1ad2c68427330770", + "https://jsr.io/@std/path/0.213.1/_common/normalize.ts": "684df4aa71a04bbcc346c692c8485594fc8a90b9408dfbc26ff32cf3e0c98cc8", + "https://jsr.io/@std/path/0.213.1/_common/normalize_string.ts": "dfdf657a1b1a7db7999f7c575ee7e6b0551d9c20f19486c6c3f5ff428384c965", + "https://jsr.io/@std/path/0.213.1/_common/relative.ts": "faa2753d9b32320ed4ada0733261e3357c186e5705678d9dd08b97527deae607", + "https://jsr.io/@std/path/0.213.1/_common/strip_trailing_separators.ts": "7024a93447efcdcfeaa9339a98fa63ef9d53de363f1fbe9858970f1bba02655a", + "https://jsr.io/@std/path/0.213.1/_common/to_file_url.ts": "7f76adbc83ece1bba173e6e98a27c647712cab773d3f8cbe0398b74afc817883", + "https://jsr.io/@std/path/0.213.1/_interface.ts": "a1419fcf45c0ceb8acdccc94394e3e94f99e18cfd32d509aab514c8841799600", + "https://jsr.io/@std/path/0.213.1/_os.ts": "8fb9b90fb6b753bd8c77cfd8a33c2ff6c5f5bc185f50de8ca4ac6a05710b2c15", + "https://jsr.io/@std/path/0.213.1/basename.ts": "5d341aadb7ada266e2280561692c165771d071c98746fcb66da928870cd47668", + "https://jsr.io/@std/path/0.213.1/common.ts": "4c80da2ee5563eb31f87cf7d21879db90d614a3fae83358670625e4b90342745", + "https://jsr.io/@std/path/0.213.1/constants.ts": "0c206169ca104938ede9da48ac952de288f23343304a1c3cb6ec7625e7325f36", + "https://jsr.io/@std/path/0.213.1/dirname.ts": "85bd955bf31d62c9aafdd7ff561c4b5fb587d11a9a5a45e2b01aedffa4238a7c", + "https://jsr.io/@std/path/0.213.1/extname.ts": "593303db8ae8c865cbd9ceec6e55d4b9ac5410c1e276bfd3131916591b954441", + "https://jsr.io/@std/path/0.213.1/format.ts": "98fad25f1af7b96a48efb5b67378fcc8ed77be895df8b9c733b86411632162af", + "https://jsr.io/@std/path/0.213.1/from_file_url.ts": "7c87244ca07e4065cb024016b03d012facb856cc7aed089d9b6f1e4ea6152316", + "https://jsr.io/@std/path/0.213.1/glob.ts": "04510962905d4b1513b44da9cb195914e0fa46c24359f6feaca20848d797dcb0", + "https://jsr.io/@std/path/0.213.1/glob_to_regexp.ts": "83c5fd36a8c86f5e72df9d0f45317f9546afa2ce39acaafe079d43a865aced08", + "https://jsr.io/@std/path/0.213.1/is_absolute.ts": "4791afc8bfd0c87f0526eaa616b0d16e7b3ab6a65b62942e50eac68de4ef67d7", + "https://jsr.io/@std/path/0.213.1/is_glob.ts": "a65f6195d3058c3050ab905705891b412ff942a292bcbaa1a807a74439a14141", + "https://jsr.io/@std/path/0.213.1/join.ts": "ae2ec5ca44c7e84a235fd532e4a0116bfb1f2368b394db1c4fb75e3c0f26a33a", + "https://jsr.io/@std/path/0.213.1/join_globs.ts": "e9589869a33dc3982101898ee50903db918ca00ad2614dbe3934d597d7b1fbea", + "https://jsr.io/@std/path/0.213.1/mod.ts": "8a61b81dd91a8cca0326bf0011db8d227b23b982dd4647fb119674594e29e544", + "https://jsr.io/@std/path/0.213.1/normalize.ts": "4155743ccceeed319b350c1e62e931600272fad8ad00c417b91df093867a8352", + "https://jsr.io/@std/path/0.213.1/normalize_glob.ts": "98ee8268fad271193603271c203ae973280b5abfbdd2cbca1053fd2af71869ca", + "https://jsr.io/@std/path/0.213.1/parse.ts": "65e8e285f1a63b714e19ef24b68f56e76934c3df0b6e65fd440d3991f4f8aefb", + "https://jsr.io/@std/path/0.213.1/posix/_util.ts": "1e3937da30f080bfc99fe45d7ed23c47dd8585c5e473b2d771380d3a6937cf9d", + "https://jsr.io/@std/path/0.213.1/posix/basename.ts": "265d3360c49c1af372a10891518b785fc2ae138f019892c89642e1f1c523b2dc", + "https://jsr.io/@std/path/0.213.1/posix/common.ts": "4c896e6e9357f33c3ffe027cb13cb2ccf5dbe3575604b43c195befffb0f40b2b", + "https://jsr.io/@std/path/0.213.1/posix/constants.ts": "93481efb98cdffa4c719c22a0182b994e5a6aed3047e1962f6c2c75b7592bef1", + "https://jsr.io/@std/path/0.213.1/posix/dirname.ts": "ecdaeec17d5fdd00da89bb05962e209c7aa41ad4967279bc8662c0bb3a243b2f", + "https://jsr.io/@std/path/0.213.1/posix/extname.ts": "b1400d9d0ac2160accda327790c93daa4ee8325b87f4c4d9b21887e7c8fd73db", + "https://jsr.io/@std/path/0.213.1/posix/format.ts": "47318e54ac8cd2e9c35ef2a143d02c198ce093e31f9789b6ecb95cbc60fec71b", + "https://jsr.io/@std/path/0.213.1/posix/from_file_url.ts": "dc4a092de0d117d94bfd54390b4bc360ea1c68d4a1e42d2ea94d6fe75b483c37", + "https://jsr.io/@std/path/0.213.1/posix/glob_to_regexp.ts": "4db789540039ea4c75f1ba8182c43fc2965a019df3c26a825945642452e8bf75", + "https://jsr.io/@std/path/0.213.1/posix/is_absolute.ts": "e7147b25e786abb51dd888eca89d2fd3770c41e6bd556d19db26cca348fb78a4", + "https://jsr.io/@std/path/0.213.1/posix/is_glob.ts": "135ac8b1e647f673ea650fb713e2d9c42d0108c29cae3a2b77399fec0dae8864", + "https://jsr.io/@std/path/0.213.1/posix/join.ts": "1bbf0d9303160d4b9be76161d0ef73d67198cf7bf66e84d88eb560abc492070f", + "https://jsr.io/@std/path/0.213.1/posix/join_globs.ts": "3d77c1a2e29997f6d993105b5f5e8e89a280320a3e0e3df7e6b912506d69103f", + "https://jsr.io/@std/path/0.213.1/posix/mod.ts": "c9d57eb43df561742cf545816a7d6e1382680425de245588197bbf3d325931ad", + "https://jsr.io/@std/path/0.213.1/posix/normalize.ts": "9b9f666159c0e5ee3df292cf56555547b1be4cd3ca54da6a263a3074b8e44964", + "https://jsr.io/@std/path/0.213.1/posix/normalize_glob.ts": "c1b8a6f001d7cad1a6c8eefb4d7f7a027d3a7bc7a0c91c6e08222f4cbac6105f", + "https://jsr.io/@std/path/0.213.1/posix/parse.ts": "96aad4733eb1091db6b3de423f23c25a2ac3e3a5b29b35c3ee808b123eef73e5", + "https://jsr.io/@std/path/0.213.1/posix/relative.ts": "f0617bf5614ac45462d71d8d03a5bbe3db9f5aaadc9e470a560013d0416d4cc0", + "https://jsr.io/@std/path/0.213.1/posix/resolve.ts": "00f39f36478ad11b64604ad9b508b137a930aae2423e757ba53ec5f11a919ee1", + "https://jsr.io/@std/path/0.213.1/posix/separator.ts": "c9ecae5c843170118156ac5d12dc53e9caf6a1a4c96fc8b1a0ab02dff5c847b0", + "https://jsr.io/@std/path/0.213.1/posix/to_file_url.ts": "e1c2f7b256100610ae85a443f89404f4b5d730d882c388a76b8e4fa1ecfc5ac7", + "https://jsr.io/@std/path/0.213.1/posix/to_namespaced_path.ts": "28b216b3c76f892a4dca9734ff1cc0045d135532bfd9c435ae4858bfa5a2ebf0", + "https://jsr.io/@std/path/0.213.1/relative.ts": "ab739d727180ed8727e34ed71d976912461d98e2b76de3d3de834c1066667add", + "https://jsr.io/@std/path/0.213.1/resolve.ts": "a6f977bdb4272e79d8d0ed4333e3d71367cc3926acf15ac271f1d059c8494d8d", + "https://jsr.io/@std/path/0.213.1/separator.ts": "c6c890507f944a1f5cb7d53b8d638d6ce3cf0f34609c8d84a10c1eaa400b77a9", + "https://jsr.io/@std/path/0.213.1/to_file_url.ts": "ce1a439e03377882e58f06ef43ef2259d483bab235d1eb727f1637b0a6bd7070", + "https://jsr.io/@std/path/0.213.1/to_namespaced_path.ts": "b706a4103b104cfadc09600a5f838c2ba94dbcdb642344557122dda444526e40", + "https://jsr.io/@std/path/0.213.1/windows/_util.ts": "d5f47363e5293fced22c984550d5e70e98e266cc3f31769e1710511803d04808", + "https://jsr.io/@std/path/0.213.1/windows/basename.ts": "20179a24e3b4a8d5d957f0b6c5515d1d05c47c7e5824d595844f3ff5558e6e5b", + "https://jsr.io/@std/path/0.213.1/windows/common.ts": "4c896e6e9357f33c3ffe027cb13cb2ccf5dbe3575604b43c195befffb0f40b2b", + "https://jsr.io/@std/path/0.213.1/windows/constants.ts": "5afaac0a1f67b68b0a380a4ef391bf59feb55856aa8c60dfc01bd3b6abb813f5", + "https://jsr.io/@std/path/0.213.1/windows/dirname.ts": "f5aee3cff1830aa804bee6b947c51a667dfc713b339923d884e590cffdf5d8e0", + "https://jsr.io/@std/path/0.213.1/windows/extname.ts": "297ff46e51d75b97d4096cf5664471dca65b529f557c2e6e08aec3f2441767bf", + "https://jsr.io/@std/path/0.213.1/windows/format.ts": "8986f9e9b1cd48b404aa7c3873bfb976a9af08eeb40a58f1001a8d887d0dfe14", + "https://jsr.io/@std/path/0.213.1/windows/from_file_url.ts": "d67e4c8e7453597bf8071da6a995d6c9ad41f3c30192dc6494a25beb14647ff7", + "https://jsr.io/@std/path/0.213.1/windows/glob_to_regexp.ts": "5a9251ea357ec619f8b370a87e3ec010f36ceb9a0112973b6a1122684b72ccdb", + "https://jsr.io/@std/path/0.213.1/windows/is_absolute.ts": "d3534d9fd5680d4c6895bbb59193335e5753cdef875f095297be66eb96f2f530", + "https://jsr.io/@std/path/0.213.1/windows/is_glob.ts": "135ac8b1e647f673ea650fb713e2d9c42d0108c29cae3a2b77399fec0dae8864", + "https://jsr.io/@std/path/0.213.1/windows/join.ts": "a62e4f0cc65e0f6f2b033f5df3b11e0b51362aef2e1fb7c9aef2b299ac224810", + "https://jsr.io/@std/path/0.213.1/windows/join_globs.ts": "3d77c1a2e29997f6d993105b5f5e8e89a280320a3e0e3df7e6b912506d69103f", + "https://jsr.io/@std/path/0.213.1/windows/mod.ts": "8b483812e8f38abcbf5aad4352409e7828d9ef9ecd4aa0a241fbeb0f8ba7a890", + "https://jsr.io/@std/path/0.213.1/windows/normalize.ts": "f5d8b971161eff7b4f8e45c7520cbb0c6553ccff7c4b3ced2dfe0d6ad46a2328", + "https://jsr.io/@std/path/0.213.1/windows/normalize_glob.ts": "c37afcaf52f2ce977f52a2b7820cad7e1fb7b9651df1fe130dda52401ae12263", + "https://jsr.io/@std/path/0.213.1/windows/parse.ts": "c63488c9d581576f955eaa8c4ab09c165b8d922ec3911b302c31331c8303973f", + "https://jsr.io/@std/path/0.213.1/windows/relative.ts": "366eb25bd3469433e47dd4cac52d03048d5e27e8a89e059217065d3afa4e7e71", + "https://jsr.io/@std/path/0.213.1/windows/resolve.ts": "671e70d150bd933832ffcf02e97572fdfbb8ed199082bdabdf4e92d3e898636e", + "https://jsr.io/@std/path/0.213.1/windows/separator.ts": "e51c5522140eff4f8402617c5c68a201fdfa3a1a8b28dc23587cff931b665e43", + "https://jsr.io/@std/path/0.213.1/windows/to_file_url.ts": "cdead9ba8f1e4062c3c45a7c9fa6384e209b734526b4c6ab36ce2f17339367f5", + "https://jsr.io/@std/path/0.213.1/windows/to_namespaced_path.ts": "96dd0d55d484905e06553fd7d5feb6b3e4c0c99c337fda4199b6c32bce44833a", + "https://jsr.io/@std/streams/0.214.0/_common.ts": "4f9f2958d853b9a456be033631dabb7519daa68ee4d02caf53e2ecbffaf5805f", + "https://jsr.io/@std/streams/0.214.0/delimiter_stream.ts": "e017e58ba6c726003106d2414a769d83ad94b4c506d73ebbcef3025fd943908d", + "https://jsr.io/@std/streams/0.214.0/text_delimiter_stream.ts": "fecfa37b83b9d57296ec6c83637f15c82b76d0e52cd9b46352cc9862ca454f01" } } diff --git a/deps.ts b/deps.ts index bfa6841..04af911 100644 --- a/deps.ts +++ b/deps.ts @@ -1,2 +1,2 @@ -export { dlopen } from "https://deno.land/x/plug@1.0.3/mod.ts"; -export type { FetchOptions } from "https://deno.land/x/plug@1.0.3/mod.ts"; +export { dlopen } from "jsr:@denosaurs/plug@1.0.3"; +export type { FetchOptions } from "jsr:@denosaurs/plug@1.0.3"; diff --git a/examples/classification/README.md b/examples/classification/README.md index f40cad2..d9c3962 100644 --- a/examples/classification/README.md +++ b/examples/classification/README.md @@ -1,3 +1,4 @@ # Binary Classification -This example showcases binary classification on the Iris dataset. -The `Iris Virginica` class is omitted for this example. \ No newline at end of file + +This example showcases binary classification on the Iris dataset. The +`Iris Virginica` class is omitted for this example. diff --git a/examples/classification/binary_iris.ts b/examples/classification/binary_iris.ts index 684a4b7..01d647b 100644 --- a/examples/classification/binary_iris.ts +++ b/examples/classification/binary_iris.ts @@ -75,7 +75,7 @@ net.train( 150, 1, // Use a smaller learning rate - 0.02 + 0.02, ); console.log(`training time: ${performance.now() - time}ms`); diff --git a/examples/classification/iris.ts b/examples/classification/iris.ts index b91fb3f..c9e262d 100644 --- a/examples/classification/iris.ts +++ b/examples/classification/iris.ts @@ -16,12 +16,12 @@ import { parse } from "https://deno.land/std@0.204.0/csv/parse.ts"; // Import helpers for metrics import { - ClassificationReport, - // Split the dataset - useSplit, // One-hot encoding of targets CategoricalEncoder, + ClassificationReport, Matrix, + // Split the dataset + useSplit, } from "https://deno.land/x/vectorizer@v0.3.7/mod.ts"; // Read the training dataset @@ -40,7 +40,7 @@ const y = encoder.fit(y_pre).transform(y_pre, "f32"); // @ts-ignore Matrices can be split const [train, test] = useSplit({ ratio: [7, 3], shuffle: true }, x, y) as [ [typeof x, typeof y], - [typeof x, typeof y] + [typeof x, typeof y], ]; // Setup the CPU backend for Netsaur @@ -87,7 +87,7 @@ net.train( // Train for 300 epochs 400, 1, - 0.02 + 0.02, ); console.log(`training time: ${performance.now() - time}ms`); @@ -96,8 +96,8 @@ console.log(`training time: ${performance.now() - time}ms`); const res = await net.predict(tensor2D(test[0])); const y1 = encoder.untransform( CategoricalEncoder.fromSoftmax( - new Matrix(res.data, [res.shape[0], res.shape[1]]) - ) + new Matrix(res.data, [res.shape[0], res.shape[1]]), + ), ); const y0 = encoder.untransform(test[1]); @@ -106,5 +106,5 @@ const cMatrix = new ClassificationReport(y0, y1); console.log(cMatrix); console.log( "Total Accuracy: ", - y1.filter((x, i) => x === y0[i]).length / y1.length + y1.filter((x, i) => x === y0[i]).length / y1.length, ); diff --git a/examples/classification/spam.ts b/examples/classification/spam.ts index 3103da8..15ce5b6 100644 --- a/examples/classification/spam.ts +++ b/examples/classification/spam.ts @@ -35,7 +35,7 @@ const y = data.map((msg) => ymap.indexOf(msg[0])); // Split the dataset for training and testing const [train, test] = useSplit({ ratio: [7, 3], shuffle: true }, x, y) as [ [typeof x, typeof y], - [typeof x, typeof y] + [typeof x, typeof y], ]; // Vectorize the text messages @@ -88,7 +88,7 @@ net.train( // Train for 20 epochs 20, 2, - 0.01 + 0.01, ); console.log(`training time: ${performance.now() - time}ms`); @@ -97,7 +97,6 @@ const x_vec_test = vec.transform(test[0]); // Calculate metrics const res = await net.predict(tensor(x_vec_test.data, x_vec_test.shape)); -const y1 = res.data.map(i => i < 0.5 ? 0 : 1) +const y1 = res.data.map((i) => i < 0.5 ? 0 : 1); const cMatrix = new ClassificationReport(test[1], y1); console.log("Confusion Matrix: ", cMatrix); - diff --git a/examples/linear.ts b/examples/linear.ts index be609ee..70b8015 100644 --- a/examples/linear.ts +++ b/examples/linear.ts @@ -70,7 +70,7 @@ network.train( /** * The learning rate is set to 0.01. */ - 0.01 + 0.01, ); console.log("training time", performance.now() - start, " milliseconds"); @@ -84,6 +84,6 @@ for (const [i, res] of predicted.data.entries()) { console.log( `input: ${testData[i]}\noutput: ${res.toFixed(2)}\nexpected: ${ 2 * testData[i] + 1 - }\n` + }\n`, ); } diff --git a/examples/mnist/predict.ts b/examples/mnist/predict.ts index 29b1145..3518c6f 100644 --- a/examples/mnist/predict.ts +++ b/examples/mnist/predict.ts @@ -32,8 +32,8 @@ let correct = 0; for (const test of testSet) { const prediction = argmax( await network.predict( - tensor(test.inputs.data, [1, ...test.inputs.shape] as Shape[keyof Shape]) - ) + tensor(test.inputs.data, [1, ...test.inputs.shape] as Shape[keyof Shape]), + ), ); const expected = argmax(test.outputs as Tensor); if (expected === prediction) { diff --git a/examples/mnist/train_batchnorm.ts b/examples/mnist/train_batchnorm.ts index 0635ee5..6461153 100644 --- a/examples/mnist/train_batchnorm.ts +++ b/examples/mnist/train_batchnorm.ts @@ -55,4 +55,4 @@ const start = performance.now(); network.train(trainSet, epochs, 1, 0.01); console.log("Training complete!", performance.now() - start); -network.saveFile("examples/mnist/mnist.test.st"); \ No newline at end of file +network.saveFile("examples/mnist/mnist.test.st"); diff --git a/examples/visualize.ipynb b/examples/visualize.ipynb index aefa859..1179a1f 100644 --- a/examples/visualize.ipynb +++ b/examples/visualize.ipynb @@ -63,19 +63,19 @@ } ], "source": [ - "import { tensor1D } from \"https://deno.land/x/netsaur@0.3.0/mod.ts\";\n", - "import { Visualizer } from \"https://deno.land/x/netsaur@0.3.0/visualizer/mod.ts\";\n", + "import { tensor1D } from \"https://deno.land/x/netsaur@0.3.1/mod.ts\";\n", + "import { Visualizer } from \"https://deno.land/x/netsaur@0.3.1/visualizer/mod.ts\";\n", "\n", "import {\n", - " Cost,\n", " AUTO,\n", + " Cost,\n", " DenseLayer,\n", " Sequential,\n", " setupBackend,\n", " SigmoidLayer,\n", " tensor2D,\n", - "} from \"https://deno.land/x/netsaur@0.3.0/mod.ts\";\n", - " \n", + "} from \"https://deno.land/x/netsaur@0.3.1/mod.ts\";\n", + "\n", "await setupBackend(AUTO);\n", "\n", "const net = new Sequential({\n", @@ -107,10 +107,9 @@ " ],\n", " 1000000,\n", ");\n", - " \n", + "\n", "const visualizer = new Visualizer(\"XOR Example\");\n", - "await visualizer.graph(net,\n", - " [\n", + "await visualizer.graph(net, [\n", " tensor1D([0, 0]),\n", " tensor1D([1, 0]),\n", " tensor1D([0, 1]),\n", @@ -119,8 +118,8 @@ " tensor1D([0]),\n", " tensor1D([1]),\n", " tensor1D([1]),\n", - " tensor1D([0])\n", - "])" + " tensor1D([0]),\n", + "]);" ] } ], diff --git a/examples/xor.ipynb b/examples/xor.ipynb index 659ad37..e007c85 100644 --- a/examples/xor.ipynb +++ b/examples/xor.ipynb @@ -36,7 +36,7 @@ } ], "source": [ - "import { setupBackend, CPU } from \"https://deno.land/x/netsaur@0.3.0/mod.ts\";\n", + "import { CPU, setupBackend } from \"https://deno.land/x/netsaur@0.3.1/mod.ts\";\n", "await setupBackend(CPU);" ] }, @@ -68,7 +68,7 @@ } ], "source": [ - "import { setupBackend, WASM } from \"https://deno.land/x/netsaur@0.3.0/mod.ts\";\n", + "import { setupBackend, WASM } from \"https://deno.land/x/netsaur@0.3.1/mod.ts\";\n", "await setupBackend(WASM);" ] }, @@ -92,7 +92,7 @@ "metadata": {}, "outputs": [], "source": [ - "import { setupBackend, GPU } from \"https://deno.land/x/netsaur@0.3.0/mod.ts\";\n", + "import { GPU, setupBackend } from \"https://deno.land/x/netsaur@0.3.1/mod.ts\";\n", "await setupBackend(GPU);" ] }, @@ -100,7 +100,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Create a new Sequential neural network. A Sequential model is a linear stack of layers." + "Create a new Sequential neural network. A Sequential model is a linear stack of\n", + "layers." ] }, { @@ -109,47 +110,54 @@ "metadata": {}, "outputs": [], "source": [ - "import { Sequential, DenseLayer, SigmoidLayer, Cost, tensor2D, tensor1D } from \"https://deno.land/x/netsaur@0.3.0/mod.ts\";\n", + "import {\n", + " Cost,\n", + " DenseLayer,\n", + " Sequential,\n", + " SigmoidLayer,\n", + " tensor1D,\n", + " tensor2D,\n", + "} from \"https://deno.land/x/netsaur@0.3.1/mod.ts\";\n", "const net = new Sequential({\n", - " /**\n", - " * The number of minibatches is set to 4 and the output size is set to 2.\n", - " */\n", - " size: [4, 2],\n", - " \n", - " /**\n", - " * The silent option is set to false, which means that the network will output logs during training\n", - " */\n", - " silent: false,\n", - " \n", - " /**\n", - " * Defines the layers of a neural network in the XOR function example.\n", - " * The neural network has two input neurons and one output neuron.\n", - " * The layers are defined as follows:\n", - " * - A dense layer with 3 neurons.\n", - " * - sigmoid activation layer.\n", - " * - A dense layer with 1 neuron.\n", - " * -A sigmoid activation layer.\n", - " */\n", - " layers: [\n", - " DenseLayer({ size: [3] }),\n", - " SigmoidLayer(),\n", - " DenseLayer({ size: [1] }),\n", - " SigmoidLayer(),\n", - " ],\n", - " \n", - " /**\n", - " * The cost function used for training the network is the mean squared error (MSE).\n", - " */\n", - " cost: Cost.MSE,\n", - " });\n", - " " + " /**\n", + " * The number of minibatches is set to 4 and the output size is set to 2.\n", + " */\n", + " size: [4, 2],\n", + "\n", + " /**\n", + " * The silent option is set to false, which means that the network will output logs during training\n", + " */\n", + " silent: false,\n", + "\n", + " /**\n", + " * Defines the layers of a neural network in the XOR function example.\n", + " * The neural network has two input neurons and one output neuron.\n", + " * The layers are defined as follows:\n", + " * - A dense layer with 3 neurons.\n", + " * - sigmoid activation layer.\n", + " * - A dense layer with 1 neuron.\n", + " * -A sigmoid activation layer.\n", + " */\n", + " layers: [\n", + " DenseLayer({ size: [3] }),\n", + " SigmoidLayer(),\n", + " DenseLayer({ size: [1] }),\n", + " SigmoidLayer(),\n", + " ],\n", + "\n", + " /**\n", + " * The cost function used for training the network is the mean squared error (MSE).\n", + " */\n", + " cost: Cost.MSE,\n", + "});" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Once the network is created and configured we can begin training it. We will train it for 10000 epochs." + "Once the network is created and configured we can begin training it. We will\n", + "train it for 10000 epochs." ] }, { @@ -162,29 +170,30 @@ " * Train the network on the given data.\n", " */\n", "net.train(\n", - " [\n", - " {\n", - " inputs: tensor2D([\n", - " [0, 0],\n", - " [1, 0],\n", - " [0, 1],\n", - " [1, 1],\n", - " ]),\n", - " outputs: tensor2D([[0], [1], [1], [0]]),\n", - " },\n", - " ],\n", - " /**\n", - " * The number of iterations is set to 10000.\n", - " */\n", - " 10000,\n", - " );" + " [\n", + " {\n", + " inputs: tensor2D([\n", + " [0, 0],\n", + " [1, 0],\n", + " [0, 1],\n", + " [1, 1],\n", + " ]),\n", + " outputs: tensor2D([[0], [1], [1], [0]]),\n", + " },\n", + " ],\n", + " /**\n", + " * The number of iterations is set to 10000.\n", + " */\n", + " 10000,\n", + ");" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Once we have trained the network we can test it by passing in the input values into the predict method." + "Once we have trained the network we can test it by passing in the input values\n", + "into the predict method." ] }, { diff --git a/examples/xor_auto.ts b/examples/xor_auto.ts index c41131c..973ca6b 100644 --- a/examples/xor_auto.ts +++ b/examples/xor_auto.ts @@ -91,4 +91,4 @@ const out3 = (await net.predict(tensor2D([[0, 1]]))).data; console.log(`0 xor 1 = ${out3[0]} (should be close to 1)`); const out4 = (await net.predict(tensor2D([[1, 1]]))).data; -console.log(`1 xor 1 = ${out4[0]} (should be close to 0)`); \ No newline at end of file +console.log(`1 xor 1 = ${out4[0]} (should be close to 0)`); diff --git a/examples/xor_gpu.ts b/examples/xor_gpu.ts index e0c4810..81c6ee5 100644 --- a/examples/xor_gpu.ts +++ b/examples/xor_gpu.ts @@ -3,92 +3,92 @@ */ import { - Cost, - GPU, - DenseLayer, - Sequential, - setupBackend, - SigmoidLayer, - tensor2D, - } from "../mod.ts"; - + Cost, + DenseLayer, + GPU, + Sequential, + setupBackend, + SigmoidLayer, + tensor2D, +} from "../mod.ts"; + +/** + * Setup the GPU backend. This backend is fast but doesn't work on the Edge. + */ +await setupBackend(GPU); + +/** + * Creates a sequential neural network. + */ +const net = new Sequential({ /** - * Setup the GPU backend. This backend is fast but doesn't work on the Edge. + * The number of minibatches is set to 4 and the output size is set to 2. */ - await setupBackend(GPU); - + size: [4, 2], + /** - * Creates a sequential neural network. + * The silent option is set to true, which means that the network will not output any logs during trainin */ - const net = new Sequential({ - /** - * The number of minibatches is set to 4 and the output size is set to 2. - */ - size: [4, 2], - - /** - * The silent option is set to true, which means that the network will not output any logs during trainin - */ - silent: true, - - /** - * Defines the layers of a neural network in the XOR function example. - * The neural network has two input neurons and one output neuron. - * The layers are defined as follows: - * - A dense layer with 3 neurons. - * - sigmoid activation layer. - * - A dense layer with 1 neuron. - * -A sigmoid activation layer. - */ - layers: [ - DenseLayer({ size: [3] }), - SigmoidLayer(), - DenseLayer({ size: [1] }), - SigmoidLayer(), - ], - - /** - * The cost function used for training the network is the mean squared error (MSE). - */ - cost: Cost.MSE, - }); - - const time = performance.now(); - + silent: true, + + /** + * Defines the layers of a neural network in the XOR function example. + * The neural network has two input neurons and one output neuron. + * The layers are defined as follows: + * - A dense layer with 3 neurons. + * - sigmoid activation layer. + * - A dense layer with 1 neuron. + * -A sigmoid activation layer. + */ + layers: [ + DenseLayer({ size: [3] }), + SigmoidLayer(), + DenseLayer({ size: [1] }), + SigmoidLayer(), + ], + /** - * Train the network on the given data. + * The cost function used for training the network is the mean squared error (MSE). */ - net.train( - [ - { - inputs: tensor2D([ - [0, 0], - [1, 0], - [0, 1], - [1, 1], - ]), - outputs: tensor2D([[0], [1], [1], [0]]), - }, - ], - /** - * The number of iterations is set to 10000. - */ - 10000, - ); - - console.log(`training time: ${performance.now() - time}ms`); - + cost: Cost.MSE, +}); + +const time = performance.now(); + +/** + * Train the network on the given data. + */ +net.train( + [ + { + inputs: tensor2D([ + [0, 0], + [1, 0], + [0, 1], + [1, 1], + ]), + outputs: tensor2D([[0], [1], [1], [0]]), + }, + ], /** - * Predict the output of the XOR function for the given inputs. + * The number of iterations is set to 10000. */ - const out1 = (await net.predict(tensor2D([[0, 0]]))).data; - console.log(`0 xor 0 = ${out1[0]} (should be close to 0)`); - - const out2 = (await net.predict(tensor2D([[1, 0]]))).data; - console.log(`1 xor 0 = ${out2[0]} (should be close to 1)`); - - const out3 = (await net.predict(tensor2D([[0, 1]]))).data; - console.log(`0 xor 1 = ${out3[0]} (should be close to 1)`); - - const out4 = (await net.predict(tensor2D([[1, 1]]))).data; - console.log(`1 xor 1 = ${out4[0]} (should be close to 0)`); \ No newline at end of file + 10000, +); + +console.log(`training time: ${performance.now() - time}ms`); + +/** + * Predict the output of the XOR function for the given inputs. + */ +const out1 = (await net.predict(tensor2D([[0, 0]]))).data; +console.log(`0 xor 0 = ${out1[0]} (should be close to 0)`); + +const out2 = (await net.predict(tensor2D([[1, 0]]))).data; +console.log(`1 xor 0 = ${out2[0]} (should be close to 1)`); + +const out3 = (await net.predict(tensor2D([[0, 1]]))).data; +console.log(`0 xor 1 = ${out3[0]} (should be close to 1)`); + +const out4 = (await net.predict(tensor2D([[1, 1]]))).data; +console.log(`1 xor 1 = ${out4[0]} (should be close to 0)`); diff --git a/mod.ts b/mod.ts index a30dc2a..368e4f1 100644 --- a/mod.ts +++ b/mod.ts @@ -9,19 +9,21 @@ export * from "./src/core/api/optimizer.ts"; export * from "./src/core/api/scheduler.ts"; export { GPU } from "./src/backends/gpu/mod.ts"; -import { CPU } from "./src/backends/cpu/mod.ts"; -import { WASM } from "./src/backends/wasm/mod.ts"; +import { CPU, CPUBackendLoader } from "./src/backends/cpu/mod.ts"; +import { WASM, WASMBackendLoader } from "./src/backends/wasm/mod.ts"; import { BackendLoader } from "./src/core/engine.ts"; /** * The AUTO backend is chosen automatically based on the environment. */ -const AUTO = Deno.dlopen === undefined ? WASM : CPU; +const AUTO: WASMBackendLoader | CPUBackendLoader = Deno.dlopen === undefined + ? WASM + : CPU; /** * The OPTION function is used to choose a backend from a list of options. */ -export function OPTION(...backends: BackendLoader[]) { +export function OPTION(...backends: BackendLoader[]): BackendLoader { for (const backend of backends) { if (backend.isSupported()) { return backend; diff --git a/src/backends/cpu/backend.ts b/src/backends/cpu/backend.ts index 54c0243..06c61ba 100644 --- a/src/backends/cpu/backend.ts +++ b/src/backends/cpu/backend.ts @@ -29,7 +29,7 @@ export class CPUBackend implements Backend { this.#id = id; } - static create(config: NetworkConfig, library: Library) { + static create(config: NetworkConfig, library: Library): CPUBackend { const buffer = encodeJSON(config); const shape = new Buffer(); const id = library.symbols.ffi_backend_create( @@ -37,11 +37,18 @@ export class CPUBackend implements Backend { buffer.length, shape.allocBuffer, ) as bigint; - const outputShape = Array.from(new Uint32Array(shape.buffer.slice(4).buffer)) as Shape[Rank]; + const outputShape = Array.from( + new Uint32Array(shape.buffer.slice(4).buffer), + ) as Shape[Rank]; return new CPUBackend(library, outputShape, id); } - train(datasets: DataSet[], epochs: number, batches: number, rate: number) { + train( + datasets: DataSet[], + epochs: number, + batches: number, + rate: number, + ): void { const buffer = encodeDatasets(datasets); const options = encodeJSON({ datasets: datasets.length, @@ -62,15 +69,25 @@ export class CPUBackend implements Backend { } async predict(input: Tensor): Promise>; - async predict(input: Tensor, layers: number[], outputShape: Shape[keyof Shape]): Promise>; + async predict( + input: Tensor, + layers: number[], + outputShape: Shape[keyof Shape], + ): Promise>; //deno-lint-ignore require-await - async predict(input: Tensor, layers?: number[], outputShape?: Shape[keyof Shape]): Promise> { + async predict( + input: Tensor, + layers?: number[], + outputShape?: Shape[keyof Shape], + ): Promise> { const options = encodeJSON({ inputShape: input.shape, - outputShape: [input.shape[0], ...(outputShape ?? this.outputShape)] , + outputShape: [input.shape[0], ...(outputShape ?? this.outputShape)], layers, } as PredictOptions); - const output = new Float32Array(input.shape[0] * length(outputShape ?? this.outputShape)); + const output = new Float32Array( + input.shape[0] * length(outputShape ?? this.outputShape), + ); this.library.symbols.ffi_backend_predict( this.#id, input.data as Float32Array, @@ -78,7 +95,13 @@ export class CPUBackend implements Backend { options.length, output, ); - return new Tensor(output, [input.shape[0], ...(outputShape ?? this.outputShape)] as Shape[keyof Shape]); + return new Tensor( + output, + [ + input.shape[0], + ...(outputShape ?? this.outputShape), + ] as Shape[keyof Shape], + ); } save(): Uint8Array { diff --git a/src/backends/cpu/mod.ts b/src/backends/cpu/mod.ts index 9391918..7ccf1bd 100644 --- a/src/backends/cpu/mod.ts +++ b/src/backends/cpu/mod.ts @@ -15,7 +15,7 @@ const options: FetchOptions = { name: "netsaur", url: new URL(import.meta.url).protocol !== "file:" ? new URL( - "https://github.com/denosaurs/netsaur/releases/download/0.3.0/", + "https://github.com/denosaurs/netsaur/releases/download/0.3.1/", import.meta.url, ) : "./target/release/", @@ -68,7 +68,7 @@ export class CPUBackendLoader implements BackendLoader { return Deno.dlopen !== undefined; } - async setup(silent = false) { + async setup(silent = false): Promise { Engine.type = BackendType.CPU; return await CPUInstance.init(silent); } @@ -114,4 +114,4 @@ export class CPUBackendLoader implements BackendLoader { /** * CPU Backend written in Rust. */ -export const CPU = new CPUBackendLoader(); +export const CPU: CPUBackendLoader = new CPUBackendLoader(); diff --git a/src/backends/cpu/util.ts b/src/backends/cpu/util.ts index 5d35da5..5ae80c4 100644 --- a/src/backends/cpu/util.ts +++ b/src/backends/cpu/util.ts @@ -2,8 +2,11 @@ import { Rank, Shape } from "../../core/api/shape.ts"; import { DataSet } from "../../core/types.ts"; export class Buffer { - buffer = new Uint8Array(); - allocBuffer = new Deno.UnsafeCallback({ + buffer: Uint8Array = new Uint8Array(); + allocBuffer: Deno.PointerObject<{ + parameters: ["usize"]; + result: "buffer"; + }> = new Deno.UnsafeCallback({ parameters: ["usize"], result: "buffer", }, (length) => { @@ -35,21 +38,21 @@ export type PredictOptions = { /** * Encode JSON data. */ -export function encodeJSON(json: unknown) { +export function encodeJSON(json: unknown): Uint8Array { return new TextEncoder().encode(JSON.stringify(json)); } /** * Returns the BigInt value of a pointer. */ -export function pointer(arr: BufferSource) { +export function pointer(arr: BufferSource): bigint { return BigInt(Deno.UnsafePointer.value(Deno.UnsafePointer.of(arr))); } /** * Encode datasets. */ -export function encodeDatasets(datasets: DataSet[]) { +export function encodeDatasets(datasets: DataSet[]): BigUint64Array { const pointers: bigint[] = []; for (const dataset of datasets) { pointers.push(pointer(dataset.inputs.data as Float32Array)); diff --git a/src/backends/gpu/backend.ts b/src/backends/gpu/backend.ts index 491b769..e76bacf 100644 --- a/src/backends/gpu/backend.ts +++ b/src/backends/gpu/backend.ts @@ -25,20 +25,25 @@ export class GPUBackend implements Backend { this.#id = id; } - static create(config: NetworkConfig, library: Library) { + static create(config: NetworkConfig, library: Library): GPUBackend { const buffer = encodeJSON(config); const shape = new Buffer(); const id = library.symbols.ffi_backend_create( buffer, buffer.length, - shape.allocBuffer + shape.allocBuffer, ) as bigint; const outputShape = Array.from(shape.buffer.slice(1)) as Shape[Rank]; return new GPUBackend(library, outputShape, id); } - train(datasets: DataSet[], epochs: number, batches: number, rate: number) { + train( + datasets: DataSet[], + epochs: number, + batches: number, + rate: number, + ): void { const buffer = encodeDatasets(datasets); const options = encodeJSON({ datasets: datasets.length, @@ -54,7 +59,7 @@ export class GPUBackend implements Backend { buffer, buffer.byteLength, options, - options.byteLength + options.byteLength, ); } @@ -62,13 +67,13 @@ export class GPUBackend implements Backend { async predict( input: Tensor, layers: number[], - outputShape: Shape[keyof Shape] + outputShape: Shape[keyof Shape], ): Promise>; //deno-lint-ignore require-await async predict( input: Tensor, layers?: number[], - outputShape?: Shape[keyof Shape] + outputShape?: Shape[keyof Shape], ): Promise> { const options = encodeJSON({ inputShape: input.shape, @@ -76,21 +81,24 @@ export class GPUBackend implements Backend { layers, } as PredictOptions); const output = new Float32Array( - input.shape[0] * length(outputShape ?? this.outputShape) + input.shape[0] * length(outputShape ?? this.outputShape), ); this.library.symbols.ffi_backend_predict( this.#id, input.data as Float32Array, options, options.length, - output + output, + ); + return new Tensor( + output, + [ + input.shape[0], + ...(outputShape ?? this.outputShape), + ] as Shape[keyof Shape], ); - return new Tensor(output, [ - input.shape[0], - ...(outputShape ?? this.outputShape), - ] as Shape[keyof Shape]); } - + save(): Uint8Array { const shape = new Buffer(); this.library.symbols.ffi_backend_save(this.#id, shape.allocBuffer); @@ -106,7 +114,7 @@ export class GPUBackend implements Backend { const id = library.symbols.ffi_backend_load( buffer, buffer.length, - shape.allocBuffer + shape.allocBuffer, ) as bigint; const outputShape = Array.from(shape.buffer.slice(1)) as Shape[Rank]; diff --git a/src/backends/gpu/mod.ts b/src/backends/gpu/mod.ts index 491efbf..a4e5280 100644 --- a/src/backends/gpu/mod.ts +++ b/src/backends/gpu/mod.ts @@ -15,7 +15,7 @@ const options: FetchOptions = { name: "netsaur_gpu", url: new URL(import.meta.url).protocol !== "file:" ? new URL( - "https://github.com/denosaurs/netsaur/releases/download/0.3.0/", + "https://github.com/denosaurs/netsaur/releases/download/0.3.1/", import.meta.url, ) : "./target/release/", @@ -68,7 +68,7 @@ export class GPUBackendLoader implements BackendLoader { return Deno.dlopen !== undefined; } - async setup(silent = false) { + async setup(silent = false): Promise { Engine.type = BackendType.GPU; return await GPUInstance.init(silent); } @@ -114,4 +114,4 @@ export class GPUBackendLoader implements BackendLoader { /** * GPU Backend written in Rust. */ -export const GPU = new GPUBackendLoader(); +export const GPU: GPUBackendLoader = new GPUBackendLoader(); diff --git a/src/backends/gpu/util.ts b/src/backends/gpu/util.ts index 5d35da5..ad1dbbe 100644 --- a/src/backends/gpu/util.ts +++ b/src/backends/gpu/util.ts @@ -35,21 +35,21 @@ export type PredictOptions = { /** * Encode JSON data. */ -export function encodeJSON(json: unknown) { +export function encodeJSON(json: unknown): Uint8Array { return new TextEncoder().encode(JSON.stringify(json)); } /** * Returns the BigInt value of a pointer. */ -export function pointer(arr: BufferSource) { +export function pointer(arr: BufferSource): bigint { return BigInt(Deno.UnsafePointer.value(Deno.UnsafePointer.of(arr))); } /** * Encode datasets. */ -export function encodeDatasets(datasets: DataSet[]) { +export function encodeDatasets(datasets: DataSet[]): BigUint64Array { const pointers: bigint[] = []; for (const dataset of datasets) { pointers.push(pointer(dataset.inputs.data as Float32Array)); diff --git a/src/backends/wasm/backend.ts b/src/backends/wasm/backend.ts index 72886bf..52e0cae 100644 --- a/src/backends/wasm/backend.ts +++ b/src/backends/wasm/backend.ts @@ -22,13 +22,13 @@ export class WASMBackend implements Backend { this.#id = id; } - static create(config: NetworkConfig) { + static create(config: NetworkConfig): WASMBackend { const shape = Array(0); const id = wasm_backend_create(JSON.stringify(config), shape); return new WASMBackend(shape as Shape[Rank], id); } - train(datasets: DataSet[], epochs: number, batches: number, rate: number) { + train(datasets: DataSet[], epochs: number, batches: number, rate: number): void { this.outputShape = datasets[0].outputs.shape.slice(1) as Shape[Rank]; const buffer = []; for (const dataset of datasets) { diff --git a/src/backends/wasm/lib/netsaur.generated.js b/src/backends/wasm/lib/netsaur.generated.js index 22eea86..00aab13 100644 --- a/src/backends/wasm/lib/netsaur.generated.js +++ b/src/backends/wasm/lib/netsaur.generated.js @@ -1,7 +1,7 @@ // @generated file from wasmbuild -- do not edit // deno-lint-ignore-file // deno-fmt-ignore-file -// source-hash: c9542d0a368cde5bdc27d321129d74bf6d2c53ee +// source-hash: 7d282fb4729698c1a22d34d29e8b257e3d0f9fa9 let wasm; let cachedInt32Memory0; @@ -203,7 +203,7 @@ const imports = { __wbindgen_object_drop_ref: function (arg0) { takeObject(arg0); }, - __wbg_log_05fb09f7b2225305: function (arg0, arg1) { + __wbg_log_3703f669bffcfc1a: function (arg0, arg1) { console.log(getStringFromWasm0(arg0, arg1)); }, __wbindgen_number_new: function (arg0) { diff --git a/src/backends/wasm/lib/netsaur_bg.wasm b/src/backends/wasm/lib/netsaur_bg.wasm index a9b19e9..4bf261d 100644 Binary files a/src/backends/wasm/lib/netsaur_bg.wasm and b/src/backends/wasm/lib/netsaur_bg.wasm differ diff --git a/src/backends/wasm/mod.ts b/src/backends/wasm/mod.ts index 3317387..ca4198b 100644 --- a/src/backends/wasm/mod.ts +++ b/src/backends/wasm/mod.ts @@ -17,12 +17,12 @@ import { Sequential } from "../../core/mod.ts"; export class WASMInstance { static initialized = false; - static async init(silent = false) { + static async init(silent = false): Promise { if (WASMInstance.initialized) return true; await instantiate({ url: new URL(import.meta.url).protocol !== "file:" ? new URL( - "https://github.com/denosaurs/netsaur/releases/download/0.3.0/netsaur_bg.wasm", + "https://github.com/denosaurs/netsaur/releases/download/0.3.1/netsaur_bg.wasm", import.meta.url, ) : undefined, @@ -43,7 +43,7 @@ export class WASMBackendLoader implements BackendLoader { return true; } - async setup(silent = false) { + async setup(silent = false): Promise { Engine.type = BackendType.WASM; return await WASMInstance.init(silent); } @@ -87,4 +87,4 @@ export class WASMBackendLoader implements BackendLoader { /** * Web Assembly Backend written in Rust & compiled to Web Assembly. */ -export const WASM = new WASMBackendLoader(); +export const WASM: WASMBackendLoader = new WASMBackendLoader(); diff --git a/src/core/api/layers.ts b/src/core/api/layers.ts index e7ed1ea..9b74ce7 100644 --- a/src/core/api/layers.ts +++ b/src/core/api/layers.ts @@ -171,7 +171,7 @@ export function FlattenLayer(config: FlattenLayerConfig): Layer { */ export function BatchNorm1DLayer(config: BatchNormLayerConfig = {}): Layer { config.epsilon = config.epsilon || 0.001; - config.momentum = config.momentum || 0.99; + config.momentum = config.momentum || 0.99; return { type: LayerType.BatchNorm1D, config }; } @@ -183,6 +183,6 @@ export function BatchNorm1DLayer(config: BatchNormLayerConfig = {}): Layer { */ export function BatchNorm2DLayer(config: BatchNormLayerConfig = {}): Layer { config.epsilon = config.epsilon || 0.001; - config.momentum = config.momentum || 0.99; + config.momentum = config.momentum || 0.99; return { type: LayerType.BatchNorm2D, config }; } diff --git a/src/core/api/optimizer.ts b/src/core/api/optimizer.ts index 4e357f0..dd6efd0 100644 --- a/src/core/api/optimizer.ts +++ b/src/core/api/optimizer.ts @@ -5,18 +5,18 @@ export type Optimizer = | { type: OptimizerType.Adam; config: AdamOptimizerConfig }; export type AdamOptimizerConfig = { - beta1?: number; - beta2?: number; - epsilon?: number; + beta1?: number; + beta2?: number; + epsilon?: number; }; export function SGDOptimizer(): Optimizer { - return { type: OptimizerType.SGD }; + return { type: OptimizerType.SGD }; } export function AdamOptimizer(config: AdamOptimizerConfig = {}): Optimizer { - config.beta1 = config.beta1 || 0.9; - config.beta2 = config.beta2 || 0.999; - config.epsilon = config.epsilon || 1e-8; - return { type: OptimizerType.Adam, config }; + config.beta1 = config.beta1 || 0.9; + config.beta2 = config.beta2 || 0.999; + config.epsilon = config.epsilon || 1e-8; + return { type: OptimizerType.Adam, config }; } diff --git a/src/core/api/scheduler.ts b/src/core/api/scheduler.ts index 225f91b..cfedb81 100644 --- a/src/core/api/scheduler.ts +++ b/src/core/api/scheduler.ts @@ -35,7 +35,7 @@ export function ExponentialDecay(config: DecaySchedulerConfig = {}): Scheduler { } export function OneCycle(config: OneCycleSchedulerConfig = {}): Scheduler { - config.max_rate = config.max_rate || 0.01; - config.step_size = config.step_size || 100; - return { type: SchedulerType.OneCycle, config }; - } + config.max_rate = config.max_rate || 0.01; + config.step_size = config.step_size || 100; + return { type: SchedulerType.OneCycle, config }; +} diff --git a/src/core/engine.ts b/src/core/engine.ts index c7a9947..91dd7b0 100644 --- a/src/core/engine.ts +++ b/src/core/engine.ts @@ -25,7 +25,7 @@ export interface BackendLoader { * Whether the backend is supported. */ isSupported(): boolean; - + /** * Setup the backend. Returns true if the backend was successfully setup. */ @@ -55,7 +55,10 @@ export interface BackendLoader { * await setupBackend(CPU); * ``` */ -export async function setupBackend(loader: BackendLoader, silent = false) { +export async function setupBackend( + loader: BackendLoader, + silent = false, +): Promise { const success = await loader.setup(silent); if (!success) { if (!silent) console.log("Defaulting to CPU Backend"); diff --git a/src/core/mod.ts b/src/core/mod.ts index 4ec9c10..3b382ec 100644 --- a/src/core/mod.ts +++ b/src/core/mod.ts @@ -30,23 +30,24 @@ export class Sequential implements NeuralNetwork { this.backend = Engine.backendLoader.loadBackend(this.config); } - train(datasets: DataSet[], epochs = 1000, batches = 1, rate = 0.1) { + train(datasets: DataSet[], epochs = 1000, batches = 1, rate = 0.1): void { this.backend.train(datasets, epochs, batches, rate); } /** - * - * @param data + * @param data * @param layers Range of layers [a, b) (inclusive of a, exclusive of b) to execute. - * @returns + * @returns */ - async predict(data: Tensor, layers?: [number, number]) { + async predict(data: Tensor, layers?: [number, number]): Promise> { if (layers) { - if (layers[0] < 0 || layers[1] > this.config.layers.length) + if (layers[0] < 0 || layers[1] > this.config.layers.length) { throw new RangeError( - `Execution range should be within (0, ${ - this.config.layers.length - }). Received (${(layers[0], layers[1])})` + `Execution range should be within (0, ${this.config.layers.length}). Received (${(layers[ + 0 + ], + layers[1])})`, ); + } const lastLayer = this.config.layers[layers[1] - 1]; const layerList = new Array(layers[1] - layers[0]); for (let i = 0; i < layerList.length; i += 1) { @@ -56,7 +57,11 @@ export class Sequential implements NeuralNetwork { lastLayer.type === LayerType.Dense || lastLayer.type === LayerType.Flatten ) { - return await this.backend.predict(data, layerList, lastLayer.config.size); + return await this.backend.predict( + data, + layerList, + lastLayer.config.size, + ); } else if (lastLayer.type === LayerType.Activation) { const penultimate = this.config.layers[layers[1] - 2]; if ( @@ -66,16 +71,16 @@ export class Sequential implements NeuralNetwork { return await this.backend.predict( data, layerList, - penultimate.config.size + penultimate.config.size, ); } else { throw new Error( - `The penultimate layer must be a dense layer, or a flatten layer if the last layer is an activation layer. Received ${penultimate.type}.` + `The penultimate layer must be a dense layer, or a flatten layer if the last layer is an activation layer. Received ${penultimate.type}.`, ); } } else { throw new Error( - `The output layer must be a dense layer, activation layer, or a flatten layer. Received ${lastLayer.type}.` + `The output layer must be a dense layer, activation layer, or a flatten layer. Received ${lastLayer.type}.`, ); } } @@ -85,14 +90,14 @@ export class Sequential implements NeuralNetwork { /** * Load model from buffer */ - static load(data: Uint8Array) { + static load(data: Uint8Array): Sequential { return Engine.backendLoader.load(data); } /** * Load model from binary file */ - static loadFile(data: string) { + static loadFile(data: string): Sequential { return Engine.backendLoader.loadFile(data); } @@ -100,7 +105,7 @@ export class Sequential implements NeuralNetwork { return this.backend.save(); } - saveFile(path: string) { + saveFile(path: string): void { this.backend.saveFile(path); } } diff --git a/src/core/tensor/tensor.ts b/src/core/tensor/tensor.ts index c1d9f27..1f98bdd 100644 --- a/src/core/tensor/tensor.ts +++ b/src/core/tensor/tensor.ts @@ -38,7 +38,7 @@ export class Tensor { /** * Serialise a tensor into JSON. */ - toJSON() { + toJSON(): { data: number[]; shape: Shape[R] } { const data = new Array(this.data.length).fill(1); this.data.forEach((value, i) => data[i] = value); return { data, shape: this.shape }; @@ -51,7 +51,10 @@ export class Tensor { * tensor([1, 2, 3, 4], [2, 2]); * ``` */ -export function tensor(values: Float32Array, shape: Shape[R]) { +export function tensor( + values: Float32Array, + shape: Shape[R], +): Tensor { return new Tensor(values, shape); } @@ -62,7 +65,7 @@ export function tensor(values: Float32Array, shape: Shape[R]) { * tensor1D([1, 2, 3, 4]); * ``` */ -export function tensor1D(values: Array1D) { +export function tensor1D(values: Array1D): Tensor<1> { const shape = inferShape(values) as Shape1D; return new Tensor(new Float32Array(values), shape); } @@ -77,7 +80,7 @@ export function tensor1D(values: Array1D) { * ]); * ``` */ -export function tensor2D(values: Array2D) { +export function tensor2D(values: Array2D): Tensor<2> { const shape = inferShape(values) as Shape2D; return new Tensor(new Float32Array(values.flat(1)), shape); } @@ -98,7 +101,7 @@ export function tensor2D(values: Array2D) { * ]); * ``` */ -export function tensor3D(values: Array3D) { +export function tensor3D(values: Array3D): Tensor<3> { const shape = inferShape(values) as Shape3D; return new Tensor(new Float32Array(values.flat(2)), shape); } @@ -131,7 +134,7 @@ export function tensor3D(values: Array3D) { * ]); * ``` */ -export function tensor4D(values: Array4D) { +export function tensor4D(values: Array4D): Tensor<4> { const shape = inferShape(values) as Shape4D; return new Tensor(new Float32Array(values.flat(3)), shape); } @@ -166,7 +169,7 @@ export function tensor4D(values: Array4D) { * ]); * ``` */ -export function tensor5D(values: Array5D) { +export function tensor5D(values: Array5D): Tensor<5> { const shape = inferShape(values) as Shape5D; return new Tensor(new Float32Array(values.flat(4)), shape); } @@ -202,7 +205,7 @@ export function tensor5D(values: Array5D) { * ]); * ``` */ -export function tensor6D(values: Array6D) { +export function tensor6D(values: Array6D): Tensor<6> { const shape = inferShape(values) as Shape6D; return new Tensor(new Float32Array(values.flat(5)), shape); } diff --git a/src/core/tensor/util.ts b/src/core/tensor/util.ts index 8c89d46..fcfd3d2 100644 --- a/src/core/tensor/util.ts +++ b/src/core/tensor/util.ts @@ -24,7 +24,7 @@ export function inferShape(arr: ArrayMap): number[] { /** * return the length of a shape. */ -export function length(shape: Shape[Rank]) { +export function length(shape: Shape[Rank]): number { let length = 1; shape.forEach((i) => length *= i); return length; @@ -58,29 +58,29 @@ export function toShape(shape: Shape[Rank], rank: R): Shape[R] { /** * convert a shape to a 1D shape. */ -export function to1D(shape: Shape[Rank]) { +export function to1D(shape: Shape[Rank]): Shape[1] { return toShape(shape, Rank.R1); } /** * convert a shape to a 2D shape. */ -export function to2D(shape: Shape[Rank]) { +export function to2D(shape: Shape[Rank]): Shape[2] { return toShape(shape, Rank.R2); } /** * convert a shape to a 3D shape. */ -export function to3D(shape: Shape[Rank]) { +export function to3D(shape: Shape[Rank]): Shape[3] { return toShape(shape, Rank.R3); } /** * convert a shape to a 4D shape. */ -export function to4D(shape: Shape[Rank]) { - return toShape(shape, Rank.R3); +export function to4D(shape: Shape[Rank]): Shape[4] { + return toShape(shape, Rank.R4); } /** diff --git a/src/core/types.ts b/src/core/types.ts index 3d601fd..408a4c3 100644 --- a/src/core/types.ts +++ b/src/core/types.ts @@ -25,7 +25,11 @@ export interface Backend { * representing the input to the neural network and returns a Promise that resolves to a Tensor object representing the output of the network. * This method is used to make predictions on new data after the network has been trained. */ - predict(input: Tensor, layers?: number[], outputShape?: Shape[keyof Shape]): Promise>; + predict( + input: Tensor, + layers?: number[], + outputShape?: Shape[keyof Shape], + ): Promise>; /** * The save method is a function that saves the network to a Uint8Array. diff --git a/tokenizers/lib/netsaur_tokenizers.generated.js b/tokenizers/lib/netsaur_tokenizers.generated.js index c9ee2ee..5d22148 100644 --- a/tokenizers/lib/netsaur_tokenizers.generated.js +++ b/tokenizers/lib/netsaur_tokenizers.generated.js @@ -1,7 +1,7 @@ // @generated file from wasmbuild -- do not edit // deno-lint-ignore-file // deno-fmt-ignore-file -// source-hash: 3d08e026eef12c6bc0c88735975ec03dac196e29 +// source-hash: 08acf45a3c5a9b9313c0fcc84fb6f1921fa4e2bf let wasm; const heap = new Array(128).fill(undefined); @@ -12,6 +12,20 @@ function getObject(idx) { return heap[idx]; } +let heap_next = heap.length; + +function dropObject(idx) { + if (idx < 132) return; + heap[idx] = heap_next; + heap_next = idx; +} + +function takeObject(idx) { + const ret = getObject(idx); + dropObject(idx); + return ret; +} + const cachedTextDecoder = new TextDecoder("utf-8", { ignoreBOM: true, fatal: true, @@ -32,8 +46,6 @@ function getStringFromWasm0(ptr, len) { return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len)); } -let heap_next = heap.length; - function addHeapObject(obj) { if (heap_next === heap.length) heap.push(heap.length + 1); const idx = heap_next; @@ -43,18 +55,6 @@ function addHeapObject(obj) { return idx; } -function dropObject(idx) { - if (idx < 132) return; - heap[idx] = heap_next; - heap_next = idx; -} - -function takeObject(idx) { - const ret = getObject(idx); - dropObject(idx); - return ret; -} - function debugString(val) { // primitive types const type = typeof val; @@ -342,6 +342,9 @@ function handleError(f, args) { const imports = { __wbindgen_placeholder__: { + __wbindgen_object_drop_ref: function (arg0) { + takeObject(arg0); + }, __wbindgen_is_string: function (arg0) { const ret = typeof (getObject(arg0)) === "string"; return ret; @@ -350,9 +353,6 @@ const imports = { const ret = new Error(getStringFromWasm0(arg0, arg1)); return addHeapObject(ret); }, - __wbindgen_object_drop_ref: function (arg0) { - takeObject(arg0); - }, __wbindgen_is_object: function (arg0) { const val = getObject(arg0); const ret = typeof val === "object" && val !== null; diff --git a/tokenizers/lib/netsaur_tokenizers_bg.wasm b/tokenizers/lib/netsaur_tokenizers_bg.wasm index 1cf15cd..f39c38a 100644 Binary files a/tokenizers/lib/netsaur_tokenizers_bg.wasm and b/tokenizers/lib/netsaur_tokenizers_bg.wasm differ diff --git a/tokenizers/mod.ts b/tokenizers/mod.ts index 6c70b65..814d29d 100644 --- a/tokenizers/mod.ts +++ b/tokenizers/mod.ts @@ -5,18 +5,18 @@ import { wasm_tokenizer_from_json, wasm_tokenizer_get_vocab, wasm_tokenizer_get_vocab_size, - wasm_tokenizer_save, wasm_tokenizer_id_to_token, + wasm_tokenizer_save, wasm_tokenizer_token_to_id, } from "./lib/netsaur_tokenizers.generated.js"; let initialized = false; -export async function init() { +export async function init(): Promise { if (initialized) return; await instantiate({ url: new URL(import.meta.url).protocol !== "file:" ? new URL( - "https://github.com/denosaurs/netsaur/releases/download/0.3.0/netsaur_tokenizers_bg.wasm", + "https://github.com/denosaurs/netsaur/releases/download/0.3.1/netsaur_tokenizers_bg.wasm", import.meta.url, ) : undefined, @@ -28,7 +28,7 @@ export async function init() { * Tokenizer class */ export class Tokenizer { - #id; + #id: number; constructor(id: number) { this.#id = id; } @@ -36,46 +36,47 @@ export class Tokenizer { /** * Get the vocab size */ - getVocabSize(withAddedTokens = true) { + getVocabSize(withAddedTokens = true): number { return wasm_tokenizer_get_vocab_size(this.#id, withAddedTokens); } /** * Get the vocab */ - getVocab(withAddedTokens = true) { + // deno-lint-ignore no-explicit-any + getVocab(withAddedTokens = true): any { return wasm_tokenizer_get_vocab(this.#id, withAddedTokens); } /** * Get the token from an id */ - idToToken(id: number) { + idToToken(id: number): string { return wasm_tokenizer_id_to_token(this.#id, id); } /** * Get the id from a token */ - tokenToId(token: string) { + tokenToId(token: string): number { return wasm_tokenizer_token_to_id(this.#id, token); } - + /** - * Encode a sentence + * Encode a sentence to tokens * @param sentence sentence to tokenize * @returns */ - encode(sentence: string) { + encode(sentence: string): Uint32Array { return wasm_tokenizer_encode(this.#id, sentence); } /** - * Decode a sentence + * Decode a sentence from its encoded tokens to a string * @param tokens tokens to decode * @returns */ - decode(ids: Uint32Array, skipSpecialTokens = false) { + decode(ids: Uint32Array, skipSpecialTokens = false): string { return wasm_tokenizer_decode(this.#id, ids, skipSpecialTokens); } @@ -88,7 +89,7 @@ export class Tokenizer { * @param pretty pretty print the json */ save(pretty: boolean): string; - save(...args: [boolean?]) { + save(...args: [boolean?]): string { return wasm_tokenizer_save(this.#id, args[0] ?? false); } /** @@ -96,7 +97,7 @@ export class Tokenizer { * @param json string * @returns */ - static fromJSON(json: string) { + static fromJSON(json: string): Tokenizer { return new Tokenizer(wasm_tokenizer_from_json(json)); } }