├── babel.config.js ├── vue.config.js ├── screenshot.png ├── src ├── shims-vue.d.ts ├── assets │ └── logo.png ├── main.ts ├── shims-tsx.d.ts ├── utils.ts ├── interfaces.ts ├── neurons.ts ├── geometry.ts ├── App.vue ├── examples │ ├── example1.ts │ └── example2.ts ├── translations.ts └── components │ └── VueBackpropagationExercise.vue ├── public ├── favicon.ico └── index.html ├── .gitignore ├── tests └── unit │ └── example.spec.ts ├── tsconfig.json ├── .travis.yml ├── README.md └── package.json /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ["@vue/cli-plugin-babel/preset"] 3 | }; 4 | -------------------------------------------------------------------------------- /vue.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | lintOnSave: false, 3 | publicPath: "./" 4 | }; 5 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/into-ai/vue-backpropagation-exercise/master/screenshot.png -------------------------------------------------------------------------------- /src/shims-vue.d.ts: -------------------------------------------------------------------------------- 1 | declare module "*.vue" { 2 | import Vue from "vue"; 3 | export default Vue; 4 | } 5 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/into-ai/vue-backpropagation-exercise/master/public/favicon.ico -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/into-ai/vue-backpropagation-exercise/master/src/assets/logo.png -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import App from "./App.vue"; 3 | 4 | Vue.config.productionTip = false; 5 | 6 | new Vue({ 7 | render: h => h(App) 8 | }).$mount("#app"); 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | package-lock.json 5 | 6 | # local env files 7 | .env.local 8 | .env.*.local 9 | 10 | # Log files 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | 15 | # Editor directories and files 16 | .idea 17 | .vscode 18 | *.suo 19 | *.ntvs* 20 | *.njsproj 21 | *.sln 22 | *.sw? 23 | -------------------------------------------------------------------------------- /src/shims-tsx.d.ts: -------------------------------------------------------------------------------- 1 | import Vue, { VNode } from "vue"; 2 | 3 | declare global { 4 | namespace JSX { 5 | // tslint:disable no-empty-interface 6 | interface Element extends VNode {} 7 | // tslint:disable no-empty-interface 8 | interface ElementClass extends Vue {} 9 | interface IntrinsicElements { 10 | [elem: string]: any; 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/example.spec.ts: -------------------------------------------------------------------------------- 1 | import { expect } from "chai"; 2 | import { shallowMount } from "@vue/test-utils"; 3 | import HelloWorld from "@/components/HelloWorld.vue"; 4 | 5 | describe("HelloWorld.vue", () => { 6 | it("renders props.msg when passed", () => { 7 | const msg = "new message"; 8 | const wrapper = shallowMount(HelloWorld, { 9 | propsData: { msg } 10 | }); 11 | expect(wrapper.text()).to.include(msg); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <%= htmlWebpackPlugin.options.title %> 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/utils.ts: -------------------------------------------------------------------------------- 1 | export function formatString(s: string, ...insertions: string[]): string { 2 | return s.replace(/{(\d+)}/g, function(match, number) { 3 | return typeof insertions[number] != "undefined" 4 | ? insertions[number] 5 | : match; 6 | }); 7 | } 8 | 9 | export function roundNd(n: number, d: number): number { 10 | return Math.round(n * Math.pow(10, d)) / Math.pow(10, d); 11 | } 12 | 13 | export function round2d(n: number): number { 14 | return roundNd(n, 2); 15 | } 16 | 17 | export function fixedNd(n: number, before: number, after: number): string { 18 | return ("0".repeat(before) + roundNd(n, after).toFixed(after)).slice( 19 | -before - after 20 | ); 21 | } 22 | 23 | export function parseFloatStrict(value: string) { 24 | if (/^(-|\+)?([0-9]+(\.[0-9]+)?)$/.test(value)) return Number(value); 25 | return NaN; 26 | } 27 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "module": "esnext", 5 | "strict": true, 6 | "jsx": "preserve", 7 | "importHelpers": true, 8 | "moduleResolution": "node", 9 | "experimentalDecorators": true, 10 | "esModuleInterop": true, 11 | "allowSyntheticDefaultImports": true, 12 | "sourceMap": true, 13 | "baseUrl": ".", 14 | "types": [ 15 | "webpack-env", 16 | "mocha", 17 | "chai" 18 | ], 19 | "paths": { 20 | "@/*": [ 21 | "src/*" 22 | ] 23 | }, 24 | "lib": [ 25 | "esnext", 26 | "dom", 27 | "dom.iterable", 28 | "scripthost", 29 | "es2019" 30 | ] 31 | }, 32 | "include": [ 33 | "src/**/*.ts", 34 | "src/**/*.tsx", 35 | "src/**/*.vue", 36 | "tests/**/*.ts", 37 | "tests/**/*.tsx" 38 | ], 39 | "exclude": [ 40 | "node_modules" 41 | ] 42 | } 43 | -------------------------------------------------------------------------------- /src/interfaces.ts: -------------------------------------------------------------------------------- 1 | export interface Point { 2 | x: number; 3 | y: number; 4 | } 5 | 6 | export interface Example { 7 | errorHandler: (observed: number, expected: number) => number; 8 | netFuncTex: string; 9 | errFuncTex: string; 10 | netTree: BackpropGraph; 11 | } 12 | 13 | export interface Graph { 14 | func: string; 15 | nodeId: number; 16 | ffValue?: number; 17 | currentFFValue?: number; 18 | bpValue?: number; 19 | children?: Graph[]; 20 | accumulate: (c: number[]) => number; 21 | derivative?: (c: Record) => number; 22 | } 23 | 24 | export class BackpropGraph implements Graph { 25 | func = ""; 26 | nodeId = 0; 27 | ffValue?: number; 28 | currentFFValue?: number; 29 | bpValue?: number; 30 | children?: Graph[]; 31 | accumulate: (c: number[]) => number = (): number => NaN; 32 | derivative?: (c: Record) => number; 33 | } 34 | 35 | export enum Step { 36 | FF = "FF", 37 | BP = "BP", 38 | WOW = "WOW" 39 | } 40 | 41 | export enum Language { 42 | DE = "de", 43 | EN = "en" 44 | } 45 | -------------------------------------------------------------------------------- /src/neurons.ts: -------------------------------------------------------------------------------- 1 | export const powFunc = (c: number[]): number => { 2 | if (c.length != 1) { 3 | throw new TypeError( 4 | `Pow can only handle exactle one input (not ${c.length})` 5 | ); 6 | } 7 | return Math.pow(c[0], 2); 8 | }; 9 | 10 | export const errorFunction = (observed: number, expected: number): number => { 11 | // observed and expected have been rounded to errorPrecisionDigits digits 12 | // the return value will also be rounded to errorPrecisionDigits digits 13 | return Math.pow(observed - expected, 2); 14 | }; 15 | 16 | export const addFunc = (c: number[]): number => { 17 | return c.reduce((acc, elem) => acc + elem, 0); 18 | }; 19 | 20 | export const multFunc = (c: number[]): number => { 21 | return c.reduce((acc, elem) => acc * elem, 1); 22 | }; 23 | 24 | export const leafFunc = (): number => { 25 | return NaN; 26 | }; 27 | 28 | export const addFuncDerivative = ( 29 | inputValues: Record 30 | ): number => { 31 | return inputValues.parentBp; 32 | }; 33 | 34 | export const multFuncDerivative = ( 35 | inputValues: Record 36 | ): number => { 37 | const result: number = inputValues.siblingFf * inputValues.parentBp; 38 | 39 | return +result.toFixed(2); 40 | }; 41 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - stable 4 | before_script: 5 | - npm install 6 | jobs: 7 | include: 8 | - stage: deploy 9 | name: Deploy to GitHub Pages 10 | script: npm run build && touch dist/.nojekyll 11 | deploy: 12 | provider: pages 13 | local_dir: dist 14 | skip_cleanup: true 15 | token: "$GH_TOKEN" 16 | keep_history: true 17 | on: 18 | branch: master 19 | - stage: deploy 20 | name: Deploy to NPM 21 | script: 22 | - npm run build:npm 23 | deploy: 24 | provider: npm 25 | email: introintoai@gmail.com 26 | api_key: 27 | secure: RpZxkZC0f0hJGheDV/1wJMPGUWs7Ri7ydLKam4ePAqCYaZNGW4nuXQnhAjh9G39XnHXrCKLlmpWuW3LhzoukqzJBM0M9USHSIzt+QAkviLZoKFgBt6hlQbyihPzU4F3V9+mx43gE+7JolfbRQwSyUkGroLbQcfv0u66XkitOggksLXdbldelZSNFflE2qZk3zt16uSAM7zA6Qxhkg2NXYbREuxJqmrWwgjvry3YzD4aSKbdZqm3F3Ya5Dk8JdneDUcgBuIhxFAggL2V6WO8nqIgpzKuZ2ywmZnAP+SLR87q4jVHzHWTN/C+J7ZRA7N6itSVtgs3LgYHfE4GNZvPBL8QdVOZozIkuhzs0F806agZyWucMy4QNOZDvVTPEW4DvWJ9rnlnlV4qWrxceFvWVvedqEGTedZlKdaxyuJjP02Al/QBZ9cb6tgcBnyQQcYlloFBs4iNq7+qe96PaMMBVt8J+343Q7npRAa96DIyEpAjvPXdvxhqSCZjqBVRIxh1vKOpBLkcm7Z41t0Or8jPRntGVRK/86rkB4fRWvo+j5a+C3djq7656c6ncauQU8gNwIELZwzaySR2jkMTYQV4571CHKkr+4Ud6UtwvXlKfCWab+C0K/uiR58CGHHmoUZTv/rCj5ZmX7n0cnkH4YglRRHTh5EVW8iqB/4eaVw3RDhA= 28 | project: ./dist/ 29 | skip_cleanup: true 30 | tag: next 31 | on: 32 | branch: master 33 | tags: true 34 | -------------------------------------------------------------------------------- /src/geometry.ts: -------------------------------------------------------------------------------- 1 | import * as d3 from "d3"; 2 | 3 | import { Point, BackpropGraph } from "./interfaces"; 4 | 5 | export function bezierPoint( 6 | percent: number, 7 | p1: Point, 8 | cp1: Point, 9 | cp2: Point, 10 | p2: Point 11 | ): Point { 12 | function b1(t: number): number { 13 | return t * t * t; 14 | } 15 | function b2(t: number): number { 16 | return 3 * t * t * (1 - t); 17 | } 18 | function b3(t: number): number { 19 | return 3 * t * (1 - t) * (1 - t); 20 | } 21 | function b4(t: number): number { 22 | return (1 - t) * (1 - t) * (1 - t); 23 | } 24 | const pos: Point = { x: 0, y: 0 }; 25 | pos.x = 26 | p1.x * b1(percent) + 27 | cp1.x * b2(percent) + 28 | cp2.x * b3(percent) + 29 | p2.x * b4(percent); 30 | pos.y = 31 | p1.y * b1(percent) + 32 | cp1.y * b2(percent) + 33 | cp2.y * b3(percent) + 34 | p2.y * b4(percent); 35 | return pos; 36 | } 37 | 38 | export function linePointAt( 39 | s: d3.HierarchyPointNode, 40 | d: d3.HierarchyPointNode, 41 | percent: number 42 | ): Point { 43 | const center = (s.y + d.y) / 2; 44 | const source = { x: s.y, y: s.x }; 45 | const dest = { x: d.y, y: d.x }; 46 | return bezierPoint( 47 | percent, 48 | source, 49 | { x: center, y: s.x }, 50 | { x: center, y: d.x }, 51 | dest 52 | ); 53 | } 54 | 55 | export function diagonal(s: Point, d: Point): string { 56 | const path = `M ${s.y} ${s.x} 57 | C ${(s.y + d.y) / 2} ${s.x}, 58 | ${(s.y + d.y) / 2} ${d.x}, 59 | ${d.y} ${d.x}`; 60 | return path; 61 | } 62 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 53 | 54 | 67 | -------------------------------------------------------------------------------- /src/examples/example1.ts: -------------------------------------------------------------------------------- 1 | import { Example } from "../interfaces"; 2 | import { 3 | errorFunction, 4 | powFunc, 5 | addFunc, 6 | multFunc, 7 | leafFunc 8 | } from "../neurons"; 9 | 10 | const example: Example = { 11 | errorHandler: errorFunction, 12 | netFuncTex: ` 13 | \\begin{aligned} 14 | &n(w_0, x_0, w_1, x_1, b) \\\\ 15 | = &(w_0\\cdot x_0 + w_1\\cdot x_1 + b)^2 16 | \\end{aligned}`, 17 | 18 | errFuncTex: ` 19 | \\begin{aligned} 20 | &C(w_0, x_0, w_1, x_1, b, e) \\\\ 21 | = &(n(w_0, x_0, w_1, x_1, b) - e)^2 22 | \\end{aligned}`, 23 | netTree: { 24 | func: "x^2", 25 | nodeId: 0, 26 | bpValue: 1, 27 | accumulate: powFunc, 28 | children: [ 29 | { 30 | func: "+", 31 | nodeId: 1, 32 | accumulate: addFunc, 33 | children: [ 34 | { 35 | func: "+", 36 | nodeId: 2, 37 | accumulate: addFunc, 38 | children: [ 39 | { func: "b", nodeId: 3, ffValue: 2.4, accumulate: leafFunc }, 40 | { 41 | func: "\\cdot", 42 | nodeId: 4, 43 | accumulate: multFunc, 44 | children: [ 45 | { 46 | func: "w_1", 47 | nodeId: 5, 48 | ffValue: 3.4, 49 | accumulate: leafFunc 50 | }, 51 | { 52 | func: "x_1", 53 | nodeId: 6, 54 | ffValue: 1.2, 55 | accumulate: leafFunc 56 | } 57 | ] 58 | } 59 | ] 60 | }, 61 | { 62 | func: "\\cdot", 63 | nodeId: 7, 64 | accumulate: multFunc, 65 | children: [ 66 | { 67 | func: "w_0", 68 | nodeId: 8, 69 | ffValue: 1.4, 70 | accumulate: leafFunc 71 | }, 72 | { 73 | func: "x_0", 74 | nodeId: 9, 75 | ffValue: 2.4, 76 | accumulate: leafFunc 77 | } 78 | ] 79 | } 80 | ] 81 | } 82 | ] 83 | } 84 | }; 85 | 86 | export default example; 87 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Vue Backpropagation Exercise 2 | 3 | [![Build Status](https://travis-ci.com/into-ai/vue-backpropagation-exercise.svg?branch=master)](https://travis-ci.com/into-ai/vue-backpropagation-exercise) 4 | [![NPM License](https://img.shields.io/npm/l/vue-backpropagation-exercise)](https://www.npmjs.com/package/vue-backpropagation-exercise) 5 | [![NPM version](https://img.shields.io/npm/v/vue-backpropagation-exercise)](https://www.npmjs.com/package/vue-backpropagation-exercise) 6 | [![NPM Downloads](https://img.shields.io/npm/dy/vue-backpropagation-exercise)](https://www.npmjs.com/package/vue-backpropagation-exercise) 7 | 8 | This vue component packages an interactive web based exercise about visually retracing the backpropagation steps performed when training neural nets. See a [live demo](https://into-ai.github.io/vue-backpropagation-exercise). 9 | 10 | ```bash 11 | npm install --save vue-backpropagation-exercise 12 | ``` 13 | 14 | ![Screenshot](screenshot.png) 15 | 16 | #### Configuration 17 | 18 | Add the component to your Vue project (this assumes typescript is used): 19 | ```javascript 20 | import VueBackpropagationExercise, { 21 | BackpropGraph 22 | } from "vue-backpropagation-exercise"; 23 | 24 | @Component({ 25 | components: { 26 | VueBackpropagationExercise 27 | } 28 | }) 29 | export default class App extends Vue {} 30 | ``` 31 | 32 | Use props to configure the component 33 | ```html 34 | 42 | ``` 43 | 44 | For an example configuration, see `src/App.vue`. 45 | 46 | #### Development 47 | - To set up: 48 | ``` 49 | npm install 50 | ``` 51 | 52 | - Compiles and hot-reloads for development: 53 | ``` 54 | npm run serve 55 | ``` 56 | 57 | - Compiles and minifies for production: 58 | ``` 59 | npm run build 60 | ``` 61 | 62 | - Run your unit tests: 63 | ``` 64 | npm run test:unit 65 | ``` 66 | 67 | - Lints and fixes files 68 | ``` 69 | npm run lint 70 | ``` 71 | 72 | #### Publishing to NPM 73 | Tagged commits to the master branch are automatically published to NPM. You can tag a commit using the `npm` cli: 74 | ```bash 75 | npm version patch -m "Bump the version number" 76 | git push origin master --follow-tags 77 | ``` -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-backpropagation-exercise", 3 | "version": "0.1.6", 4 | "description": "Web based exercise about visually retracing the backpropagation steps performed when training neural nets.", 5 | "private": false, 6 | "author": { 7 | "name": "into-ai" 8 | }, 9 | "repository": "https://github.com/into-ai/vue-backpropagation-exercise", 10 | "bugs": "https://github.com/into-ai/vue-backpropagation-exercise/issues", 11 | "keywords": [ 12 | "backpropagation", 13 | "mooc", 14 | "exercise", 15 | "learning", 16 | "vuejs", 17 | "vue-component" 18 | ], 19 | "license": "MIT", 20 | "files": [ 21 | "dist" 22 | ], 23 | "main": "dist/VueBackpropagationExercise.umd.js", 24 | "unpkg": "dist/VueBackpropagationExercise.umd.min.js", 25 | "scripts": { 26 | "serve": "vue-cli-service serve", 27 | "build": "vue-cli-service build", 28 | "build:npm": "vue-cli-service build --target lib --name VueBackpropagationExercise src/components/VueBackpropagationExercise.vue", 29 | "test:unit": "vue-cli-service test:unit", 30 | "lint": "vue-cli-service lint" 31 | }, 32 | "dependencies": { 33 | "@types/d3": "^5.7.2", 34 | "@types/d3-hierarchy": "^1.1.6", 35 | "core-js": "^3.6.4", 36 | "d3": "^5.15.0", 37 | "detect-browser": "^5.0.0", 38 | "katex": "^0.11.1", 39 | "vue": "^2.6.11", 40 | "vue-class-component": "^7.2.2", 41 | "vue-property-decorator": "^8.3.0" 42 | }, 43 | "devDependencies": { 44 | "@types/chai": "^4.2.8", 45 | "@types/katex": "^0.11.0", 46 | "@types/mocha": "^5.2.4", 47 | "@typescript-eslint/eslint-plugin": "^2.18.0", 48 | "@typescript-eslint/parser": "^2.18.0", 49 | "@vue/cli-plugin-babel": "~4.2.0", 50 | "@vue/cli-plugin-eslint": "~4.2.0", 51 | "@vue/cli-plugin-typescript": "~4.2.0", 52 | "@vue/cli-plugin-unit-mocha": "~4.2.0", 53 | "@vue/cli-service": "~4.2.0", 54 | "@vue/eslint-config-prettier": "^6.0.0", 55 | "@vue/eslint-config-typescript": "^5.0.1", 56 | "@vue/test-utils": "1.0.0-beta.31", 57 | "chai": "^4.1.2", 58 | "eslint": "^6.7.2", 59 | "eslint-plugin-prettier": "^3.1.1", 60 | "eslint-plugin-vue": "^6.1.2", 61 | "husky": "^4.2.3", 62 | "node-sass": "^4.12.0", 63 | "prettier": "^1.19.1", 64 | "sass-loader": "^8.0.2", 65 | "typescript": "~3.7.5", 66 | "vue-template-compiler": "^2.6.11" 67 | }, 68 | "eslintConfig": { 69 | "root": true, 70 | "env": { 71 | "node": true 72 | }, 73 | "extends": [ 74 | "plugin:vue/essential", 75 | "eslint:recommended", 76 | "@vue/typescript/recommended", 77 | "@vue/prettier", 78 | "@vue/prettier/@typescript-eslint" 79 | ], 80 | "parserOptions": { 81 | "ecmaVersion": 2020 82 | }, 83 | "rules": { 84 | "no-inner-declarations": "off" 85 | }, 86 | "overrides": [ 87 | { 88 | "files": [ 89 | "**/__tests__/*.{j,t}s?(x)", 90 | "**/tests/unit/**/*.spec.{j,t}s?(x)" 91 | ], 92 | "env": { 93 | "mocha": true 94 | } 95 | } 96 | ] 97 | }, 98 | "husky": { 99 | "hooks": { 100 | "pre-commit": "npm run lint" 101 | } 102 | }, 103 | "browserslist": [ 104 | "> 1%", 105 | "last 2 versions" 106 | ] 107 | } 108 | -------------------------------------------------------------------------------- /src/translations.ts: -------------------------------------------------------------------------------- 1 | import { Language as L } from "./interfaces"; 2 | 3 | export const translations: { [key: string]: Map } = { 4 | submit: new Map([ 5 | [L.DE, "Lösung einreichen"], 6 | [L.EN, "Submit solution"] 7 | ]), 8 | netFunction: new Map([ 9 | [L.DE, "Dieses Netz berechnet die folgende Funktion:"], 10 | [L.EN, "This network calculates the following function:"] 11 | ]), 12 | errFunction: new Map([ 13 | [L.DE, "Dieses Netz nutzt die folgende Fehlerfunktion:"], 14 | [L.EN, "This network uses the following cost function:"] 15 | ]), 16 | tip: new Map([ 17 | [ 18 | L.DE, 19 | "Tipp: Benutze Stift und Papier für diese Übung! Das Formular dient nur zur Abgabe!" 20 | ], 21 | [ 22 | L.EN, 23 | "Tip: Use pen and paper to solve this exercise! This form is only for the submission!" 24 | ] 25 | ]), 26 | invalidNumber: new Map([ 27 | [L.DE, `Der eingegebene Wert "{0}" ist keine gültige Zahl!`], 28 | [L.EN, `The number {0} you entered is not a valid number!`] 29 | ]), 30 | missingValues: new Map([ 31 | [L.DE, "Es fehlen {0} Eingabewert(e)!"], 32 | [L.EN, `{0} value(s) are missing!`] 33 | ]), 34 | wrongFFValue: new Map([ 35 | [ 36 | L.DE, 37 | "Bist du dir sicher? Wir haben {0} andere(n) Wert(e) heraus! Tip: {1} sieht falsch aus. Alle Werte davor stimmen, also versuche doch nochmal diesen Wert zu berechnen ;)" 38 | ], 39 | [ 40 | L.EN, 41 | "Are you sure? We have {0} value(s) different! Hint: {1} seems wrong. All values before are correct, so try to recalculate this number ;)" 42 | ] 43 | ]), 44 | change: new Map([ 45 | [L.DE, "Änderung von"], 46 | [L.EN, "Changing"] 47 | ]), 48 | to: new Map([ 49 | [L.DE, "zu"], 50 | [L.EN, "to"] 51 | ]), 52 | submitted: new Map([ 53 | [L.DE, "Abgegeben"], 54 | [L.EN, "Submitted"] 55 | ]), 56 | yieldsError: new Map([ 57 | [L.DE, "ergibt einen Fehler von"], 58 | [L.EN, "yields error"] 59 | ]), 60 | step: new Map([ 61 | [L.DE, "Schritt"], 62 | [L.EN, "Step"] 63 | ]), 64 | expected: new Map([ 65 | [L.DE, "Soll-Wert"], 66 | [L.EN, "Expected"] 67 | ]), 68 | nextStep: new Map([ 69 | [L.DE, "Weiter zum Backpropagation Schritt"], 70 | [L.EN, "Move on to the backpropagation step"] 71 | ]), 72 | thanks: new Map([ 73 | [ 74 | L.DE, 75 | "Danke dass du dir Zeit für diese Übung genommen hast! Deine Ergebnisse wurden an den Server übermittelt und du wirst gleich eine Antwort erhalten!" 76 | ], 77 | [ 78 | L.EN, 79 | "Thank you for taking the time for this exercise! Your results were successfully transmitted to the server and you will receive an answer shortly!" 80 | ] 81 | ]), 82 | 83 | resultSuccess: new Map([ 84 | [L.DE, "Deine Werte sind alle korrekt! Sehr gut gemacht!"], 85 | [L.EN, "All your values are correct! Good job!"] 86 | ]), 87 | 88 | resultError: new Map([ 89 | [ 90 | L.DE, 91 | "Die Werte sind leider nicht alle korrekt. Versuche es doch noch einmal, du hast so viele Versuche wie du brauchst." 92 | ], 93 | [L.EN, "Not all your values are correct. Try again and take your time!"] 94 | ]), 95 | 96 | unsupportedBrowser: new Map([ 97 | [ 98 | L.DE, 99 | "Dein Browser {0} konnte nicht als einer der getesteten Browser (Chrome, Firefox und Opera) identifiziert werden. Wenn der Graph nicht korrekt angezeigt wird solltest du vielleicht auf die neuste Version eines dieser Browser upgraden." 100 | ], 101 | [ 102 | L.EN, 103 | "Could not detect your browser {0} as one of the tested browsers (Chrome, Firefox and Opera). If the graph and is not displayed properly consider upgrading to the latest version of one of these browsers." 104 | ] 105 | ]), 106 | 107 | whywow: new Map([ 108 | [ 109 | L.DE, 110 | "Du hast erfolreich den Backpropagation Schritt durchgeführt! Nun kannst du deine berechneten Gradienten einmal selbst nutzen um den Fehler dieses Netzes zu verringern! Du errinnerst dich bestimmt daran, dass der Gradient eines Gewichtes/Bias uns sagt mit welcher Intensität das Gewicht/Bias vergrößert oder verkleinert werden sollte. Probiere doch einmal das Netz mit dem Schieberegler unten auf dieser Seite zu verbessern :)" 111 | ], 112 | [ 113 | L.EN, 114 | "You have successfully performed the backpropagation step! You can now use your calculated gradients to decrease the network's error! You might remember that the gradient of a weight/bias tells us how much this weight/bias needs to be increased or decreased to minimize the error. Go ahead and try to improve this network with the slider at the bottom of the page :)" 115 | ] 116 | ]), 117 | wowinstructions: new Map([ 118 | [ 119 | L.DE, 120 | "Hier kannst du den Wert von {0} anpassen und sehen, wie sich die Änderung auf den Fehler des Netzes auswirkt. Du wirst sehen, dass sich der Fehler bei Änderung in Richtung des negativen Gradienten verringern wird. Nichts anderes passiert im Gradient Descent Verfahren beim Trainieren von künstlichen neuronalen Netzen..." 121 | ], 122 | [ 123 | L.EN, 124 | "Here you can change the value of {0} and see how the changes will affect the networks error. You will see that the error decreases when {0} is changed in the direction of the negative gradient. This is what is done with Gradient Descent during training of artificial neural networks..." 125 | ] 126 | ]) 127 | }; 128 | -------------------------------------------------------------------------------- /src/examples/example2.ts: -------------------------------------------------------------------------------- 1 | import { Example } from "../interfaces"; 2 | import { 3 | errorFunction, 4 | addFunc, 5 | multFunc, 6 | leafFunc, 7 | addFuncDerivative, 8 | multFuncDerivative 9 | } from "../neurons"; 10 | 11 | const powThreeQuarterFunc = (c: number[]): number => { 12 | if (c.length != 1) { 13 | throw new TypeError( 14 | `Pow can only handle exactly one input (not ${c.length})` 15 | ); 16 | } 17 | return Math.pow(c[0], 0.75); 18 | }; 19 | 20 | export const powThreeQuarterFuncDerivative = ( 21 | inputValues: Record 22 | ): number => { 23 | const result: number = 24 | (3 / (4 * Math.pow(inputValues.ff, 1 / 4))) * inputValues.parentBp; 25 | 26 | return +result.toFixed(2); 27 | }; 28 | 29 | const example: Example = { 30 | errorHandler: errorFunction, 31 | netFuncTex: ` 32 | \\begin{aligned} 33 | &n(w_0, w_1, w_2, w_3, w_4, w_5, x_0, x_1, b_0, b_1, b_2) \\\\ 34 | = (&(w_0\\cdot x_0 + w_1\\cdot x_1 + b_0)^{3/4} \\cdot w_4 + \\\\ 35 | &(w_2\\cdot x_0 + w_3\\cdot x_1 + b_1)^{3/4} \\cdot w_5 + b_2)^{3/4} 36 | \\end{aligned}`, 37 | 38 | errFuncTex: ` 39 | \\begin{aligned} 40 | &C(w_0, w_1, w_2, w_3, w_4, w_5, x_0, x_1, b_0, b_1, b_2, e) \\\\ 41 | = &(n(w_0, w_1, w_2, w_3, w_4, w_5, x_0, x_1, b_0, b_1, b_2) - e)^2 42 | \\end{aligned}`, 43 | 44 | netTree: { 45 | func: "x^{3/4}", 46 | nodeId: 0, 47 | bpValue: 1, 48 | accumulate: powThreeQuarterFunc, 49 | derivative: powThreeQuarterFuncDerivative, 50 | children: [ 51 | { 52 | func: "+", 53 | nodeId: 1, 54 | accumulate: addFunc, 55 | derivative: addFuncDerivative, 56 | children: [ 57 | { 58 | func: "+", 59 | nodeId: 2, 60 | accumulate: addFunc, 61 | derivative: addFuncDerivative, 62 | children: [ 63 | { 64 | func: "\\cdot", 65 | nodeId: 3, 66 | accumulate: multFunc, 67 | derivative: multFuncDerivative, 68 | children: [ 69 | { 70 | func: "w_4", 71 | nodeId: 4, 72 | ffValue: 1.4, 73 | accumulate: leafFunc 74 | }, 75 | { 76 | func: "x^{3/4}", 77 | nodeId: 5, 78 | accumulate: powThreeQuarterFunc, 79 | derivative: powThreeQuarterFuncDerivative, 80 | children: [ 81 | { 82 | func: "+", 83 | nodeId: 6, 84 | accumulate: addFunc, 85 | derivative: addFuncDerivative, 86 | children: [ 87 | { 88 | func: "+", 89 | nodeId: 7, 90 | accumulate: addFunc, 91 | derivative: addFuncDerivative, 92 | children: [ 93 | { 94 | func: "\\cdot", 95 | nodeId: 8, 96 | accumulate: multFunc, 97 | derivative: multFuncDerivative, 98 | children: [ 99 | { 100 | func: "w_0", 101 | nodeId: 9, 102 | ffValue: 0.4, 103 | accumulate: leafFunc 104 | }, 105 | { 106 | func: "x_0", 107 | nodeId: 10, 108 | ffValue: 5, 109 | accumulate: leafFunc 110 | } 111 | ] 112 | }, 113 | { 114 | func: "\\cdot", 115 | nodeId: 11, 116 | accumulate: multFunc, 117 | derivative: multFuncDerivative, 118 | children: [ 119 | { 120 | func: "w_1", 121 | nodeId: 12, 122 | ffValue: 0.6, 123 | accumulate: leafFunc 124 | }, 125 | { 126 | func: "x_1", 127 | nodeId: 13, 128 | ffValue: 3, 129 | accumulate: leafFunc 130 | } 131 | ] 132 | } 133 | ] 134 | }, 135 | { 136 | func: "b_0", 137 | nodeId: 14, 138 | ffValue: 0.5, 139 | accumulate: leafFunc 140 | } 141 | ] 142 | } 143 | ] 144 | } 145 | ] 146 | }, 147 | { 148 | func: "\\cdot", 149 | nodeId: 15, 150 | accumulate: multFunc, 151 | derivative: multFuncDerivative, 152 | children: [ 153 | { 154 | func: "w_5", 155 | nodeId: 16, 156 | ffValue: 0.7, 157 | accumulate: leafFunc 158 | }, 159 | { 160 | func: "x^{3/4}", 161 | nodeId: 17, 162 | accumulate: powThreeQuarterFunc, 163 | derivative: powThreeQuarterFuncDerivative, 164 | children: [ 165 | { 166 | func: "+", 167 | nodeId: 18, 168 | accumulate: addFunc, 169 | derivative: addFuncDerivative, 170 | children: [ 171 | { 172 | func: "+", 173 | nodeId: 19, 174 | accumulate: addFunc, 175 | derivative: addFuncDerivative, 176 | children: [ 177 | { 178 | func: "\\cdot", 179 | nodeId: 20, 180 | accumulate: multFunc, 181 | derivative: multFuncDerivative, 182 | children: [ 183 | { 184 | func: "w_2", 185 | nodeId: 21, 186 | ffValue: 1.2, 187 | accumulate: leafFunc 188 | }, 189 | { 190 | func: "x_0", 191 | nodeId: 22, 192 | ffValue: 5, 193 | accumulate: leafFunc 194 | } 195 | ] 196 | }, 197 | { 198 | func: "\\cdot", 199 | nodeId: 23, 200 | accumulate: multFunc, 201 | derivative: multFuncDerivative, 202 | children: [ 203 | { 204 | func: "w_3", 205 | nodeId: 24, 206 | ffValue: 0.65, 207 | accumulate: leafFunc 208 | }, 209 | { 210 | func: "x_1", 211 | nodeId: 25, 212 | ffValue: 3, 213 | accumulate: leafFunc 214 | } 215 | ] 216 | } 217 | ] 218 | }, 219 | { 220 | func: "b_1", 221 | nodeId: 26, 222 | ffValue: 0.5, 223 | accumulate: leafFunc 224 | } 225 | ] 226 | } 227 | ] 228 | } 229 | ] 230 | } 231 | ] 232 | }, 233 | { func: "b_2", nodeId: 27, ffValue: 0.5, accumulate: leafFunc } 234 | ] 235 | } 236 | ] 237 | } 238 | }; 239 | 240 | export default example; 241 | -------------------------------------------------------------------------------- /src/components/VueBackpropagationExercise.vue: -------------------------------------------------------------------------------- 1 | 88 | 895 | 896 | 1011 | 1012 | 1018 | --------------------------------------------------------------------------------