のんびりしているエンジニアの日記

ソフトウェアなどのエンジニア的な何かを書きます。

Android Studioを起動しようとするとエラーが出た

皆さんこんにちは
お元気ですか。私は元気です。

Android Studioでエミュレータを立ち上げようとするとまさかのエラーが発生した。

/Users/Tereka/Library/Android/sdk/tools/emulator -avd Small -netspeed full -netdelay none
emulator: ERROR: x86 emulation currently requires hardware acceleration!
Please ensure Intel HAXM is properly installed and usable.
CPU acceleration status: HAX is not installed on this machine (/dev/HAX is missing).

解決方法software.intel.com

上記のサイトより、HAXをダウンロード
HAX is not installed on this machine と言われてエミュレータが起動しないやつ - エンジニアですよ!のサイトを参照すると、現状インストールされているHAXは古いようで、新しいのをダウンロードしなければなりません。

因みにこれをダウンロードし、インストールすると直りました。
再インストールして、最初に発生して心底焦った。

ある日、いきなりOpenCVが動かなくなった

こんにちは。
お元気ですか?私は元気です。

今日は突然OpenCVが動かなくなった話をします。

どんなエラー?

>>> import numpy
>>> import cv2
RuntimeError: module compiled against API version 9 but this version of numpy is 6

原因

必要なのはAPIが9のバージョンに対して、今使われているのは6ですと。

解決方法

古いNumpyが優先されているので、優先されないように
古いNumpyをリネームしておく。

cd /System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/
sudo mv numpy numpy_bad

分析

とりあえず、まずはnumpyのバージョンを調べてみる。
必要な部分以外は省略する。

sudo pip list
numpy (1.9.2)

ソースコードでも調べてみた。

>>> print numpy.__version__
1.6.2

なんか違う。
おそらく原因はこれです。
元々Macが持っている古いNumpyが利用されていることが原因です。

原因を探ると以下のサイトが出てきたので同様の行動を行ってみる。

cd /System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/
sudo mv numpy numpy_bad

Pythonで確認してみる

>>> import numpy
>>> import cv2
>>> print numpy.__version__
1.9.2

これでOpenCVを動作させることができます。

Kaggleで、Deep Oceanの画像コンペの結果が出ました

皆さんこんにちは
お元気ですか。私は元気です。

久々の投稿ですね。Kaggleで出場したコンペについて記載します。

どんなコンペティション?

コンペティションのページはこちらです。
プランクトン121種類の画像を識別します。プランクトンの画像サイズは異なり、
画像はモノクロ画像です。

どんな手法を使ったの?

ConvolutionalNeuralNetwork(CNN)を使って、識別を行いました
スコア自体はpublic 0.899218,private 0.904137と非常にお粗末なスコアでした

実装アルゴリズムは
①リサイズ(32 x 32)
②150枚以下のクラスについては学習する前に150前後まで数を増加させる
③pre-processing(flip、切り取り)で28倍に増加
④CNNで学習
⑤Baggingでテスト

CNNは3x3のカーネルを組み合わせ、多層にして構築しました。
構成は気が向いたら書きますが、そこまで良いモデルではないので割愛しようと思います。

敗因
①画像のサイズが小さかったこと
CNNの層を重ねることができる結果的に、表現力がほかと比べて低かったことが一つの原因であると思っています。

②微弱な回転をランダムに入れるべきだった
実際のプランクトンのケースは微妙に回転しているものだったりが存在します。これを認識する為に微妙に回転させるなど工夫が必要でした。

③切り取りに加えて、拡大縮小も入れるべきだった
同じサイズのプランクトンはいないので、拡大縮小を入れて細かくやればよかった

優勝者

http://benanne.github.io/2015/03/17/plankton.htmlに優勝者の手法が記載されています。
凄まじい、Data ArgumentationやCylic Poolingなどを用いています。CylicPoolingが何かはあまりわかりませんがまぁ凄い方法なのかな?

これを見ながら、色々と勉強したいと思っています。

Scikit-learnのモデルをまとめてみた

皆さんこんにちは
お元気ですか。私は元気です。

今日はScikit-learnで扱えるモデルについて紹介したいと思います。気が向いたら追加します。
※Sampleは割りと公式サイトのを少々改変したもの使っていたりします。ご了承ください。

モデル全般について

Parameter

パラメータ内容 書き換え対象
閾値 tolの書き換え
初期値 random_stateを入れる
途中経過 verboseを1にする(Defaultは0)
最大回数 max_iter(defaultは永久に止まらない(-1))が選択されていることもある
並列thread数 n_jobsの変更、n_jobs=-1とすると動かせる最大の数となる

Method

関数 内容
fit 渡したデータに基いて学習を行う
predict 予測する、所属しているクラスが返ってくる
get_params パラメータを取得する
predict_proba 所属しているクラスの確率が戻ってくる。Kaggleとかでよく使う出力ですね

基本的に学習手順ですが、モデルのインスタンスを作る→fitする→predictするのみです。
Cross Validationとかは考えていません。

Supervised Machine Learning(教師あり学習)

Support Vector Machine

超がつくぐらい有名な機械学習Support Vector Machine(SVM)です。
最も特徴的なのは、カーネル関数を用いて線形分離ができないものを特徴空間にマッピングを行い
分離することができるようにしていることが最大の特徴ともいえます。

from sklearn import svm
X = [[0, 0], [1, 1]]
y = [0, 1]
clf = svm.SVC()
clf.fit(X, y) 

カーネルの種類は4つあり、kernelのパラメータを変更すれば、問題ありません。
linear,polynomial,rbf,sigmoidがあります。

多クラスの決定法としてはOne VS OneとOne VS Restの二種類ありますが、基本的にはOne VS Oneを用いるようです。

Nearest Neighbors(K近傍法)

有名なのだと、K-NN,近いK個の中から最も近いものを探索し、最も数が多いクラスをその予測データのクラスとする
n_neighborsで、Kの値を決定します。

X = [[0], [1], [2], [3]]
y = [0, 0, 1, 1]
from sklearn.neighbors import KNeighborsClassifier
neigh = KNeighborsClassifier(n_neighbors=3)
neigh.fit(X, y) 
KNeighborsClassifier(...)
print(neigh.predict([[1.1]]))
print(neigh.predict_proba([[0.9]]))

Logistic Regression

ロジスティック回帰です。よく、AutoEncoderの最後にくっつけられていたりします。

X = [[0], [1], [2], [3]]
y = [0, 0, 1, 1]
from sklearn.linear_model import LogisticRegression
clf = LogisticRegression()
clf.fit(X, y)
print(clf.predict([[1.1]]))
print(clf.predict_proba([[0.9]]))

Random Forest

学習データから木の構造を学習し、その構造を元にし、テストデータを予測するアルゴリズム
案外、KaggleのBench Markで見るアルゴリズム

X = [[0], [1], [2], [3]]
y = [0, 0, 1, 1]
from sklearn.ensemble import RandomForestClassifier
clf = RandomForestClassifier()
clf.fit(X, y)
print(clf.predict([[1.1]]))
print(clf.predict_proba([[0.9]]))

Gradient Boosting Decision Tree

正直、Kaggleで初めて見た。結構性能としては高性能らしく、かなり使われているよう

X = [[0], [1], [2], [3]]
y = [0, 0, 1, 1]
from sklearn.ensemble import GradientBoostingClassifier
clf = GradientBoostingClassifier()
clf.fit(X, y)
print(clf.predict([[1.1]]))
print(clf.predict_proba([[0.9]]))

Unsupervised Machine Learning(教師なし学習)

K-Means(K平均法)

超有名、かつ割りと高速で有名なクラスタリング手法K平均法
その汎用性から皆さんの機械学習で実装されることも多いとか少ないとか

X = [[0], [1], [2], [3],[4],[5],[10],[100]]
from sklearn.cluster import KMeans
clf = KMeans(n_clusters=2)
clf.fit(X)
print(clf.predict([[1.1]]))

n_clustersがクラスタの分割数です。

Gaussian Mixture Model(GMM)

有名なクラスタリング手法、一つ一つのクラスタが正規分布として表現され、
その重ね合わせによって構築されるクラスタリング手法
クラスタリングとして利用する場合こちらはn_componentsでクラスタの数を指定することができます。
K-平均法よりはこちらの方が良いクラスタリングになると言われています。

X = [[0], [1], [2], [3],[4],[5],[10],[100]]
from sklearn.mixture import GMM
clf = GMM(n_components=2)
clf.fit(X)
print(clf.predict([[1.1]]))

BernoulliRBM

Restricted Boltzmann Machineの一種、正直あまり使ったことがない。
最後にLogistic Regressionとかを持ってきて利用するのが妥当だと思う。

import numpy as np
from sklearn.neural_network import BernoulliRBM
X = np.array([[0, 0, 0], [0, 1, 1], [1, 0, 1], [1, 1, 1]])
model = BernoulliRBM(n_components=2)
model.fit(X)
print model.transform(X)

その他

Principal Component Analysis(主成分分析)

次元圧縮などでよく利用されます。n_componentsで次元数を選択することができます。

from sklearn import decomposition
from sklearn import datasets

iris = datasets.load_iris()
X = iris.data
y = iris.target

pca = decomposition.PCA(n_components=3)
pca.fit(X)
print X
X = pca.transform(X)
print X

C++でモンテカルロ法を書いて、円周率を計算した

皆さんこんにちは
お元気ですか。私は元気です。

さて、今日はモンテカルロ法を書いて、円周率を計算してみました。
基本的な戦略は簡単で、円の中にあるかどうかを判定します。判定式ですが(x**2 + y**2 <= 1.0)の時に
円より中にあると計算します。

f:id:tereka:20150215221746p:plain

四角の中に対してランダムに点を打ち、オレンジ色の箇所の数を数えます。最終的に4倍を行い、円周率とします。

Source Code

#include <iostream>
#define N 10000

using namespace std;

int main(void){
        double cnt = 0.0;
        for(int i = 0; i < N; i++){
                double x = (double)rand()/RAND_MAX;
                double y = (double)rand()/RAND_MAX;

                if((x*x + y*y) <= 1.0){
                        cnt += 1.0;
                }
        }
        cout << "円周率:" << cnt / N * 4.0 << endl;
}

Output

円周率3.1496