kkana's blog

新米コーダーの忘れそうなことメモ

nature of code : 今日の練習「ネットワークのアニメーション」

the nature of code 10章最後の課題

これまで読んできたニューラルネットワークのさわりの部分を可視化したアニメーション

See the Pen ネットワークのアニメーション by kanaparty (@kanaparty) on CodePen.

2016年にギリギリ間に合った・・・!

nature of code : 今日の練習「ビークルの訓練」

前回作成したのは教師あり学習(正解があって、結果と正解から誤差を計算し重みを調整する)だったが
今回は簡易的な強化学習(結果から誤差を計算し、環境に対応する)を作ってみる練習。

今回のビークルにはbrainプロパティがあって、操舵力を決めるときにbrainから処理された操舵力を受け取って それに従って運動させる。

See the Pen ビークルの訓練 by kanaparty (@kanaparty) on CodePen.

環境(黄色い点)から受ける力をbrainに渡して処理してもらい、 その結果が画面の中心(灰色の点)からどれだけ離れているかをエラーとしてトレーニングしている。今回は活性化関数がない。

ビークル

//操舵力を計算
steer(target){
  var force = [];
  for (var i = 0; i < target.length; i++) {
    force[i] = this.seek(target[i]);
  }
  //ターゲットから受ける力をbrainプロパティに渡して結果をもらう
  var result = this.brain.feedfoward(force);
  this.applyForce(result);
  //トレーニング
  var error = Vector.sub(this.desired, this.position);
  this.brain.train(force, error);
}

brain内では受け取った力の分だけ重み(今回は位置なのでxとyの2つ分)を調整している。

//調整
train(forces, error){
  for (var i = 0; i < this.weightLength; i++) {
    this.weight[i] += this.c * error.x * forces[i].x;
    this.weight[i] += this.c * error.y * forces[i].y;
  }
}

1000回トレーニングを繰り返したら、点の位置を変える。
位置が切り替わった直後は前の位置のときに調整した重みに従って動くので目標がわからなくてフラフラしているように見えるが、
まただんだん調整されて画面の真ん中を目指すようになる。

the nature of codeの一番最初の課題はランダムウォークだった。
ついに動きをつける対象にbrainが〜!!すごい、私も進化してきた感がある。

nature of code : 今日の練習「選択的遺伝」

See the Pen 選択的遺伝 by kanaparty (@kanaparty) on CodePen.

9章でやり残してしまっていた課題。
自分で適応度を変更して次の世代のパターンを作る。 例は顔みたいな図形だったけど、タータンチェックのパターンで作ってみた。

nature of code : 今日の練習「単純なパーセプトロン」

ニューラルネットワークとは

脳に基づいて特定の問題を解決するための計算モデル。複雑系の一種

ニューラルネットワーク - Wikipedia

ニューロン...細胞網に存在している単一細胞で、入力を受け取り、処理し、出力を生成する。
コネクショニスト計算系...情報がネットワーク全域で集合的に並列で処理される

ニューラルネットワークの学習機能

ニューラルネットワークの主な要素の一つ。
ニューラルネットワークは単なる複雑系にあらず。内部を流れる情報に基づいて構造を変化させることができる複雑適応系
普通は重み(二つのニューロン間の信号を制御する数値)を調整することで適合させる。
ニューラルネットワークが適していない出力を使た場合はこの重みを変更して後続の結果を改善する。

いろいろな学習方法

  • 教師あり学習
    ネットワークのだした答えと、正しい答え(教師)を比較して誤差にあわせて調整する。

  • 教師なし学習
    既知の答えのデータがない場合に行う。隠されたパターンを検索するイメージ。適用例にクラスタリングがある。

  • 強化学習
    観察に基づいた方法。結果に従って判断し、環境の観察をする。ロボット工学で広く使われている。

ニューラルネットワークの代表的な使用方法

  • パターン認識(顔認識)
  • 時系列予測(明日の天気など)
  • 信号処理(補聴器のノイズの除去など・・・)
  • 制御(自動運転など)
  • ソフトセンサー(複数の個別センサーを処理して総合的に判断したり)
  • 異常検出

パーセプトロンとは

最も単純なニューラルネットワーク。単一ニューロンの計算モデル。
1つか複数の入力、プロセッサー、出力で構成される。
フィードフォワードモデル(送信、処理、出力)?

入力から出力まで

  1. 入力を受けとる
  2. 重みを入力する(特定のあたいをかける。通常は最初ランダムな0〜1の値で行う。)
  3. 入力に重みをかける
  4. 重み付けされたすべての入力を合計する
  5. 出力を生成する(活性化関数を通じて合計値を渡す。出力するかどうかをパーセプトロンに通知する。)

実装した単純なパーセプトロン

パーセプトロンを使って、単純なパターン認識をする。
与えられた座標が線より上にあるか、下にあるか判断するパーセプトロンを作る。

できたもの↓

See the Pen シンプルパーセプトロン by kanaparty (@kanaparty) on CodePen.

正しい線は背景にうっすら見える紺色の線。
点は教師。1フレームづつ教師の入力をパーセプトロンに渡して訓練させる。
紺色の点は線より上に、黄色い点は線より下にあるとパーセプトロンが判断した位置。
これが正しい線にだんだん近づけば訓練が成功している!

登場人物は2つ。

処理の流れ

  1. 答えが用意されている入力をパーセプトロンにわたす
  2. 答えを推測
  3. エラーを計算(正しいか、間違っているか)
  4. エラーに従ってすべての重みを計算する
  5. (繰り返し)

エラーの定義と重さの定義

  • エラー = 適切な出力 - 推測の出力

  • 新しい重み = 今の重み + 重みの変化量

(重みの変化量 = エラー * 入力)

  • 新しい重み = 重み + エラー * 入力

学習定数(ビークルの操舵のときに出てきたmaxSpeedのような感じで、最大力を制御する変数)を加えると答えに行き着くまでの時間を調整することができる。
学習定数が大きいと短時間で済むが微調整が難しい。小さいと時間がかかるが正確性が増す。

教師オブジェクト

線の上にあるか下にあるかは線の関数を使って調べればよい。f(x)のyよりの上にあるか、ないか。


おしまい

たしかこの章を読み始めたのは7月だったはず・・・。
私には難しくて危うく積ん読になってしまうところだった。 のこす課題はあと3つ。

それにしても教師オブジェクト2000個でも正しい斜めのラインぴったりにはなかなかならないのだなぁ。

参考にしたサイト

ニューラルネットワーク

hokuts.com

イテレータ・ジェネレータ(ついでにシンボルもちょっとだけ)覚えたことメモ

tuitui.hatenablog.com

↑昨年イテレータについて後日読もうと思っていたんですが、ようやくその「後日」が来ました。
イテレータ・ジェネレータ(ついでにシンボルもちょっとだけ)について覚えたことをメモ。
自分でIterableなオブジェクトを書いてもいいし、arrayやstringにはそもそも備わっているということで
なんだ〜となりました。もっと早くちゃんと読んでおけばよかったなと思った次第です。  

Iterationについて

繰り返し処理を行うための決まりに従った実装。
繰り返し処理を適用したときの挙動 → Iteration

IterableとIterator

Iterable = Iteratorを備えた(Symbol.iteratorプロパティにIteratorを返すメソッドを実装している)オブジェクト。Iteratorを備えているのでfor-ofで処理できる。
Iterator = next()メソッドを実装したオブジェクト。nextメソッドを呼ぶと以下2つのプロパティをもったオブジェクトを返す。

  • value 現在の値
  • done 値を出し終えたかどうか

最初からIterableな挙動が備わっているもの

はじめからSymbol.iteratorプロパティにIteratorを返すメソッドが実装されているもの

  • Array
  • String
  • NodeList
  • Generator Object
  • Array, Map, Set が持つ entries(), keys(), values()の戻り値

など。
たとえば文字列で順番にとりだしたいとき以下のように書ける

const s = 'javascript';
const sIterator =  s[Symbol.iterator]();
sIterator.next();//Object {value: "j", done: false}
sIterator.next();//Object {value: "a", done: false}
sIterator.next();//Object {value: "v", done: false}
sIterator.next();//Object {value: "a", done: false}
sIterator.next();//Object {value: "s", done: false}
sIterator.next();//Object {value: "c", done: false}
sIterator.next();//Object {value: "r", done: false}
sIterator.next();//Object {value: "i", done: false}
sIterator.next();//Object {value: "p", done: false}
sIterator.next();//Object {value: "t", done: false}
sIterator.next();//Object {value: undefined, done: true}

for-ofを使ってとりだすとき

const a = ['j','a','v','a','s','c','r','i','p','t'];
const aIterator =  a[Symbol.iterator]();
for (variable of aIterator) {
  console.log(variable);
}
//j
//a
//v
//a
//s
//c
//r
//i
//p
//t

使い方はここ qiita.com

がとてもまとまってました。ありがとうございます。

Symbolについて

オブジェクトに対して、ある状況に応答するためのインターフェースを組み込む(プロトコルを定義する)ために使う。

const sym = Symbol();

で生成できる。newをつけない。
常に別々のユニークな値として生まれる。

オブジェクトのプロパティとして使うとObject.keys()などで無視される。

GlobalSymbolRegistry

グローバルスコープを越えて共有されるSymbolの領域。 iframeなどを隔てたとしても同じSymbolを共有することができる。
Symbol.for(key)メソッドを使うと keyとして渡した値を持ったSymbolがGlobalSymbolRegistryに存在しなければ、新しく生成したSymbolを生成して返す。

Generatorについて

処理を途中で抜けられる。そのときに値を取り出すことができる。 Generatorオブジェクトはnextメソッドを呼びだすと、 yieldの後に置かれている処理を評価するところまで進み、その評価結果を返す。 返ってくるオブジェクトの中身は

  • value : yieldの後の処理
  • done : すべての値を取り出し終えたかどうか

書き方

function* generatorFunc() {
  yield 1;
  yield 2;
  return 3;
}
var g = generatorFunc();
console.log(g.next()); //Object {value: 1, done: false}
console.log(g.next()); //Object {value: 2, done: false}
console.log(g.next()); //Object {value: 3, done: true}

function* と記述すると定義できる。

vue.jsでマインスイーパ

See the Pen Minesweeper(vue.js) by kanaparty (@kanaparty) on CodePen.

はじめてMVCフレームワーク使ってみた。なんて簡単なんだ〜〜いい感じ〜!

読書メモ:イシューからはじめよ(1)

バリューのある仕事とは

  • イシュー度(置かれた局面での答えをだす必要性の高さ)と解の質(どこまで明確に答えがだせているかの度合い)が高い仕事
  • 解の質が高い仕事であってもイシュー度が低いと結果的にバリューのある仕事は生まれにくい(犬の道)
  • 誤:「問題かもしれない」 正:「今この局面で白黒はっきりさせるべき問題」

イシューの見極め

  • 相談できる相手をもつ(本当に受け手にとってインパクトがあるのか?)
  • 具体的な仮説を立てる(答えが出せる形になる、必要な情報と分析がわかる、解釈が明確になる ので)
  • 言葉にする
    • 主語と動詞をいれる
    • 「〜はなぜ?」という形にしない、「〜すべきか?」にする
    • 比較表現にする
  • よいイシューの条件を満たす
    • 本質的(イシューは状況に応じて変わる)
    • 深い仮説
    • 答えが出る

イシューが見つけにくい時

  • 変数を削る
  • 視覚化する
  • 後ろから考える
  • so what?を繰り返す
  • 極端な場合をかんがえる

イシューからはじめよ―知的生産の「シンプルな本質」

イシューからはじめよ―知的生産の「シンプルな本質」