我實在不知道期末作業做什麼比較好,而且我也想做到期末作品人家可以投我的作品,找了很久有沒有一些有趣的應用
我發現有人做一個使用arduino與tensorflow.js的應用
但這可能有點進階,在還沒有任何web開發經驗的我來說有點早,因此我找了幾個影片學怎麼寫node跟javascript等等
然後socket的寫法我大部分是跟著這影片學,再加上一些其他文章的參考
發現其實google有個叫做chrome music lab的地方,也很有趣,也讓我確定要做的東西
實在想做一點機器學習的東西,剛好有個函式庫叫做ml5.js他是基於tensorflow.js的一個簡單容易上手的函示庫
等等會有更詳細的解說
p5.js serial的寫法 [ doc ]
簡述
- index.html > 網頁進入點 沒有特別的,不多加論述
- p5.serialport.js > 要匯入的library 請參照 [ doc ]
- main.js > 裡面有setup()跟draw()
- serial.js > 直接把一些重要函式包再一起放在這
執行前需要先把整個repository clone下來,執行node startserver.js,由於它是由node去做的
serial.js
initSerial() 會放在到時候彙整的setup() 或在此實驗是在main.js呼叫
let serial="/dev/ttyACM0"; let latestData = "waiting for data";
function initSerial() { serial = new p5.SerialPort(); serial.list();
serial.open("/dev/ttyACM0"); serial.on('connected', serverConnected);
serial.on('list', gotList); serial.on('data', gotData); serial.on('error', gotError); serial.on('open', gotOpen);
serial.on('close', gotClose); }
function serverConnected() { print("Connected to Server"); } function gotList(thelist) { print("List of Serial Ports:"); for (let i = 0; i < thelist.length; i++) { print(i + " " + thelist[i]); } }
function gotOpen() { print("Serial Port is Open"); }
function gotClose(){ print("Serial Port is Closed"); latestData = "Serial Port is Closed"; }
function gotError(theerror) { print(theerror); } let ax,ay,az; function gotData() { let currentString = serial.readLine(); trim(currentString); if (!currentString) return; let splitString = split(currentString, '\t'); ax=float(splitString[1]); ay=float(splitString[2]); az=float(splitString[3]); latestData = currentString; } function gotRawData(thedata) { }
|
p5.js的介面函式庫 [ doc ]
由於在期中作業時發現有人使用gui的函式庫,我也找了一個是p5.touchgui,節省一點時間
簡述
- index.html > 網頁進入點 沒有特別的,不多加論述
- g_m.js > 做場景切換等環境變數的設定
- gui.js > 直接在此畫gui
gui.js
let b_go, t_set, s_volume;
let pre_stage;
function init_gui_layout() { pre_stage=0; gui = createGui(); gui.loadStyle("Blue"); b_go = createButton("start", cx-50,cy,100,50); t_set = createToggle("▽", cx/10, cy/10, 50,50); s_volume = createSlider("volume", cx,cy-75); b_go.onPress = function() { if (stage==0) stage++; } t_set.onPress = function() { if (stage!=-1) pre_stage=stage; if (t_set.val) stage=-1; else stage=pre_stage; } t_set.labelOn = "△"; t_set.labelOff = "▽";
}
function gui_layout() { drawGui(); switch(stage) { default: break; case -1: b_go.visible = false; break; case 0: b_go.visible = true; break; case 1: b_go.visible = false; break; case 2: } s_volume.visible = t_set.val; if (s_volume.isChanged) { volume = s_volume.val; } s_volume.val = volume; }
|
ml5.js [ doc ]
簡述
- index.html > 網頁進入點
- sketch.js > 裡面有setup()跟draw() 做主要控制
- ml5.js > 把ml5.js分為初始的函式跟loop
- serial.js
- p5.serialport.js
index.html
<head> <meta charset="UTF-8"> <title>XY Classifier</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/p5.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/addons/p5.dom.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/addons/p5.sound.min.js"></script> <script src="https://unpkg.com/ml5@0.4.3/dist/ml5.min.js" type="text/javascript"></script> </head>
<body> <h1>Teachable Air Drum</h1> <script src="sketch.js"></script> <script src="ml5.js"></script> <script src="serial.js"></script> <script src="p5.serialport.js"></script> <p> Label: <select id="label"> <option value="bdrum">bdrum</option> <option value="crash">crash</option> <option value="hh_c">hh_c</option> <option value="tom1">tom1</option> <option value="tom2">tom2</option> <option value="up">up</option>
</select> <button id="train">train</button> </p> <p> Classification: <span id="classification"></span> </p>
<p> Click in canvas to add training data. <span id="device_data"></span> </p>
</body>
</html>
|
sketch.js
let brain;
function setup() { let canvas = createCanvas(400, 400); canvas.mousePressed(addData); init_ml5js(); // Train Model button select('#train').mousePressed(trainModel);
background(0); initSerial(); }
function draw() { textAlign(LEFT); select('#device_data').html("acc is "+ax+","+ay+","+az); }
|
ml5.js
function init_ml5js() { // Create ethe model const options = { inputs: ['x', 'y'], outputs: ['label'], layers: [ ml5.tf.layers.dense({ units: 50, inputShape: [3], activation: 'relu', }), ml5.tf.layers.dense({ units: 25, activation: 'relu', }), ml5.tf.layers.dense({ units: 6, activation: 'sigmoid', }) ], debug: true, task: 'classification' } brain = ml5.neuralNetwork(options); }
// Add a data record function addData() {
let label = select('#label').value(); // Add data brain.addData({x:ax, y:ay, z:az}, {label});
stroke(255); noFill(); ellipse(mouseX, mouseY, 32); fill(255); textSize(16); textAlign(CENTER, CENTER); text(label, mouseX, mouseY); }
// Train the model function trainModel() { brain.normalizeData(); brain.train({ epochs: 200 }, finishedTraining); }
// When the model is trained function finishedTraining() { brain.classify([ax, ay, az], gotResults); }
// Got a result function gotResults(error, results) { if (error) { console.error(error); return; } // Show classification select('#classification').html(results[0].label); // Predict again brain.classify([ax, ay, az], gotResults); }
|
serial.js
請參考前一部分的serial
沒有留言:
張貼留言