空飛ぶロボットのつくりかた

ロボットをつくるために必要な技術をまとめます。ロボットの未来についても考えたりします。

機械学習のお勉強(chainerでkaggleに初挑戦)

Kaggleとは

公式:Kaggle: Your Home for Data Science

Kaggleは企業や研究者がデータを投稿し、世界中の統計家やデータ分析家がその最適モデルを競い合う、予測モデリング及び分析手法関連プラットフォーム及びその運営会社である。

Kaggle - Wikipedia

Kaggleを始めるのに参考になるサイト

Kaggle事始め - Qiita

Kaggle に Python で入門しました(Digit Recognizer) | Futurismo

Kaggle の Titanic チュートリアルに挑戦した話

Kaggleのtitanic問題で上位10%に入るまでのデータ解析と所感 - mirandora.commirandora.com

全体の流れ

Kaggle: Your Home for Data Science

  1. アカウントを作る

  2. トライするCompetitionを決める

  3. Dataをダウンロードする

  4. Dataを解析して、提出用csvファイルを作る

  5. 提出する

Digit Recognizerをやってみる(chainerを使用)

trainとtestのcsvファイルのダウンロード

Digit Recognizer | Kaggle

chainer用のデータセットの作り方

とてもわかりやすい 👇

chainerのデータセットの作り方 LinearやCNN - Qiita

chainerの独自datasetの作り方 - 午睡二時四十分

ChainerのCNNにおけるデータセットの作り方 – ハックマン.com

Chainer: ビギナー向けチュートリアル Vol.1 - Qiita

chainerはtupleで[data,label]となるようにdatasetsを作ってから、学習を行う

Import

# -*- coding: utf-8 -*-
import chainer
import pandas as pd
import chainer.functions as F
import chainer.links as L
from chainer import training
from chainer.training import extensions
import pandas as pd
import numpy as np
from chainer import datasets
from chainer.datasets import tuple_dataset

from chainer import serializers

kaggle dataをchainerデータセットに変換

train = pd.read_csv('./train.csv')
test  = pd.read_csv('./test.csv')

features = train.ix[:,1:].values
labels = train.ix[:,0]

features = features.reshape(features.shape[0],28,28)

imageData = []
labelData = []
for i in range(len(labels)):
    img = features[i]
    imgData = np.asarray(np.float32(img)/255.0)
    imgData = np.asarray([imgData])
    imageData.append(imgData)
    labelData.append(np.int32(labels[i]))

threshold = np.int32(len(imageData)/8*7)
train = tuple_dataset.TupleDataset(imageData[0:threshold], labelData[0:threshold])
val  = tuple_dataset.TupleDataset(imageData[threshold:],  labelData[threshold:])

Trainerで学習

モデル

class CNN(chainer.Chain):
    def __init__(self, train=True):
        super(CNN, self).__init__(
            conv1=L.Convolution2D(1, 32, 5),
            conv2=L.Convolution2D(32, 64, 5),
            l1=L.Linear(1024, 10),
        )
        self.train = train

    def __call__(self, x):
        h = F.max_pooling_2d(F.relu(self.conv1(x)), 2)
        h = F.max_pooling_2d(F.relu(self.conv2(h)), 2)
        return self.l1(h)

学習

model = L.Classifier(CNN())

optimizer = chainer.optimizers.Adam()
optimizer.setup(model)

train_iter = chainer.iterators.SerialIterator(train, batch_size=100)
test_iter = chainer.iterators.SerialIterator(val, batch_size=100, repeat=False, shuffle=False)

updater = training.StandardUpdater(train_iter, optimizer)
trainer = training.Trainer(updater, (5, 'epoch'), out='result')

trainer.extend(extensions.Evaluator(test_iter, model))
trainer.extend(extensions.LogReport())
trainer.extend(extensions.PrintReport(
    ['epoch', 'main/loss', 'validation/main/loss',
     'main/accuracy','validation/main/accuracy']))
trainer.extend(extensions.ProgressBar())

trainer.run()
serializers.save_npz("digit-learn5.data", model)

テストデータの準備

test = test.ix[:,:].values.astype('float32')
test_data = test.reshape(test.shape[0],28,28)

testData = []
for i in range(len(test_data)):
    img = test_data[i]
    imgData = np.asarray(np.float32(img)/255.0)
    imgData = np.asarray([imgData])
    testData.append(imgData)

作成モデルでの予測

def predict(model, test):
    # テストデータ全部に対して予測を行う
    preds = []
    for img in test:
        img = img.reshape(-1, 1, 28, 28)
        pred = F.softmax(model.predictor(img)).data.argmax()
        preds.append(pred)
    return preds

predictions = predict(model, testData)

kaggle提出用フォーマットに変換

submissions = pd.DataFrame({"ImageId": list(range(1, len(predictions)+1)),
                             "Label": predictions})
submissions.to_csv("digit_cnn_output.csv", index=False, header=True)

提出

f:id:robonchu:20171008213311p:plain

ここのsubmit predictionsに上記でできたdigit_cnn_output.csvをアップロード

結果

527位 (/ 1661)

f:id:robonchu:20171008213327p:plain

これからコツコツ学んだことを活かして、100位以内を目指してみる〜

コードも適当なので、もっと綺麗にかけるよう練習する

2017/10/11

331位

f:id:robonchu:20171011225357p:plain

全体参考

nocotan.github.io 👈 最高にわかりやすい

GitHub - nocotan/chainer-examples: This is implementation examples by Chainer.

Chainer: ビギナー向けチュートリアル Vol.1 - Qiita

Kaggleを始めてみる - サイバースイッチ

top2%の私が教えるKaggleの極意, Bosch Production Line Performance | RCO Ad-Tech Lab Blog

機械学習のお勉強(scikit-learnを使ってみる:分類問題)

教科書

GitHub - rasbt/python-machine-learning-book: The "Python Machine Learning (1st edition)" book code repository and info resource

Perceptron

実装

# -*- coding: utf-8 -*

from sklearn import datasets
import numpy as np

# Added version check for recent scikit-learn 0.18 checks
from distutils.version import LooseVersion as Version
from sklearn import __version__ as sklearn_version

if Version(sklearn_version) < '0.18':
    from sklearn.cross_validation import train_test_split
else:
    from sklearn.model_selection import train_test_split

# 正規化
from sklearn.preprocessing import StandardScaler
# パーセプトロン
from sklearn.linear_model import Perceptron
from sklearn.metrics import accuracy_score


# load data
iris = datasets.load_iris()
X = iris.data[:, [2, 3]]
y = iris.target
print('Class labels:', np.unique(y))

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.3, random_state=0)

# 正規化
sc = StandardScaler()
sc.fit(X_train)
X_train_std = sc.transform(X_train)
X_test_std = sc.transform(X_test)

# Perceptron Fit
ppn = Perceptron(n_iter=40, eta0=0.1, random_state=0)
ppn.fit(X_train_std, y_train)

# show accuracy
y_pred = ppn.predict(X_test_std)
print('Misclassified samples: %d' % (y_test != y_pred).sum())
print('Accuracy: %.2f' % accuracy_score(y_test, y_pred))

大事なのは

# Perceptron Fit
ppn = Perceptron(n_iter=40, eta0=0.1, random_state=0)
ppn.fit(X_train_std, y_train)

結果

Misclassified samples: 4
Accuracy: 0.91

結果を可視化(コードは教科書Git参照) 👇

f:id:robonchu:20171007142545p:plain

3クラス分類において、線形の決定境界で完全に区切ることができない

ロジスティック回帰

分類のためのモデルで、線形分類問題と2値分類問題に使用される

f:id:robonchu:20171007145614p:plain

ロジスティック関数

起こりやすさを表すオッズ比(P =p/(1-p))の対数の逆関数

f:id:robonchu:20171007144018p:plain

入力として実数を受け取り、[0,1]の範囲の値に変換する。出力はそのクラスに所属している確率と解釈できる。

例として、降水確率や病気の確率を出す際などに利用されている

コスト関数

J = cost func
p = probability

if y==0:
    J = -log(1-p)
elis y==1:
    J = -log(p)

f:id:robonchu:20171007145559p:plain

実装

上記パーセプトロンPerceptron Fit以降を下のように書き換える

from sklearn.linear_model import LogisticRegression

lr = LogisticRegression(C=1000.0, random_state=0)
lr.fit(X_train_std, y_train)

y_pred = lr.predict(X_test_std)
print('Misclassified samples: %d' % (y_test != y_pred).sum())
print('Accuracy: %.2f' % accuracy_score(y_test, y_pred))

# output probability
print lr.predict_proba(X_test_std[0,:])

結果

Misclassified samples: 1
Accuracy: 0.98
[[  2.05743774e-11   6.31620264e-02   9.36837974e-01]]

パーセプトロンより向上している

f:id:robonchu:20171007150358p:plain

lr = LogisticRegression(C=1000.0, random_state=0)

のCについて以下で説明する

L2正規化

極端なパラメータの重みにペナルティをかす。コスト関数に正規化の項を追加すればよい

+ lambda / 2 * w2 **をコスト関数に足すことで、さらには、lambdaを大きくすることで、重みを小さく保ちながら学習させることができる。

J = cost func
p = probability
w = weight

if y==0:
    J = -log(1-p) + lambda / 2 * w**2 
elis y==1:
    J = -log(p) + lambda / 2 * w**2 

C = 1 / lambdaを表している。Cの値を減らすと重みが小さくなる。

f:id:robonchu:20171007152629p:plain

正規化をするメリットは?

参考:ニューラルネットワークと深層学習

直感的には、正規化することによりニューラルネットワークがより小さな重みを好むようになります。 大きな重みが許されるのは、そうすることがコスト関数の第1項を余程大きく改善する場合だけです。 言い換えると、正規化とは重みを小さくすることと元のコスト関数を小さくすることの間でバランスを取る方法であると 見ることもできます。このバランスを取る上で、2つの要素の相対的な重要性を決定するのが λλ の値です: λλ が小さい時は元のコスト関数を最小化することを好み、λλ が大きい時には より小さな重みを好むのです。

さて、実際のところ、そのようなバランスを取ることがなぜ過適合を軽減する助けになるのか、 その理由は誰の目にもすぐさま明らかなものではありません。しかし、正規化が実際に過適合を軽減することは分かっています。

もっと深堀りすると 👇

正規化されたニューラルネットワークで期待されるように、 ニューラルネットワークの大部分では小さな重みを持つと仮定しましょう。 重みが小さいということは、ここそこでランダムな入力を変化させても ニューラルネットワークの振る舞いが大きくは変わらないことを意味します。 そのため、正規化されたニューラルネットワークでは、 データに含まれる局所的なノイズの効果を学習しづらくなっています。 その代わり、正規化されたニューラルネットワークは訓練データの中で繰り返し見られる データの特徴に反応するのです。対照的に、大きな重みを持つニューラルネットワークは、 入力の小さな変化に敏感に反応してその振る舞いを大きく変えてしまいます。 そのため、正規化されていないニューラルネットワークは、大きな重みを使って、 訓練データのノイズに関する情報をたくさん含んだ複雑なモデルを学習してしまうのです。 要するに、正規化されたニューラルネットワークは訓練データに頻繁に現れるパターンに基づいた 比較的シンプルなモデルを構築します。そして、訓練データが持つノイズの特異性を学ぶことに対して 耐性を持つのです。このため、ニューラルネットワークがノイズではなく現象そのものに対する真の学習をして、 それをより良く汎化できるのではないかと、希望が持てます。

サポートベクターマシン

マージン最大化を行う

f:id:robonchu:20171007154052p:plain

コスト関数

cost func = 1 / 2 * w**2

スラック変数を用いた際のコスト関数

epsilon = slack variable
cost func = 1 / 2 * w**2 + C * (sum(epsilon))

このCを変化させることで、バイアスとバリアンスのトレードオフを調整できる

f:id:robonchu:20171007164718p:plain

二次計画法

線形SVM - 人工知能に関する断創録

数学的に考えてみる(ハードマージンSVM) - Shogo Computing Laboratory

http://numaf.net/Z9/Z9a/html/THESIS/H15/abst_toda.pdf

http://www.r.dl.itc.u-tokyo.ac.jp/~nakagawa/SML1/kernel1.pdf

実装

上記パーセプトロンPerceptron Fit以降を下のように書き換える

svm = SVC(kernel='linear', C=1.0, random_state=0)
svm.fit(X_train_std, y_train)

y_pred = svm.predict(X_test_std)
print('Misclassified samples: %d' % (y_test != y_pred).sum())
print('Accuracy: %.2f' % accuracy_score(y_test, y_pred))

結果

Misclassified samples: 1
Accuracy: 0.98

f:id:robonchu:20171007165203p:plain

カーネルSVM

考え方:射影関数によってデータを高次元空間へ射影し、線形分離できるようにする

f:id:robonchu:20171007170455p:plain

デメリット

射影変換(phi(x))を行うと本来、学習過程で生じるxxである計算がphi(x)phi(x)となるため、計算コストがかかる

しかし、カーネルトリックを用いることで軽減できる

k(x_i,x_j) = phi(x_i) * phi(x_j)

# Radial Basis Function kernel
k(x_i,x_j) = exp(-(x_i - x_j)**2 / (2 * sigma**2))

# Simple Radial Basis Function kernel
k(x_i,x_j) = exp(- gamma *(x_i - x_j)**2 )

Radial Basis Function kernelは2つのサンプル間の類似度を表してる

実装

上記パーセプトロンPerceptron Fit以降を下のように書き換える

先のkernelのパラメータがlinearからrbfに変わっただけ 👇

svm = SVC(kernel='rbf', random_state=0, gamma=0.10, C=10.0)
svm.fit(X_train_std, y_train)
y_pred = svm.predict(X_test_std)
print('Misclassified samples: %d' % (y_test != y_pred).sum())
print('Accuracy: %.2f' % accuracy_score(y_test, y_pred))

パラメータのgammaは

# Simple Radial Basis Function kernel
k(x_i,x_j) = exp(- gamma *(x_i - x_j)**2 )

のgammaで小さくするとなめらかに、大きくすると複雑になる

gamma = 0.2にすると 👇

f:id:robonchu:20171007172620p:plain

gamma = 100.0にすると 👇

f:id:robonchu:20171007172701p:plain

未知のデータでは汎化誤差が生じることが予想される

決定木

意味解釈可能性に配慮する場合に良いモデル

f:id:robonchu:20171007173102p:plain

上記のようなカテゴリだけでなく実数でも可能。閾値を1.0などと決めるだけで良い。

決定木の深さが深くなる場合、深さの制限や剪定が必要になる。

情報利得の最大化

目的関数(二分木)

親ノードの不純度と子ノードの不純度の合計の差。つまり、子ノードの不純度が低いほど情報利得は大きくなる

I = Impurity(不純度)
Dp = Parent DataSet
Dleft = Child DataSet
Dright
f = function

I(Dp, f) = I(Dp) - Nleft/Np * I (Dleft) - Nright/Np * I (Dright)
不純度:エントロピー

t:ノード

相互情報量が最大化になるよう試みる。p(1|t)=1 or p(0|t)=0の時エントロピーは0。p(1|t)=1/2 or p(0|t)=1/2の時エントロピーは1。

Ih = - sum(p(i|t)log2 p(i|t))
不純度:ジニ不純度

誤分類の確率を最小化

Ig = sum(p(i|t) * (1 - p(i|t))) = 1 - sum(p(i|t)**2)

エントロピーと同様、p(1|t)=1 or p(0|t)=0の時エントロピーは0。p(1|t)=1/2 or p(0|t)=1/2の時エントロピーは1。

不純度:分類誤差

すべてのサンプルが最大条件付き確率を与えるクラスに所属すると予測した時に間違えるサンプルの割合を表現する

Ie = 1 - max(p(i|t))
不純度の比較

f:id:robonchu:20171007180032p:plain

実装

上記パーセプトロンPerceptron Fit以降を下のように書き換える

決定木の場合、特徴量のスケーリングは必要ない。

from sklearn.tree import DecisionTreeClassifier

tree = DecisionTreeClassifier(criterion='entropy', max_depth=3, random_state=0)
tree.fit(X_train, y_train)
y_pred = tree.predict(X_test_std)
print('Misclassified samples: %d' % (y_test != y_pred).sum())
print('Accuracy: %.2f' % accuracy_score(y_test, y_pred))

# 決定木の可視化
from sklearn.tree import export_graphviz

export_graphviz(tree, 
                out_file='tree.dot', 
                feature_names=['petal length', 'petal width'])

f:id:robonchu:20171007181056p:plain

f:id:robonchu:20171007181113p:plain

ランダムフォレスト

決定木のアンサンブルと考えることができる

  1. トレーニングデータからランダムにn個のサンプルを抽出

  2. 決定木を成長させる

  3. 上記を繰り返す

  4. 決定木ごとの予測をまとめて多数決に基づいてクラスラベルを割り当てる

アンサンブル学習

ランダムフォレスト

「はじめてでもわかる RandomForest 入門-集団学習による分類・予測 -」 -第7回データマイニング+WEB勉強会@東京

メリット

パラメータの設定に悩む必要が少なく、上記ステップ1,2を何回繰り返すかを設定すれば良い。繰り返す回数を増やせば性能が上がるが計算コストが増える。

ポイント

上記ステップ1のnは多くの場合サンプルと同じ数に設定するのが良い

実装

上記パーセプトロンPerceptron Fit以降を下のように書き換える

10個決定木からランダムフォレストをトレーニング

from sklearn.ensemble import RandomForestClassifier

forest = RandomForestClassifier(criterion='entropy',
                                n_estimators=10, 
                                random_state=1,
                                n_jobs=2)
forest.fit(X_train, y_train)
y_pred = forest.predict(X_test_std)
print('Misclassified samples: %d' % (y_test != y_pred).sum())
print('Accuracy: %.2f' % accuracy_score(y_test, y_pred))

f:id:robonchu:20171007185228p:plain

k近傍法

怠惰学習の代表例。識別関数を学習せずトレーニングデータセットを暗記する。ノンパラメトリックモデル。

  1. kの値と距離指標を選択

  2. 分類したいサンプルからk個の最近傍のデータ点を見つける

  3. 多数決によりクラスラベルを割り当てる

f:id:robonchu:20171007185813p:plain

実装

from sklearn.neighbors import KNeighborsClassifier

knn = KNeighborsClassifier(n_neighbors=5, p=2, metric='minkowski')  # Power parameter for the Minkowski metric
knn.fit(X_train_std, y_train)

y_pred = knn.predict(X_test_std)
print('Misclassified samples: %d' % (y_test != y_pred).sum())
print('Accuracy: %.2f' % accuracy_score(y_test, y_pred))

f:id:robonchu:20171007190729p:plain

結果

Misclassified samples: 0
Accuracy: 1.00

機械学習のお勉強(Tiny Yoloを動かしてみる:予測のみ)

やりたいこと

低スペックパソコンで Tiny YOLOを使ってざっくりとした人の位置と大きさを出力する

教科書 👇

わかりやすい記事ありがとうございます。

ChainerでYOLO - Qiita

今回扱うTinyYOLOの説明

上記でもあるように、

Pascal VOCという20クラス分類問題のデータセットに対して係数は最適化されています。

全画面を7x7のグリッドに区切り、グリッドごとのクラス確率と、そのグリッド内に中心をもつバウンディングボックスを1グリッドにつき最大2つずつ、そして、その2つのバウンディングボックス信頼度、というすべての情報を直接推論します。

バウンディングボックスの座標は中心位置のx,yをグリッドサイズで0から1.0に正規化した数値、サイズは幅と高さを画像サイズで0から1.0に正規化した数値の平方根になっています。平方根にする理由は、サイズが大きくなったときの誤差のペナルティを減らしたいからだそうです。

最終段の出力ベクトルは、

7x7x20 のグリッドごとの20クラスの確率
7x7x2 の各グリッドに2組のバウンディングボックスごとの信頼度
7x7x2x4 の各グリッドに2組のバウンディングボックス座標(0-1で正規化してある)

という順番で並んでいるので、reshapeしたあと、信頼度の高いバウンディングボックスを特定して、その座標とクラスを取り出します。

推論時はクラス確率とバウンディングボックスの信頼度を乗算してしきい値で切ればよいですが、学習時は重要なところだけロス関数に乗りやすいような工夫をするそうです。

という感じ。

モデル自体はシンプルで、使っているのは

  • 畳み込み層

  • 全結合層

  • leaky_relu(活性関数)

  • Max Pooling

くらい

実装(CPU)

[https://github.com/ashitani/YOLO_chainer:title] さんの実装を少しだけ変更する。ありがたや。

predict.py

import numpy as np

def predict(model,im_org):
  im0=cv2.cvtColor(im_org, cv2.COLOR_BGR2RGB)
  im_size=np.shape(im0)
  im0=cv2.resize(im0,(448,448))
  im=np.asarray(im0,dtype=np.float32)/255.0
  im=im*2.0-1.0

  ans=model.predict( im.transpose(2,0,1).reshape(1,3,448,448)).data[0]

  probs=ans[0:980].reshape((7,7,20))     # class probabilities
  confs=ans[980:1078].reshape((7,7,2))   # confidence score for Bounding Boxes
  boxes = ans[1078:].reshape((7,7,2,4))  # Bounding Boxes positions (x,y,w,h)

  p=np.zeros((7,7,2,20))
  for i in range(20):
      for j in range(2):
          p[:,:,j,i]=np.multiply(probs[:,:,i],confs[:,:,j])

  th=0.1

  im_h=im_size[0]
  im_w=im_size[1]

  im_marked=im_org

  classes = ["aeroplane", "bicycle", "bird", "boat", "bottle",
             "bus", "car", "cat", "chair", "cow",
             "diningtable", "dog", "horse", "motorbike", "person",
             "pottedplant", "sheep", "sofa", "train","tvmonitor"]

  pos_size = None
  class_label = None

  for z in np.argwhere(p>th):
      by,bx,j,i = z
      box=boxes[by,bx,j,:]
      x= (bx+box[0])*(im_w/7)
      y = (by+box[1])*(im_h/7)
      w = box[2]**2.0*im_w
      h = box[3]**2.0*im_h
      im_marked=cv2.rectangle(im_marked, (int(x-w/2), int( y-h/2)),( int(x+w/2), int(y+h/2)),[0,0,255],thickness=2)
      im_marked=cv2.rectangle(im_marked, (int(x-w/2), int( y-h/2)),( int(x-w/2+100), int(y-h/2+20)),[0,0,255],thickness=-1)
      cv2.putText(im_marked, classes[i],(int(x-w/2+5),int(y-h/2+15)), cv2.FONT_HERSHEY_SIMPLEX,0.5,(0,0,0),thickness=2)

      pos_size = [x, y, box[2]**2.0, box[3]**2.0]
      class_label = classes[i]

  return im_marked, class_label, pos_size

replay.py

#!/usr/bin/env python

from YOLOtiny_chainer import *
import cv2
import sys
import os
import numpy as np

print "Loading model"
model=YOLOtiny()
serializers.load_npz('YOLOtiny_chainer/YOLOtiny.model',model)

cap = cv2.VideoCapture(0)

while(1):
    _, frame = cap.read()

    im_marked, class_label, pos_size = predict(model,frame)

    if class_label is "person":
        size = pos_size[2] * pos_size[3]  # volume of bounding box 
    print "position_x:{}".format(pos_size[0]) , "position_y:{}".format(pos_size[1])
    print "person_size:{}".format(size)

    cv2.imshow('im_marked',im_marked)
    k = cv2.waitKey(5) & 0xFF
    if k == 27:
        break

cap.release()
cv2.destroyAllWindows()

出力結果はこんな感じ 👇

  • bounding boxの中心位置(取得画像サイズでの横軸X,縦軸Yの値)
  • bounding boxの面積 (ざっくりとしたサイズ)

f:id:robonchu:20171007111844p:plain

実装(GPU)

import cv2
import numpy as np
from chainer import cuda

def predict(model, im_org, device = -1):    
  im0=cv2.cvtColor(im_org, cv2.COLOR_BGR2RGB)
  im_size=np.shape(im0)
  im0=cv2.resize(im0,(448,448))
  im=np.asarray(im0,dtype=np.float32)/255.0
  im=im*2.0-1.0

  img = im.transpose(2,0,1).reshape(1,3,448,448)

  if device == 0:
    cuda.get_device(device).use()
    model.to_gpu(device)
    img = cuda.to_gpu(img, device)
    xp = cuda.cupy
  else:
    xp = np
    
  ans=model.predict(img).data[0]

  probs=ans[0:980].reshape((7,7,20))     # class probabilities
  confs=ans[980:1078].reshape((7,7,2))   # confidence score for Bounding Boxes
  boxes = ans[1078:].reshape((7,7,2,4))  # Bounding Boxes positions (x,y,w,h)

  p=xp.zeros((7,7,2,20))
  for i in range(20):
      for j in range(2):
          p[:,:,j,i]=xp.multiply(probs[:,:,i],confs[:,:,j])

  th=0.1

  im_h=im_size[0]
  im_w=im_size[1]

  im_marked=im_org

  classes = ["aeroplane", "bicycle", "bird", "boat", "bottle",
             "bus", "car", "cat", "chair", "cow",
             "diningtable", "dog", "horse", "motorbike", "person",
             "pottedplant", "sheep", "sofa", "train","tvmonitor"]

  pos_size = None
  class_label = None

  for z in np.argwhere(p>th):
      by,bx,j,i = z
      print i
      box=boxes[by,bx,j,:]
      x= (bx+box[0])*(im_w/7)
      y = (by+box[1])*(im_h/7)
      w = box[2]**2.0*im_w
      h = box[3]**2.0*im_h
      im_marked=cv2.rectangle(im_marked, (int(x-w/2), int( y-h/2)),( int(x+w/2), int(y+h/2)),[0,0,255],thickness=2)
      im_marked=cv2.rectangle(im_marked, (int(x-w/2), int( y-h/2)),( int(x-w/2+100), int(y-h/2+20)),[0,0,255],thickness=-1)
      cv2.putText(im_marked, classes[int(i)],(int(x-w/2+5),int(y-h/2+15)), cv2.FONT_HERSHEY_SIMPLEX,0.5,(0,0,0),thickness=2)

      pos_size = [x, y, box[2]**2.0, box[3]**2.0]
      class_label = classes[int(i)]

  return im_marked, class_label, pos_size

インストール

chainerでサポートしているversionチェックするの大事

  1. CUDA 8.0
  2. cuDNN v6.0

参考サイト:

Installation Guide — Chainer 3.0.0rc1 documentation

Installation Guide — CuPy 2.0.0rc1 documentation

Ubuntu16.04にCUDA8.0とChainerをインストールする - Qiita

CUDA 8.0とcuDNN 6をUbuntu 16.04LTSにインストールする - Qiita

Chainerアップデート(ver1系→2)にはまったCuPyインストール編…sudoの甘い(嘘)罠… - Qiita

機械学習のお勉強(chainerのTrainerについて)

公式Docs

How to write a training loop in Chainer — Chainer 3.0.0rc1 documentation

わかりやすいまとめ

Chainer の Trainer 解説と NStepLSTM について

MNIST分類コードをChainer-v1.11.0のTrainerで書き換える - Monthly Hacker's Blog

Chainer: ビギナー向けチュートリアル Vol.1 - Qiita

使い方

  1. Trainerオブジェクト(trainer)をつくる

  2. trainer.run()で実行

Trainerオブジェクトの例

ChainerのTrainerを使ってみた - のんびりしているエンジニアの日記さんわかりやすい記事ありがとうございます👇

# coding:utf-8
from __future__ import absolute_import
from __future__ import unicode_literals
import chainer
import chainer.datasets
from chainer import training
from chainer.training import extensions
import chainer.links as L
import chainer.functions as F


class MLP(chainer.Chain):
    def __init__(self, n_units, n_out):
        super(MLP, self).__init__(
            l1=L.Linear(None, n_units),
            l2=L.Linear(None, n_units),
            l3=L.Linear(None, n_out),
        )

    def __call__(self, x):
        h1 = F.relu(self.l1(x))
        h2 = F.relu(self.l2(h1))
        return self.l3(h2)


train, test = chainer.datasets.get_mnist()
train_iter = chainer.iterators.SerialIterator(train, 32)
test_iter = chainer.iterators.SerialIterator(test, 32,
                                             repeat=False, shuffle=False)
model = L.Classifier(MLP(784, 10))
optimizer = chainer.optimizers.SGD()
optimizer.setup(model)
updater = training.StandardUpdater(train_iter, optimizer, device=-1)
trainer = training.Trainer(updater, (10, 'epoch'), out="result")  # epoch数の指定

trainer.extend(extensions.Evaluator(test_iter, model, device=10)) # 評価
trainer.extend(extensions.dump_graph('main/loss'))
trainer.extend(extensions.snapshot(), trigger=(10, 'epoch'))
trainer.extend(extensions.LogReport())
trainer.extend(extensions.PrintReport(
    ['epoch', 'main/loss', 'validation/main/loss',
     'main/accuracy', 'validation/main/accuracy']))
trainer.extend(extensions.ProgressBar())
trainer.run()

参考:

chainer/train_mnist.py at master · chainer/chainer · GitHub

chainer 1.11.0のMNISTサンプルを例にtrainerを読み解く - Monthly Hacker's Blog

Extension

Trainer extensions — Chainer 2.0.2 documentation

Trainerオブジェクトから学習済みモデルを取り出す方法

model = trainer.updater.get_optimizer('main').target.predictor
prediction = model(img)

chainer全体のわかりやすい記事

【機械学習】ディープラーニング フレームワークChainerを試しながら解説してみる。 - Qiita

機械学習のお勉強(データセット)

Segmentation

ADK20K

いい感じ

ADE20K dataset

SUN RGB-D

  • Introduced: CVPR 2015

  • Device: Kinect v1, Kinect v2, Intel RealSense and Asus Xtion Live Pro

  • Description: New images, plus images taken from NYUv2, B3DO and SUN3D. All of indoor scenes.

  • Labelling: 10,335 images with polygon annotation, and 3D bounding boxes around objects

  • The dataset contains RGB-D images from NYU depth v2 [1], Berkeley B3DO [2], and SUN3D [3]. Besides this paper, you are required to also cite the following papers if you use this dataset.

SUN RGB-D: A RGB-D Scene Understanding Benchmark Suite

NYU Dataset v2

  • ~408,000 RGBD images from 464 indoor scenes, of a somewhat larger diversity than NYU v1. Per-frame accelerometer data.

NYU Depth V2 « Nathan Silberman

SceneNet RGB-D

  • Description: 5 million images rendered of 16,895 indoor scenes. Room configuration randomly generated with physics simulator.

  • Labelling: Camera pose, plus per-pixel instance, class labelling and optical flow.

SceneNet RGB-D: Photorealistic Rendering of 5M Images with Perfect Ground Truth

機械学習のお勉強(Classification,Detection,Segmentationの有名論文)

All

CVPR論文まとめ

http://hirokatsukataoka.net/temp/cvpaper.challenge/cvpr17_finalize.pdf

Classification,Detection,Segmentation

UberNet

https://arxiv.org/pdf/1609.02132.pdf

Classification

全体

chainer/examples/imagenet at master · chainer/chainer · GitHub

AlexNet

論文

https://www.cs.toronto.edu/~kriz/imagenet_classification_with_deep_convolutional.pdf

論文まとめ

AlexNet論文 | 有意に無意味な話

【深層学習】畳み込みニューラルネットで画像分類 [DW 4日目] - Qiita

VGG16

論文

https://arxiv.org/pdf/1409.1556.pdf

論文まとめ

機械学習論文読み:VERY DEEP CONVOLUTIONAL NETWORKS FOR LARGE-SCALE IMAGE RECOGNITION - Qiita

Fine-tuning

http://www.nlab.ci.i.u-tokyo.ac.jp/pdf/CNN_survey.pdf

ResNet

論文

https://arxiv.org/pdf/1512.03385.pdf

論文まとめ

ResNet論文を読んだメモ(arXiv:1512.03385) - 緑茶思考ブログ

Res netと派生研究の紹介

機械学習論文読み:Deep Residual Learning for Image Recognition - Qiita

[Survey]Deep Residual Learning for Image Recognition - Qiita

Residual Network(ResNet)の理解とチューニングのベストプラクティス - DeepAge

SqueezeNet

Fireブロックを8つ重ねたモデル

論文

https://arxiv.org/pdf/1602.07360.pdf

論文まとめ

SqueezeNet: AlexNet-level accuracy with 50x fewer parameters and <1MB model sizeを読んだ

chainerbook/fcn_squeeze.py at master · ghmagazine/chainerbook · GitHub

https://www.semiconportal.com/archive/contribution/applications/170418-neurochip5-2.html

20160901 jwein

Squeezenet-residual by songhan

[Survey]SqueezeNet: AlexNet-level accuracy with 50x fewer parameters and <1MB model size - Qiita

2016年の深層学習を用いた画像認識モデル - Qiita

DenseNet

論文

https://arxiv.org/pdf/1608.06993.pdf

Git

GitHub - liuzhuang13/DenseNet: Densely Connected Convolutional Networks, In CVPR 2017 (Best Paper Award).

Local Binary Convolutional Neural Networks

https://arxiv.org/pdf/1608.06049.pdf

Detection

全体

Deep Learningによる一般物体検出アルゴリズムの紹介 - ABEJA Tech Blog

Object Detection & Instance Segmentationの論文紹介 | OHS勉強会#3

R-CNN

論文

https://arxiv.org/pdf/1311.2524.pdf

論文まとめ

R-CNNの原理とここ数年の流れ

20140131 R-CNN

Faster R-CNN

論文

https://arxiv.org/pdf/1506.01497.pdf

論文まとめ

論文紹介: Fast R-CNN&Faster R-CNN

yolo

YOLO: Real-Time Object Detection

論文

https://arxiv.org/pdf/1506.02640.pdf

https://arxiv.org/pdf/1612.08242.pdf

論文まとめ

Introduction to YOLO detection model

YOLO CVPR 2016 - Google スライド

SSD

論文

https://arxiv.org/pdf/1512.02325.pdf

論文まとめ

SSD: Single Shot MultiBox Detector (ECCV2016)

SSD:Single Shot Multibox Detector - Qiita

Mask R-CNN

論文

https://arxiv.org/pdf/1703.06870.pdf

論文まとめ

最新の物体検出手法Mask R-CNNのRoI AlignとFast(er) R-CNNのRoI Poolingの違いを正しく理解する - Qiita

輪郭/物体抽出の新スタンダードになるか? – Mask R-CNN

A Brief History of CNNs in Image Segmentation: From R-CNN to Mask R-CNN

https://lmb.informatik.uni-freiburg.de/lectures/seminar_brox/seminar_ss17/maskrcnn_slides.pdf

http://classes.engr.oregonstate.edu/eecs/spring2017/cs637/Slides/CS_637_Fast_Faster_Mask_RCNN.pdf

Segmentation

全体

A Review on Deep Learning Techniques Applied to Semantic Segmentation : https://arxiv.org/pdf/1704.06857.pdf

【ディープラーニング】 セマンティックセグメンテーション手法のまとめ - 旅行好きなソフトエンジニアの備忘録

FCN

論文

https://arxiv.org/pdf/1411.4038.pdf

論文まとめ

memo: Fully Convolutional Networks 〜 Chainerによる実装 〜

Implementation of FCN via Keras - MATHGRAM

ディープラーニング セグメンテーション手法のまとめ - 前に逃げる 〜宇宙系大学院生のブログ〜

A brief introduction to recent segmentation methods

Net Surgery

caffe/net_surgery.ipynb at master · BVLC/caffe · GitHub

Shift and Stitch trick

https://www.cs.virginia.edu/yanjun/paperA14/2016-MustCnn.pdf

Delated Convolution

論文

https://arxiv.org/pdf/1511.07122.pdf

論文まとめ

Dilated Convolution - ジョイジョイジョイ

wave net

https://arxiv.org/pdf/1609.03499.pdf

Instance sensitive FCN

論文

https://arxiv.org/pdf/1603.08678.pdf

論文まとめ

論文輪読: Instance-sensitive Fully Convolutional Networks

SegNet

論文

https://arxiv.org/pdf/1511.00561.pdf

論文まとめ

Semantic Segmentationのサーベイ - takminの書きっぱなし備忘録

A Brief Introduction to Recent Segmentation Methods - YouTube

ディープラーニング セグメンテーション手法のまとめ - 前に逃げる 〜宇宙系大学院生のブログ〜

Refine Net

論文

https://arxiv.org/pdf/1611.06612.pdf

Semantic Segmentation using Adversarial Networks

論文

https://arxiv.org/pdf/1611.08408.pdf

DeepMask

論文

https://arxiv.org/pdf/1506.06204.pdf

SharpMask

論文

https://arxiv.org/pdf/1603.08695.pdf

U Net

論文

U-Net: Convolutional Networks for Biomedical Image Segmentation

Pyramid Scene Parsing Network

イケてるらしい

CNNにて階層化されたマップを統合して意味情報を復元

セマンティックセグメンテーションにて一位@ILSVRC2016

論文

https://arxiv.org/pdf/1612.01105.pdf

論文まとめ

[unofficial] Pyramid Scene Parsing Network (CVPR 2017)

Git

GitHub - Vladkryvoruchko/PSPNet-Keras-tensorflow: original code : https://github.com/hszhao/PSPNet

GitHub - hszhao/PSPNet: Pyramid Scene Parsing Network

Pohlen_Full-Resolution_Residual_Networks

論文

http://openaccess.thecvf.com/content_cvpr_2017/papers/Pohlen_Full-Resolution_Residual_Networks_CVPR_2017_paper.pdf

Git

GitHub - TobyPDE/FRRN: Full Resolution Residual Networks for Semantic Image Segmentation

End-to-End Instance Segmentation with Recurrent Attention

論文

http://openaccess.thecvf.com/content_cvpr_2017/papers/Ren_End-To-End_Instance_Segmentation_CVPR_2017_paper.pdf

Object Region Mining with Adversarial Erasing(弱教師あり学習)

論文

https://arxiv.org/pdf/1703.08448.pdf

Bayesian SegNet

論文

https://arxiv.org/pdf/1511.02680.pdf

Git

GitHub - alexgkendall/SegNet-Tutorial: Files for a tutorial to train SegNet for road scenes using the CamVid dataset

Semi and Weakly Supervised Semantic Segmentation Using Generative Adversarial Network

論文

https://arxiv.org/pdf/1703.09695.pdf

論文の参考

http://www.mi.t.u-tokyo.ac.jp/kanezaki/pdf/3D_and_weaklearning.pdf

Global Average Pooling Layers for Object Localization

分類ラベルからsegmentationする新しいもの

論文

http://cnnlocalization.csail.mit.edu/Zhou_Learning_Deep_Features_CVPR_2016_paper.pdf

論文まとめ

Global Average Pooling Layers for Object Localization

比較論文

論文

https://arxiv.org/pdf/1605.07678.pdf

Speed/accuracy trade-offs for modern convolutional object detectors : https://arxiv.org/pdf/1611.10012.pdf

論文まとめ

CNNモデル比較論文 "An Analysis of Deep Neural Network Models for Practical Applications"を読んだ - 人間だったら考えて

その他の機械学習手法

CNN-SLAM

http://campar.in.tum.de/pub/tateno2017cvpr/tateno2017cvpr.pdf

CNN-SLAM: Real-time dense monocular SLAM with learned depth prediction - YouTube

http://campar.in.tum.de/Chair/ProjectCNNSLAM

OpenPose

GitHub - CMU-Perceptual-Computing-Lab/openpose: OpenPose: Real-Time Multi-Person Keypoint Detection Library for Body, Face, and Hands

ScanNet

ScanNet: Richly-annotated 3D Reconstructions of Indoor Scenes (CVPR 2017 Spotlight) - YouTube

PointNet

PointNet

Network Dessecion(中間層の理解)

https://arxiv.org/pdf/1704.05796.pdf

Multi-Scale Continuous CRFs as Sequential Deep Networks for Monocular Depth Estimation

RGBからDepthの推定

https://arxiv.org/pdf/1704.02157.pdf

Global Hypothesis Generation for 6D Object Pose Estimation

https://arxiv.org/pdf/1612.02287.pdf

Cognitive Mapping and Planning for Visual Navigation

ロボット視点からの画像から、マッピングとナビゲーションを同時に⾏い、ゴールまでの経路を推測する研究

https://arxiv.org/pdf/1702.03920.pdf

Cognitive Mapping and Planning

Kehl_Real-Time_3D_Model Tracking

RGB-D映像による3次元追跡を,シングルコアCPUで,2msの処理速度を実現

http://openaccess.thecvf.com/content_cvpr_2017/papers/Kehl_Real-Time_3D_Model_CVPR_2017_paper.pdf

Budget-Constrained 6D Object Pose Estimation via Reinforcement Learning

http://openaccess.thecvf.com/content_cvpr_2017/papers/Krull_PoseAgent_Budget-Constrained_6D_CVPR_2017_paper.pdf

Global hypothesis generation for 6D object-pose estimation

http://openaccess.thecvf.com/content_cvpr_2017/papers/Michel_Global_Hypothesis_Generation_CVPR_2017_paper.pdf

Fine-Tuning by Increasing Model Capacity

http://ri.cmu.edu/wp-content/uploads/2017/06/yuxiongw_cvpr17_growingcnn.pdf

A Point Set Generation Network for 3D Object Reconstruction From a Single Image

http://openaccess.thecvf.com/content_cvpr_2017/papers/Fan_A_Point_Set_CVPR_2017_paper.pdf

pix2pix

Image-to-Image Demo - Affine Layer

Learning Local Geometric Descriptors from RGBD Reconstructions

https://arxiv.org/pdf/1603.08182.pdf

Git

GitHub - andyzeng/3dmatch-toolbox: 3DMatch - a 3D ConvNet-based local geometric descriptor for aligning 3D meshes and point clouds.

Image Caption Generator

論文まとめ

Show and tell takmin

Neural Style Transfer

論文

https://www.cv-foundation.org/openaccess/content_cvpr_2016/papers/Gatys_Image_Style_Transfer_CVPR_2016_paper.pdf

論文まとめ

Neural Style Transfer: Prismaの背景技術を解説する

Conditional Random Fields

CRFがよくわからなくてお腹が痛くなってしまう人のための30分でわかるCRFのはなし - EchizenBlog-Zwei

latent Dirichlet allocation

LDA入門

スーパーピクセル

kmeans を使った画像のセグメンテーション - Qiita

http://www.vision.cs.chubu.ac.jp/flabresearcharchive/master/m07/paper/kida_paper.pdf

http://www.vision.cs.chubu.ac.jp/FLABResearchArchive/Master/M07/Abstract/kida_abst.pdf

http://www.nlab.ci.i.u-tokyo.ac.jp/pdf/ssii2015tamanaha.pdf

機械学習のお勉強(セグメンテーション)

画像認識のタスク

  1. Classification : What?

  2. Detection : What? Where?

  3. Segmentation : What? Where? Shape?

セグメンテーション

  • ピクセルごとにクラス分類を行う。推定はピクセル✕分類クラス数。

  • 入力と同じサイズに出力を合わせる必要がある。逆畳み込みを行う。つまり、画像を入力として画像を出力する。

こんな感じ👇

f:id:robonchu:20171003215824p:plain

ポイント

ひとつのピクセルだけを見て、何かを推測することは難しい。なので、いかに周囲の情報を加味しながら、ピクセルの分類をするかが重要。

Sample

以下ではこれを例にsegmentationをお勉強する

chainerbook/ch6 at master · ghmagazine/chainerbook · GitHub

前処理

入力画像のサイズ調整

ストライドの累乗値の倍数に画像の大きさを変更

ex:ストライド2のMax Poolingが3つある場合、8の倍数に調整する必要がある

chainerbook/mini_batch_loader.py at master · ghmagazine/chainerbook · GitHub

画像の正規化

Local Contrast Normalization: theanoで局所コントラスト正規化(Local Contrast Normalization)を使う - 備忘録とか日常とか

Global Contrast Normalization: chainerbook/image_normalizer.py at master · ghmagazine/chainerbook · GitHub

オーギュメンテーション

左右上下反転: chainerbook/mini_batch_loader.py at master · ghmagazine/chainerbook · GitHub

Train

    # データセットのロード
    train_mini_batch_loader, train_data_size = prepare_dataset()
    # モデルのロード
    model = FCN(chainer.global_config.user_train_args.n_class,
                chainer.global_config.user_train_args.in_ch)

    # オプティマイザーの定義
    optimizer = chainer.optimizers.Adam()
    optimizer.setup(model)
    optimizer.add_hook(
        chainer.optimizer.WeightDecay(
            chainer.global_config.user_train_args.training_params.weight_decay))

Model

SqueezeNet 👈 Fire Moduleを8つ重ねたモデル

class Fire(chainer.Chain):
    def __init__(self, in_size, s1, e1, e3):
        super().__init__()
        with self.init_scope():
            self.conv1=L.Convolution2D(in_size, s1, 1)
            self.conv2=L.Convolution2D(s1, e1, 1)
            self.conv3=L.Convolution2D(s1, e3, 3, pad=1)

    def __call__(self, x):
        h = F.elu(self.conv1(x))
        h_1 = self.conv2(h)
        h_3 = self.conv3(h)
        h_out = F.concat([h_1, h_3], axis=1)
        return F.elu(h_out)


class FireDilated(chainer.Chain):
    def __init__(self, in_size, s1, e1, e3):
        super().__init__()
        with self.init_scope():
            self.conv1=L.DilatedConvolution2D(in_size, s1, 1)
            self.conv2=L.DilatedConvolution2D(s1, e1, 1)
            self.conv3=L.DilatedConvolution2D(s1, e3, 3, pad=2, dilate=2)

    def __call__(self, x):
        h = F.elu(self.conv1(x))
        h_1 = self.conv2(h)
        h_3 = self.conv3(h)
        h_out = F.concat([h_1, h_3], axis=1)
        return F.elu(h_out)


class FCN(chainer.Chain):
    def __init__(self, n_class, in_ch):
        super().__init__()
        with self.init_scope():
            self.conv1=L.Convolution2D(in_ch, 96, 7, stride=2, pad=3)
            self.fire2=Fire(96, 16, 64, 64)
            self.fire3=Fire(128, 16, 64, 64)
            self.fire4=Fire(128, 16, 128, 128)
            self.fire5=Fire(256, 32, 128, 128)
            self.fire6=Fire(256, 48, 192, 192)
            self.fire7=Fire(384, 48, 192, 192)
            self.fire8=Fire(384, 64, 256, 256)
            self.fire9=FireDilated(512, 64, 256, 256)

            self.score_pool1=L.Convolution2D(96, n_class, 1, stride=1, pad=0)
            self.score_pool4=L.Convolution2D(256, n_class, 1, stride=1, pad=0)
            self.score_pool9=L.Convolution2D(512, n_class, 1, stride=1, pad=0)

            self.add_layer=L.Convolution2D(n_class*3, n_class, 1, stride=1, pad=0)

            # padding means reduce pixels in deconvolution.
            self.upsample_pool4=L.Deconvolution2D(n_class, n_class, ksize= 4, stride=2, pad=1)
            self.upsample_pool9=L.Deconvolution2D(n_class, n_class, ksize= 4, stride=2, pad=1)
            self.upsample_final=L.Deconvolution2D(n_class, n_class, ksize=16, stride=4, pad=6)

        self.n_class = n_class
        self.active_learn = False
        self.evaluator = Evaluator(False, n_class)

    def clear(self):
        self.loss = None
        self.accuracy = None

    def __call__(self, x, t):
        h = F.elu(self.conv1(x))
        h = F.max_pooling_2d(h, 3, stride=2)
        p1 = self.score_pool1(h)

        h = self.fire2(h)
        h = self.fire3(h)
        h = self.fire4(h)
        h = F.max_pooling_2d(h, 3, stride=2)
        u4 = self.upsample_pool4(self.score_pool4(h))

        h = self.fire5(h)
        h = self.fire6(h)
        h = self.fire7(h)
        h = self.fire8(h)

        # h = F.max_pooling_2d(h, 3, stride=2)
        h = self.fire9(h)
        u9 = self.upsample_pool9(self.score_pool9(h))

        h = F.concat((p1, u4, u9), axis=1)
        h = self.add_layer(h)
        h = self.upsample_final(h)

        self.h = h
        self.loss = F.softmax_cross_entropy(h, t)

        self.evaluator.preparation(h, t)
        self.accuracy = self.evaluator.get_accuracy()
        self.iou = self.evaluator.get_iou()

        return self.loss

参考:

chainerbook/fcn_squeeze.py at master · ghmagazine/chainerbook · GitHub

https://www.semiconportal.com/archive/contribution/applications/170418-neurochip5-2.html

20160901 jwein

Squeezenet-residual by songhan

[Survey]SqueezeNet: AlexNet-level accuracy with 50x fewer parameters and <1MB model size - Qiita

2016年の深層学習を用いた画像認識モデル - Qiita

Convolution層
  • paddingを使って計算後の出力サイズを維持しやすくするため,カーネルサイズを奇数に。(int(ksize/2)をpadに指定すると,stride=1の際に画像サイズが維持)

  • 出力feature mapを小さくしたい場合は,1より大きいstrideに。(stride=nだと1/n)

  • 出力サイズは、(input_size - ksize + pad×2) / stride+1に。 (strideを大きくすると出力特徴マップは小)

Deconvolution層

Transposed convolutionやBackward convolutionと呼ばれることも。入力特徴マップに対するアップサンプリング。

可視化:GitHub - vdumoulin/conv_arithmetic: A technical report on convolution arithmetic in the context of deep learning

  • カーネルサイズをstrideで割り切れる数に。参考:Deconvolution and Checkerboard Artifacts

  • 出力サイズは、stride×(input_size − 1) + ksize − 2×pad。

  • feature mapの周囲を「削る量」がpadになっている。Convolutionの逆。

参考:

ニューラルネットワークにおけるDeconvolution - Qiita

GitHub - vdumoulin/conv_arithmetic: A technical report on convolution arithmetic in the context of deep learning

【保存版】chainerのconvolutionとdeconvolution周りを理解する - Monthly Hacker's Blog

chainerでx方向にconv、y方向にdeconvする - Qiita

モデルの結合

F.concat

In [2]: x1 = chainer.Variable(numpy.array([[1, 2], [3, 4]]))

In [3]: x2 = chainer.Variable(numpy.array([[5, 6], [7, 8]]))

In [4]: x1.data
Out[4]: 
array([[1, 2],
       [3, 4]])

In [5]: x2.data
Out[5]: 
array([[5, 6],
      [7, 8]])

In [6]: chainer.functions.concat([x1, x2], axis=1).data
Out[6]: 
array([[1, 2, 5, 6],
       [3, 4, 7, 8]])

参考:

python - Chainerでネットワークの途中でのデータの合成方法は? - スタック・オーバーフロー

chainer.functions.concat — Chainer 3.0.0rc1 documentation

Segmentationのサンプル

Deep Learning Tutorial - Second Annual Data Science Bowl | Kaggle

Segmenatation論文まとめ

robonchu.hatenablog.com

ディープラーニング セグメンテーション手法のまとめ - 前に逃げる 〜宇宙系大学院生のブログ〜

Tips