├── 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 |
2 |
3 |
17 |
18 |
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 | [](https://travis-ci.com/into-ai/vue-backpropagation-exercise)
4 | [](https://www.npmjs.com/package/vue-backpropagation-exercise)
5 | [](https://www.npmjs.com/package/vue-backpropagation-exercise)
6 | [](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 | 
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 |
2 |
3 |
4 |
5 | {{ tl("tip") }}
6 |
7 |
8 |
9 | | {{ tl("netFunction") }} |
10 | {{ tl("errFunction") }} |
11 |
12 |
13 | |
14 | |
15 |
16 |
17 |
18 |
19 | -
20 | Feedforward {{ tl("step") }}
21 |
22 | -
23 | Backpropagation {{ tl("step") }}
24 |
25 |
26 |
27 |
28 |
29 |
30 | Debug: Add FF
33 | Debug: Add BP
36 |
37 |
38 |
39 |
40 |
41 |
44 |
52 |
56 | {{ weightChange.formatted }}
57 |
58 |
59 |
60 | {{ tl("change") }}
61 | {{ tl("to") }} {{ newEditableWeightValue.toFixed(2) }} ({{ weightChange.formatted }}) {{ tl("yieldsError") }}
66 | {{ totalNetError.toFixed(errorPrecisionDigits) }} ({{ costChange.formatted }})
71 |
72 |
73 |
74 |
83 | {{ proceedButtonText }}
84 |
85 |
86 |
87 |
88 |
895 |
896 |
1011 |
1012 |
1018 |
--------------------------------------------------------------------------------