体験授業 AIプログラミング

講師:大森田不可止



Iris (アヤメ) の分類




spaceshift + space での操作が快適です。

表示が変な場合はリロードF5してください。

スライドの操作

キー操作
or lスライドを右方向に進む
or h前のスライドに移動
or j下のスライドに移動
or k上のスライドに移動
Space or n次のスライドへ垂直→水平の順に移動
Shift + spaceSpace の順序を逆にたどる。
Home最初のスライドへ
End最後のスライドへ
Esc or o概要表示
f全画面表示。Escで戻す。




AI・機械学習・ディープラーニング

今日の授業

  • 「AI」でグーグルニュース検索をかけると沢山の記事がヒットします。AI - Google 検索
  • これらの記事の中では AI は、一番広い意味で使われてますが、内容を読むと「ディープラーニング」を使った「ニューラルネットワーク」のことを AI と呼んでる場合が多いです。
  • AIは応用範囲が広く、強力なので アルビン・トフラー風に言えば、人類の歴史上、農業革命・産業革命・情報革命に続く 4th wave になる可能性を秘めています。今後、プログラマだけでなく、すべての人の常識になるだろうと言われています。
  • 今日は、各用語の違いを理解して、「ディープラーニング」のプログラムを体験してみます。
  • 初めて聞くような用語が多いと思いますが、言葉に惑わされずに、どんなものなのかを覗いてみましょう。

AI関連の近頃のニュース

AlphaGo

その他

AI の歴史

  • 1956年 ダートマス会議で、Artificial Intelligence (AI) という用語が初めて使われました。日本語訳は「人工知能」。翌年に、 人工ニューラルネットワークの萌芽である、パーセプトロンが発表されます。
  • パーセプトロンは、単純な分類問題しか解けませんでしたが、工夫された 多層フィードフォワードニューラルネットワーク が考案されます。ただし、このシステムは複雑すぎて、どう扱えば良いのかは手探り状態で、ゆっくり進歩しました。
  • 長年、華々しい成果が無かった技術ですが、ここ5年ほどで、数学的に厳密な解析手法が確立され、巨大データ処理技術を背景に ディープラーニングという手法が、現在驚異的な発展段階にあります。

ai history

AI関連技術

AI は、音声認識や画像識別、言語認識なども含めた最も広い概念を指す用語なのですが、最近のニュースなどでは、ディープラーニングことを指す場合が多い。ニュースにするには、用語が長いためと思われます。

機械学習きかいがくしゅう(machine learning)というのは、データを与えることで自動的に学習する無生物を指す用語。その中で最も成功してるのがニューラルネットワークと呼ばれるシステムで、その学習手法として成功したのが、ディープラーニングです。

大量の入力データを分析して学習するため、統計学やデータマイニング・ビッグデータの手法が流入して、発展を支えています。

AI words

ニューロン (神経細胞)

  • 最初のアイデアは、動物の感覚神経です。触覚・視覚・聴覚・味覚・嗅覚の五感を脳に伝える仕組みは、精巧なシステムです。例えば、嗅覚は新しい匂いには敏感ですが、その刺激が続くと無視するようになります。
  • この仕組をプログラムで実現しようとしたのが、ニューラルネットワークです。

  • Dendrites: (神経細胞の) 樹状突起
  • Cell nucleus: 細胞核
  • Axon: (神経細胞の) 軸索
  • Myelin: ミエリン(髄鞘を組織する脂肪質の物質)
  • sheath: さや、おおい、被覆

パーセプトロン

  • ある入力に対して、その出力を分析して「学習」する仕組みを実現するシステムを「機械学習」と呼びます。
  • 下図は機械学習の基本の1957年発祥の「パーセプトロン」の概念図です。ニューラルネットワークによるディープラーニングが成果を挙げてますが、基本構造はパーセプトロンが原点です。学習結果は「重み」が担っています。

多層パーセプトロン

  • 下図は「多層フィードフォワードニューラルネットワーク」(multi-layer feedforward neural network)、多層パーセプトロン(Multi-Layer Percepton: MLP) とも呼ばれる概念図である。
  • 隠れ層(hidden layer)のユニットは入力層と完全に結合しており、出力層は隠れ層と完全に結合してる。このように隠れ層が1つ以上存在するものを「ディープ」人工ニューラルネットワークと呼ぶ。隠れ層も含めた沢山の「重み」を学習させないといけないので、高度な技術が必要になります。AlphaGo は、21層の隠れ層を持っています。

ニューラルネットワーク

  • 隠れ層が多くなると、出力をフィードバックして学習させる事が困難になってきます。この解決のために、以下のふたつの技術が登場しました。
    1. 1986年 バックプロパゲーション(Backpropagation)。日本語訳は誤差逆伝播法。
    2. 2012年頃以降 ディープラーニング(deep learning)。日本語訳は深層学習。
  • ディープラーニングの考え方は 1980年頃からあったが、近年のデータ分析手法の発達と、計算機資源の進化とが合致して、爆発的な成果を出すに至っている。
  • データ分析手法は、近年のデータマイニングからビッグデータと呼ばれる雑多な巨大データから、意味のある情報を取り出そうとする流れです。オープンソースで制作されている Rという統計ソフトが貢献してます。例えば改札を利用した個々の乗客がどの路線のどの区間を利用したかを集計して、混雑を緩和する最適解を探すような技術です。
  • 計算機資源は、最近ではグラフィック表示を行うGPUを計算機として利用する、GPGPU (General-Purpose computing on Graphics Processing Units) という技術の発展があります。複雑な計算は出来ませんが、PCの計算能力を数十倍に引き上げることができます。




Python

プログラム言語 Python

  • Python は以前は日本ではあまり人気がありませんでした。これは、ここ10年ほどの間が移行期間として、version 2 と version 3 が両立した混乱状態に見えて、固い性格の日本人が敬遠していたためです。世界では人気言語のひとつであり続けています。近年は、AI開発言語として、日本でも人気が跳ね上がっています。
  • 機械学習に向いたライブラリが多数作成されてますので、機械学習の定番言語となっています。
  • ライブラリは、import 文で手軽に利用できます。
  • 今までは環境構築が大変だったのですが、ANACONDA というソフトをインストールすると、様々なライブラリが最初から利用できて、便利な機能も提供されてます。TECH.C. の PC には、インストールされています。

Python 情報源

公式サイト Python.orgの以下の文章を参照。チュートリアルは読み物、それ以外はリファレンスです。

Python 学習サイト

Windows の基本操作

Copyctrl + C HelpF1
Cutctrl + X RenameF2
Pastectrl + V SearchF3
Undoctrl + Z 行頭Home
Select Allctrl + A 行末End
Savectrl + S 上に1ページ移動PageUp
エクスプローラ + E 下に1ページ移動PageDown
窓の最小化・復元 + D ブラウザ 開発者ツールF12
コマンド実行 + R ブラウザ ReloadF5
タスクマネージャctrl + Shift + ESC ブラウザ 完全ReloadCtrl + F5





Python で プログラムしてみる

ipython の起動

  • エクスプローラを起動します。 + e
  • 作業用のフォルダを作成します。
  • そのフォルダでコンソールを起動します。エクスプローラのアドレスバーに、"jupyter qtconsole" + Enter
  • エディタで、myapp.py などのプログラムを書いて、コンソールから python myapp.py で実行するのが、本来のやり方ですが、今回は qtconsole で直接プログラムを入力してみる方法にします。

qtconsole

  • python 自体にもプログラム入力インターフェイスがあるのだけど貧弱なので、インターフェイスを強化した IPython が作られている。それを更に強化したのが qtconsole。
  • 文字の大きさは Ctrl + + で拡大、 Ctrl + - で縮小。
  • コピー・カット・貼り付けが Ctrl + CCtrl + XCtrl + V 複数行のコピペも可能。
  • で、入力した履歴をたどれる。
  • 「%」を頭につけたマジック関数と言われる追加機能があり、様々な操作が行える。ファイルの実行: %run ファイル名、実行時間の計測: %timeit [ プログラム ] などなど。詳細は %quickref で表示される。
  • 豊富な help。ヘルプ画面は Q でぬける。

変数

  • 最初の文字がアルファベットで、続く文字がアルファベットか数字で出来た文字列は 変数として扱える。Python では、変数自体には型というものが無くて、どんな形式でも代入できる。(関数も)
  • 数値の演算は、+ - * / // (整数割り算) % (剰余) ** (べき乗)、文字列は + (連結) * (繰り返し)。

a = 123
b = "Hello world"
c1 = True
print(10 / 3)
print(10 // 3)
print(10 % 3)
print(2**3)
print("Hello " + "world!")
print("Hello " + "world!" * 4)
            
  • 定数の機能は無いが、「大文字で書かれた変数は、定数として扱う」という暗黙のルールがある。

PI = 3.14159265358979
ADMIN_EMAIL = "omorita@xxxxx.com"

配列・辞書

  • 配列は、数値や文字列が複数順番に格納されたものです。最初の要素は0番目になります。
    
    a = [22, 33, 44, 55, 66]
    print(a[0], a[3])
    b = ["abc", "def", "ghi", "jkl"]
    print(b[2])
                    
  • 配列は順番で呼び出したの対して、辞書は名前(key)で呼び出します。
    
    dict = {"itou":64, "yamada":75, "endou":82}
    print( dict )
    print(dict["itou"])
                    
  • 辞書の中の順番は保持されないので注意。この機能は強力なため、多くの言語で採用されてますが、辞書、連想配列、MAP、ハッシュなど様々に呼ばれています。
  • 他の言語では、dict["itou"] を dict.itou でも呼び出せる場合が多いのですが、Python では使えません。

ループ

  • 変数 i が 0~4 になるまで5回繰り返す。インデント(字下げ)でブロックを表す。
    
    for i in range(5):
        a = i ** 2
        print(i, a)
    
  • range([start,] stop [,step]) と指定すると、startからstopの直前まで間隔stepでの、数値の配列を返す。なので、任意の区間で繰り返す場合は、startを指定する。
    
    li = range(1,10,2)
    print( list( li ) )
    for i in li:
        print(i)
                    
  • while は、ある条件が成り立つ間繰り返します。
    
    a = ["ok","ok","ok","ng","ok"]
    i = 0
    while a[i] == 'ok':
        print("a[{0}] is ok".format(i))
        i = i + 1
                  

関数

  • 一連の処理を繰り返し行う場合は、その処理を関数(function)として独立させると便利です。関数に渡す値を引数ひきすうといいます。省略された場合にデフォルト値を使う場合は、"=" で指定します。
    
    def printOperation(a = 10, b = 3):
        print(a + b)
        print(a - b)
        print(a * b)
        print(a / b)
        print(a % b)
                    
  • return で値を返すことができます。
    
    def add(x, y):
        return x + y
    
    print( add(3, 5) )
    
  • return は、"," カンマで区切って複数の値を返すこともできます。
    
    def calc(a,b):
        return a*b, a//b, a%b
    
    a1,a2,a3 = calc(10,3)
    print(a1,a2,a3)
                    

クラス

  • class は、変数(プロパティ)をいくつか持って、それに対する様々なクラス処理関数(メソド)がパッケージになったものです。class には、大文字で始まる名前を付けます。"__" (アンダースコア2つ)で始まる名前は、クラス内からだけアクセスできます。
    
    class Foo(object):
        def __init__(self):
            self.a = 0
        def add(self):
            self.a = self.a + 1
            return self.a
                    
  • クラスを使うときは、変数に代入します。他の言語では new クラス名 で実体(instance)を作りますが、Python では代入だけ。この時に初期化のメソド(constructor) __init__ が呼ばれます。self は、自分自身のインスタンスを指す変数です。
    
    o = Foo()
    for i in range(10):
        print (o.add())
                  

ライブラリの使用

  • Python には、膨大な数のライブラリが存在し、手軽に利用できます。特にAI関連のライブラリは充実していて、数値計算、データ分析、統計計算、GPGPU計算のライブラリが揃っています。数値計算ライブラリ Numpy を使ってみましょう。
    
    import numpy as np
    print(np.power(1.08,30))  # 8%の金利で30年借りると?
    print(np.power(2.0, 52.0/1.5)) # 1965 ムーアの法則
    print(np.sqrt(2))
    print(np.pi)
    print(np.e)
    print(np.sin(np.pi/6))
                    
  • AIでは、膨大な量のデータを扱う。それらのデータは、数字を縦横に並べた「行列」という形式にまとめられる。numpy はその行列をまとめて計算できるように設計されている。
    
    o = np.ones((3, 3))
    6*o
    o+8
    b = np.asarray([[2,3,4],[5,6,7],[8,9,10]])
    a+b
    np.exp(b)
    np.max(b)  #最大値
    np.sum(b)  #合計
    np.mean(b) #平均
    np.std(b)  #標準偏差
    

3種類の機械学習

  • 教師なし学習(unsupervised learning) … 正解なし。データのみ。
  • 教師あり学習(supervised learning) … 正解(label)付きデータ。
  • 強化学習(reinforcement learning) … 正解ではなくヒント付き。


基本用語と表記法

  • 右の図は、機械学習分野の代表的な例である Irisデータセットからの抜粋である。150枚のアヤメの花の計測データが収録されている。これらのデータは、Setosa、Versicolor、Virginica の3つの品種に分類される。花のサンプルはそれぞれデータセットの1つの行を表しており、花びらの測定データが特徴量として格納されてる。
  • データは行列やベクトルを用いて表す。花のサンプルはそれぞれ特徴行列 \(\mathbf{X}\) の行として表し、特徴量はそれぞれ別の列に格納する。

Iris の行列データ

Iris データセットは 150個のサンプルと4つの特徴量で構成されるため、150x4の行列で以下のように記述できる。

\[ \begin{pmatrix} x_1^{(1)} & x_2^{(1)} & x_3^{(1)} & x_4^{(1)} \\ x_1^{(2)} & x_2^{(2)} & x_3^{(2)} & x_4^{(2)} \\ \vdots & \vdots & \vdots & \vdots \\ x_1^{(150)} & x_2^{(150)} & x_3^{(150)} & x_4^{(150)} \end{pmatrix} \]






パーセプトロン

パーセプトロン

  • Frank Rosenblatt がMCPモデルに基づくパーセプトロンの学習規則を発表したのは1957年。
  • ローゼンブラットのアルゴリズムは、最適な重み係数を自動的に学習した後、入力信号と掛け合わせ、ニューロンが発火するかを判断する。すなわち、「教師あり学習」の「分類」に相当する。


パーセプトロン(2)

  • 左の図は、総入力 \(z=\mathbf{w}^T\mathbf{x}\) がパーセプトロンの活性化関数によって二値出力(-1 または 1)のいずれに押し込まれるかを示している。右の図は、線形分離可能な2つのクラスを区別するにあたって、それをどのように使用できるかを示している。





パーセプトロンを実装する

Python のライブラリ

Python で機械学習を実装する場合、以下のライブラリを利用する。

パーセプトロンを実装する

Code: Perceptron.py File: perceptron.py

  • クラス Perceptron の初期化には、指定された学習率 eta と、エポック数 n_iter を使用する。
  • fit メソドを使用して、self.w_ に格納されている重みをゼロベクトルに初期化。
  • その後、トレーニングデータの全てのサンプルを順番に処理し、重みを更新する。
  • クラスラベルは predict メソドによって予測される。各エポックでの誤分類の個数はリスト self.errors_ で収集する。
  • net_input メソドで使用される np.dot 関数はベクトルのドット積(内積)を計算する。

Iris データセットでトレーニング

pandas ライブラリを使用して、UCI Machine Learning Repository から Iris データセットを DataFrame オブジェクトに直接読み込む。

貴重な本家のサーバに負荷をかけないように、omorita.comサーバから読み込む。


import pandas as pd
df = pd.read_csv('http://techc.omorita.com/data/iris.data', header=None)
df.tail()
            

次に、Iris-setosa の50枚の花と Iris-versicolor の50枚の端に対応する先頭の100個のクラスレベルを抽出。クラスレベルを 1(versicolor) と -1(setosa)に変換。100個のトレーニングサンプルの特徴量の列から1列目(萼片の長さ)と3列目(花びらの長さ)を抽出して、それらのデータを特徴行列 \(X\)に代入して散布図で可視化。

Iris データセットでトレーニング(2)


                 import matplotlib.pyplot as plt
                 import numpy as np
                 y = df.iloc[0:100, 4].values
                 y = np.where(y == 'Iris-setosa', -1, 1)
                 X = df.iloc[0:100, [0, 2]].values
                 plt.scatter(X[:50,0], X[:50,1], color='red', marker='o', label='setosa')
                 plt.scatter(X[50:100,0], X[50:100,1], color='blue', marker='x', label='versicolor')
                 plt.xlabel('sepal length [cm]')
                 plt.ylabel('petal length [cm]')
                 plt.legend(loc='upper left')
                 plt.show()
            

Iris データセットでトレーニング(3)


               %run perceptron.py
               ppn = Perceptron(eta=0.1, n_iter=10)
               ppn.fit(X, y)
               plt.plot(range(1, len(ppn.errors_) + 1), ppn.errors_, marker='o')
               plt.xlabel('Epochs')
               plt.ylabel('Number of misclassifications')
               plt.show()
              

  • 横軸をエポック数、縦軸を誤分類の個数とするグラフを表示させる。
  • このグラフからわかるように、6回めのエポックで、パーセプトロンは収束しており、トレーニングサンプルを完璧に分類できてる。

データセットの決定境界

簡単なサポート関数をつくる。 plot_decision_regions.py File: plot_decision_regions.py

  • colors と markers を複数定義した後、ListedColormap を使って色リストをからカラーマップを作成する。次に、2つの特徴量の最小値と最大値を求め、それらの特徴ベクトルを使ってグリッド xx1 と xx2 のペアを作成する。これには、NumPy の meshgrid 関数を使用する。
  • 2次元の特徴量でパーセプトロンの分類器をトレーニングしたため、グリッド配列を1次元にし。Iris トレーニングサブセットと同じ個数の列を持つ行列を作成する必要がある。そのために、predict メソッドを使って対応するグリッドポイントのクラスレベルをZ を予測する。
  • クラスレベル Z を予測した後は、xx1 および xx2 と同じ次元を持つグリッドに作り変えた上で、等高線図を描画できる。これは、matplotlib の contourf 関数を使用し、グリッド配列内の予測されたクラスごとに、決定領域をそれぞれ異なる色にマッピングする。

データセットの決定境界(2)


               run plot_decision_regions.py
               plot_decision_regions(X,y,classifier=ppn)
                 plt.xlabel('sepal length [cm]')
                 plt.ylabel('petal length [cm]')
                 plt.legend(loc='upper left')
                 plt.show()