機械学習のお勉強(特徴量)
Haar-Like
物体の局所的な明暗差の組み合わせにより、画像を判別する
LBP(Local Binary Pattern)
物体の局所的な輝度の分布の組み合わせにより、画像を判別する
HOG(Histogram of Oriented Gradients)
物体の局所的な輝度の勾配方向の分布の組み合わせにより、画像を判別する
SHIFT
移動、回転に加えてズーム対してロバストな特徴を持つ
SURF
SIFTは計算量が多く、低速だったため、速度を改良したアルゴリズム
ORB
移動、回転、ズームの3つに対してロバストで、計算速度も速い
AKAZE
計算量がORBよりもやや多いものの、低周波領域、高周波領域の抽出精度がORBよりも優れている
主成分分析
OpenCV3とPython3で形状のある物体の輪郭と方向を認識する(主成分分析:PCA、固有ベクトル) - Qiita
エッジ検出
カラーヒストグラム
領域分割
画像を同じ特徴を持つ複数の領域に分ける方法 (1/2):CodeZine(コードジン)
pythonで画像領域分割を実装 (Union-Find) - Qiita
http://www.riken.jp/brict/Yoshizawa/Lectures/Kyuusyu/Lectures2011_05.pdf
解決済み: 画像から色指定で領域抽出する方法 - NI Community
複数の特徴量の組み合わせ
https://www.toshiba.co.jp/tech/review/2010/07/65_07pdf/f02.pdf
http://www.me.cs.scitec.kobe-u.ac.jp/~takigu/pdf/2009/C-03.pdf
http://www.vision.cs.chubu.ac.jp/MPRG/F_group/F074_fujiyoshi2008.pdf
参考:
深層学習 を 用いた 異常値検知 手法まとめ 〜 (Denosing) AutoEncoder, LSTM, TDA(Topological Data Analysis) + CNN - Qiita
SSD: Single Shot MultiBox Detector 高速リアルタイム物体検出デモをKerasで試す - Qiita
http://www.vision.cs.chubu.ac.jp/features/PPT/SSII2009/090610_SSII2009_Tutorial.pdf
http://www.vision.cs.chubu.ac.jp/cvtutorial/PDF/02SIFTandMore.pdf
http://www.vision.cs.chubu.ac.jp/sift/PDF/pcsjimps2008_ppt.pdf
https://www.pro-s.co.jp/engineerblog/opencv/post_6231.html
OpenCV 3とPython 3で特徴量マッチング(A-KAZE, KNN) - Qiita
機械学習のお勉強に役立つサイト↓ http://qiita.com/daxanya1/items/218f2e3b922142550ef9?utm_content=buffer40ad9&utm_medium=social&utm_source=facebook.com&utm_campaign=buffer
機械学習のお勉強(最小二乗法、最尤推定法、パーセプトロン)
最小二乗法
ex: 観測値と真値の二乗誤差を最小にするようにn次多項式を解く。
データセットがn以上あると解析的に平方根平均二乗誤差が0の多項式を導くことができる。
パラメトリックモデルの解き方 1. パラメータを含むモデルを設定する
パラメータを評価する基準を定める
最良の評価を与えるパラメータを決定する
オーバフィッティングの検証
仮説/検証を行う。
これによってモデルの汎化能力がわかる。
オーバーフィッテイング:トレーニングデータセットだけに特化したチューニングが発生する状況
クロスバリデーションによる汎化性能の検証
参考: 交差確認(交差検証、Cross-Validation)の簡単な説明 - 具体例で学ぶ数学
交差検定(クロスバリデーション)など機械学習の評価方法まとめ : 新規事業のつくり方
最尤推定法
データの背後にある関数に加えて、データに含まれる誤差を併せて推定する手法。
ex: データから多項式の係数と正規分布に基づいているとして標準偏差を求める
尤度関数:「トレーニングデータセットのデータが得られる確率」をパラメータ(ex1:観測値、標準偏差 , ex2:平均、標準偏差)の関数とみなしたもの
この確率が最大になるようにパラメータを決定する方法を最尤推定法と呼ぶ。
多項式の係数の推定値は最小二乗と同じになり、標準偏差の推定値は平方根平均二乗誤差と同じになる。
異なるアプローチをとったにもかかわらず同じ多項式が得られる。つまり、最小二乗法は最尤推定法の中でも、正規分布の誤差を仮定した特別な場合に対応するとみなすことができる。
推定量の一致性と不偏性
- データ数を大きくしていくことで真の値に近づいていくことを一致性と呼ぶ
- 不偏性を持つ推定量はデータが少ない場合、真の母数から外れる可能性があるが、大きい方と小さい方にはずれる場合が均等にあるということを意味する。
参考: 18-3. 推定量の性質 | 統計学の時間 | 統計WEB
パーセプトロン
pandas
Pandas でデータフレームを作ってみよう – Python でデータサイエンス
[Python] pandasの使い方まとめ - Qiita
Pythonでpandasを使う - 計算物理屋の研究備忘録
scipy
【Python入門】絶対に知っとくべきライブラリscipyの基本的な使い方 - Qiita
1.5. Scipy: 高水準の科学技術計算 — Scipy lecture notes
問題を解きながら学ぶ
PFNさんが公開してくださっている機械学習の問題↓
GitHub - pfnet/intern-coding-tasks: Coding tasks for PFN internship
ネットワークのお勉強その2
SSIDとは
Service Set IDentifier!
SSIDとは、無線LANのアクセスポイントを識別するための名前のこと。
参考:
無線LANルーターのSSIDとは?-ELECOM WEB SITE!
アクセスポイントとは
「アクセスポイント」は、Wi-Fiの通信における”中継点”となる場所。
参考:
マルチSSID
マルチSSIDとは、1つのWi-Fi親機で複数のSSIDが使える機能。1つの親機が複数のアクセスポイントを持つ。
メリット
それぞれのアクセスポイントで別々の設定ができる(特に、セキュリティ方式を分けることができるのが魅力)
問題:最大何個のマルチSSIDを同時に使用できるの?
Ciscoだと最大16個までできるよ。
参考:
最大何個のマルチSSIDを同時に使用できますか(法人向けアクセスポイント) - アンサー詳細 | BUFFALO バッファロー
無線LAN - Cisco無線LANソリューション : 基本設計と基本構成
Wi-Fiのセキュリティ機能 - Wi-Fiの使い方初心者用ガイド
ステルスID
SSIDステルス機能とは、アクセスポイントが発信する電波にSSIDを含めないようにする機能のこと。
参考:
アクティブスキャンとパッシブスキャン
アクティブスキャンをすればステルスIDにも接続することができる。
参考:
http://www0.info.kanagawa-u.ac.jp/~matsuo/theses/pdf/matsuo_lab_20140202_kawashima_abst.pdf
wpa_supplicant.conf
wpa_supplicantは、無線LANアクセスポイントに対し、WPAで接続要求を行うためのコマンド。
ステルスIDに接続したい時
scan_ssid = 1 でOK!
# scan_ssid: # 0 = do not scan this SSID with specific Probe Request frames (default) # 1 = scan with SSID-specific Probe Request frames (this can be used to # find APs that do not accept broadcast SSID or use multiple SSIDs; # this will add latency to scanning, so enable this only when needed)
# disabled: # 0 = this network can be used (default) # 1 = this network block is disabled (can be enabled through ctrl_iface, # e.g., with wpa_cli or wpa_gui)
key_mgmt: accepted authenticated key management protocol
無線LANのステルスAPにLinux(wpa_supplicant)から接続する - Dマイナー志向
設定例:
ctrl_interface=DIR=/var/run/wpa_supplicant update_config=1 network={ scan_ssid=1 key_mgmt=WPA-PSK ssid="xxxx" psk=xxxx disaxled=1 } network={ scan_ssid=1 key_mgmt=WPA-PSK ssid="xxxx" psk=xxxx }
参考:
http://www.cs.upc.edu/lclsi/Manuales/wireless/files/wpa_supplicant.conf
ネットワーク管理の基本Tips:無線LANにWPAで接続するには? wpa_supplicantコマンド - @IT
wpa_cli
以下のコマンドでSSIDに接続できる
$ sudo wpa_cli select_network 0 //一番目に設定したSSIDに接続 $ sudo wpa_cli select_network 1 //二番目に設定したSSIDに接続
DNS
「DNS(Domain Name System)」とは、、コンピュータ名やドメイン名などの名前を表す文字列とIPアドレスの対応を管理したり、検索したりする階層構造のサービス。
Google Public DNS「8.8.8.8」「8.8.4.4」
参考:
DNS(Domain Name System)とは-インターネット入門ガイド
VLAN
VLANとは、「Virtual LAN」の略で以下の図のように、論理的に1台のスイッチに独立した複数のLANを持たせることが出来る機能
参考:
ネットワーク全般
参考:
わかりやすい! ネットワークエンジニアを目指して - ネットワーク技術の解説
keras2とchainerの使い方をCNNでくらべてみる
目的:keras2とchainerの使い方の違いを知る
まとめ:
keras2はmodelの最初の層以外の入力は記述しなくても良い。バックエンドがtheanoとtensorflowで入力の配列が異なる。
chainerはmodelの層追加時、入力と出力の数を記入。入力でNoneと記述すると自動的に計算してくれる。Conv->Linearの際に便利。
参考:
出力ノード数を手計算せずにConvolutionの出力をLinearに入力する(chainer 1.15) - Qiita
わかりやすい↓
Chainer: ビギナー向けチュートリアル Vol.1 - Qiita
わかりやすい↓
Keras tips: 様々な画像の前処理をカンタンにやってくれるkeras.preprocessingのまとめ - MATHGRAM
keras2
mnistをcnnで学習するサンプル
'''Trains a simple convnet on the MNIST dataset. Gets to 99.25% test accuracy after 12 epochs (there is still a lot of margin for parameter tuning). 16 seconds per epoch on a GRID K520 GPU. ''' from __future__ import print_function import keras from keras.datasets import mnist from keras.models import Sequential from keras.layers import Dense, Dropout, Flatten from keras.layers import Conv2D, MaxPooling2D from keras import backend as K batch_size = 128 num_classes = 10 epochs = 12 # input image dimensions img_rows, img_cols = 28, 28 # the data, shuffled and split between train and test sets (x_train, y_train), (x_test, y_test) = mnist.load_data() # backendがtensorflowとtheanoで配列のshapeが異なる if K.image_data_format() == 'channels_first': x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols) # theano x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols) input_shape = (1, img_rows, img_cols) else: x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1) # tensorflow x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1) input_shape = (img_rows, img_cols, 1) x_train = x_train.astype('float32') x_test = x_test.astype('float32') x_train /= 255 x_test /= 255 print('x_train shape:', x_train.shape) print(x_train.shape[0], 'train samples') print(x_test.shape[0], 'test samples') # convert class vectors to binary class matrices y_train = keras.utils.to_categorical(y_train, num_classes) y_test = keras.utils.to_categorical(y_test, num_classes) model = Sequential() model.add(Conv2D(32, kernel_size=(3, 3), # 32:出力を与える activation='relu', input_shape=input_shape)) # input_shape = x_train.shape[1:]としてもよい。最初のみ入力の値(img_rows, img_cols, 1)が必要。 model.add(Conv2D(64, (3, 3), activation='relu')) # 畳み込み。32:出力だけ与える model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Dropout(0.25)) model.add(Flatten()) model.add(Dense(128, activation='relu')) # 全結合相。2:出力だけ与える model.add(Dropout(0.5)) model.add(Dense(num_classes, activation='softmax')) # 活性化関数 model.compile(loss=keras.losses.categorical_crossentropy, # 損失関数 optimizer=keras.optimizers.Adadelta(), # 最適化 metrics=['accuracy']) model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, verbose=1, validation_data=(x_test, y_test)) # 学習 score = model.evaluate(x_test, y_test, verbose=0) print('Test loss:', score[0]) print('Test accuracy:', score[1]) model.save('./model.hdf5')
参考: keras/mnist_cnn.py at master · fchollet/keras · GitHub
予測するサンプル * 写真を一枚指定しそのクラスを出力
# coding: UTF-8 from __future__ import print_function import keras from keras.models import load_model from keras.preprocessing import image import numpy as np import sys model = load_model('model.hdf5') if len(sys.argv) != 2: print("usage: python [image file]") sys.exit(1) filename = sys.argv[1] img = image.load_img(filename, target_size=(32, 32)) x = image.img_to_array(img) #x = x / 255.0 #この操作を行うと正しく予測されない(TBD) # rows, cols, channels) -> (samples, rows, cols, channels) x = np.expand_dims(x, axis=0) pred = model.predict(x) print(pred)
参考: KerasでVGG16を使う - 人工知能に関する断創録
chainer
mnistをcnnで学習するサンプル
# -*- coding: utf-8 -* import numpy as np import matplotlib.pylab as plt from sklearn.datasets import fetch_mldata import chainer import chainer.links as L import chainer.functions as F from chainer import Chain, optimizers, Variable, serializers mnist = fetch_mldata('MNIST original', data_home='.') mnist.data = mnist.data.astype(np.float32) # image data 784*70000 [[0-255, 0-255, ...], [0-255, 0-255, ...], ... ] mnist.data /= 255 # to 0-1 mnist.target = mnist.target.astype(np.int32) # label data 70000 N = 60000 x_train, x_test = np.split(mnist.data, [N]) t_train, t_test = np.split(mnist.target, [N]) # to (n_sample, channel, height, width) x_train = x_train.reshape((len(x_train), 1, 28, 28)) x_test = x_test.reshape((len(x_test), 1, 28, 28)) class CNN(Chain): def __init__(self): super(CNN, self).__init__( conv1 = L.Convolution2D(1, 20, 5), # 入力:1 , 出力:20。両方記述。filter 5 conv2 = L.Convolution2D(20, 50, 5), # 入力:1 , 出力:20。両方記述。filter 5 l1 = L.Linear(800, 500), # ここの入力の計算は以下の参考HPを参照。 l2 = L.Linear(500, 500), l3 = L.Linear(500, 10, initialW=np.zeros((10, 500), dtype=np.float32)) ) def forward(self, x): h = F.max_pooling_2d(F.relu(self.conv1(x)), 2) h = F.max_pooling_2d(F.relu(self.conv2(h)), 2) h = F.relu(self.l1(h)) h = F.relu(self.l2(h)) h = self.l3(h) return h model = CNN() optimizer = optimizers.Adam() # 最適化関数 optimizer.setup(model) n_epoch = 5 batch_size = 1000 for epoch in range(n_epoch): sum_loss = 0 sum_accuracy = 0 perm = np.random.permutation(N) for i in range(0, N, batch_size): x = Variable(x_train[perm[i:i+batch_size]]) t = Variable(t_train[perm[i:i+batch_size]]) y = model.forward(x) model.zerograds() loss = F.softmax_cross_entropy(y, t) # 活性化関数と損失関数 acc = F.accuracy(y, t) loss.backward() optimizer.update() sum_loss += loss.data*batch_size sum_accuracy += acc.data*batch_size print("epoch: {}, mean loss: {}, mean accuracy: {}".format(epoch, sum_loss/N, sum_accuracy/N)) cnt = 0 for i in range(10000): x = Variable(np.array([x_test[i]], dtype=np.float32)) t = t_test[i] y = model.forward(x) y = np.argmax(y.data[0]) if t == y: cnt += 1 print("accuracy: {}".format(cnt/10000)) serializers.save_npz("model.npz", model)
予測するサンプル1(TBD)
import numpy as np %matplotlib inline import matplotlib.pylab as plt from sklearn.datasets import fetch_mldata import chainer import chainer.links as L import chainer.functions as F from chainer import Chain, optimizers, Variable, serializers mnist = fetch_mldata('MNIST original', data_home='.') mnist.data = mnist.data.astype(np.float32) # image data 784*70000 [[0-255, 0-255, ...], [0-255, 0-255, ...], ... ] mnist.data /= 255 # to 0-1 mnist.target = mnist.target.astype(np.int32) # label data 70000 N = 60000 x_train, x_test = np.split(mnist.data, [N]) t_train, t_test = np.split(mnist.target, [N]) # to (n_sample, channel, height, width) x_train = x_train.reshape((len(x_train), 1, 28, 28)) x_test = x_test.reshape((len(x_test), 1, 28, 28)) class CNN(Chain): def __init__(self): super(CNN, self).__init__( conv1 = L.Convolution2D(1, 20, 5), # 入力:1 , 出力:20。両方記述。filter 5 conv2 = L.Convolution2D(20, 50, 5), # 入力:1 , 出力:20。両方記述。filter 5 l1 = L.Linear(800, 500), # ここの入力の計算は以下の参考HPを参照。 l2 = L.Linear(500, 500), l3 = L.Linear(500, 10, initialW=np.zeros((10, 500), dtype=np.float32)) ) def forward(self, x): h = F.max_pooling_2d(F.relu(self.conv1(x)), 2) h = F.max_pooling_2d(F.relu(self.conv2(h)), 2) h = F.relu(self.l1(h)) h = F.relu(self.l2(h)) h = self.l3(h) return h model = CNN() serializers.load_npz("model.npz", model) image_data = (TBD) x = Variable(np.array([image_data], dtype=np.float32)) y = model.forward(x) y = np.argmax(y.data[0])
予測するサンプル2 : 機械学習フレームワークchainerを使って1からコードをかいてみる(mnist編) - Qiita
def forwardではなくdef callにすると
class MLP(Chain): def __init__(self): super(MLP, self).__init__( l1=L.Linear(784, 100), l2=L.Linear(100, 100), l3=L.Linear(100, 10), ) def __call__(self, x): h1 = F.relu(self.l1(x)) h2 = F.relu(self.l2(h1)) y = self.l3(h2) return y
以下のようにpredictorで予測することができる
def predict(model, x_data): x = Variable(x_data.astype(np.float32)) y = model.predictor(x) return np.argmax(y.data, axis = 1)
答え合わせ。モデルの保存
def predict(model, x_data): x = Variable(x_data.astype(np.float32)) y = model.predictor(x) return np.argmax(y.data, axis = 1)
予測サンプル3 : Chainer: ビギナー向けチュートリアル Vol.1 - Qiita
import numpy as np from chainer import serializers from chainer.cuda import to_gpu from chainer.cuda import to_cpu model = MLP() serializers.load_npz('mnist_result/model_epoch-10', model) model.to_gpu(gpu_id) %matplotlib inline import matplotlib.pyplot as plt x, t = test[0] plt.imshow(x.reshape(28, 28), cmap='gray') plt.show() print('label:', t) x = to_gpu(x[None, ...]) y = model(x) y = to_cpu(y.data) print('predicted_label:', y.argmax(axis=1)[0])
参考:
Chainerでニューラルネットワーク及び畳み込みニューラルネットワークを実装してみた – データ分析エンジニアが気まぐれに更新するブログ
https://github.com/nocotan/chainer-examples/blob/master/examples/mnist-cnn.py
Convolutional Neural Networkを実装する - Qiita
機械学習フレームワークchainerを使って1からコードをかいてみる(mnist編) - Qiita
Chainer: ビギナー向けチュートリアル Vol.1 - Qiita
わかりやすい ↓
C++のお勉強(2)
一歩ずつ!
型・インスタンス・オブジェクト
構造体は型、型を使って作られた変数はインスタンス。特に、構造体は意味のある情報の塊なので、構造体変数のことをオブジェクトということがある。
アクセスの仕方:①オブジェクト.メンバ ②オブジェクトのポインタ->メンバ
列挙型
何らかのフラグを宣言するときによく用いられる
enum ResultFlag{ Success = 1, Failure = 0 }
三項演算子
a > b ? a : b 真ならばa、偽ならばb
静的変数
プログラムが実行される前にすでに位置がきまっている変数のこと。グローバル変数は静的変数。
初期化はローカル変数であっても一度しか行われない。関数を抜けても値が保存される。
スコープ
::をつけるとグローバル関数にアクセスできる
#inculde <iostream> int a = 1; int main(){ std::cout<< ::a << std::endl; }
メモリの動的確保
newとdeleteはセット。newでメモリを動的に確保でき、ポインタで受ける。
int *p = new int; *p = 0; cout << *p << endl; delete p;
配列
int *array; cin >> size; array = new int[size] delete[] array;
ポインタ
アドレスを入れることのできる変数
ポインタと参照の違い
参照は初期化時に一度参照を決めたら変更できないのに対し、ポインタは再代入すれば何度でも書き換えることが可能。その代わりポインタは*をつけないと参照先のメモリにアクセスできない。
const
ポインタや参照の前にconstをつけると参照先の値の変更ができなくなる。
int StrCount(char* str, char ch){ if (str[i] = ch) < contents > } //書き換わってしまう int StrCount(const char* str, char ch){ if (str[i] = ch) < contents > } //書き換わらない
本来はstr[i] == chとしたかったので、constとするとエラーにより気づくことができる
const char* p //参照先の値が定数 char* const p = &a //ポインタpが定数 const char* const p = &a //両方定数
コピーコンストラクタ
参考: コピーコンストラクタ
初期化と代入の違い
b = a ; //代入 コピーコンストラクタが呼ばれない intArray b = a; //初期化->コピーコンストラクタ intArray b(a); //初期化->コピーコンストラクタ
継承
privateは派生クラスにさえ公開されない。派生クラスにのみ公開する場合はprotectedにする。
基底クラスからコンストラクタが呼ばれ、派生クラスからデストラクタが呼ばれる。
基底クラスのコンストラクタに引数を持つ、派生クラスのコンストラクタを呼ぶときは以下のように指定する。
コンストラクタ(仮引数リスト) : 基底クラス名(実引数のリスト) , メンバ変数(初期化の値) { ... }
補足:基本の方であってもコンストラクタを持っている
int x(3); int x = 3;
参考:
アップキャスト
派生クラスのオブジェクトは基底クラスへの参照に渡すことができ、この暗黙のキャストをアップキャストという。
オーバーライド
同じ形の関数を派生クラスで再定義することをオーバーライドという。virtualをつけるとアップキャストしても派生クラスのメンバ関数が呼ばれる。
class hoge{ public: virtual bool Set(); };
オーバーライドとアップキャストなどで得られる性質をポリモーフィズムという
純粋仮想関数
protected: virtual void HogeBase() = 0
のようにvirtual ~ =0とすると純粋仮想関数になる。これが含まれているクラスは抽象クラスとよばれ、オブジェクトが作れない。
テンプレート
テンプレート引数、実引数
templete <typename TYPE> // <- テンプレート引数 void Test(TYPE* num, TYPE value) { int a = 1 } Test(0.1 , 0) //コンパイルエラー ∵double か intかわからない Test<double>(0.1 , 0) // <-テンプレート実引数
テンプレートクラス
templete <typename TYPE> class Array{...} int Array::Size() const{...} // コンパイルエラー ∵Arrayはクラステンプレートでクラスではない int Array<int>::Size() const{...} //テンプレート引数をもって初めてクラスになる int Array<double>::Size() const{...} //テンプレート引数をもって初めてクラスになる //↓ templete <typename TYPE> int Array<TYPE>::Size() const {...} //テンプレート引数をもって初めてクラスになる
エラー処理
try { if (エラー判定処理){ throw エラーメッセージ; } }catch(変数宣言){ エラー処理 }
throwなどで投げれれた例外は伝播するので、関数内で発生してもそれを用いている上位でtry catchがあれば、処理される。
例外のキャッチ漏れが無いように注意しよう。
例外の再送出
try{ throw "エラー発生" catch(...){ //したい処理をする throw; }
例外はアップキャスト可能
できる限り、基底クラスから離れた例外でcatchするようにしよう。
Exceptionへの参照のキャッチはできる限り使わない。ex:OpenFileExceptionなど基底クラスから離れたものを使う。
参考: ロベールのC++教室 - 第15章 アップキャスト -
メンバ初期化子
参考: メンバ初期化子 - ぷろみん
イテレータ
イテレータとは? | C++ フリーでぷろぐらみんぐさんから抜粋。わかりやすい。
#include <cstdlib> #include <iostream> vector<int> vec; vector<int>::iterator i; int sum = 0; vec.push_back(1); vec.push_back(2); vec.push_back(3); for(i=vec.begin(); i!=vec.end(); ++i){ sum += *i; } cout << sum << endl; // 6
参考: C++ iterator 入門
分類のお勉強
sklearnを用いた2クラス分類
#!/usr/bin/env python # coding: utf-8 import numpy as np from sklearn import datasets from sklearn import cross_validation from sklearn import metrics # DataSetの準備 iris = datasets.load_iris() # トレーニングデータ <type 'numpy.ndarray'>の(100,4) data = iris.data[0:100] # ラベルデータ (100) target = [] for t in iris.target[0:100]: if t==1: target.append(1) else: target.append(-1) # 全体のデータの2割を検証用 train_x, test_x, train_y, test_y = cross_validation.train_test_split(data, target, test_size=0.2) # 最小二乗法で学習 w = np.linalg.inv(train_x.T.dot(train_x)).dot(train_x.T).dot(train_y) # 最小二乗法で推定 for x in test_x: if w.dot(x) > 0: pred_y = np.array([1 if w.dot(x) > 0 else -1 for x in test_x]) # テストデータに対する正答率 print metrics.accuracy_score(test_y, pred_y)
参考:
Home · levelfour/machine-learning-2014 Wiki · GitHub
https://kaigi.org/jsai/webprogram/2012/pdf/340.pdf
とにかくCNNに学習させる大量の画像データが欲しいでごわすという人のためのスクリプト - shi3zの長文日記
画像データの2クラス分類
#!/usr/bin/env python #-*- encoding: utf-8 -*- from PIL import Image import numpy as np import os import pandas as pd import pylab as pl from sklearn.decomposition import RandomizedPCA from sklearn.externals import joblib from sklearn.svm import LinearSVC # STANDARD_SIZE = (300, 167) STANDARD_SIZE = (480, 640) def img_to_matrix(filename, verbose=False): img = Image.open(filename) if verbose: print 'changing size from %s to %s' % (str(img.size), str(STANDARD_SIZE)) img = img.resize(STANDARD_SIZE) imgArray = np.asarray(img) return imgArray # imgArray.shape = (167 x 300 x 3) def flatten_image(img): s = img.shape[0] * img.shape[1] * img.shape[2] img_wide = img.reshape(1, s) return img_wide[0] def main(): img_dir = 'images/' images = [img_dir + f for f in os.listdir(img_dir)] labels = ['takuya' if 'takuya' in f.split('/')[-1] else 'iron_man' for f in images] #labels = ['takuya' if 'takuya' in f.split('/')[-1] else 'iron_man' for f in images] #print images #print labels data = [] for image in images: img = img_to_matrix(image) img = flatten_image(img) data.append(img) data = np.array(data) #print data.shape # dataの数だけ一様乱数を生成し、0.7以下のものだけtrainに is_train = np.random.uniform(0, 1, len(data)) <= 0.7 # np.array(labels) == 'takuya'の時は1を、そうでないときは0を返す # yはlabel y = np.where(np.array(labels) == 'takuya', 1, 0) # train用をぶちこむ train_x, train_y = data[is_train], y[is_train] # plot in 2 dimensions # 主成分分析 pca = RandomizedPCA(n_components=2) # 分析結果を元にデータセットを主成分に変換する X = pca.fit_transform(data) #print X.shape df = pd.DataFrame({"x": X[:, 0], "y": X[:, 1], "label": np.where(y == 1, 'takuya', 'iron_man')}) colors = ['red', 'yellow'] for label, color in zip(df['label'].unique(), colors): mask = df['label'] == label pl.scatter(df[mask]['x'], df[mask]['y'], c=color, label=label) pl.legend() pl.savefig('pca_feature.png') # training a classifier pca = RandomizedPCA(n_components=5) train_x = pca.fit_transform(train_x) # C : ペナルティ項 svm = LinearSVC(C=1.0) svm.fit(train_x, train_y) joblib.dump(svm, 'model.pkl') # evaluating the model test_x, test_y = data[is_train == False], y[is_train == False] test_x = pca.transform(test_x) print pd.crosstab(test_y, svm.predict(test_x), rownames=['Actual'], colnames=['Predicted']) if __name__ == '__main__': main()
参考:
pythonを使って簡単な画像分類を実現する - stMind
Numpyのwhereで配列インデックスを取得(python) | コード7区
Python: scikit-learn で主成分分析 (PCA) してみる - CUBE SUGAR CONTAINER
scikit.learn手法徹底比較! SVM編 - Risky Dune
オブジェクト指向プログラミング(OOP)のお勉強
C++をベースの考えてみる
c++のコンパイルの仕方
参考
構造化言語では解決できない2つの問題
- グローバル変数
- 再利用性
参考:いまさら聞けない構造化手法とオブジェクト指向の違い(めっちゃわかりやすい) http://www.ogis-ri.co.jp/casestudy/docs/CaseStudy_ESEC2010_StructOO.pdf
OOPの優れた3つの仕組み
- クラス
- ポリモーフィズム
- 継承
これらは構造化言語の課題を解決することができる。重複した無駄なロジックを排除し、必要な機能を整理整頓する仕組みを提供する。
参考:
新人プログラマに知っておいてもらいたい人類がオブジェクト指向を手に入れるまでの軌跡 - Qiita
クラスとは
関連性の強いサブルーチンとグローバル変数を1つにまとめて粒度の大きいソフトウェアを作る仕組み
- サブルーチンと変数をまとめる
- クラスの内部だけで使うサブルーチンを隠す
- 一つのクラスからインスタンスをたくさん作る
クラスの効能1:まとめる
結びつきの強いサブルーチンとグローバル変数を一つのクラスにまとめることができ、以下のメリットが得られる。
- 部品数が減る
- メソッドの名前付けが楽になる
- メソッドが探しやすくなる
まとめ前
- 準備:test.txtにatomと記入
#include <iostream> #include <fstream> using namespace std; fstream file; int fileNO; void openFile(const char* fileName){ file.open(fileName, ios::in); } void closeFile(){ file.close(); } char readFile(){ char str; file.get(str); return str; } int main(){ char result; const char* filename = "test.txt"; openFile(filename); result = readFile(); closeFile(); cout << result << endl; }
結果:
a
まとめ後
#include <iostream> #include <fstream> using namespace std; class TextFileReader{ //クラスという単位で見ると一つに!また、大きなまとまりになるため探しやすい!! private: fstream file; int fileNO; public: void open(const char* fileName){ //名前がシンプルに!!! file.open(fileName, ios::in); } void close(){ file.close(); } char read(){ char str; file.get(str); return str; } }; int main(){ char ch1; char ch2; const char* filename = "test.txt"; TextFileReader reader1; reader1.open(filename); ch1 = reader1.read(); reader1.close(); cout << ch1 << endl; TextFileReader* reader2 = new TextFileReader; reader2->open(filename); ch2 = reader2->read(); reader2->close(); delete reader2; cout << ch2 << endl; }
結果:
a
a
クラスの効能2:隠す
クラスに定義した変数やメソッドを他のクラスから隠すことができる
これにより保守性悪化の原因となるグローバル変数を使わずにプログラムを書くことができる。
上記コードの抜粋↓
class TextFileReader{ private: //privateとするとクラス内部にあるメソッドだけがアクセスできる!変更されたないし、勝手にいじらせへんよ〜 fstream file; int fileNO; public: //アプリケーションのどこからでもアクセスできる!いつでも呼び出してや〜 void open(const char* fileName){ file.open(fileName, ios::in); } void close(){ file.close(); } char read(){ char str; file.get(str); return str; }
ちなみになにもしてしないと勝手にprivateになるよ〜
クラスの効能3:たくさん作る
インスタンスはクラスを定義しておけばそこから実行時にいくつでも作る(メモリ領域を確保する)ことができる
そのインスタンスのメソッドの呼び方↓
インスタンスを格納する変数. メソッド名(引数)
インスタンスを格納する変数ポインタ->メソッド名(引数)
- 準備:robot1.txtにatomと記入 . robot2.txtにbig hero 6 と記入.
#include <iostream> #include <fstream> using namespace std; class TextFileReader{ private: fstream file; int fileNO; public: void open(const char* fileName){ file.open(fileName, ios::in); } void close(){ file.close(); } char read(){ char str; file.get(str); return str; } }; int main(){ char ch1; char ch2; char ch3; const char* filename1 = "robot1.txt"; const char* filename2 = "robot2.txt"; TextFileReader* reader1 = new TextFileReader; //インスタンス一つ目製造 TextFileReader* reader2 = new TextFileReader; //インスタンス二つ目製造 reader1->open(filename1); ch1 = reader1->read(); reader1->close(); reader2->open(filename2); ch2 = reader2->read(); reader2->close(); delete reader1; delete reader2; // open(filename); // result = read(); // close(); cout << ch1 << endl; cout << ch2 << endl; TextFileReader reader3; //インスタンス三つ目製造 reader3.open(filename1); ch3 = reader3.read(); reader3.close(); cout << ch3 << endl; }
結果:
a
b
a
インスタンス変数、グローバル変数、ローカル変数
インスタンス変数
- 別クラスからアクセスできないよう隠すことができる
- 一度インスタンス化されば破棄されるまでメモリ上に残る
ポリモーフィズム(多様性)とは(インターフェースの継承)
共通メインルーチンを作るための仕組み、つまり、呼び出す側のロジックを一本化する
ポリモーフィズムはサブルーチンを呼び出す側のロジックを一本化する仕組み、共通サブルーチンを作る仕組み
継承(実装の継承)
クラス定義の共通部分を別クラスにまとめて、コードの重複を排除する仕組み
型にはまろう
型を指定することのメリットは 1. コンパイラにメモリ領域を教える 1. プログラムのエラーを防止する
型にクラスを指定できる
型チェックには強い型付けと弱い型付けの2種類の方式がある
python:弱い型付け(実行時点でエラーを検出)
ポリモ・継承・型はめのサンプル
基底クラス | 派生クラス | mainクラス |
---|---|---|
Stream | <- InputStream | Polymorphism |
<- ArrayStream |
Stream.h
#ifndef STREAM_H_ #define STREAM_H_ class Stream { public : double Get() const; virtual bool Set() = 0; //純粋仮想関数->このクラス(抽象クラス)は実体をつくることができない。 //virtual bool Set(); //仮想関数 private : double m_n; }; #endif
Stream.cpp
#include "Stream.h" #include <iostream> using namespace std; double Stream::Get() const { return m_n; } // bool Stream::Set() { // cout << "Stream::Set" << endl; // m_n = -1; // return false; // }
InputStream.h
#ifndef INPUTSTREAM_H_ #define INPUTSTREAM_H_ #include "Stream.h" class InputStream : public Stream{ //継承することでGetを定義する必要がなくなる。(コードの重複を排除) public: bool Set(); }; #endif
InputStream.cpp
#include "InputStream.h" #include <iostream> using namespace std; bool InputStream::Set(){ //Setをオーバーライド cin >> m_n; return m_n >= 0; }
ArrayStream.h
#ifndef ARRAYSTREAM_H_ #define ARRAYSTREAM_H_ #include "Stream.h" class ArrayStream : public Stream //継承することでGetを定義する必要がなくなる。(コードの重複を排除) { public : ArrayStream(const double* array); bool Set(); private: const double* m_array; int m_i; }; #endif
ArrayStream.cpp
#include "ArrayStream.h" ArrayStream::ArrayStream(const double* array){ m_array = array; m_i = 0; } bool ArrayStream::Set(){ //Setをオーバーライド m_n = m_array[m_i]; if ( m_n >= 0){ ++m_i; return true; }else{ return false; } }
Polymorphism.cpp
#include "InputStream.h" #include "ArrayStream.h" #include <iostream> using namespace std; bool Average(Stream& stream){ //こうすることで、InputStreamとArrayStreamr両方のAverage関数を作る必要がなくなる。(呼び出す側のロジックの一本化) int count; double avr = 0; for( count = 0 ; stream.Set(); ++count){ //virtual bool Set() = 0;サブクラスのSetが呼ばれる。virtualがないとスーパークラスのSetが呼ばれる。 avr += stream.Get(); } if (count == 0){ return false; } avr /= count; cout << "平均値は" << avr << "です。" << endl; return true; } int main () { InputStream istream; //型の**クラス**指定 Average(istream); //アップキャスト static const double ARRAY[] = {0.5, 1.5, -1}; ArrayStream astream(ARRAY); //型の**クラス**指定 Average(astream); //アップキャスト }
$ g++ Stream.cpp InputStream.cpp ArrayStream.cpp Polymorphism.cpp
結果 :
1
2
3
-1
平均値は2です。
平均値は1です。
パッケージ
クラスをさらにまとめる仕組み
#include <iostream> using namespace std; namespace { //無名名前空間 void PowerOn(){ cout << "Robot Start" << endl; } } namespace Robot1 { void Func(){ cout << "Robot1::Func" << endl; } void Mode(){ cout << "Robot1::Mode" << endl; } } namespace Robot2 { void Func(){ cout << "Robot2::Func" << endl; } } void Func(){ cout << "::Func" << endl; } namespace Robot3{ namespace Robot4{ namespace Robot5{ void Attack(){ cout << "Robot3~5::Attack" <<endl; } } } } namespace R345 = Robot3::Robot4::Robot5; int main() { PowerOn(); Robot1::Func(); Robot1::Mode(); Robot2::Func(); ::Func(); R345::Attack(); return 0; }
例外
戻り値とは違う形でメソッドから特別なエラーを返す仕組み
- 例外を宣言しているメソッドを呼び出す側では例外を処理するロジックを正しく書いていないとプログラムはエラーになる
- そのまま上位にエラーを伝えるときはメソッドで例外を宣言するだけでよい
Exception.cpp
#include <iostream> #include <fstream> #include <cstdlib> using namespace std; void Open(ifstream& file, const char* filename){ file.open(filename); if(! file.is_open()){ throw "ファイルを開けませんでした!"; //メソッドで例外を宣言すると関数外、上位へエラーが伝わる } } void GetLine(ifstream& file, string& line){ getline(file, line); if (file.fail()){ throw "ファイルから読み込めませんでした!"; } } int main(){ try { //OpenやGetLineで投げられたエラーがここで処理される ifstream file; Open(file, "test.txt"); string line; GetLine(file, line); cout << line << endl; }catch(const char* error){ //char -> intにするとエラーになる(terminate called after throwing an instance of 'char const*') cerr << error << endl; return EXIT_FAILURE; } }
test.txtがない場合の結果:
ファイルを開けませんでした!
test.txtが空の場合の結果:
ファイルから読み込めませんでした!
ガベージコレクション
インスタンスを削除する処理をシステムが自動的に実行する仕組み
参考:めっちゃわかりやすい
5分で分かるガベージコレクションの仕組み | geechs magazine
所感
整理整頓の仕組みがたくさんあるな〜。整理整頓上手になりたい。
参考: