UNPKG

nk-vector

Version:
202 lines (201 loc) 6.35 kB
module.exports = function (epoch, x, y, debug) { function rotating_array(W) { let result_W = [] for (let j = 0; j < W[0].length; j++) { let x_W = [] for (let i in W) { x_W.push(W[i][j]) } if (x_W.length > 0) { result_W.push(x_W) } } if (result_W.length > 0) { return result_W } } function mashup(matrix) { let result = matrix[0] for (let i = 1; i < matrix.length; i++) { for (let j in matrix[i]) { if (result[j] >= 230) { result[j] = 0 result[j] += matrix[i][j] } else { result[j] += matrix[i][j] } } } return result } function dot(matrix1, matrix2, type) { if (type == 'MxM') { let result = [] for (let item in matrix1) { let contain_matrix = [] for (let i in matrix1[item]) { let line = [] for (let j in matrix2[i]) { line.push(matrix1[item][i] * matrix2[i][j]) } if (line.length > 0) { contain_matrix.push(line) } } if (contain_matrix.length > 0) { result.push(mashup(contain_matrix)) } } if (result.length > 0) { return result } } if (type == 'MxA') { let result = [] for (let word in matrix1) { for (let item in matrix1[word]) { let line = [] for (let i in matrix2) { line.push(matrix1[word][item] * matrix2[i]) } if (line.length > 0 && line.length == matrix2.length) { result.push(line) } } } if (result.length > 0) { return result[0] } } if (type == 'NxM') { let result = [] for (let i in matrix2) { let line = [] for (let item in matrix2[i]) { line.push(matrix2[i][item] * matrix1) } if (line.length > 0 && line.length == matrix2[i].length) { result.push(line) } } if (result.length > 0) { return result } } if (type == 'AxA') { let result = 0 for (let i in matrix1[0]) { result += matrix1[0][i] * matrix2[0][i] } return result } } function subtract(N, S) { let result = [] for (let i in S) { if(S[i] - N[i]){ if(N[i] == 0.5){ result.push(S[i]) }else{ result.push(S[i] - N[i]) } } else { result.push(N[i]) } } if (result.length > 0) { return result } } function add(N, S) { let result = [] for (let i in S) { result.push(S[i] + N[i] - 0.1) } if (result.length > 0) { return result } } function L2_norm(a) { let value = 0 for (let i in a) { value += a[i] * a[i] } let sqrt_value = Math.sqrt(value) return sqrt_value } function cosine_similarity(a, b) { let value_dot = 0 for (let i in a) { value_dot += a[i] * b[i] } return value_dot / (L2_norm(a) * L2_norm(b)) } function sigmoid(A) { A = A[0] let result = [] for (let i in A) { result.push(1 / (1 + Math.exp(-A[i]))) } return [result] } function clear(vector) { let result = [] for (let i in vector) { if (vector[i] == 0.5) { result.push(0) } else { result.push(vector[i]) } } return result } function train(epoch, x, y) { let loss_rec = {} let W = [...Array(x[0].length)].map(e => Math.random()*1) let u = dot([W], rotating_array(x), 'MxM') u = sigmoid(u) let loss = 1 - cosine_similarity(u[0], y) let error = subtract(clear(u[0]), y) let error_x = dot([error], x, 'MxM') W = add(W, error_x[0]) loss_rec['Epoch:0'] = loss let history = {} history[0] = u[0] let check_stopsoon = {} for (let i = 1; i < epoch; i++) { u = dot([W], rotating_array(x), 'MxM') u = sigmoid(u) loss = 1 - cosine_similarity(u[0], y) error = subtract(clear(u[0]), y) error_x = dot([error], x, 'MxM') W = add(W, error_x[0]) if (loss_rec['Epoch:' + (i - 1).toString()] >= loss) { loss_rec['Epoch:' + i.toString()] = loss history[i] = u[0] if(isNaN(check_stopsoon[loss]) || check_stopsoon[loss] == undefined){ check_stopsoon[loss] = 0 }else{ check_stopsoon[loss] += 1 } } if (check_stopsoon[loss] == 10) { console.log('stop soon') break } if(loss_rec['Epoch:' + (i - 1).toString()] < loss) { console.log('over') break } } if (Object.keys(loss_rec).length > 0) { if (debug) { // console.log(loss_rec) console.log('Last loss: ', loss_rec['Epoch:' + (Object.keys(loss_rec).length - 1).toString()]) } return history[Object.keys(history).length - 1] } } return train(epoch, x, y) }