Commit 7ba3c887 authored by Petr Kubeš's avatar Petr Kubeš

Initial commit of network working for one training example

parents
[Dolphin]
Timestamp=2018,7,5,23,50,32
Version=4
[Settings]
HiddenFilesShown=true
node_modules/*
This source diff could not be displayed because it is too large. You can view the blob instead.
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
crossorigin="anonymous">
<script src="./dist/main.js"></script>
<title>Neural network visualized</title>
</head>
<body>
<div class="container mt-3">
<h1>Neural network visualized</h1>
<p class="lead">Visualization of the simplest possible neural network. :)</p>
<div id="content"></div>
</div>
</body>
</html>
This diff is collapsed.
{
"name": "vanilla",
"main": "index.js",
"version": "1.0.0",
"scripts": {
"build": "webpack --mode production",
"watch": "webpack --mode development --watch"
},
"devDependencies": {
"ts-loader": "^4.0.0",
"typescript": "^2.6.2",
"webpack": "^4.0.0",
"webpack-cli": "^2.0.4"
},
"dependencies": {
"@types/lodash": "^4.14.110",
"linear-algebra": "^3.1.4",
"lodash": "^4.17.10"
}
}
interface Constructable<T> {
new(input) : T;
}
declare interface LinearAlgebra {
Matrix: Constructable<la.Matrix>;
}
declare function la(): LinearAlgebra;
declare module la {
interface Matrix {
rows: number;
cols: number;
data: number[][];
constructor(input: number[][]);
mul(m: Matrix): Matrix;
div(m: Matrix): Matrix;
plus(m: Matrix): Matrix;
minus(m: Matrix): Matrix;
dot(m: Matrix): Matrix;
log(): Matrix;
sigmoid(): Matrix;
mul_(m: Matrix): Matrix;
div_(m: Matrix): Matrix;
plus_(m: Matrix): Matrix;
minus_(m: Matrix): Matrix;
dot_(m: Matrix): Matrix;
log_(): Matrix;
sigmoid_(): Matrix;
trans(): Matrix;
trans_(): Matrix;
mulEach(num: number);
plusEach(num: number);
identity(size: number): Matrix;
scalar(size: number, num: number): Matrix;
zero(rows: number, columns: number): Matrix;
reshapeFrom(data: number[][], rows: number, columns: number): Matrix;
map(funct: (v:number) => number);
eleMap(funct: (v:number, row: number, column: number) => number);
getSum(): number;
clone(): Matrix;
toArray(): number[][];
}
}
declare module 'linear-algebra' {
export = la;
}
\ No newline at end of file
import * as linearAlgebra from 'linear-algebra';
const la = linearAlgebra();
export class NeuralCore {
private inputSize: number;
private hiddenLayerSizes: number[];
private outputSize: number;
private weights: la.Matrix[];
private trainTarget: la.Matrix;
private trainInput: la.Matrix;
private rate = 1;
public initNetwork(
inputSize: number, hiddenLayerSizes: number[], outputSize: number,
randomInit: boolean) {
this.inputSize = inputSize;
this.hiddenLayerSizes = hiddenLayerSizes;
this.outputSize = outputSize;
if (randomInit) {
this.weights = [];
if (hiddenLayerSizes.length > 0) {
for (let i = 0; i < hiddenLayerSizes.length + 1; i++) {
switch (i) {
case 0:
this.weights.push(this.randMatrix(hiddenLayerSizes[0], inputSize));
break;
case hiddenLayerSizes.length:
this.weights.push(this.randMatrix(outputSize, hiddenLayerSizes[i-1]));
break;
default:
this.weights.push(this.randMatrix(hiddenLayerSizes[i], hiddenLayerSizes[i-1]));
break;
}
}
} else {
this.weights.push(this.randMatrix(outputSize, inputSize));
}
}
}
// TODO for each example
public setTrainingSet(input: number[], output: number[]) {
this.trainTarget = new la.Matrix(output);
this.trainInput = new la.Matrix(input);
}
public evaluate(input: number[]): la.Matrix[] {
if (input.length != this.inputSize) {
throw Error(`Invalid input size, should be ${this.inputSize}.`);
}
const neurons = [];
// Forward propagation
let currLayer = new la.Matrix(input).trans();
for (let i = 0; i < this.hiddenLayerSizes.length + 1; i++) {
neurons.push(currLayer);
currLayer = this.weights[i].dot(currLayer).sigmoid();
}
neurons.push(currLayer);
return neurons;
}
public getCost(): number {
const outputLayer = this.evaluate(this.trainInput.data[0])[this.weights.length];
return (1/2) * outputLayer.minus(this.trainTarget.trans()).map((x) => {return x**2;}).getSum();
}
public train() {
const L = this.weights.length;
// Compute each layer
let x = this.evaluate(this.trainInput.data[0]);
// Last layer
const sigmas = [];
sigmas[L] = x[L].mul(x[L].plusEach(-1)).mul(x[L].minus(this.trainTarget.trans()));
// All hidden layers
for (let i=L-1; i>=1;i--) {
sigmas[i] = x[i].mul(x[i].plusEach(-1)).mulEach(-1).mul((x[i+1].trans().dot(this.weights[i])).trans());
}
sigmas.shift();
//console.log('sigmas: ', sigmas);
//console.log('weights: ', this.weights.map((m) => m.data));
//console.log('x: ', x.map((m) => m.data));
// Update all weights
for (let j=0;j<L;j++) {
this.weights[j] = this.weights[j].plus((sigmas[j].dot(x[j].trans())));
}
x = this.evaluate(this.trainInput.data[0]);
console.log('x: ', x[L].data);
}
private randMatrix(height: number, width: number): la.Matrix {
const res = [];
for (let j = 0; j < height; j++) {
let row = [];
for (let i = 0; i < width; i++) {
row.push(Math.random());
}
res.push(row);
}
const m = new la.Matrix(res);
return m;
}
}
export class Visualizer {
private content: HTMLElement;
constructor(content: HTMLElement) {
this.content = content;
}
public printNumber = (num: number) => {
this.content.innerText = `${num}`;
}
}
import {Visualizer} from './Visualize';
import {NeuralCore} from './NeuralCore';
window.onload = () => {
main();
};
let neuralCore: NeuralCore;
let visualizer: Visualizer;
const main = () => {
const content: HTMLElement = document.getElementById('content');
visualizer = new Visualizer(content);
neuralCore = new NeuralCore();
neuralCore.initNetwork(2, [2], 2, true);
neuralCore.setTrainingSet([1,1], [0,1]);
for (let i = 0; i<1000; i++) {
neuralCore.train();
}
}
{
"compilerOptions": {
"target": "es6",
"sourceMap": true,
"moduleResolution": "node"
}
}
'use strict';
module.exports = {
devtool: 'inline-source-map',
entry: './src/index.ts',
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'ts-loader'
}
]
},
resolve: {
extensions: [ '.ts', '.tsx', '.js' ]
}
};
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment