Teachers open the door but You must enter by yourself.

Open Media Lab.
オープンメディアラボ

【事前学習】前回までの内容を再確認しておきましょう。

論理回路
Logic Circuit

論理積回路

論理積(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>

ニューラルネットの学習結果

x軸は入力の和 x1+x2 。 ただし(0,1),(1,0)は重なるので左右に少しずらしてある。

学習後のネットの出力値

第1層のパラメータ

2乗誤差の平均 (MSE)

※ 結果が表示されるまでしばらくお待ちください。

Lesson

  1. 出力層に非線形の活性化関数を設定してみましょう。
    (デフォルトは活性化関数なし)
  2. const layer=tf.layers.dense({inputShape:[2],units:1,activation:'relu'});
    model.add(layer);

    ※ 非線形の関数が出力層に付加されることにより、単純線形だったネットワークより、より良い学習結果になることを確認してください。(学習回数 epochs を 1000 に増やした方が良いかもしれません。)

  3. 論理和(OR)回路を学習させてみましょう。
  4. const x = [[0,0],[0,1],[1,0],[1,1]];
    const y = [0,1,1,1];
    

    ※ AND 回路ほど誤差が小さくならないかもしれません。

  5. 排他的論理和(XOR)回路を学習させてみましょう。
  6. const x = [[0,0],[0,1],[1,0],[1,1]];
    const y = [0,1,1,0];
    
  7. 前問の 2-1 ネットワークでは線形の当てはめにしかならないことを確認して、 2-2-1 ネットワークに変更しましょう。
    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 Powered by MathJax