blocklyでobjectを動かす。 その13



#概要
blocklyでobjectを動かして見る。
tensorflow.js、やってみた。

#写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/881d271e-c300-8893-c56a-a1dfc6c75e40.png)


#ステージを作る。


```
    教師データ<br>
    <div id="out0"></div>
    ロス推移<br>
    <canvas id="canvas" width="300" height="200"></canvas><br>
    最終ロス<br>
    <div id="out1"></div>
    予測<br>
    <div id="out2"></div>
```

#ブロックを書く。


```

Blockly.Blocks.data = {
	init: function() {
		this.jsonInit({
    		message0: "教師データ 01 %1 10 %2 11 %3 00 %4",
	    	args0: [{
        		type: "input_value",
		        name: "d01",
		        check: "Number",
	        	align: "RIGHT"
        	}, {
	        	type: "input_value",
	        	name: "d10",
	        	check: "Number",
	        	align: "RIGHT"
	        }, {
	        	type: "input_value",
	        	name: "d11",
	        	check: "Number",
	        	align: "RIGHT"
	        }, {
	        	type: "input_value",
	        	name: "d00",
	        	check: "Number",
	        	align: "RIGHT"
		    }],
		    previousStatement: null,
		    nextStatement: null,
		    style: "text_blocks",
		    tooltip: Blockly.Msg.TEXT_PRINT_TOOLTIP,
		    helpUrl: Blockly.Msg.TEXT_PRINT_HELPURL
	    })
    }
};


Blockly.Blocks.model = {
	init: function() {
		this.jsonInit({
			message0: "モデル %1",
			args0: [{
				type: "input_value",
				name: "n",
        check: "Number",
	      align: "RIGHT"
			}],
			previousStatement: null,
			nextStatement: null,
			style: "text_blocks",
			tooltip: Blockly.Msg.TEXT_PRINT_TOOLTIP,
			helpUrl: Blockly.Msg.TEXT_PRINT_HELPURL
		})
	}
};


Blockly.Blocks.train = {
	init: function() {
		this.jsonInit({
			message0: "学習、予測 %1",
			args0: [{
				type: "input_value",
				name: "n",
        check: "Number",
	      align: "RIGHT"
			}],
			previousStatement: null,
			nextStatement: null,
			style: "text_blocks",
			tooltip: Blockly.Msg.TEXT_PRINT_TOOLTIP,
			helpUrl: Blockly.Msg.TEXT_PRINT_HELPURL
		})
	}
};


```

#フローを書く。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/7186c985-3252-c9e8-cb43-2621a739b180.png)


#objectを書く。


```


Blockly.JavaScript.data = function(a) {
  var b = Blockly.JavaScript.valueToCode(a, "d10", Blockly.JavaScript.ORDER_COMMA) || 0;
	var c = Blockly.JavaScript.valueToCode(a, "d01", Blockly.JavaScript.ORDER_COMMA) || 0;
	var d = Blockly.JavaScript.valueToCode(a, "d11", Blockly.JavaScript.ORDER_COMMA) || 0;
	a = Blockly.JavaScript.valueToCode(a, "d00", Blockly.JavaScript.ORDER_COMMA) || 0;
  return "data(" + b + "," + c + "," + d + "," + a + ");\n"
};


Blockly.JavaScript.model = function(a) {
    return "model_(" + (Blockly.JavaScript.valueToCode(a, "n", Blockly.JavaScript.ORDER_NONE) || "''") + ");\n"
};


Blockly.JavaScript.train = function(a) {
    return "train(" + (Blockly.JavaScript.valueToCode(a, "n", Blockly.JavaScript.ORDER_NONE) || "''") + ");\n"
};

tf.setBackend('cpu');
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
function draw(data) {
	var hc = 100;
	ctx.strokeStyle = "#f00";
	ctx.lineWidth = 1;
	ctx.moveTo(0, 80);
	for (var i = 1; i < data.length; i++)
	{
		ctx.lineTo(i, hc - data[i] * 30);
	}
	ctx.stroke();
}
const x = [[1, 0], [0, 1], [1, 1], [0, 0]];
const xs = tf.tensor2d([[1, 0], [0, 1], [1, 1], [0, 0]], [4, 2]);
var y;
var ys;
function data(d10, d01, d11, d00) {
	y = [d10, d01, d11, d00];
	ys = tf.tensor2d([[d10], [d01], [d11], [d00]], [4, 1]);
	var h = '<table><tr><th>a</th><th>b</th><th>c</th></tr>';
	for (var row = 0; row < 4; row++)
	{
   	h += '<tr>';
    h += '<td>' + x[row][0] + '<\/td>';
    h += '<td>' + x[row][1] + '<\/td>';
    h += '<td>' + y[row] + '<\/td>';
    h += '<\/tr>';
	}
	h += '<\/table>';
	document.getElementById('out0').innerHTML = h;
}
const model = tf.sequential();
function model_(n) {
	model.add(tf.layers.dense({
    units: n,
    activation: 'tanh',
    inputShape: [2]
	}));
	model.add(tf.layers.dense({
    units: 1,
    activation: 'sigmoid'
	}));
	model.compile({
    optimizer: 'adam',
    loss: 'binaryCrossentropy'
	});
}
function train(n) {
	var c = [];
	model.fit(xs, ys, {
    batchSize: 4, 
    epochs: n,
    callbacks: {
			onEpochEnd: (epoch, logs) => {
				if (epoch % 10 == 0) 
				{
				  c.push(logs.loss);
				  draw(c);
				}
			},
		}
	}).then((d) => {
    var str = "loss = ";
    str += d.history.loss[0]; 
    document.getElementById('out1').innerHTML = str;
    var pre0 = model.predict(tf.tensor2d([1, 0], [1, 2]));
    var r0 = pre0.dataSync() < 0.5 ? 0 : 1;
    var pre1 = model.predict(tf.tensor2d([0, 1], [1, 2]));
    var r1 = pre1.dataSync() < 0.5 ? 0 : 1;
    var pre2 = model.predict(tf.tensor2d([1, 1], [1, 2]));
    var r2 = pre2.dataSync() < 0.5 ? 0 : 1;
    var pre3 = model.predict(tf.tensor2d([0, 0], [1, 2]));
    var r3 = pre3.dataSync() < 0.5 ? 0 : 1;
    const py = [r0, r1, r2, r3];
    var h = '<table><tr><th>a</th><th>b</th><th>c</th></tr>';
    for (var row = 0; row < 4; row++)
    {
   	  h += '<tr>';
      h += '<td>' + x[row][0] + '<\/td>';
      h += '<td>' + x[row][1] + '<\/td>';
      h += '<td>' + py[row] + '<\/td>';
      h += '<\/tr>';
    }
    h += '<\/table>';
    document.getElementById('out2').innerHTML = h;
	});
}





```

#成果物

https://embed.plnkr.co/plunk/JVAADGthdmOqhdek

以上。