@mineproness/tensorloop 2.1.55 → 2.1.57
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +14 -20
- package/package.json +5 -2
- package/readme.md +907 -72
- package/src/Embedding/index.d.ts +5 -5
- package/src/Embedding/index.js +118 -33
- package/src/FFN/index.d.ts +5 -5
- package/src/FFN/index.js +34 -39
- package/src/Linear/index.d.ts +7 -8
- package/src/Linear/index.js +173 -49
- package/src/OperationManager.js +100 -0
- package/src/Relu/index.d.ts +5 -0
- package/src/Relu/index.js +103 -0
- package/src/SelfAttention/index.d.ts +7 -13
- package/src/SelfAttention/index.js +108 -55
- package/src/Softmax/index.d.ts +4 -3
- package/src/Softmax/index.js +192 -12
- package/src/Tokenizer/index.d.ts +1 -0
- package/src/Tokenizer/index.js +92 -7
- package/src/TransformerBlock/index.d.ts +6 -7
- package/src/TransformerBlock/index.js +24 -23
- package/src/getVec.js +28 -0
- package/src/shaders/CalculateAcc.wgsl +50 -0
- package/src/shaders/CalculateLoss.wgsl +35 -0
- package/src/shaders/ComputeDInput.wgsl +32 -0
- package/src/shaders/EB.wgsl +31 -0
- package/src/shaders/EF.wgsl +25 -0
- package/src/shaders/LB.wgsl +57 -0
- package/src/shaders/LF.wgsl +44 -0
- package/src/shaders/RB.wgsl +37 -0
- package/src/shaders/RF.wgsl +33 -0
- package/src/shaders/ReductionFunction.wgsl +28 -0
- package/src/shaders/SB.wgsl +36 -0
- package/src/shaders/SF.wgsl +65 -0
- package/src/shaders/SoftmaxBackward.wgsl +31 -0
- package/src/shaders/attentionShader/CompueFinalForwardOutput.wgsl +29 -0
- package/src/shaders/attentionShader/ComputeDA.wgsl +30 -0
- package/src/shaders/attentionShader/ComputeDV.wgsl +37 -0
- package/src/shaders/attentionShader/ComputeK.wgsl +30 -0
- package/src/shaders/attentionShader/ComputedQ.wgsl +31 -0
- package/src/shaders/attentionShader/attentionSocres.wgsl +40 -0
- package/src/shaders/attentionShader/sumGradient.wgsl +24 -0
- package/src/GELU/index.d.ts +0 -6
- package/src/GELU/index.js +0 -33
- package/src/GetConfigs.js +0 -35
- package/src/Model/index.d.ts +0 -10
- package/src/Model/index.js +0 -88
- package/src/PositionEmbedding/index.d.ts +0 -11
- package/src/PositionEmbedding/index.js +0 -49
- package/src/ReLU/index.d.ts +0 -5
- package/src/ReLU/index.js +0 -17
- package/src/gpiInit.js +0 -764
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
struct Params {
|
|
2
|
+
contextSize: u32,
|
|
3
|
+
embeddingSize: u32,
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
@group(0) @binding(0)
|
|
7
|
+
var<storage, read> A: array<f32>;
|
|
8
|
+
|
|
9
|
+
@group(0) @binding(1)
|
|
10
|
+
var<storage, read> dOutput: array<f32>;
|
|
11
|
+
|
|
12
|
+
@group(0) @binding(2)
|
|
13
|
+
var<storage, read_write> dV: array<f32>;
|
|
14
|
+
|
|
15
|
+
@group(0) @binding(3)
|
|
16
|
+
var<uniform> params: Params;
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@compute @workgroup_size(16, 16)
|
|
20
|
+
fn main(@builtin(global_invocation_id) id: vec3<u32>)
|
|
21
|
+
{
|
|
22
|
+
let row = id.x;
|
|
23
|
+
let col = id.y;
|
|
24
|
+
let T = params.contextSize;
|
|
25
|
+
let D = params.embeddingSize;
|
|
26
|
+
if (row >= T || col >= D) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
var sum = 0.0;
|
|
30
|
+
for (var i = 0u; i < T; i++) {
|
|
31
|
+
let aIndex = i * T + row;
|
|
32
|
+
let gradIndex = i * D + col;
|
|
33
|
+
sum += A[aIndex] * dOutput[gradIndex];
|
|
34
|
+
}
|
|
35
|
+
let outputIndex = row * D + col;
|
|
36
|
+
dV[outputIndex] = sum;
|
|
37
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
struct Params {
|
|
2
|
+
contextSize: u32,
|
|
3
|
+
embeddingSize: u32,
|
|
4
|
+
}
|
|
5
|
+
@group(0) @binding(0)
|
|
6
|
+
var<storage, read> dS: array<f32>;
|
|
7
|
+
@group(0) @binding(1)
|
|
8
|
+
var<storage, read> Q: array<f32>;
|
|
9
|
+
@group(0) @binding(2)
|
|
10
|
+
var<storage, read_write> dK: array<f32>;
|
|
11
|
+
@group(0) @binding(3)
|
|
12
|
+
var<uniform> params: Params;
|
|
13
|
+
@compute @workgroup_size(16, 16)
|
|
14
|
+
fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
15
|
+
let row = id.x;
|
|
16
|
+
let col = id.y;
|
|
17
|
+
let T = params.contextSize;
|
|
18
|
+
let D = params.embeddingSize;
|
|
19
|
+
if (row >= T || col >= D) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
var sum = 0.0;
|
|
23
|
+
for (var i = 0u; i < T; i++) {
|
|
24
|
+
let dsIndex = i * T + row;
|
|
25
|
+
let qIndex = i * D + col;
|
|
26
|
+
sum += dS[dsIndex] * Q[qIndex];
|
|
27
|
+
}
|
|
28
|
+
let scale = sqrt(f32(D));
|
|
29
|
+
dK[row * D + col] = sum / scale;
|
|
30
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
struct Params {
|
|
2
|
+
contextSize: u32,
|
|
3
|
+
embeddingSize: u32,
|
|
4
|
+
}
|
|
5
|
+
@group(0) @binding(0)
|
|
6
|
+
var<storage, read> dS: array<f32>;
|
|
7
|
+
@group(0) @binding(1)
|
|
8
|
+
var<storage, read> K: array<f32>;
|
|
9
|
+
@group(0) @binding(2)
|
|
10
|
+
var<storage, read_write> dQ: array<f32>;
|
|
11
|
+
@group(0) @binding(3)
|
|
12
|
+
var<uniform> params: Params;
|
|
13
|
+
@compute @workgroup_size(16, 16)
|
|
14
|
+
fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
15
|
+
let row = id.x;
|
|
16
|
+
let col = id.y;
|
|
17
|
+
let T = params.contextSize;
|
|
18
|
+
let D = params.embeddingSize;
|
|
19
|
+
if (row >= T || col >= D) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
var sum = 0.0;
|
|
23
|
+
for (var i = 0u; i < T; i++) {
|
|
24
|
+
let dsIndex = row * T + i;
|
|
25
|
+
let kIndex = i * D + col;
|
|
26
|
+
|
|
27
|
+
sum += dS[dsIndex] * K[kIndex];
|
|
28
|
+
}
|
|
29
|
+
let scale = sqrt(f32(D));
|
|
30
|
+
dQ[row * D + col] = sum / scale;
|
|
31
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
struct Params {
|
|
2
|
+
contextSize: u32,
|
|
3
|
+
embeddingSize: u32,
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
@group(0) @binding(0)
|
|
7
|
+
var<storage, read> Q: array<f32>;
|
|
8
|
+
|
|
9
|
+
@group(0) @binding(1)
|
|
10
|
+
var<storage, read> K: array<f32>;
|
|
11
|
+
|
|
12
|
+
@group(0) @binding(2)
|
|
13
|
+
var<storage, read_write> scores: array<f32>;
|
|
14
|
+
|
|
15
|
+
@group(0) @binding(3)
|
|
16
|
+
var<uniform> params: Params;
|
|
17
|
+
|
|
18
|
+
@compute @workgroup_size(16, 16)
|
|
19
|
+
fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
20
|
+
let row = id.x;
|
|
21
|
+
let col = id.y;
|
|
22
|
+
|
|
23
|
+
if (row >= params.contextSize || col >= params.contextSize) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
var sum = 0.0;
|
|
27
|
+
for (var k = 0u; k < params.embeddingSize; k++) {
|
|
28
|
+
let qIndex = row * params.embeddingSize + k;
|
|
29
|
+
let kIndex = col * params.embeddingSize + k;
|
|
30
|
+
sum += Q[qIndex] * K[kIndex];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
let outIndex = row * params.contextSize + col;
|
|
34
|
+
if (col > row) {
|
|
35
|
+
scores[outIndex] = - 1e9;
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
let scale = sqrt(f32(params.embeddingSize));
|
|
39
|
+
scores[outIndex] = sum / scale;
|
|
40
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
struct Params {
|
|
2
|
+
contextSize: u32,
|
|
3
|
+
embeddingSize: u32,
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
@group(0) @binding(0)
|
|
7
|
+
var<storage, read> dXq: array<f32>;
|
|
8
|
+
@group(0) @binding(1)
|
|
9
|
+
var<storage, read> dXk: array<f32>;
|
|
10
|
+
@group(0) @binding(2)
|
|
11
|
+
var<storage, read> dXv: array<f32>;
|
|
12
|
+
@group(0) @binding(3)
|
|
13
|
+
var<storage, read_write> dX: array<f32>;
|
|
14
|
+
@group(0) @binding(4)
|
|
15
|
+
var<uniform> params: Params;
|
|
16
|
+
@compute @workgroup_size(256)
|
|
17
|
+
fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
18
|
+
let index = id.x;
|
|
19
|
+
let total = params.contextSize * params.embeddingSize;
|
|
20
|
+
if (index >= total) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
dX[index] =dXq[index] +dXk[index] +dXv[index];
|
|
24
|
+
}
|
package/src/GELU/index.d.ts
DELETED
package/src/GELU/index.js
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { GELUGPU } from "../gpiInit.js";
|
|
2
|
-
|
|
3
|
-
export class GELU {
|
|
4
|
-
gpu;
|
|
5
|
-
inputs = [];
|
|
6
|
-
constructor() {
|
|
7
|
-
this.inputs = []
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
forward(input) {
|
|
12
|
-
this.inputs = input
|
|
13
|
-
if(!this.gpu){
|
|
14
|
-
this.gpu = new GELUGPU(input[0].length, input.length)
|
|
15
|
-
}
|
|
16
|
-
// const output = new Float32Array(input.length)
|
|
17
|
-
// const k = Math.sqrt(2 / Math.PI)
|
|
18
|
-
// for (let i = 0; i < input.length; i++) {
|
|
19
|
-
// const x = input[i]
|
|
20
|
-
// const u = k * (x + 0.044715 * x * x * x)
|
|
21
|
-
// output[i] = 0.5 * x * (1 + Math.tanh(u))
|
|
22
|
-
// }
|
|
23
|
-
return this.gpu.forward(input)
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
backward(dOutput) {
|
|
27
|
-
return this.gpu.backward(dOutput, this.inputs)
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
ClearInputCache() {
|
|
31
|
-
this.inputs = []
|
|
32
|
-
}
|
|
33
|
-
}
|
package/src/GetConfigs.js
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import fs from 'fs'
|
|
2
|
-
import { join } from 'path'
|
|
3
|
-
|
|
4
|
-
export function SaveVectors(vectors, path){
|
|
5
|
-
const rows = vectors.length;
|
|
6
|
-
const cols = vectors[0].length;
|
|
7
|
-
const flatArray = new Float32Array(rows * cols)
|
|
8
|
-
vectors.forEach((e,i)=>{
|
|
9
|
-
flatArray.set(e, i * cols)
|
|
10
|
-
})
|
|
11
|
-
const bufferArray = Buffer.from(flatArray.buffer, flatArray.byteOffset, flatArray.byteLength)
|
|
12
|
-
fs.writeFileSync(path, bufferArray)
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export function LoadVectors(path, cols){
|
|
16
|
-
const buffer = fs.readFileSync(path)
|
|
17
|
-
const flatArray = new Float32Array(buffer.buffer, buffer.byteOffset, buffer.byteLength / 4 )
|
|
18
|
-
const vectors = []
|
|
19
|
-
const rows = flatArray.length / cols;
|
|
20
|
-
for(let a = 0; a < rows; a++){
|
|
21
|
-
vectors.push(flatArray.slice(a * cols, (a+1) * cols))
|
|
22
|
-
}
|
|
23
|
-
return vectors
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export function SaveBias(vectors, path){
|
|
27
|
-
const bufferArray = Buffer.from(vectors.buffer, vectors.byteOffset, vectors.byteLength)
|
|
28
|
-
fs.writeFileSync(path, bufferArray)
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export function LoadBias(path){
|
|
32
|
-
const buffer = fs.readFileSync(path)
|
|
33
|
-
const flatArray = new Float32Array(buffer.buffer, buffer.byteOffset, buffer.byteLength / 4 )
|
|
34
|
-
return flatArray
|
|
35
|
-
}
|
package/src/Model/index.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export default class Model {
|
|
2
|
-
constructor(embeddingSize: number, contextSize: number, configs: {
|
|
3
|
-
dirname: string,
|
|
4
|
-
activation: "gelu" | "relu",
|
|
5
|
-
})
|
|
6
|
-
train(pair: {
|
|
7
|
-
inputIDX: number[],
|
|
8
|
-
targetIDX: number[]
|
|
9
|
-
}[], batchSize: number, batchExecution: number, epochs: number, learningRate: number): void
|
|
10
|
-
}
|
package/src/Model/index.js
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import { Embedding, PositionEmbedding, Linear, Tokenizer, TransformerBlock, Softmax } from '../../index.js'
|
|
2
|
-
import path, { join } from 'path'
|
|
3
|
-
|
|
4
|
-
export default class Model {
|
|
5
|
-
embedding;
|
|
6
|
-
linear;
|
|
7
|
-
posEmbedding;
|
|
8
|
-
softmax;
|
|
9
|
-
tokenizer;
|
|
10
|
-
block1;
|
|
11
|
-
block2;
|
|
12
|
-
contextSize;
|
|
13
|
-
constructor(embeddingSize, contextSize, configs) {
|
|
14
|
-
this.tokenizer = new Tokenizer()
|
|
15
|
-
this.contextSize = contextSize
|
|
16
|
-
this.embedding = new Embedding(embeddingSize, this.tokenizer.vocabSize, contextSize, {
|
|
17
|
-
save: {
|
|
18
|
-
filename: path.join(configs.dirname, "vectors.bin")
|
|
19
|
-
}
|
|
20
|
-
})
|
|
21
|
-
this.posEmbedding = new PositionEmbedding(embeddingSize, contextSize, {
|
|
22
|
-
save: {
|
|
23
|
-
filename: join(configs.dirname, 'posVec.bin')
|
|
24
|
-
}
|
|
25
|
-
})
|
|
26
|
-
this.linear = new Linear(embeddingSize, this.tokenizer.vocabSize, {
|
|
27
|
-
save: {
|
|
28
|
-
filename: [join(configs.dirname, 'weights.bin'), join(configs.dirname, 'bias.bin')]
|
|
29
|
-
}
|
|
30
|
-
})
|
|
31
|
-
this.softmax = new Softmax()
|
|
32
|
-
this.block1 = new TransformerBlock(embeddingSize, {
|
|
33
|
-
dirname: join(configs.dirname, "block1"),
|
|
34
|
-
activation: configs.activation
|
|
35
|
-
})
|
|
36
|
-
this.block2 = new TransformerBlock(embeddingSize, {
|
|
37
|
-
dirname: join(configs.dirname, "block2"),
|
|
38
|
-
activation: configs.activation
|
|
39
|
-
})
|
|
40
|
-
}
|
|
41
|
-
train(pair = {
|
|
42
|
-
inputIDX: [],
|
|
43
|
-
targetIDX: []
|
|
44
|
-
}, epochs = 500, learningRate = 0.01) {
|
|
45
|
-
process.stdout.write("\x1Bc")
|
|
46
|
-
console.log("Preparing Training Pairs....")
|
|
47
|
-
const trainingPair = pair
|
|
48
|
-
let firstRun = true;
|
|
49
|
-
console.log(`TotalPairs: ${trainingPair.length}`)
|
|
50
|
-
if (trainingPair.length == 0 || !trainingPair) throw new Error(`The Batch Execution ${batchExecution} is doesn't exist.`);
|
|
51
|
-
for (let i = 0; i < epochs; i++) {
|
|
52
|
-
let totalLoss = 0;
|
|
53
|
-
for (let a = 0; a < trainingPair.length; a++) {
|
|
54
|
-
const input = trainingPair[a].inputIDX
|
|
55
|
-
const target = trainingPair[a].targetIDX
|
|
56
|
-
let vector = this.embedding.forward(input)
|
|
57
|
-
vector = this.posEmbedding.forward(vector)
|
|
58
|
-
vector = this.block1.forward(vector)
|
|
59
|
-
vector = this.block2.forward(vector)
|
|
60
|
-
const logits = this.linear.forward(vector)
|
|
61
|
-
const probs = this.softmax.forward(logits)
|
|
62
|
-
const loss = this.softmax.crossEntropy(probs, target)[0]
|
|
63
|
-
const dLogits = this.softmax.backward(probs, target)
|
|
64
|
-
totalLoss += loss;
|
|
65
|
-
let dOutput = this.linear.backward(dLogits, learningRate);
|
|
66
|
-
dOutput = this.block2.backward(dOutput, learningRate)
|
|
67
|
-
dOutput = this.block1.backward(dOutput, learningRate)
|
|
68
|
-
this.posEmbedding.backward(dOutput, learningRate)
|
|
69
|
-
this.embedding.backward(dOutput, learningRate)
|
|
70
|
-
if (firstRun) {
|
|
71
|
-
firstRun = null;
|
|
72
|
-
console.log("")
|
|
73
|
-
console.log("")
|
|
74
|
-
}
|
|
75
|
-
const percentense = (((a + 1) / trainingPair.length) * 100).toFixed(2)
|
|
76
|
-
const filted = Math.round((percentense / 100) * 20);
|
|
77
|
-
const empty = 20 - filted
|
|
78
|
-
|
|
79
|
-
process.stdout.write(`\rEPOCHS: ${i} [${"=".repeat(filted)}${" ".repeat(empty)}] ${percentense}% (${a + 1}/${trainingPair.length}) | loss ${(totalLoss / (a + 1)).toFixed(2)}`)
|
|
80
|
-
}
|
|
81
|
-
console.log("")
|
|
82
|
-
this.embedding.Save()
|
|
83
|
-
this.linear.Save()
|
|
84
|
-
this.block1.Save()
|
|
85
|
-
this.block2.Save()
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export class PositionEmbedding{
|
|
2
|
-
vectors: Float32Array[]
|
|
3
|
-
constructor(embeddingSize: number, contextSize: number, configs: {
|
|
4
|
-
save: {
|
|
5
|
-
filename: string
|
|
6
|
-
}
|
|
7
|
-
})
|
|
8
|
-
forward(vectors: Float32Array[]) :Float32Array[]
|
|
9
|
-
backward(inputGradient: Float32Array[], learingRate: number) : void
|
|
10
|
-
Save() : void;
|
|
11
|
-
}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import fs, { existsSync } from 'fs'
|
|
2
|
-
import { LoadVectors, SaveVectors } from '../GetConfigs.js'
|
|
3
|
-
// import { config } from 'process'
|
|
4
|
-
import { GPUEmbedding, GPUPosition } from '../gpiInit.js'
|
|
5
|
-
|
|
6
|
-
function GenerateVectors(embeddingSize, vocabSize) {
|
|
7
|
-
const vector = []
|
|
8
|
-
for (let token = 0; token < vocabSize; token++) {
|
|
9
|
-
vector[token] = new Float32Array(embeddingSize)
|
|
10
|
-
for (let a = 0; a < embeddingSize; a++) {
|
|
11
|
-
vector[token][a] = (Math.random() * 2 - 1) * 0.2
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
return vector
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export class PositionEmbedding {
|
|
18
|
-
vectors = []
|
|
19
|
-
configs;
|
|
20
|
-
embeddingSize = 0;
|
|
21
|
-
gpu;
|
|
22
|
-
constructor(embeddingSize, vocabSize, configs) {
|
|
23
|
-
this.configs = configs
|
|
24
|
-
this.embeddingSize = embeddingSize
|
|
25
|
-
if (configs && configs.save) {
|
|
26
|
-
if (existsSync(configs.save.filename)) {
|
|
27
|
-
this.vectors = LoadVectors(configs.save.filename, embeddingSize)
|
|
28
|
-
} else {
|
|
29
|
-
this.vectors = GenerateVectors(embeddingSize, vocabSize)
|
|
30
|
-
SaveVectors(this.vectors, this.configs.save.filename)
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
} else {
|
|
34
|
-
this.vectors = GenerateVectors(embeddingSize, vocabSize)
|
|
35
|
-
}
|
|
36
|
-
this.gpu = new GPUPosition(this.vectors, embeddingSize, vocabSize)
|
|
37
|
-
}
|
|
38
|
-
forward(vec) {
|
|
39
|
-
return this.gpu.forward(vec)
|
|
40
|
-
}
|
|
41
|
-
backward(inputGradient, learingRate) {
|
|
42
|
-
this.gpu.backward(inputGradient, learingRate)
|
|
43
|
-
}
|
|
44
|
-
Save() {
|
|
45
|
-
const save = this.gpu.Save()
|
|
46
|
-
SaveVectors(save, this.configs.save.filename)
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
}
|
package/src/ReLU/index.d.ts
DELETED
package/src/ReLU/index.js
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { GPUHiddenLayer } from "../gpiInit.js";
|
|
2
|
-
|
|
3
|
-
export class ReLU{
|
|
4
|
-
input;
|
|
5
|
-
gpu;
|
|
6
|
-
constructor(){
|
|
7
|
-
this.gpu = new GPUHiddenLayer()
|
|
8
|
-
}
|
|
9
|
-
forward(logits){
|
|
10
|
-
return this.gpu.forward(logits)
|
|
11
|
-
}
|
|
12
|
-
backward(outGradient){
|
|
13
|
-
return this.gpu.backward(outGradient)
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
ClearInputCache(){}
|
|
17
|
-
}
|