遅かれ早かれこれは起こらなければならない
遅かれ早かれ、フロントエンドの開発者は自分のフレームワークで遊ぶのに飽き、同僚を煩わせるのに飽きます-バックエンド、開発者のプレイに飽きて、機械学習に目を向け始めます。データは科学であり、それだけです。幸いなことに、ウェブサイトにアクセスしたい人のための1つおきのコースがこれに貢献し、すべてのプラットフォームでそれがいかに簡単かを叫んでいます。私も、データベースからAPIにデータを転送し、次にAPIからテーブルとフォームにデータを転送することにうんざりして、短い休暇を取り、フロントエンドのスキルを機械学習に適用しようと決心しました。幸いなことに、ダニエル・シフマン や チャーリー・ジェラールのような人々 は、彼らの例では、数式で最初のページを見た後に始めたものをやめないように助けます。
少し戻ってタイトルを見ると、本からコピーしたり、 自分のやったことを説明しようとするハイテクな言葉を投げたりしないことがわかり ます。
「機械学習」という言葉を聞いた誰もが、何層もの多くのニューロンが絡み合っている絵を想像しているとほぼ確信しています。したがって、これは偶然ではありません。これがまさに、人間の脳とその神経ネットワークをデジタル形式で実装するために機械学習が考案された理由です。
? , . , , . - , , , . , , .
. , , - , . - () .
, ? , - , ( , , ).
- , - . .
- . . . .
“ ” - , , , , .
, . , , , . , -, , .
, , . , 0.1*X1 (W1 == 0.1) X1. (, , , , , , -1 1). , 10 . , , 1*X2 (W2 == 1).
, . , .
, , -? , ( - ). f() = . - input , - output , f, - .
, . input X output . , - , , , , .
, , , , - i .
label . , , - 3, label = “ ”, , . , , , .
. “ !” . -, , , ?
, . , ?
thecodingtrain, . , .
, . .
, , ( ). .
? , . - , . . . , , .
, . score, .
. , , () , , , , . , , , .
, , , raid shadow legends. dino game google chrome. , , ?
Dino game
p5.js. , , . 5 : setup, , ; draw - , , .
? , , , . , , .
- , , . . .
class Cactus {
constructor() {}
}
class Dino {
constructor() {}
}
, - - ( - , ), . ? , , , - GameObject, onTick, . , , . .
...
onTick(cb = () => { }) {
cb(this);
}
...
, , . , , , .
(, , ). , . , : - , , , , , , . , , .
switch (this.state) {
case DinoStateEnum.run: break;
case DinoStateEnum.jump: {
this.currH += this.jumpSpeed;
if (this.currH == this.maxH) {
this.state = DinoStateEnum.fall;
}
break;
}
case DinoStateEnum.fall: {
this.currH -= this.jumpSpeed;
if (this.currH == 0) {
this.state = DinoStateEnum.run;
}
break;
}
}
, . , . . .
function updateCactuses() {
const copy = cactuses.slice();
for (let i = 0; i < copy.length; i++) {
let c = copy[i];
c.onTick(cactus => {
drawCactus(cactus)
cactus.currDistance -= dinoVelocitySlider.value();
if (cactus.currDistance + cactusW < initialDinoW && !cactus.passDinoPosition) {
updateDinoScore()
cactus.passDinoPosition = true;
}
if (cactus.currDistance < 0) {
cactuses.splice(i, 1);
}
})
}
}
tensorflowjs , - . , . .
<script
src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@2.0.0/dist/tf.min.js">
</script>
<script>
tf.setBackend('cpu') // tf
</script>
, ? . : . , ?
, . , , . - . , . , , , . , .
, . . , . , ?
, - . , , . ( , , , ).
, , . ? .
? - 200-300 , . , (best score) , , . , . . ().
, , , .
.
- .
C - .
- , .
, :
T .
.
.
, .
4 .
8 . 2, : .
:
createModel() {
const model = tf.sequential();
const hiddenLayer = tf.layers.dense({
units: this.hidden_nodes, // - (8)
inputShape: [this.input_nodes], // - (4)
activation: "sigmoid" //
});
model.add(hiddenLayer);
const outputLayer = tf.layers.dense({
units: this.output_nodes, // - (2)
activation: "sigmoid"
});
model.add(outputLayer);
return model;
}
sequential() . , . - , . . , sigmoid.
, , - , tensorflow .
, . , .
predict(inputs) {
return tf.tidy(() => {
const xs = tf.tensor([inputs]); // ( )
const ys = this.model.predict(xs); //
const output = ys.dataSync(); //
return output;
});
}
tensorflow , tensor ( ) , , , , tidy.
, tensorflow , , . , , . ( , ). 2, 2 . , , , , . , output[0] > output[1], .
dino npc.
- , , .
, - .
function drawDino(dino) {
if (dino.isDead) return;
if (dino.state != DinoStateEnum.run) {
// ,
image(dino2, initialDinoW, initialDinoH - dino.currH, dinoW, dinoH); // 5
} else if (iteration % 7 == 0)
//
image(dino1, initialDinoW, initialDinoH, dinoW, dinoH);
else
image(dino2, initialDinoW, initialDinoH, dinoW, dinoH);
}
. , , , , , . .
function updateGenerationIfNeeded() {
if (dinos.every(d => d.isDead)) {
cactuses = [];
dinoVelocitySlider.value(initDinoVelocity);
dinos = newGeneration(dinos)
}
}
, , . , . .
, , . , .
: .
mutate(rate) {
tf.tidy(() => {
const weights = this.model.getWeights(); //
const mutatedWeights = [];
for (let i = 0; i < weights.length; i++) {
let tensor = weights[i]; // -
let shape = weights[i].shape;
let values = tensor.dataSync().slice();
for (let j = 0; j < values.length; j++) {
if (Math.random() < rate) { //
let w = values[j];
values[j] = w + this.gaussianRandom(); // -1 1
}
}
let newTensor = tf.tensor(values, shape);
mutatedWeights[i] = newTensor;
}
this.model.setWeights(mutatedWeights); //
});
}
, . . e . fitness ( ).
const calculateFitness = (dinos) => {
let sum = 0;
dinos.map(d => sum += d.score)
dinos.map(d => d.fitness = d.score / sum)
}
. . ( ), , .
:
const pickOne = (dinos) => { // fitness
let index = 0;
let r = Math.random();
while (r > 0) {
r = r - dinos[index].fitness;
index++;
}
index--;
let dino = dinos[index] // - , rate
const dinoBrain = dino.brain.copy();
dinoBrain.mutate(0.2) //
let newDino = new Dino(dinoBrain) //
return newDino;
}
. , . , , .
for (let i = 0; i < TOTAL; i++) {
newDinos.push(pickOne(oldDinos));
}
console.log(currentGeneration++);
return newDinos;
P.S. , welcome to PR's. v_hadoocken