体験授業 ゲームAI

講師:大森田不可止




機械学習で「じゃんけんゲーム」








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

スライドの操作

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




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

AI関連の近頃のニュース

AlphaGo



その他

AI の歴史

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

ai history

AI関連技術

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

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

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

AI words




Python

プログラム言語 Python

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

Python の特徴

  • 文法がシンプルで書きやすく読みやすい
  • 字下げ(インデント)に意味がある
  • 専門分野での実績がある
  • 実用的なライブラリで開発を簡単に高速化できる

Python で作れるアプリケーション

  • Webアプリケーション
  • デスクトップアプリケーション
  • 「組み込みアプリケーション
  • ゲーム
  • 機械学習(人工知能)」

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 で プログラムしてみる

Anaconda Navigator の起動

  • TECH.C. のPCには、Python 環境を構築してくれる Anaconda という ディストリビューション(配給物)がインストールされています。Pythonの関連アプリが様々一括でインストールされ、インストール後のアプリの追加、削除、アップデートなどは conda コマンドで簡単に管理できます。
  • スタートメニュー > プログラム > Anaconda3(64-bit) > Anaconda Navigator を起動して、qtconsole を Launch(起動) する。


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)  #標準偏差 





じゃんけんゲーム

じゃんけん

ルール: 省略

ぐー

gu

ちょき

gu

ぱー

gu

定数・判定

import random

# 定数
GOO = 0
CHOKI = 1
PAR = 2
SELECT = [GOO, CHOKI, PAR]
JANKEN = ['ぐー', 'ちょき', 'ぱー']
RESULT_LOSE = 0  # 負け
RESULT_DRAW = 1  # 引き分け
RESULT_WIN = 2   # 勝ち
RESULT = ['負け', 'あいこ', '勝ち']

# 関数
def result(player, cpu):
    if player == cpu:
        return RESULT_DRAW
    if (player + 1) % 3 == cpu:
        return RESULT_WIN
    return RESULT_LOSE      

普通のじゃんけんゲーム

def battle():
    inp = ""
    while inp not in CHECK:
        print('何を出しますか?(0:ぐー、1:ちょき、2:ぱー 9:Quit) >>> ', end= '')
        inp = input()
        if inp == "9":
            return False
    player = int(inp)
"""
    hist.insert(0, player)
    move[2] = move[1]
    move[1] = move[0]
    move[0] = player
"""

    #cpuの手
    cpu = random.choice(SELECT)
    print('あなた: ' + JANKEN[player] + ' vs ' + JANKEN[cpu] + ': cpu')

    rslt = result(player, cpu)
    if rslt == RESULT_WIN:
        print('あなたの勝ちです!')
        return True
    elif rslt == RESULT_LOSE:
        print('あなたの負けです')
        return True
    else:
        print('あいこです\nもう1回!')
        return battle() 

普通のじゃんけんゲーム

全ソースコード

ソースコードを見る: battle.py

ソースコードのダウンロード: battle.py

機械学習 じゃんけんゲーム

  • ゲーム理論によれば、じゃんけんの最適戦術は、ランダムに3つの選択肢を選ぶことです。
  • ところが、人間のプレイヤーはランダムに選ぶことができず、様々な傾向を持ってしまいます。例えば、同じ選択肢を3回続けて選ぶことは少ない、「ぐー」の次は「ぱー」を選ぶ場合が多い、などなど。
  • cpu側は、じゃんけんを繰り返しながら人間の選択肢を記録して、過去2回の選択肢から次の選択肢で確率が高いものを調べて、それに勝つ選択肢を選ぶようにしていきます。
  • 収集したデータを活用して、自動的により良い選択肢を選ぶように学習していくわけです。
    これが、最も簡単な「機械学習」です。

参考リンク: 「サザエさんじゃんけん」戦いを挑み続ける男 27年の研究、勝率は

参考リンク: サザエさんじゃんけん研究所公式ウェブサイト

記録を取り確率の高い選択肢を選ぶ

count = [[[0 for i in range(3)] for j in range(3)] for k in range(3)]
move = [-1, -1, -1]
hist = []

nBattle = 0
nWin = 0

# 出現回数が多い選択肢を選ぶ
def getMax(arr, move1, move2):
    index = -1
    maxVal = -1
    for i in SELECT:
        if maxVal < arr[move1][move2][i]:
            maxVal = arr[move1][move2][i]
            index = i
    if maxVal <= 0:
        return -1
    else:
        return index

# 出現回数を増加させる
def addCount(arr, move1, move2, move3):
    if move2 >= 0:
        arr[move1][move2][move3] += 1 

プログラマになるには

  • キーボードを操作することも、慣れないうちは大変です。プログラムも、何をやってるか良くわからない。英語が苦手、などなど。
  • どんな凄腕すごうでのプログラマでも、最初はそうでした。慣れてくるに従って、面白くなってきて、ある段階から自発的に、いろいろなプログラムを作ってみたくなります。その段階になれば、実力は勝手に伸びていきます。
  • 英語が苦手では、プログラマは苦労しますが、今は google翻訳も優秀です。それから、英語は単語の数が圧倒的に少ないです。だから、1つの単語にいろいろな意味を持たせています。その事に気付くと、英語は急に簡単に感じられるようになりますよ。