Teachers open the door but You must enter by yourself.
【事前学習】前回までの内容を再確認しておきましょう。
論理積(AND)回路を学習させてみましょう。
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@4.13.0/dist/tf.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-vis@latest"></script>
<script>
async function trainModel(model, inputs, labels){
model.compile({
optimizer: tf.train.sgd(0.01), //tf.train.adam()
loss: tf.losses.meanSquaredError,
metrics: ['mse'],
});
const batchSize = 32;
const epochs = 500;//学習の反復回数
return await model.fit(inputs, labels,{
batchSize,
epochs,
shuffle:true,
callbacks: tfvis.show.fitCallbacks(
document.getElementById('training'),
['mse'],
{width:350, height:200, callbacks:['onEpochEnd']}
)
});
}
async function run() {
//学習データの設定
const x = [[0,0],[0,1],[1,0],[1,1]];
const y = [0,0,0,1];
const xs = tf.tensor2d(x,[x.length,2]);
const ys = tf.tensor2d(y,[y.length,1]);
const x2 = [0, 0.9, 1.1, 2];//プロット用
const model=tf.sequential();
const layer=tf.layers.dense({inputShape:[2], units:1});
model.add(layer);
await trainModel(model, xs, ys);
document.getElementById('output').innerHTML
= '<pre>'+model.predict(xs).toString()+'</pre>';
document.getElementById('weight').innerHTML
= '<pre>'+layer.getWeights().toString()
.replace(',Tensor',',<br>Tensor')+'</pre>';
document.getElementById('loss').innerHTML
= '<pre>'+model.evaluate(xs,ys).toString()
.replace(',Tensor',',<br>Tensor')+'</pre>';
const answer = Array(x.length).fill()
.map((ai, i) => ({x:x2[i], y:y[i]}));
const predict = model.predict(xs).arraySync()
.map((yi, i) => ({x:x2[i], y:yi}));
tfvis.render.scatterplot(
document.getElementById('chart'),
{values:[answer,predict], series:['Answer','Predict']},
{xLabel:'x1+x2', yLabel:'y values', width:350, height:320}
);
}
document.addEventListener('DOMContentLoaded', run);
</script>
</head>
<body>
<h3>ニューラルネットの学習結果</h3>
<div id="training"></div>
<div id="chart"></div>
<p><small>※ <math><mi>x</mi></math>軸は入力の和 <math><msub><mi>x</mi><mn>1</mn></msub><mo>+</mo><msub><mi>x</mi><mn>2</mn></msub></math> 。
ただし(0,1),(1,0)は重なるので左右に少しずらしてある。</small></p>
<h4>学習後のネットの出力値</h4>
<div id="output"></div>
<h4>第1層のパラメータ</h4>
<div id="weight"></div>
<h4>2乗誤差の平均 (MSE)</h4>
<div id="loss"></div>
<p><small>※ 結果が表示されるまでしばらくお待ちください。</small></p>
</body>
</html>
※ 軸は入力の和 。 ただし(0,1),(1,0)は重なるので左右に少しずらしてある。
※ 結果が表示されるまでしばらくお待ちください。
const layer=tf.layers.dense({inputShape:[2],units:1,activation:'relu'});
model.add(layer);
※ 非線形の関数が出力層に付加されることにより、単純線形だったネットワークより、より良い学習結果になることを確認してください。(学習回数 epochs を 1000 に増やした方が良いかもしれません。)
const x = [[0,0],[0,1],[1,0],[1,1]];
const y = [0,1,1,1];
※ AND 回路ほど誤差が小さくならないかもしれません。
const x = [[0,0],[0,1],[1,0],[1,1]];
const y = [0,1,1,0];
const layer=tf.layers.dense({inputShape:[2], units:2, activation:'relu'});
model.add(layer);
const layer2=tf.layers.dense({units:1, activation:'relu'});
model.add(layer2);
※ 反復学習100回ぐらいの時点でMSEの値が0.1近くまで落ちていると成功する。学習状況が思わしくないときはブラウザの再読み込みボタンを押すとネットワークの初期状態が変わって新しい学習が始まる。学習回数は1000回に増やすとより誤差が少ない結果が得られる。
【事後学習】本日学んだ内容を再確認しておきましょう。
This site is powered by