巷では一時期流行になっていた(今はあまり騒がれなくなった?)ディープラーニングとやらに挑戦してみました。
一度システムを構成できてしまえればいろいろ改造して「ああなるほど!」となるのだけど、IT系無関係の僕には「ディープラーニング?ニューラルネットワーク? なにそれ?おいしいの?」状態だったので見るもの全てが新鮮で構築が難しい世界・・・。
Webでの情報もあるんだけど、やはり一般的に普及しているものではないのでJavaの使い方とかpythonの使い方のようにさっさとググれないし、ググる用語が解らない!ググっても筆者の書いている用語がまたサッパリ理解できないというループに陥った。
てぇことで、同じように困っている人がいると思うので用語とかわかりにくかった事を記録として残しておくことにしました。ありがたく思ってー!(笑笑)
まず初めにディープラーニングを手軽に扱うためのパッケージ情報
0からディープラーニングライブラリを作る変態様もいるが(理系の人が適切な書籍を読んで理解すれば3〜6ヶ月くらいで0から完成出来るレベルだそう・・・)、初心者にはまず無理!
↓中でもこの本が大人気でこれさえ理解できれば0から作れるそうな。
初めて手軽に扱えるパッケージを探すと、まあ情報錯綜で迷う迷う。
そのなかでも、
有志の研究科たちが共同開発したというTheano(テアノ)、日本での利用者が多く、情報が集めやすいと聞くChainer(チェイナー)、天下の大企業Google様が開発したTensorFlow(テンソルフロー)というパッケージがとにかく有名で情報も多いらしい。
けど上記のパッケージも初心者には扱いにくい!ということでさらに「人に易しく」をモットーに開発されたラッパーライブラリが提供されている。
それがKeras。Kerasは現在TensorFlowとTheanoに対応している(将来的にはもっと増やす予定らしい)。
現時点ではデフォルトでTenserFlow対応になっているようだけど、少し前まではTheanoだけだったらしい。このへんがWebの情報でややこしいところ。
で、Kerasが使っているパッケージ(TensorFlowとかTheanoとか)のことを「バックエンド」と呼ぶそうな。
けど、Kerasもまだまだ開発途上だそうで設定項目がバージョンによって変わっていたりする(ぜんぜん人に易しく無い感が・・・)
さて、僕はバックエンドにTensorFlowを選ぶことにした。
理由は単純に、両方動かしてみてTensorFlowの方が初回起動が速かったから。
実際のKerasのインストールやらサンプロコードの扱いは他のサイトに委ねるとする。
(バージョンが違えばインストール方法が違うから、だいたいのパッケージはpipでインストールできるらしい。「keras インストール pip」←検索)
kerasのサンプルコードによく「MNIST」というのが出てくる。
これは、手書き文字を機械学習できますよーっていうサンプルデータが大体どのパッケージにも入っているので、それの分類するためのコードやサンプルのこと。
「keras MNIST」で検索すると大量のサンプルコードが出て来るので書き方も割愛。
※サンプルコード動かせなかったら本でも買ってとりあえずサンプルだけは動かせるようにしてください。
↓この本の人気が高いがkerasのバックエンドはTheanoのようだ。(違いはよく解らない)
で、サンプルコードが無事に動いたら
「へー!すっご!で!?結局どーやって自分の作りたいデータを入力するのさ????情報無さすぎ」ってなると思う。
僕もここからなかなか良い情報を見つけられずにいた。適当なリストを作って突っ込んでみて理解不能なエラーいっぱい吐かれて心が折れかけた。
(やっぱり人に易しくない・・・)
結論から言うとkerasへのデータ入力は、numpy配列という配列に入れたデータを扱うことになるらしい。
(僕はリスト形式だと思い込んでいて失敗した。)
「numpy配列」で検索すると機械学習に関するページが沢山見つかると思う。それだけ機械学習にはnumpy配列が重要ってこと。
(なんならnumpyだけで人工知能の構築が出来ちゃうらしい)
numpy配列はPyhonのリストとは扱いが違うが、例えば
p_list = [1,2,3,4,5]
ってーリスト形式なら
n = numpy.array(p_list)
で簡単にnumpy配列に変換できる。
そして、numpyで便利なのが物理的な「次元」という概念の多次元配列が簡単に作り替えられること!(機械学習では10次元とか100次元とかサラッと出て来るけど、ここで述べている物理(空間図形)的な時間とか立体とかの「次元」や「多次元配列」としての次元と、後で述べる「機械学習での次元」は意味合いが違うことに注意)
例えば1次元配列は
[ 0 1 2 3 4 5 6 7 8 9 10 11]
2次元
[[ 0 1 2 3 4 5]
[ 6 7 8 9 10 11]]
3次元
[[[ 0 1 2]
[ 3 4 5]]
[[ 6 7 8]
[ 9 10 11]]]
4次元
[[[[ 0]
[ 1]]
[[ 2]
[ 3]]]
[[[ 4]
[ 5]]
[[ 6]
[ 7]]]
[[[ 8]
[ 9]]
[[10]
[11]]]]
これは「物理(空間図形)的な次元」の意味を込めた多次元配列ですね、けどこれを頭で考えてて入力するのって大変!
まあ、こういうことがnumpyなら[何列,何列]と書いていくだけで一発で変換出来るんです。
上記の次元を出すコード
import numpy as np #numpyをnpとして扱いますよー!宣言
p_list = range(0,12) #0〜11までリストに格納
n = np.array(p_list) #ここでnumpy配列に変換っ!
print('1次元')
print n
print('2次元')
print n.reshape([2,6])
print('3次元')
print n.reshape([2,2,3])
print('4次元')
print n.reshape([3,2,2,1])
というように多次元配列が簡単に使えるというのです。
これをkerasに入力する時にサラッと扱うので下記の機械学習での「入力次元」と混同しちゃうのです。
えと、先に結論を言っちゃえば、機械学習での「次元」ってのは「ベクトル」のことです!
この説明で理解できちゃう人は以下を読む必用は無いと思われます。
さて、機械学習で言う入力次元ってのは、少し違っていて画像でいうなら縦横のピクセル数を言うそうです。
例)100×100pxの2次元画像を扱うなら「100次元×100次元=10000次元のデータ」と言うような感じ。
どういうことかというと、
機械学習の基本型サンプルデータ(チャート等の単純な数値のデータ)は物理的な多次元のデータでも、一旦フラットな状態、1つのまとまったデータを1次元配列にして入力するのです。
[1.0, 4.9, 3.2, 6.4, 2.0]
↑のような数列型(1次元配列で5個の数値)のことです
実際の入力は1次元配列なんだけど、これらの数値を一纏めにしたものを「ベクトル」と呼び、この一纏めの数値を機械学習で扱うので、上記例の数列は5次元のベクトルデータとして扱われるそうです。
ベクトルは、中学?の物理の授業で出て来ますよね。
2次元のベクトルはこんな感じ
3次元空間のベクトルならこんな感じ
しかし、ここでは単純に「xに多数の数字を当てはめたもの」と見ておきましょう。
人間には3次元以上のベクトルデータは理解困難ですけれど、機械学習でのベクトルは3次元以上のデータも2次元のベクトルも同じベクトルデータとして扱います。
なので先述例の、100×100pxの2次元画像は「100次元×100次元=10000次元のベクトルデータ(10000個の数値を一纏めにしたもの)」なのです。
↑
(このあたりがなかなか理解出来なかった・・・ずーっと配列の次元のことだと思って混乱してました)
さらに!
Kerasに入力するデータは「0〜1の数値に正規化」といって、0~1の間の値で表現するそうで、
例えば上記の
[1.0, 4.9, 3.2, 6.4, 2.0]
という配列ならば1.0を0.0、6.4を1.0としてその間の数値は1.0以下で表現します
[0.0, 0.7222222222222222, 0.40740740740740744, 1.0, 0.18518518518518517]
このような数値を手入力するのは大変なので便利なライブラリの機能を使ったり、簡単な自作関数を用意したりします。
(scikit-learnの機能を使った例)
from sklearn.preprocessing import MinMaxScaler
ms = MinMaxScaler()
X = ms.fit_transform(X)
(自作コードの例)
def minmax(data):
lst = []
x = max(data)
n = min(data)
mx = x - n
for d in data:
d = d - n
d = d / mx
lst.append(d)
return lst
X = minmax(X)
このように、機械学習にはいろいろと入力データのお膳立てが必用なのでまだまだ一般に普及しないんだろーなーと思いました。
次回は、kerasに入力するデータとターゲットのお話です。