至此,你可以自主決定你運行中的神經(jīng)網(wǎng)絡(luò)的可視化方式。使用一個 canvas 和 repuestAnimationFrame API 可以使 JavaScript 代碼更簡單。但就這篇文章來說,我會使用 React.js 進(jìn)行展示,因為我在博客上寫過 React.js。
因此在使用 create-react-app 設(shè)置完項目后,App 組件可成為我們可視化的進(jìn)入點。首先,導(dǎo)入神經(jīng)網(wǎng)絡(luò)類別和函數(shù),從你的文件中生成數(shù)據(jù)集。進(jìn)而,為訓(xùn)練集大小、測試集大小和訓(xùn)練迭代次數(shù)添加若干個常量。
import React, { Component } from 'react';
import './App.css';
import generateColorSet from './data';
import ColorAccessibilityModel from './neuralNetwork';
const ITERATIONS = 750;
const TRAINING_SET_SIZE = 1500;
const TEST_SET_SIZE = 10;
class App extends Component {
...
}
export default App;
App 的組件包括生成數(shù)據(jù)集(訓(xùn)練集和測試集)、通過傳遞訓(xùn)練集建立神經(jīng)網(wǎng)絡(luò)會話、定義組件的初始狀態(tài)。在訓(xùn)練階段的時間內(nèi),代價函數(shù)的值和迭代次數(shù)會在控制臺上顯示,它也表示了組件的狀態(tài)。
import React, { Component } from 'react';
import './App.css';
import generateColorSet from './data';
import ColorAccessibilityModel from './neuralNetwork';
const ITERATIONS = 750;
const TRAINING_SET_SIZE = 1500;
const TEST_SET_SIZE = 10;
class App extends Component {
testSet;
trainingSet;
colorAccessibilityModel;
constructor() {
super();
this.testSet = generateColorSet(TEST_SET_SIZE);
this.trainingSet = generateColorSet(TRAINING_SET_SIZE);
this.colorAccessibilityModel = new ColorAccessibilityModel();
this.colorAccessibilityModel.setupSession(this.trainingSet);
this.state = {
currentIteration: 0,
cost: -42,
};
}
...
}
export default App;
接下來,設(shè)置了神經(jīng)網(wǎng)絡(luò)會話之后,就可以迭代地訓(xùn)練神經(jīng)網(wǎng)絡(luò)了。最簡單的版本只需要一直運行 React 的一個 for 循環(huán)就可以了。
class App extends Component {
...
componentDidMount () {
for (let i = 0; i <= ITERATIONS; i++) {
this.colorAccessibilityModel.train(i);
}
};
}
export default App;
然而,以上代碼不會在 React 的訓(xùn)練階段提供(render)輸出,因為組件不會在神經(jīng)網(wǎng)絡(luò)阻塞單個 JavaScript 線程的時候 reRender。這也正是 React 使用 requestAnimationFrame 的時候。與其自己定義一個 for 循環(huán),每一個請求的瀏覽器的動畫幀都可以被用于運行一次訓(xùn)練迭代。
class App extends Component {
...
componentDidMount () {
requestAnimationFrame(this.tick);
};
tick = () => {
this.setState((state) => ({
currentIteration: state.currentIteration + 1
}));
if (this.state.currentIteration < ITERATIONS) {
requestAnimationFrame(this.tick);
this.colorAccessibilityModel.train(this.state.currentIteration);
}
};
}
export default App;
此外,代價函數(shù)可以每 5 步進(jìn)行一次計算。如前所述,需要訪問 GPU 來檢索代價函數(shù)。因此需要防止神經(jīng)網(wǎng)絡(luò)訓(xùn)練過快。
class App extends Component {
...
componentDidMount () {
requestAnimationFrame(this.tick);
};
tick = () => {
this.setState((state) => ({
currentIteration: state.currentIteration + 1
}));
if (this.state.currentIteration < ITERATIONS) {
requestAnimationFrame(this.tick);
let computeCost = !(this.state.currentIteration % 5);
let cost = this.colorAccessibilityModel.train(
this.state.currentIteration,
computeCost
);
if (cost > 0) {
this.setState(() => ({ cost }));
}
}
};
}
export default App;
一旦組件裝載好訓(xùn)練階段就可以開始運行?,F(xiàn)在是使用程序化計算輸出和預(yù)測輸出提供測試集的時候了。經(jīng)過時間推移,預(yù)測輸出應(yīng)該變得和程序化計算輸出一樣。而訓(xùn)練集本身并未被可視化。
class App extends Component {
...
render() {
const { currentIteration, cost } = this.state;
return (
Neural Network for Font Color Accessibility
Iterations: {currentIteration}
Cst: {cost}
/>
testSet={this.testSet}
/>
);
}
}
const ActualTable = ({ testSet }) =>
Programmatically Computed
const InferenceTable = ({ testSet, model }) =>
Neural Network Computed
export default App;
評論