{"id":674899,"student_id":10,"content":"{\"html\":\"\u003c!DOCTYPE html\u003e\\n\u003chtml lang=\\\"en\\\"\u003e\\n\u003chead\u003e\\n \u003cmeta charset=\\\"UTF-8\\\"\u003e\\n \u003cmeta name=\\\"viewport\\\" content=\\\"width=device-width, initial-scale=1.0\\\"\u003e\\n \u003ctitle\u003eDocument\u003c/title\u003e\\n\u003c/head\u003e\\n\u003cbody\u003e\\n \u003ccanvas id=\\\"data\\\" width=\\\"28000\\\" height=\\\"280\\\" \u003e\u003c/canvas\u003e\\n \\n \\n \u003ccanvas id=\\\"canvas\\\" width=\\\"28\\\" height=\\\"28\\\" style=\\\"width: 280px; height: 280px; image-rendering: pixelated;\\\"\u003e\u003c/canvas\u003e\\n \u003ccanvas id=\\\"mini\\\" width=\\\"28\\\" height=\\\"28\\\"\u003e\u003c/canvas\u003e\\n\\n \u003ctextarea id=\\\"error_log\\\" rows=\\\"20\\\" style=\\\"width: 400px;\\\"\u003e\u003c/textarea\u003e\\n\\n \u003cp\u003e辨識結果:\u003c/p\u003e\\n\\n \u003cdiv\u003e\\n \u003cbutton onclick=\\\"train()\\\"\u003e進行訓練\u003c/button\u003e\\n \\n \u003cbutton onclick=\\\"clearCanvas()\\\"\u003e清除\u003c/button\u003e\\n \\n \u003cbutton onclick=\\\"test()\\\"\u003e辨識\u003c/button\u003e\\n\\n \u003c/div\u003e\\n\\n\\n \\n\\n \u003ccanvas id=\\\"brain\\\" width=\\\"1200\\\" height=\\\"600\\\" style=\\\"border: 1px solid black;\\\"\u003e\u003c/canvas\u003e\\n\\n \\n \\n\u003c/body\u003e\\n\u003c/html\u003e\",\"css\":\"\",\"js\":\"function makeArray(i) {\\n return (new Array(i)).fill(0)\\n}\\n\\nfunction makeMatrix(i, j) {\\n const grid = makeArray(i)\\n return grid.map(_ =\u003e makeArray(j))\\n}\\n\\nfunction rand() {\\n return (Math.random() - 0.5) / 2\\n}\\n\\nfunction sigmoid(x) {\\n var tanh = (Math.exp(x) - Math.exp(-x)) / (Math.exp(x) + Math.exp(-x))\\n return tanh\\n}\\n\\nfunction dsigmoid(x) {\\n return 1.0 - x * x\\n}\\n\\nfunction NN(a, b, c, d) {\\n this.a = a\\n this.b = b\\n this.c = c\\n this.d = d\\n\\n this.n1 = makeArray(a)\\n this.n2 = makeArray(b)\\n this.n3 = makeArray(c)\\n this.n4 = makeArray(d)\\n\\n this.w1 = makeMatrix(a, b)\\n this.w2 = makeMatrix(b, c)\\n this.w3 = makeMatrix(c, d)\\n\\n this.m1 = makeMatrix(a, b)\\n this.m2 = makeMatrix(b, c)\\n this.m3 = makeMatrix(c, d)\\n\\n for (let i = 0; i \u003c a; i++) {\\n for (let j = 0; j \u003c b; j++) {\\n this.w1[i][j] = rand()\\n }\\n }\\n\\n for (let i = 0; i \u003c b; i++) {\\n for (let j = 0; j \u003c c; j++) {\\n this.w2[i][j] = rand()\\n }\\n }\\n\\n for (let i = 0; i \u003c c; i++) {\\n for (let j = 0; j \u003c d; j++) {\\n this.w3[i][j] = rand()\\n }\\n }\\n\\n this.update = function (inputs) {\\n\\n for (let i = 0; i \u003c a; i++) {\\n this.n1[i] = inputs[i]\\n }\\n\\n for (let i = 0; i \u003c b; i++) {\\n let sum = 0\\n for (let j = 0; j \u003c a; j++) {\\n sum += this.n1[j] * this.w1[j][i]\\n }\\n this.n2[i] = sigmoid(sum)\\n }\\n\\n for (let i = 0; i \u003c c; i++) {\\n let sum = 0\\n for (let j = 0; j \u003c b; j++) {\\n sum += this.n2[j] * this.w2[j][i]\\n }\\n this.n3[i] = sigmoid(sum)\\n }\\n\\n for (let i = 0; i \u003c d; i++) {\\n let sum = 0\\n for (let j = 0; j \u003c c; j++) {\\n sum += this.n3[j] * this.w3[j][i]\\n }\\n this.n4[i] = sigmoid(sum)\\n }\\n\\n return this.n4\\n }\\n\\n this.backPropagate = function (targets, rate = 0.001, moment = 0.001) {\\n\\n let n4_deltas = makeArray(d)\\n for (let i = 0; i \u003c d; i++) {\\n let error = targets[i] - this.n4[i]\\n n4_deltas[i] = dsigmoid(this.n4[i]) * error\\n }\\n\\n let n3_deltas = makeArray(c)\\n for (let i = 0; i \u003c c; i++) {\\n let error = 0\\n for (let j = 0; j \u003c d; j++) {\\n error += n4_deltas[j] * this.w3[i][j]\\n }\\n n3_deltas[i] = dsigmoid(this.n3[i]) * error\\n }\\n\\n let n2_deltas = makeArray(b)\\n for (let i = 0; i \u003c b; i++) {\\n let error = 0\\n for (let j = 0; j \u003c c; j++) {\\n error += n3_deltas[j] * this.w2[i][j]\\n }\\n n2_deltas[i] = dsigmoid(this.n2[i]) * error\\n }\\n\\n for (let i = 0; i \u003c this.c; i++) {\\n for (let j = 0; j \u003c this.d; j++) {\\n let change = n4_deltas[j] * this.n3[i]\\n this.w3[i][j] += change * rate + this.m3[i][j] * moment\\n this.m3[i][j] = change\\n }\\n }\\n\\n for (let i = 0; i \u003c this.b; i++) {\\n for (let j = 0; j \u003c this.c; j++) {\\n let change = n3_deltas[j] * this.n2[i]\\n this.w2[i][j] += change * rate + this.m2[i][j] * moment\\n this.m2[i][j] = change\\n }\\n }\\n\\n for (let i = 0; i \u003c this.a; i++) {\\n for (let j = 0; j \u003c this.b; j++) {\\n let change = n2_deltas[j] * this.n1[i]\\n this.w1[i][j] += change * rate + this.m1[i][j] * moment\\n this.m1[i][j] = change\\n }\\n }\\n\\n let error = 0\\n for (let i = 0; i \u003c this.d; i++) {\\n error += Math.pow(targets[i] - this.n4[i], 2)\\n }\\n return error\\n }\\n\\n this.train = function (patterns, rate = 0.001, moment = 0.001) {\\n\\n let error = 0\\n for (let j = 0; j \u003c patterns.length; j++) {\\n const input = patterns[j][0]\\n const target = patterns[j][1]\\n const output = this.update(input)\\n error += this.backPropagate(target, rate, moment)\\n }\\n return error\\n\\n }\\n}\\n\\nvar nn = new NN(784, 30, 10, 10)\\n\\nconst ctx = document.querySelector('#canvas').getContext('2d')\\nconst dataCtx = document.querySelector('#data').getContext('2d')\\nlet img = new Image\\nimg.src = '_merge.jpg'\\nimg.onload = function () {\\n dataCtx.drawImage(img, 0, 0)\\n}\\n\\ndocument.querySelector('#data').addEventListener('click', (e) =\u003e {\\n let rect = document.querySelector('#data').getBoundingClientRect()\\n let x = Math.floor((e.clientX - rect.left) / 28)\\n let y = Math.floor((e.clientY - rect.top) / 28)\\n\\n const data = dataCtx.getImageData(28 * x, 28 * y, 28, 28).data\\n const arr = []\\n for (let i = 0; i \u003c data.length; i += 4) {\\n const r = data[i + 0]\\n const g = data[i + 1]\\n const b = data[i + 2]\\n const avg = (r + g + b) / 3 / 255\\n arr.push(avg)\\n }\\n\\n for (let x = 0; x \u003c 28; x++) {\\n for (let y = 0; y \u003c 28; y++) {\\n const c = Math.floor(arr[x + y * 28] * 255)\\n ctx.fillStyle = `rgb(${c}, ${c}, ${c})`\\n ctx.fillRect(x * 1, y * 1, 1, 1)\\n }\\n }\\n})\\n\\n\\nfunction train() {\\n\\n const trainData = []\\n\\n for (let x = 1; x \u003c 1000; x++) {\\n for (let y = 0; y \u003c 10; y++) {\\n const data = dataCtx.getImageData(28 * x, 28 * y, 28, 28).data\\n const arr = []\\n for (let i = 0; i \u003c data.length; i += 4) {\\n const r = data[i + 0]\\n const g = data[i + 1]\\n const b = data[i + 2]\\n const avg = (r + g + b) / 3 / 255\\n arr.push(avg)\\n }\\n const output = (new Array(10)).fill(0)\\n output[y] = 1\\n trainData.push([arr, output])\\n }\\n }\\n\\n let count = 20\\n function train () {\\n const error = nn.train(trainData, 0.005, 0.005)\\n document.querySelector('#error_log').innerHTML += 'error:' + error + '\\\\n'\\n count--\\n if (count \u003e 0) setTimeout(train, 100)\\n\\n }\\n setTimeout(train, 100)\\n}\\n\\n\\n\\n\\nlet isMouseDown = false\\nlet data = (new Array(28 * 28)).fill(0)\\ncanvas.addEventListener('mousedown', () =\u003e isMouseDown = true)\\ncanvas.addEventListener('mouseup', () =\u003e isMouseDown = false)\\ncanvas.addEventListener('mousemove', (e) =\u003e {\\n if (!isMouseDown) return\\n let rect = canvas.getBoundingClientRect()\\n let x = Math.floor((e.clientX - rect.left) / 10)\\n let y = Math.floor((e.clientY - rect.top) / 10)\\n ctx.fillStyle = 'white'\\n\\n ctx.beginPath()\\n ctx.arc(x, y, 1, 0, 2 * Math.PI)\\n ctx.fill()\\n const result = test()\\n render()\\n\\n document.querySelector('p').innerText = '辨識結果為:' + result\\n\\n})\\nctx.fillRect(0, 0, 28, 28)\\n\\nfunction clearCanvas() {\\n console.log('clear')\\n data.fill(0)\\n ctx.fillStyle = 'black'\\n ctx.fillRect(0, 0, 280, 280)\\n}\\n\\n\\nfunction test() {\\n const arr = []\\n\\n const ctx = document.querySelector('#mini').getContext('2d')\\n ctx.drawImage(canvas, 0, 0, 28, 28)\\n const data = ctx.getImageData(0, 0, 28, 28).data\\n\\n for (let i = 0; i \u003c data.length; i += 4) {\\n const r = data[i + 0]\\n const g = data[i + 1]\\n const b = data[i + 2]\\n const avg = (r + g + b) / 3 / 255\\n arr.push(avg)\\n }\\n const result = nn.update(arr)\\n const num = result.indexOf(Math.max(...result))\\n return num\\n}\\n\\nfunction render() {\\n\\n const ctx = brain.getContext('2d')\\n ctx.clearRect(0, 0, 2400, 600)\\n\\n for (let i = 0; i \u003c nn.a; i++) {\\n for (let j = 0; j \u003c nn.b; j++) {\\n const w = nn.w1[i][j]\\n const x = i % 28\\n const y = Math.floor(i / 28)\\n const color = Math.floor(nn.n1[i] * 255)\\n ctx.lineWidth = 0.1\\n ctx.beginPath()\\n ctx.strokeStyle = `rgba(${color}, 0, 0, ${w})`\\n ctx.moveTo(x * 20, y * 20)\\n ctx.lineTo(300 + 400 + 50, j * 20 + 10)\\n ctx.stroke()\\n }\\n }\\n\\n for (let i = 0; i \u003c nn.b; i++) {\\n for (let j = 0; j \u003c nn.c; j++) {\\n const w = nn.w2[i][j]\\n const color = Math.floor(nn.n1[i] * 255)\\n ctx.lineWidth = 0.1\\n ctx.beginPath()\\n ctx.strokeStyle = `rgba(${color}, 0, 0, ${w})`\\n ctx.moveTo(300 + 400 + 50, i * 20 + 10)\\n ctx.lineTo(300 + 600 + 50, j * 20 + 10)\\n ctx.stroke()\\n }\\n }\\n\\n for (let i = 0; i \u003c nn.c; i++) {\\n for (let j = 0; j \u003c nn.d; j++) {\\n const w = nn.w3[i][j]\\n const color = Math.floor(nn.n1[i] * 255)\\n ctx.lineWidth = 0.1\\n ctx.beginPath()\\n ctx.strokeStyle = `rgba(${color}, 0, 0, ${w})`\\n ctx.moveTo(300 + 600 + 50, i * 20 + 10)\\n ctx.lineTo(300 + 800 + 50, j * 20 + 10)\\n ctx.stroke()\\n }\\n }\\n\\n for (let i = 0; i \u003c nn.a; i++) {\\n const x = i % 28\\n const y = Math.floor(i / 28)\\n ctx.fillStyle = `rgba(255, 0, 0, ${nn.n1[i]})`\\n ctx.beginPath()\\n ctx.arc(x * 20, y * 20, 4, 0, 2 * Math.PI)\\n ctx.fill()\\n }\\n\\n for (let i = 0; i \u003c nn.b; i++) {\\n ctx.fillStyle = `rgba(255, 0, 0, ${nn.n2[i]})`\\n ctx.beginPath()\\n ctx.arc(300 + 400 + 50, i * 20 + 10, 4, 0, 2 * Math.PI)\\n ctx.fill()\\n }\\n\\n for (let i = 0; i \u003c nn.c; i++) {\\n ctx.fillStyle = `rgba(255, 0, 0, ${nn.n3[i]})`\\n ctx.beginPath()\\n ctx.arc(300 + 600 + 50, i * 20 + 10, 4, 0, 2 * Math.PI)\\n ctx.fill()\\n }\\n\\n for (let i = 0; i \u003c nn.d; i++) {\\n ctx.fillStyle = `rgba(255, 0, 0, ${nn.n4[i]})`\\n ctx.beginPath()\\n ctx.arc(300 + 800 + 50, i * 20 + 10, 4, 0, 2 * Math.PI)\\n ctx.fill()\\n }\\n\\n\\n}\"}","created_at":"2024-01-09T20:48:30.616+08:00","updated_at":"2024-01-09T22:16:43.848+08:00","name":"手寫辨識","language":"web","screenshot":{"url":"/uploads/project/screenshot/674899/9e0348865033c79fa669f8436d4a9085.jpg"},"parent_id":3,"plugin":"","description":null,"note":null,"status":"public","like_student_ids":[],"is_featured":false,"views":271,"hashid":"ej9seq3k2","is_content_changed":false,"review_status":"unsubmitted","submitted_at":null,"reviewed_at":null,"advise":null,"is_deleted":false}
[{"id":15136023,"file_name":"koding.png","project_id":674899,"asset_id":302342,"created_at":"2024-01-09T20:48:30.622+08:00","updated_at":"2024-01-09T20:48:30.622+08:00"},{"id":15136028,"file_name":"_merge.jpg","project_id":674899,"asset_id":711550,"created_at":"2024-01-09T20:57:46.706+08:00","updated_at":"2024-01-09T20:57:54.829+08:00"}]
Orange Apple Learning Platform
My Projects
View Project Page
Export
Remix
Import
Delete
Download Android APP (APK)
Screenshot
Open Web Site
繁中
简中
English
日本語
1:1:1
1:1
Full Width
Scan the QRCode below with your phone to install
Or you can
download APK
to this computer
Scan the QRCode below with your phone to install
Or you can
download APK
to this computer