機械学習とTensorFlow

機械学習の大まかな手順
1.教師データから未知のデータを予測する式を立てる.
2.数式に含まれるパラメータを評価する損失関数を用意する.
3.損失関数を最小にするパラメータを用意する.(勾配ベクトルが小さくなるように移動)

 y = Xw で表され
Xはトレーニングセットとして与えられたデータでPlaceholderという.
wは最適化を実施するパラメータでValiableという.

TensorFlowで表すと下のようになる.

x = tf.placeholder(tf.float32,[None,5])#xは浮動小数点32bitでn*5行列
w = tf.Valiable(tf.zeros([5,1]))#wは5*1行列で要素が全て0の行列
y = tf.matmul(x,w)
loss = tf.reduce_sum(tf.square(y-t))#損失関数の定義:reduce_sumはベクトルの要素を全て足す, squareはベクトルの各要素を二乗する
train_step = tf.train.AdamOptimizer().minimize(loss)#AdamOptimizerは損失関数を計算して勾配ベクトルの反対方向にパラメータを修正する,
#学習率εに相当するパラメータを自動的に修正してくれる,minimizeは引数の損失関数を最小化する

これで損失関数を最小にするパラメータの値が決定できる.

【DL】sigmoid関数, ReLU関数

sigmoid関数
 \frac{1}{1+exp(-x)}
f:id:umashika5555:20170328081139p:plain

import numpy as np

def sigmoid(x):
    return 1/(1+np.exp(-x))

def main():
    x = np.array([-2.0 ,1.0, 2.0])
    y = sigmoid(x)
    print(x)
    print(y)
    
if __name__=='__main__':
    main()

結果は下記
入力が小さいほど出力も小さい.
入力が大きいほど出力も大きい.

[-2.  1.  2.]
[ 0.11920292  0.73105858  0.88079708]

ReLU関数
 x\ge0 f(x) = x, x\le 0 f(x) = 0
 f(x) = max(0,x)
f:id:umashika5555:20170328082054p:plain

def ReLU(x):
    return np.maximum(0,x)

sigmoid関数と同じ入力をすると結果は下記のようになった.

[-2.  1.  2.]
[ 0.  1.  2.]

Anacondaインストール

Python2.x
ここからインストーラをダウンロード
Download Anaconda Now! | Continuum

bash Anaconda2-4.3.1-Linux-x86_64.sh 

ひたすら"yes"を入力
端末を再起動する

conda -V

と入力して確認する.
Anaconda を利用した Python のインストール (Ubuntu Linux) – Python でデータサイエンス

アニメOPの顔検出

kivantiumさんの『ご注文はDeepLearningですか?』にインスピレーションを受け, まだキャラを分類するなど学習を取り入れたワケではないが作った.



kivantium.hateblo.jp

www.youtube.com
www.youtube.com

python opencv7 カスケード分類器

事前に学習したい物体の特徴を抽出して, 特徴量を機械が学習し, 学習データのまとまりをカスケード分類器というらしい.
OpenCVでは"/usr/local/share/OpenCV/haarcascades/lbpcascade_animeface.xml"のようにxml形式で扱う.

pythonでは読み込んだ画像を
1.グレースケールに変換する.

image_gray = cv2.cvtColor(image, cv2.cv.CV_BGR2GRAY)
#読み込む際にimage_gray = cv2.imread(image_path,0)でもOKだった

2.カスケード分類器の特徴量を取得

#cascade_path = "/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_alt.xml"#普通の顔
cascade_path = "/usr/local/share/OpenCV/haarcascades/lbpcascade_animeface.xml" #アニメ顔
cascade = cv2.CascadeClassifier(cascade_path)

3.認識の実行

facerect = cascade.detectMultiScale(image_gray, scaleFactor=1.2, minNeighbors=2, minSize=(10, 10))
#[ [顔1の範囲: x座標 y座標 横 縦]
#  [顔1の範囲: x座標 y座標 横 縦]
#]


より精度を上げたかったり, 標準に備わってなかったりする物体を認識させるためには自分で機械学習を行い分類器を作る必要があるらしい.


認識した顔の画像をファイルへ出力

i = 0;
for rect in facerect:
	#顔だけ切り出して保存
	x,y,width,height = rect#x座標, y座標, 横の長さ, 縦の長さ
	dst = image[y:y+height, x:x+width]#画像の切り出し
	cv2.imwrite("出力先のパス", dst)
	i += 1


画像に長方形を描画する.

cv2.rectangle(image, tuple(rect[0:2]),tuple(rect[0:2] + rect[2:4]), color, thickness=5)
#cv2.rectangle(img, 始点のタプル, 終点のタプル, 色, 線の太さ)


顔を囲った画像をファイルへ出力

if len(facerect):#顔があったら
	color = (0, 0, 255) #BGR
	for rect in facerect:
		#検出した顔を囲む矩形の作成
		cv2.rectangle(image, tuple(rect[0:2]),tuple(rect[0:2] + rect[2:4]), color, thickness=2)
	#認識結果の保存
	cv2.imwrite(出力先のパス, image)

ここにあるコードのカスケードを変更して実行すると下のようになった.
famirror.hateblo.jp
f:id:umashika5555:20170325012923j:plain
f:id:umashika5555:20170325013105j:plain
認識できていない場合もあった.
目が2つないとダメなのかな?
f:id:umashika5555:20170325013321j:plain




OpenCVで物体検出器を作成① 基礎知識【開発会社プロフェッサ】
ultraist.hatenablog.com
opencv.blog.jp
famirror.hateblo.jp



【追記:2017:03:25】
(^_^)の画像は認識されていたようなので,(・_^)のように左右の目が統一されてない画像に弱いっぽい.