TIM Labs
数値計算処理をするとき、やたらにforループのネストが増えたりする。いかにも計算している気になるかもしれないが、元の数式が複雑になってくると、それをコードに落とすのがどんどん大変になってくる。

そうなると「数式をそのままプログラム中に書きたい」となってくる。

完全にそのままは使える記号の種類とかで無理があるが、数式にできるだけ近い形でプログラムしたくなる。そうすると、プログラムも短くなり、バグの入る余地が減る。それ以上に、プログラムが圧倒的に見やすくなるのだ。

ほぼ数式どおりに書ける数値計算用のプログラミング言語がいつくかあるようだが、前回紹介したOctaveもその1つである。
人工知能で機械学習などをやろうとすると、大量のデータを行列にぶち込んで、行列演算をごちゃごちゃやることが非常に多くなる。
ということで、今回は、Octaveの行列関連の演算を紹介しようと思う。

行列は、[]の中に、行単位で数字を空白またはカンマ(,)で区切りながら並べ、行をセミコロン(;)で区切る。 転置行列は、肩にTの代わりにアポストロフィ(')を付けるだけでOK。

>> A = [1 2 1; 2 1 0; 1 3 2]
A =

   1   2   1
   2   1   0
   1   3   2

>> B = A'
B =

   1   2   1
   2   1   3
   1   0   2

以下にAの逆行列を3つの方法で計算してみた。行列の-1乗がちゃんと逆行列になってくれる。
eye(3)は、サイズ3の単位行列で、これを行列Aで割っても逆行列が求まる。
 
>> inv(A)
ans =

  -2.00000   1.00000   1.00000
   4.00000  -1.00000  -2.00000
  -5.00000   1.00000   3.00000

>> A ^ -1
ans =

  -2.00000   1.00000   1.00000
   4.00000  -1.00000  -2.00000
  -5.00000   1.00000   3.00000

>> eye(3) / A
ans =

  -2.00000   1.00000   1.00000
   4.00000  -1.00000  -2.00000
  -5.00000   1.00000   3.00000

本当に逆行列になっているか、行列Aとの積を計算してみよう。
 
>> (A ^ -1) * A
ans =

   1.00000   0.00000   0.00000
   0.00000   1.00000   0.00000
   0.00000   0.00000   1.00000

いきなり逆行列を求めてしまったが、ランク、行列式を求めてみよう。 さらに、固有ベクトル、固有値を求めてみる。
 
>> rank(A)
ans =  3
>> det(A)
ans = -1.0000
>> [V,L] =eig(A)
V =

   0.50393   0.47733   0.10741
   0.34334  -0.64817  -0.46439
   0.79257   0.59332   0.87909

L =

Diagonal Matrix

   3.93543         0         0
         0  -0.47283         0
         0         0   0.53740

こんな感じで、行列演算が簡単にできる。
ここでは、説明のために、1つ1つ示したが、これらの演算を連続してやっている数式は、Octaveなら1つの数式として書ける筈だ。

Octaveは、数値計算が便利にできるだけではなく、計算結果を3次元表示することもできる便利な道具である。なので、今後数回に渡って、色々紹介しようと思っている。
人工知能プログラミングでは、大量の数値解析が必要になるので、それをいちいちプログラムしていたら面倒でしかたがないので、何らかのソフトを利用して楽をするわけだが、その中の有力なプログラミング言語としてMATLABがある。でも、これは有料である。
やはり気楽に使うためには、オープンソースであって欲しい。実はMATLABと互換性のある GNU Octave があるので、これを使ってみよう。

gnu-octave-screenshot.pngインストールは適当にやれば簡単に終わるのだが、プログラミング言語なので、それなりに勉強しないと分からない。
行列の扱いが簡単で、転置行列、行列式、逆行列などすぐにできる。
それだけではなく、3次元表示も可能である。

とりあえず簡単な入門をネットで探していたら、WIKIBOOKSの中に、Octave Programming Tutorialがあった。
どうしても日本語という人には、東海大学稲葉研究室の Octave入門 が良いかもしれない。
日本語の本で学習したい場合は、ネットで探してみよう。何冊も出ているようであるが手元に無いので評価はしていない。

しかし、今の時代、ネットを使ったビデオ学習にしよう、その方が楽ではないか、正道ではないか。
YouTubeで探したら、Octave Tutorials として、全35本のビデオでまとまっている。
さらに、これは、カリフォルニア大学アーバイン校で行われたan introduction to computer programming courseである。講師はPaul Nissensonである。
ということが分かったので、これは見るしかあるまい。無料でUCIのコースを受講できるチャンスだ。

内容的にはTutorialなので、難しいことは何も無かった。
Tutorialなので、あまり詳しいところまでの説明はしていない。
でも、一番困ったのは、プログラムを実行している画面の文字が画面の解像度に比べて小さくて、文字の記号が判別できない。まあ、音声が分かれば何を遣っているかは全部わかるのだが、そこだけが問題だった。

でも、よく考えてみると、これはものすごく良い英語のリスニングの勉強になった。
今までは英語をいい加減に聞き流しながら、画面だけを見ていたのだが、このビデオではまったく逆になってしまったのだ。まったくの想定外だが、想定外の学習効果が期待できる一石二鳥の教材だ。


人工知能ブームで、機械学習やら深層学習の説明がネット上にはゴロゴロしている。
しかし、丁寧に、大学生はもちろん、高校生くらいなら十分に分かるように説明しているものは少ない。

data-school.pngそれで、日本語だけで探すのはあきらめて、英語で探すと色々見つかったが、その中で一番丁寧な説明をしていると思われるものを今回は紹介する。

data school というサイトには、データサイエンス関連の色々な情報が用意されている。

実際に見てみたのは、scikit-learn だけなのだが、たぶん他も丁寧hqdefault.jpgなのではないかと予想している。
scikit-learn は、pythonで機械学習をするとき非常に良く使う便利なライブラリなのだが、このビデオでは、機械学習のことも説明しながら、ライブラリの説明もしてくれるというものでるので、事前の準備は何もいらない。

scikit-learn ビデオは9本で、合計4時間もある。さらに、textからの機械学習の2時間40分の長い長いビデオが付録でついている。

それぞれのビデオには、対応した notebook がGitHub上に用意されている。
noteは、単なるメモではなく、ビデオで実演してくれる内容、プログラムが全て載っており、自分の
IPython上にnotebookのプログラムをコピペしながら実行することで簡単に確認(体感)できる。
説明は、これ以上ないほど細かいステップで行われるので、理解はとても容易だった。

説明がていねい過ぎて、考えを飛躍しないといけない箇所がないのが不満になるかも知れない。
これだけていねいに、ビデオおよび資料を用意するのは恐ろしく大変だと思う。LearningPython.gif

日本でも、色々な分野のビデオや解説書がこのくらいのていねいさで作られれば、誰でも容易に人工知能、機械学習を習得できると思うが、残念ながら日本では短いビデオ、薄い本であることが重視され、困った状態だ。
専門書は、1000ページあるのが普通という世界にならないものだろうか。
たとえば、右の"Learning Python"というPythonの入門書は、1600ページもある。
日本語版は版が古く、800ページしかない。もう英語版で読むしかないだろう。

なお、このビデオ教材の付録のtext処理のビデオは2時間40分ととても長いので、まだ見ていない。


人工知能系のプログラムは、実はとても計算量が多いので、プログラムが効率がよいかどうか常に気にしておく必要がある。

時間を計測するのに、自分で、対象範囲の前後でシステムの時間を読み取り、差を取るということで求めることはできる。でも、そんなことをしなくても、Pythonには時間計測の仕組みが用意されている。

以下では、リストに追加するときに、insertとappendでどのくらい差が出るかを計測してみたものだ。計測する部分は、それぞれ関数にまとめてある。

import timeit

def insfirstfunc(n):
    a = []
    for i in range(n):
        a.insert(0,i)

def inslastfunc(n):
    a = []
    for i in range(n):
        a.insert(len(a),i)

def apdfunc(n):
    a = []
    for i in range(n):
        a.append(i)

for i in range(1000,10001,1000):
    t = timeit.Timer("insfirstfunc(i)","from __main__ import insfirstfunc,i")
    t1 = t.timeit(number=1000)
    t = timeit.Timer("inslastfunc(i)","from __main__ import inslastfunc,i")
    t2 = t.timeit(number=1000)
    t = timeit.Timer("apdfunc(i)","from __main__ import apdfunc,i")
    t3 = t.timeit(number=1000)
    print("%6d  t1=%10.6f  t2=%10.6f  t3=%10.6f" % (i,t1,t2,t3))

timeitをインポートしておいて、timeit.Timerでタイマーを生成している。
Timerの第1引数に実行したいことを文字列で書く。ここには、変数などが含まれてもよい。
第2引数に、"from  __main__  import"の後ろにインポートしたいものを並べておけば大丈夫なようだ。

Timerを作ったら、実際の時間計測を作ったTimerオブジェクトのtimeitメソッドで計測できる。引数に number=繰り返し回数 を指定することができる。とくに短時間の計測の場合、システムの状態に大きく依存してしまうので、なんども繰り返し実行すると誤差が減る。

詳細はマニュアルを参照して欲しい。

iPython3 で実行してみた結果を以下に示す。

In [1]: %run timeit
  1000  t1=  0.395643  t2=  0.204404  t3=  0.073373
  2000  t1=  1.217943  t2=  0.423568  t3=  0.153751
  3000  t1=  2.477653  t2=  0.639693  t3=  0.238761
  4000  t1=  4.179113  t2=  0.859387  t3=  0.316046
  5000  t1=  6.390812  t2=  1.081363  t3=  0.400768
  6000  t1=  9.033100  t2=  1.297038  t3=  0.481604
  7000  t1= 12.073041  t2=  1.506441  t3=  0.561811
  8000  t1= 15.538109  t2=  1.731817  t3=  0.645874
  9000  t1= 20.012774  t2=  2.071590  t3=  0.771902
 10000  t1= 24.719389  t2=  2.313333  t3=  0.866832

In [2]: 

appendが一番高速で、insertで最後に挿入するのは3倍程度遅くなる。 そして、insertで最初に挿入するのは、O(n**2)のオーダーで遅くなっているのが分かる。
appendで済むなら、insertを使うのはやめるべきなのだ。

timeitを使うことで、big-O がどの程度か簡単に調べることができる。

前回のAngular2入門 Component編 その1 では、 Componentの基本的な使い方について紹介いたしました。

今回は以下の様な2つのComponentを作成し、お互いにデータのやり取りをする方法を紹介致します。

HelloComponent_boushoatnohua.png

  • 今回作成するサンプルについて
    • app Component と custom-button Componentの2つを作成する
    • app Component は テキスト入力欄 を持っている
    • テキスト入力欄の値と、custom-button Component内のボタンのラベルは同じものを表示する
    • custom-button をクリックすると、Consoleに今表示しているボタンのラベルを出力する
    • custom-button をクリックすると、親Component(=app)にボタンが押されたことを通知する
    • app Componentは、custom-button からのクリックイベントを受け取り、Consoleにメッセージを表示する
6月30日のPythonのe-learningを試してみたで、interractivepython.orgの用意しているe-learning How to Think Like a Computer Scientist: Interactive Edition を紹介した。
タイトルからは、これを終えるとコンピュータ科学者のように考えることができるということだが、実際にはごく普通のPythonの入門コースだった。再帰が出てきて、オブジェクト指向をちょっとかじってオシマイだった。

これだけでは、プログラムが組めるようにはならない。
ということで、この続き、より高いレベルのコースは無いかと探したら、用意されていた。
Algorithms and Data Structures using Python

「アルゴリズムとデータ構造」というタイトルは昔から非常によく見かける。

アルゴリズムの説明が中心なのだが、その前に、ちゃんと計算量、ビッグ・オーについての説明があった。
Pythonには配列はなく、何でもリストにして扱うので、柔軟性は良いのだが、リストの特徴を考えずにプログラムを組むと激遅になってしまう。そのあたりを、実際にリストの基本操作1つ1つについて丁寧に説明してある。

Big-Oを求めるだけでなく、実際に時間計測をして、きちんと体感するようになっている。
そのために、timeitモジュールを使って計測し、アルゴリズムの比較をしている。
プログラム内の小さな部分の処理時間を計測するには、timeitはとても便利に出来ているのだ。
でも、timeitについては今回は説明を省略するので、今すく知りたい場合は自分で調べてください。

まだ一部しか読んでいないが、最後はツリーやグラフのアルゴリズムまで紹介しているようだ。
ここまでやれば、まあ簡単なデータ構造は操れるようになると思う。

演習問題の形式が入門編とは違っていた。
入門編では、問題毎にブラウザ上で用意されているプログラムを修正したり、ゼロから書いたりであったが、アルゴリズム編では、演習問題は問題文だけになっていて、自分のPython環境でプログラムを作るようになっている。
問題によっては計算量が多かったりして、ブラウザ上で実行させるのが困難な問題も多い。また、ファイル入出力などいろいろ行う場合、ブラウザ上では制限があり過ぎてできない。
それよりも、もうブラウザ上でのプログラミングを卒業し、実際のPythonのプログラム開発環境で課題をやりましょうということらしい。
KD0408-170.jpg
アルゴリズムについて本格的に勉強したければ、やはりMITのアルゴリズム入門だろうか。
イントロダクションとあるので入門書と思ってはいけない。1000ページを超える本で、延々と書かれている。価格もとても立派で、税抜きで14,000円である。
この本を教科書に使っているMITの授業のビデオも多数(何年分も)公開されている。
とくに、2005年のビデオは、原著者らが講義している。
その後の同じ内容で講師が異なるものがいくつも公開されている。
ビデオが全部あるだけではなく、音声をテキストにしたものもあるので、英語の聞き取りが苦手でも大丈夫になっている。さらに、大量のドキュメントも用意されていて、至れり尽くせりで、なおかつ無料である。


すでにhomebrewでDockerをインストールしている場合は以下を実行するとDocker 1.12にバージョンアップする。

brew update
brew upgrade

Docker公式ドキュメントを見てもDocker.dmgをダウンロードしてインストールする方法しか書かれていないし、homebrewでインストールしたDockerでdaemonを動かす方法がどうしても分からなかった。

いろいろ検索した結果、以下を発見したのでぜひ共有したい。

brew cask install docker

上記を実行すると/Applications/Docker.appがインストールされ、Docker.appを起動するとdeamonも起動するようになる。もうVirtualBoxは不要なのだ。

https://github.com/eyasuyuki/docker-ansible/blob/master/install.yml

centos:
  image: centos:latest
  container_name: centos7
  entrypoint: tail -f /dev/null

Docker Composeで上記を起動すると、VirtualBoxではなくxhyve上でDockerコンテナが起動する。

docker-compose -f install.yml up -d
docker-compose -f install.yml ps
 Name          Command        State   Ports 
-------------------------------------------
centos7   tail -f /dev/null   Up            
docker exec -it centos7 bash
[root@0635f2244b2b /]# uname -a
Linux 0635f2244b2b 4.4.15-moby #1 SMP Thu Jul 28 22:03:07 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

こりゃ便利。

先日、OpenSSH 7.3 がリリースされましたが、

http://www.openssh.com/txt/release-7.3

新しい機能として、ProxyJump設定パラメータと、これに対応する「-J」コマンドラインオプションが加わっています。


以前の記事(OpenSSH のNetcat modeを使う)でも書きましたが、netcat モードができたから、ncとかconnect 使わなくても踏み台越えが楽になりましたが、さらに記述が簡素化されました。

使い方はこうです。

ssh -J user@fumidai user@innerhost

複数台踏み台ホストを経由する場合には、

ssh -J user@fumidai01,user2@fumidai02 user@innerhost

と複数の踏み台ホストをカンマ区切りで記載すれば、複数の踏み台を経由したホストにも簡単に接続することが可能です。


ssh_config に記述する場合には、

Host *.hogehoge.ugauga
          ProxyJump user@fumidai01,user2@fumidai02

と記載しておけばOKです。

すでに、各OSでは7.3パッケージをリリースしているようですので、使ってみた下さい。
コミッターはきっとロシア人とか...後で調べておきます(苦笑)

Angular2は、コンポーネント志向なJavascriptフレームワークです。

画面一つ一つの要素を部品化しコンポーネントとして切り出すことで、保守のしやすいソースを記述することができます。

今回は、Angular2の基本的な機能であるComponentの使い方を説明いたします。

今年3月、グーグル・ディープマインドの人工知能囲碁プログラムアルファ碁と、世界最強の囲碁棋士イ セドルの対戦が行われた。全5局の対戦で、賞金として百万ドルがかかっていた。
試合前の予想では、イセドルが勝つだろうとの予測が多かったが、結果はアルファ碁の4勝1敗に終わった。

現在のゲームの中では最も難しく、まだ10年くらいは人工知能はトップ棋士には勝てないだろうと言われていた。
それが、多くの人の予想に反して、アルファ碁の圧勝になってしまった。
これを契機に、知的ゲームだけでなく、人間のあらゆる知的な作業が人工知能に取って代わられるのではないかという危機感が急に沸いてきた、あるいは現実味を持ってきたと思った人が激増し、人工知能について考えざるをえない風潮になったと思う。

さて、これだけ有名になってしまった歴史的な試合だったので、インターネット上に多数の情報が存在する。
また、試合のビデオは5試合ともYouTubeに存在する。
Match 1 - Google DeepMind Challenge Match: Lee Sedol vs AlphaGo (第2局以降省略)alha-go (279x400).jpg

技術的なことも含めて、ネット上に大量に情報はあり、さらにNatureに記事も載り、さらに様々なところで取り上げられた。
そんな中、7月28日に、東京創元社から、『アルファ碁 vs イ セドル』という本試合の解説書の翻訳が出た。
帯には人工知能学会の前会長の松原氏の言葉「人工知能ではなく、囲碁棋士を内心応援していました」とあるが、この本、人工知能の解説書ではない。
多数の棋譜があり、アルファ碁の手も、イセドルの手も、さらには解説者の考えた変化などもかなり細かく解説されている。また、プロ棋士たちが、この試合の進行をどのように見ていたかもいろいろ書かれていて興味深い。

対局のレベルは高く、アルファ碁の打った手は良くない手と思っていたら、手が進むに従い非常に良い手だったということが何度も出てくる。もはやプロ棋士も判断に困る程度のレベルになっていることが分かる。

でも、アルファ碁の打った手が全てすばらしいかったかというと、そうではない。私にさえ良くないと分かるような手もときには打つようだ。実際、バグにより評価を間違えて変なところに打ってしまったこともあるようだ。
つまり、まだアルファ碁は発展の途中で、まだ何段階か強くなりそうな印象を受けた。

私も、2020年頃までは、人工知能が勝つのはないだろうと思っていたのだが、グーグル・ディープマインドは膨大なリソースをつぎ込んで、数年の時間を乗り越えた感じである。毎年毎年かなりのペースでCPUやGPUの性能、とくにコア数など並列処理能力の向上が著しいので、そのあたりをお金で数年縮めることは普通にあるだろう。

それに、人工知能は疲れない。対戦相手が人間だと練習が限られるが、対戦相手もコンピュータにしてしまえば、24時間連続で強化学習が可能になる。こうして、一度枠組みができてしまうと、一気に強くする手立ては存在する。

さて、ちょっとハード的な話を書いておこうと思う。情報は色々あるのだが、試合前に出されたアルファ碁の紹介記事
AlphaGo and AI Progress  2/28/2016 には、アルファ碁の強さと、ハードウェア資源についてのグラフなどもあり興味深い。
この記事によると、アルファ碁が非常に手強い相手だということだが、どこまで信じればよいのか不明であった。
アルファ碁は色々なバージョンがあるようで、最大スケールの AlphaGo Distributed では、280GPU、1920CPUで動くようだ。

この試合以降、囲碁ソフトに深層学習を入れたものが増え、ますます強くなったようだ。
UEC杯コンピュータ囲碁大会は毎年電気通信大学で行われており、優勝プログラムが何子か置いてプロに指導碁を打ってもらうという風になっている。来年春の第10回記念大会では大きな変化が起きるかも知れない。


最近のコメント