2017年09月06日

畳み込みニューラルネットワークのテスト その4

バグはある程度修正したのですが、まだまだ動作が怪しい気がします。とりあえず[1]などを参考にさせていただき、復習がてらニューラルネットワークの基本部分を見直してみました。

NN_006.png

とりあえずわかりやすいように入力層2+1個、中間層2+1個、出力層1個のネットワークで考えます。Pythonなどで扱いやすいこともあり、1個1個のユニットというよりは行列計算で考えることが多いようです。

NN_007.png

逆伝搬は基本的には偏微分を計算してチェインルールで戻していく感じです。微分のところは使用する活性化関数で変わってくるのでそのまま微分表記にしています。

NN_008.png

逆伝搬も行列で考えることができますが、バイアス項が邪魔だったりします。古典的なニューラルネットワークではバイアス項も入れ込んで同次座標系で考えますが、もうバイアスとして個別に扱った方がいいのかもしれません。

NN_009.png

ミニバッチ処理の場合、バッチひとまとまりは一括学習でいいんですかね。

NN_010.png

[1] 誤差逆伝播法のノート
web拍手 by FC2
posted by シンドラー at 21:12 | Comment(0) | Machine Learning | このブログの読者になる | 更新情報をチェックする

2017年08月24日

畳み込みニューラルネットワークのテスト その3

[1][2]を参考にさせていただき、畳み込み層の逆伝搬を実装してみました。一応フィルタらしきものが学習されているみたいですが、あまり精度が出ていないのと、フィルタの数を多くすると落ちるのでバグがありそうです。まだSGDもDropOutも実装していないので局所解に陥っているだけかもしれませんが。

NN_005.png

0〜9の手書き数字画像計800枚ぐらいをクラスタリングしてみました。枚数が少なすぎかもしれませんので、後でMNISTで試してみたいと思います。第1層は3枚、第2層は3×3枚のフィルタを1000回更新した結果です。教師データに対して77%ぐらいの精度しかでていません。

とりあえずC++とEigen使って実装して一通り動いたということで、仕組みは何となく理解できてきたかと思います。

[1] DeepLearning(4): CNNの逆伝播完成?
[2] 数式で書き下す Convolutional Neural Networks (CNN)

web拍手 by FC2
posted by シンドラー at 18:56 | Comment(0) | Machine Learning | このブログの読者になる | 更新情報をチェックする

2017年08月21日

畳み込みニューラルネットワークのテスト その2

昨日の続きです。昨日の画像を見るとReLUを通すのを忘れていますね…。

畳み込み層のところで勘違いしていた点で、前層出力が3枚で、フィルタを4枚準備した場合、出力は3×4で12枚の特徴マップになるのではと思っていたので、4枚の特徴マップが次の層で6枚の特徴マップになっててなんでだろうと思っていました。

[1]のサイトにも説明がありますが、前層の出力チャンネル数分のフィルタを、今の層で出力したい特徴マップ数分だけ用意する必要があるということで、4枚を6枚にするときは、4×6で24枚のフィルタが必要ということだと思います。

NN_003.png

NN_004.png

[1]のサイトには畳込み層、プーリング層の逆伝搬の方法も載っていましたので、そこを参考に実装を進めたいと思います。

[1] DeepLearning(2): まずは順伝播(下)
web拍手 by FC2
posted by シンドラー at 18:45 | Comment(0) | Machine Learning | このブログの読者になる | 更新情報をチェックする

畳み込みニューラルネットワークのテスト その1

DropOut[1][2]は一応実装できたので、畳み込みニューラルネットワークの準備に入りたいと思います。畳み込みに使うフィルタを学習するのが特長だと思いますが、いきなりそこまでの処理を実装するのは大変なので、少しずつ進めていきたいと思います。

というわけで、Gaborフィルタ[3]を使って畳み込みとプーリングの処理を試してみました。
NN_002.png
4枚のフィルタを掛けてMax poolingでさらに小さくしてそれを全結合NNに入れて分類しています。BPによる重み更新はNNしかしていません。[4]のLeNetでいうところの(C1)から(S2)への畳み込み処理がよくわかっていないのと、全結合より前の畳み込みのところのフィルタの更新方法がよくわかっていないので、[5]などを見て色々調べてみたいと思います。

[1] Dropoutの実装と重みの正則化
[2] Dropout を実装する
[3] ガボールフィルタ
[4] Convolutional Neural Networks (LeNet)
[5] Theano で Deep Learning [3] : 畳み込みニューラルネットワーク

web拍手 by FC2
posted by シンドラー at 02:23 | Comment(0) | Machine Learning | このブログの読者になる | 更新情報をチェックする

2017年08月18日

ニューラルネットワークのテスト

以前実装していたのですが、設計などが微妙でしたのでほぼ書き直しています。結構忘れていたので参考サイト[1]〜[3]辺りを見直してみましたが、計算自体は問題なさそうでした。

あまり分類が難しい問題は実装が合っているのかどうか確認しづらいので、とりあえず下記のような簡単な3クラス分類の問題にしてみました。

NN_001.png

教師画像300枚は、3枚の画像を100枚ずつランダム回転させて増やしたものですので、ものすごく簡単に分類できるかと思います。実際、2、30エポックで誤差が0.01未満になって教師データは100%の認識率です。1エポックは300枚からランダムに100枚選んで学習としました。

Softmax関数とReLU関数は問題ないみたいですので、後はDropOutを実装してから畳込みニューラルネットワークに入りたいと思います。

[1] 誤差逆伝播法のノート
[2] 誤差逆伝播法をはじめからていねいに
[3] ニューラルネットワーク
web拍手 by FC2
posted by シンドラー at 18:39 | Comment(0) | Machine Learning | このブログの読者になる | 更新情報をチェックする

2017年08月16日

画像の白色化について

夏休みがもう終わってしまいました。今回は機械学習の前処理で行われる画像の白色化のテストです。Pythonはよくわからないのでとりあえず今回はC++でEigen使ってやっています。白色化とは、共分散行列を対角行列とか単位行列にして無相関化しましょうという処理です。

まずは画像ですが、前回同様CIFAR-10のデータセットを使っています。白色化を行うときに特異値分解する場合、32x32x3だと結構な時間がかかりますので、今回はグレースケール化と諸事情により少しだけ縮小して30x30の900次元で取り扱っています。

参考にしたサイト[1]では、グレースケール化して色を反転?させていたようですので、それに倣いました。後、試してみたところGCN[2]をした方が結果画像に近づいたので、画像毎の正規化もしていると思います。

Eigenを使う場合、特異値分解するとUΛVに分解されますので、白色化の行列は下記のような感じになると思います。おそらく。
  JacobiSVD<MatrixXd> svd(covmat, ComputeFullU | ComputeFullV);
  MatrixXd inv_sigma = MatrixXd::Zero(dim, dim);
  for (int i=0; i<dim; i++) inv_simga(i, i) = 1.0 / (sqrt(svd.singularValues()[i])+EPS);
  MatrixXd white = svd.matrixU()*inv_sigma*svd.matrixV().adjoint();
実行結果

org0007.png image0007.png
org0029.png image0029.png
左がGCNして0〜1に線形変換したもの、右が[1]に倣ってEPS=0.1として白色化した画像です(見やすいように10倍に拡大したものです)。縮小したせいか微妙に違いますが大体一致していると思います。

[2]の方にありますが、ZCA白色化の各行を画像化すると、下記のような画像が得られましたので、多分処理としては合っていると思います。

white0094.png white0598.png

PythonとC++のどちらでやるかは未定ですが、次は畳込みニューラルネットワークを実装してみたいと思います。

[1] What is the difference between ZCA whitening and PCA whitening?
[2] データの前処理〜白色化 その2〜
web拍手 by FC2
posted by シンドラー at 18:06 | Comment(0) | Machine Learning | このブログの読者になる | 更新情報をチェックする

2017年08月02日

Pythonで画像処理 その2

昨日の続きです。とりあえず画像のデータセットを表示してみることにしました。CIFAR-10 and CIFAR-100 dataset[1]を使ってみようということで、Python用のデータをダウンロードしてみました。サイトにはunpickleの方法しか載っていなかったので、ググって[2]のサイトの方法を試させていただきました。サイトはPython 2系のようでしたので、3系にするためにunpickle関数を[1]に載っている3系のものに書き換えました。

ダウンロードしたデータを展開して実行してみると、下記のようなエラーが出ました。
  File "省略", line 26, in get_cifer10
      tr_data = data_dict['data']
  KeyError: 'data'
'data'なんて名前のキーは無いよというエラーのようでしたので、KeyErrorで検索してみると[3]のサイトがでてきました。
  print(data_dict.keys())
  dict_keys([b'batch_label', b'labels', b'data', b'filenames'])
キーを確認するためにdata_dict.keys()を実行してみたところ、上記のようにb'data'と頭にbがついていました。このbは何のbなんでしょうね。

とりあえずキーにすべてbをつけると、実行できました。後はconv_data2imageという関数も準備していただいていましたので、それを使って画像を表示してみました。
  img0 = tr_data10[0]   # 0番目の画像データ
  img1 = conv_data2image(img0)
  from skimage import io
  io.imshow(img1)
  io.show()

実行結果

dl2_figure_5.png

参考サイトと同じ画像が表示されましたので、とりあえず読み込みは成功したようです。

[1] CIFAR-10 and CIFAR-100 dataset
[2] Qiita - [Python]CIFAR-10, CIFAR-100のデータを読み込む方法
[3] stackoverflow - Reading Cifar10 dataset in batches
web拍手 by FC2
posted by シンドラー at 18:03 | Comment(0) | Machine Learning | このブログの読者になる | 更新情報をチェックする

2017年08月01日

Pythonで画像処理

Anaconda環境ですが、欲張って色々入れてしまうと競合するみたいですね。Anaconda 4.3.0(64ビット)だけインストールするようにしたら、前回のエラーが出なくなりました。

今回は機械学習で使うため画像の枚数を回転させて無理矢理増やす方法です。OpenCVに付属のcreatesamplesユーティリティの真似です。といってもあちらはx、y軸の回転や明るさの変化などもできますが。
  from PIL import Image
  import numpy as np
  import os

  # 「実践コンピュータビジョン」より改変
  def get_imlist(path, ext):
      # pathに指定されたディレクトリのすべてのext拡張子を持つ画像のリストを返す
      return [os.path.join(path,f) for f in os.listdir(path) if f.endswith(ext)]

  folder = "./image"
  filelist = get_imlist(folder, '.jpg')

  # 増やしたい枚数
  samples = 100
  # クラス番号
  classNo = 1

  # 増やした画像ファイル名とクラス番号のリスト
  txtfile = folder + "imagelist.txt"
  fout = open(txtfile, 'wt')

  # 画像ファイルの数だけ繰り返す
  for infile in filelist:
      # splitext: パス名を(root, ext)のペアに分割
      root = os.path.splitext(infile)[0]
      # -180.0〜180.0の回転角度を乱数で生成
      randDeg = 360.0 * np.random.rand(samples) - 180.0

      # 増やしたい枚数だけ繰り返す
      for idx in range(samples):
          # ゼロパディングしたファイル名を作成
          # 参考URL: http://www.lifewithpython.com/2015/10/python-zero-padding.html
          number_padded = '{0:05d}'.format(idx)
          filename = root + "_" + number_padded + ".png"
          # ファイル名をテキストファイルに書き出す
          fout.write(filename + ' ' + str(classNo) + '\n')
          # 画像を開いて乱数の角度で回転して保存
          out = Image.open(infile).rotate(randDeg[idx])
          out.save(filename)

  # ファイルを閉じる
  fout.close()
機械学習の時は画像のパスとクラス番号が書かれたファイルもよく使いますので、それも出力するようにしてみました。

forループのところなどはpythonに慣れていればもっとスマートに書けそうですが。後、既に混ざってしまってアレですが、シングルクォートとダブルクオートってPythonだとどういう扱いなんですかね。C言語だと文字定数と文字列の違いがあったのですが…。

実行結果

Lenna00000.png
Lenna.jpg1枚から回転した100枚が増えました。

参考文献
[1] Ja Erik Solem著,相川 愛三 訳,「実践コンピュータビジョン」,オライリー・ジャパン
[2] Bill Lubanovic著,斎藤 康毅 監訳,長尾 高弘 訳,「入門Python3」,オライリー・ジャパン
[3] Python Tips: Pythonでゼロパディングしたい
web拍手 by FC2
posted by シンドラー at 18:00 | Comment(0) | Machine Learning | このブログの読者になる | 更新情報をチェックする

2017年07月21日

Visual Studio Community 2017 + Anaconda 4.3.0 で Python環境の構築

AIとかDeep Learningが流行っていますね。色々なフレームワークが出来ていますが、Pythonを使ったものが多いので、Pythonの勉強をしてみることにします。環境としてはWindowsのVisual Studio使用です。

環境構築

まずはVisual Studioのインストールです。セットアップファイルが便利になっているので、インストールの時にPython開発にチェックしてインストールするだけです。どれを選べば良いのかいまいちわかりませんでしたが、Python 3 (3.6.0) (64ビット) Pythonネイティブ開発ツール、Anaconda3(4.3.0.1) (64ビット)辺りをインストールしました。

1. 新しいプロジェクトの作成→Python→PythonアプリケーションでPythonのプロジェクトを新規作成
2. ツール→Python→Python環境を選択→ドロップダウンリストから概要を選択→Anaconda3(2.7, 64-bit)を選択→新しいプロジェクトに対する既定の環境にする
3. プロジェクト→〇〇のプロパティ→全般→インタープリター:Anaconda 4.3.0(2.7, 64-bit)に変更

とりあえずはこのような感じです。最初Anaconda 4.3.0(3.6, 64-bit)のPython 3.6使用でやろうとしていたのですが、import numpy as npとすると、ImportError: DLL load failed: と出てうまくいきませんでした。[1]によると2.7にしましょうとありましたので、特にこだわりもないので2.7にしました。おそらく3.6でも動かせるのだと思いますので、必要があればやり方を調べたいと思います。

4. 文字コードの設定として1行目を下記のようにする
  # -*- coding: utf-8 -*-

後は[2]などを参考にMatplotlibを使って関数の描画や画像の表示を試してみました。

実行結果
figure_1.png figure_1-1.png
[2]の本を一通りやれば大体イメージは掴めそうですかね。

[1] NumPy library ImportError: DLL load failed: The specified procedure could not be found
[2] 斎藤 康毅 著,"ゼロから作るDeep Learning", オライリー・ジャパン
web拍手 by FC2
posted by シンドラー at 19:13 | Comment(0) | TrackBack(0) | Machine Learning | このブログの読者になる | 更新情報をチェックする

2016年02月10日

Extreme Learning Machineのテスト

ニューラルネットワークのような感じでバックプロパゲーションで重みを学習するのではなく、最小二乗法で計算するELM(Extreme Learning Machine)というものがあるみたいなので、試してみました[1][2]。

ネットワーク構成
elm_001.png
最初バイアス入力を入れずにやっていて、近似できないので困っていました。出力の閾値の代わりとして入れているものなので、ELMでも当然必要でした。

elm_002.png

最小二乗法の計算は、[2]にも書かれていますが、データ数>未知数の場合と、データ数<未知数の場合で場合分けするべきですが、今回は片方しか書いていません。

elm_003.png

実行結果

活性化関数にシグモイド関数を使っています。とりあえずsinc関数に一様乱数ノイズを付与した入力データに対して、ELMを使用して関数近似してみました。中間層50,データ数100です。

elm_004.png

[1] Extreme Learning Machine
[2] Extreme Learning Machine
web拍手 by FC2
posted by シンドラー at 20:38 | Comment(0) | TrackBack(0) | Machine Learning | このブログの読者になる | 更新情報をチェックする

2010年08月06日

A*アルゴリズムのテスト

またまたこれまでと全然違うことですが、有名なA*アルゴリズムによる経路探索をちょっとやってみました。

参考文献:オライリー社「ゲーム開発者のためのAI入門」

実行結果



赤がスタート地点で青が目的地で、黒が壁で薄い灰色がオープンリスト、濃い灰色がクローズドリスト、緑色が現在の探索地点と結果の経路です。

今回はタイル環境ですが、3D空間などでもほぼそのまま使えそうです。
web拍手 by FC2
posted by シンドラー at 15:09 | Comment(0) | TrackBack(0) | Machine Learning | このブログの読者になる | 更新情報をチェックする