はじめの一歩
ブログをはじめました。
pythonと関連ライブラリのインストール
ufiesiaとpyainoを公開しましたが、これらを動かす前に、まずやらなければならないのは、pythonと必要なライブラリが動作する環境を作ることです。
以下に典型的なやり方を記します。もちろん、これ以外のやり方も考えられますがお勧めしません。なぜならPCのローカルの環境で直接pythonを動かしてもらうのが基本だと考えるからです。
では、そのやり方です。インストールに先立ちwindowsは管理者権限で起動してください。
先ずpythonです。pythonは https://www.python.org/ にアクセスします。そしてDownloadsのタブを開けるとその中にwindowsの項があります。
それをクリックすると、pythonのいろいろな版数のwindows installerやWindows embeddable packageが並んでいます。
その中から、自分のPC環境にあったもので、適当(適切?)な版数のものを選んでクリックするとダウンロードされます。(私の場合はWindows installer(64-bit))
これをダウンロードしてクリックすると、Install Python 3.x.x の画面が開いて、インストーラが起動します。
ここで注意しなければならないのは、Add python.exe to PATHのオプションにチェックを入れることです。そして、Customize installationを選んでください。
次の画面はオプションにすべてチェックが入っていると思いますから、そのままnextへ進んでください。
続くAdvanced Optionsは要注意です。Install Python 3.x for all users にチェックを入れてください。インストール先はC:\Program Files\Python3xxとなっていると思います。
これはこのままでも良いし、私の場合には、一つ階層を上げて、C:\Python3xxとしています。
あとはInstallをクリックすれば、インストールが始まり、うまく行ったならばその旨のメッセージの画面になるはずです。
さてそれでは次に必要なライブラリのインストールです。
Windowsのターミナル(管理者)を起動してください。これはコマンドプロンプトを管理者権限で実行しても良いです。Power Shellでも同じことは出来るはずです。
起動したら、そのプロンプトで、python -V あるいは python --version と入力してみてください。Python 3.x.x とインストールしたpythonの版数が返されるはずです。
そしてさらに、pip list と入力すると、インストールされているライブラリがその版数とともに表示されますが、まだ何もライブラリをインストールしていない時点では何も表示されません。
そこまで確認したら、いよいよライブラリのインストールです。これはpipを使って行います。
そこでその前に、一応、pip自身の更新を行います。 これは次のコマンドで行います。
python -m pip install --upgrade pip
うまくいったらSuccessfully installed pip-xx.x と返ってきます。
そうしたら、
pip install numpy matplotlib scikit-learn
と入力したら、numpyと、matplotlibと、scikit-learnの3つのライブラリが関連するライブラリとともにインストールされます。
これもSuccessfully xxx と返ってきたら大丈夫です。
確認のため、先ほど何も表示されなかった pip list を行ってみてください。インストールされたライブラリがその版数とともに表示されるはずです。
さて最後にufiesia0やpyainoです。
日新ネットワークスのダウンロード・リンクをクリックすると、Githubの a1160h\ufiesia0 や a1160h\pyaino のレポジトリに行きます。
そこで緑色のボタン <>code をクリックすると、サブ画面が開いて、その中に Download ZIP というのがありますから、それをクリックしてフォルダごとZIP形式でダウンロードしてください。
ダウンロードしたZIPファイルは pyaino-main.zip などとなっていますから、これを全展開してください。展開したpyaino-mainの中にpyaino というフォルダがあるはずです。
このフォルダを、先にインストールしたpythonの中の以下の場所に置きます。
たとえばpythonのインストール先が C:\Program Files\Python3xx ならば、
C:\Program Files\Python3xx\Lib\site-packages の中にフォルダごと置きます。つまり、
C:\Program Files\Python3xx\Lib\site-packages\pyaino というフォルダを作って、この中にpyainoの各モジュールが置かれた構成になります。
pyainoを例として説明しましたが、ufiesia0も同様で、これでインストールは完了です。
とても原始的な方法ではありますが、はじめから python がアクセスできる場所に置くことでufiesia0もpyainoも動くようになります。
ufiesia0を使ってみる。
ufiesia0の環境ができたら、さっそく動かしてみたくなりますよね?
それで顔画像認識の例を示します。記述しなければならない行数は少ないので、ここにテキストであげておきます。
ここで使う顔画像 はOlivetti Faces です。scikit-learn をインストールすると、そこからデータを入手できます。
さっそくプログラムを以下に示します。
-----------------------------------------------------------------------------------
# ニューラルネットワークで顔画像認識
from ufiesia0.Config import *
from ufiesia0 import NN_CNN
from ufiesia0 import OlivettiFaces as OF
from ufiesia0 import common_function as cf
# データを用意
x, c, t = OF.get_data()
L = OF.label_list()
# ニューラルネットワークを定義
model = NN_CNN.NN_0(40, loss='CrossEntropyError', activate='Softmax', optimize='Adam')
model.summary()
# 学習
record = []
for i in range(100):
y, l = model.forward(x, c)
record.append(float(l))
model.backward()
model.update(eta=0.003)
print(i, l)
# 経過表示と識別テスト
cf.graph_for_error(record)
cf.test_sample(OF.show_sample, model.forward, x, t, L)
-----------------------------------------------------------------------------------
はじめに、ufiesia0の必要なモジュールをimportします。
次にデータを用意しますが、ufiesia0.OlivettiFaces に定義されたget_data()を使えば一発で用意できます。
Olivetti Facesは40人の表情や向きが異なる合計400枚の顔画像です。
続いてニューラルネットワークのmodelを定義します。
ここでは、NN_CNNにあるひな型の中から、最も単純なNN_0を選びました。
このとき、出力の本数=40(40人のうち誰か?)や、損失関数、活性化関数、最適化関数も指定します。
続いて学習です。
ここでは全400枚を一括してバッチ学習で100回ほど回しています。
ニューラルネットワークの学習は、forwardで結果と損失を出し、backwardで損失にもとづく勾配を求め、その勾配に応じてupdateということを繰り返して、
はじめはでたらめだった結果が次第次第に正解に近づいていきます。
学習が終わると、その学習の経過をグラフで確認します。うまく学習が進んでいれば、時間経過とともにエラーが減少して0に近づく様子が描かれると思います。
また、最後に画像を確認しながら、それをニューラルネットワークが誰と判定するかを確認します。
ここに示したプログラムは記述量を小さくするようにアレンジしたものなので、
学習はすべてのデータを使っていて、最後の識別テストでも同じ画像の1つを指定して判定するだけですが、
データを学習用と、検証用に分けて、検証用は学習に使わずに、ニューラルネットワークにとって、初見の状態で判定させれば、
はじめて見る写真画像を、判定できるかどうかのテストもできます。
ともかくも、まずは動かしてみて、そこから先に進むのが、一番の近道だと思いますので、ぜひやってみてください。
pyainoを使ってみる。
先にufiesia0を使った顔画像認識のプログラムを示しましたが、pyainoでも同じようにプログラムが作れます。
この例では、ufiesa0をpyainoに書き換えるだけでそのまま動きますが、少しばかりufiesa0にない機能を使っています。
-----------------------------------------------------------------------------------
# ニューラルネットワークで顔画像認識
from pyaino.Config import *
from pyaino import NN_CNN
from pyaino import sklearn_OlivettiFaces as OF
from pyaino import common_function as cf
# データを用意
x, c, t = OF.get_data(normalize=True)
L = OF.label_list()
OF.show_multi_samples(x[:100])
# ニューラルネットワークを定義
model = NN_CNN.NN_0(40, loss='CrossEntropyError', activate='Softmax', optimize='Adam')
model.summary()
# 学習
record = []
for i in range(100):
y, l = model.forward(x, c)
record.append(float(l))
model.backward()
model.update(eta=0.0003)
print(i, l)
# 経過表示と正解と結果のマップ表示と識別テスト
cf.graph_for_error(record)
cf.confident_map(model.forward, x, t, L)
cf.test_sample(OF.show_sample, model.forward, x, t, L)
-----------------------------------------------------------------------
ここでは、ufiesa0になくてpyainoにある機能を2つ使っています。
1つは、show_multi_samples()で、Olivrtti Facesの顔画像のサンプルをまとめて表示できます。
もう一つはconfident_map()で、正解値と結果の一致具合を可視化できます。
ホームページ(ブログ)上での表示について
ご存知のように、pythonはインデントが意味を持ちます。しかしながら、ホームページ上にプレーンテキストで記述したものは、空白は詰められてしまうようです。先日の記事を見ると、このホームページ上の表示方法により、インデントが外れてしまっているようです。なので私のブログから、その表示に従ってプログラムを書くか、コピペして作るとエラーします。対処は簡単です。
for i in range(100): の後に続く y, l = model.forward(x, c) から print(i, l) までの5行の行頭にインデント(標準は空白4つ)を挿入してください。
と書きましたが、 先日、この対応が可能になりました。それで、プログラムの部分の表示を直しました。
しかしpythonでインデントが意味を持つことはなんら変わりませんので、インデントは要注意です。
(追伸)入力データについて
先に示したプログラムでは、ニューラルネットワークを動かしてもらうことを優先し、また、ufiesia0とpyainoの互換という点からも、最も簡単な単層のニューラルネットワークをmodelとしました。
先のプログラムが完了したのちに、スクリプトの画面で、x.shapeと入力すると、(400, 4096) と表示されます。これは1枚の画像が4096の大きさで、それが400枚あるということを意味します。この4096というのは4096個の数値の並びです。そしてそのそれぞれの数値は画像のピクセルの明るさを示しています。単純に4096個並べただけなので、元画像の縦横の関係はその並びからは分からなくなっています。実は、元画像は64×64の大きさであって、連続する64個の並びは横であり、64個先の数値を拾っていくとそれが縦の数値の並びです。それを4096の大きなベクトルにしてニューラルネットワークに入力しているのです。
畳込みを行うCNN
64×64の画像を4096の大きさのベクトルにしてしまうと画像の縦横の情報が失われるのは先に述べた通りです。それで、元の64×64のまま扱えないかということになりますが、それを畳込みによって行うことができます。pyainoのNeuronにはConv2dLayerという2次元の畳込みを行う層を定義しています。そして、そういう畳込み層を含むニューラルネットワークをCNNと呼びます。NN_CNNには様々なニューラルネットワークのひな型がありますが、ここではその中で最も簡単なCNNとして、畳込み層1つと単純なニューロン層1つで構成されるニューラルネットワークCNN_cを使います。もちろん、これ以外のより複雑なCNNもありますが、それは扱う問題に応じて選ぶべきでしょう。いずれにせよ、pyainoのNN_CNNに定義されているものから選んで使うならば簡単に動かすことができます。
modelをCNNにすると、当然ながら入力する画像は元の形状のままとする必要があります。もちろんそれが目的なのですから。
そのためには、x, c, t = OF.get_data(normalize=True)でデータを用意する際に、データの次元数を3ないし4に指定する必要があります。ここでは、ndim=3としましょう。さっそくプログラムを示します。先のプログラムからの変更箇所はわずかです。
-----------------------------------------------------------------------
# ニューラルネットワークで顔画像認識
from pyaino.Config import *
from pyaino import NN_CNN
from pyaino import sklearn_OlivettiFaces as OF
from pyaino import common_function as cf
# データを用意
x, c, t = OF.get_data(ndim=3, normalize=True)
L = OF.label_list()
OF.show_multi_samples(x[:100])
# ニューラルネットワークを定義
model = NN_CNN.CNN_c(40, loss='CrossEntropyError', optimize='Adam')
model.summary()
# 学習
record = []
for i in range(100):
y, l = model.forward(x, c)
record.append(float(l))
model.backward()
model.update(eta=0.00005)
print(i, l)
# 経過表示と正解と結果のマップ表示と識別テスト
cf.graph_for_error(record)
cf.confident_map(model.forward, x, t, L)
cf.test_sample(OF.show_sample, model.forward, x, t, L)
-----------------------------------------------------------------------
この場合には x.shape=(400, 64, 64) となっています。学習率は先に示したような単純なNNよりも小さめが適切です。ともかくも、これでCNNを動かすことができますが、ここで示したケースでは、CNNの威力を感じることは難しいでしょう。しかし、データを学習用と、検証用に分けて、検証用は学習に使用しないようにする、すなわち、modelにとって覚えのないもの=初見の画像とする、あるいは、問題自体がもっと難しい、そのようなより実践的な場合においては、明らかな差となってくるでしょう。
ブログのご感想やAIフレームワーク「ufiesia」「pyaino」に関するお問い合わせは、
問い合わせフォームからお送りください。
- お問い合わせ内容によりましては、ご期待に添えない場合やご回答が出来ない事が有ります。