ソフトウェアエンジニアの勉強ログ

興味があるのは、computer vision, three.js, python, 深層学習, emacs

深層学習の超基礎知識を勉強した(ニューラルネットワークの学習)

  • 「ゼロから作るDeep Learning」の4章「ニューラルネットワークの学習」を読んで勉強したときの自分用メモです
    • 実際にPythonを走らせて、手を動かす勉強はまだ
  • 認識の大雑把な変遷
    1. 昔は人が全て設計
    2. 一時期は、SIFT + SVMなどが流行った
    3. 全てニューラルネットで行うのが現在流行っている
      • 深層学習の真骨頂は、「end-to-end」な学習
      • 生データから目的の結果を得るということ
      • とはいえ、データの前処理の重要性はかなりのウェイトを占めている印象
  • 機械学習は、汎化能力が大事で、訓練データではないテストデータで、性能を評価する
  • 基本的には損失関数で学習を行う
    • 例えば、正解率が80%のような「認識精度」を直接上げるようにしない理由
      • 認識精度が改善されたとしても、(テストデータが整数なので)離散値になってしまう
        • 連続値でないと微分を使って学習を行う、機械学習の枠組みと相性が良くない
      • 私見だが、明らかに、一回一回のテストデータでフィードバックが入ったほうが、効率が良い
    • 個人的には、強化学習の枠組みでは、どちらかという「認識精度」を上げるように学習するイメージに近い
      • どのように性能を上げるかについては、今は不明なので将来的に勉強する
  • 損失関数は主に、2乗和誤差と交差エントロピー誤差がある

    • 多分、出力層がソフトマックスなため、総和が1.0に正規化されていることが重要?
    • 2乗和誤差  \displaystyle E = \frac{1}{2}\sum_{k}(y_k - t_k)^2
    • 交差エントロピー誤差  \displaystyle E = - \sum_{k}t_k log y_k
      • tが0 or 1で、0 <= y <= 1なので、-∞ < logy <= 0であることがポイント。正解ラベルに対する結果yが0に近いと、損失が非常に大きいという特徴がある
      • 正解ラベル以外は気にしなくて良いので、多分こっちの方が好まれているのではないか?と思う
  • ミニバッチ処理

    • ある程度まとめた訓練データ、例えば100個にまとめたデータを基に学習を行うという話
    • 詳しくは書かれていないが、多分 n^2とかそういう指数オーダーで、計算量が増えてしまうので、全ての訓練データをまとめて計算するのは現実的でないため
  • ただし、個人的な見解では、ミニバッチは小さすぎてはいけない
  • 以下、そう思う理由

    • 後述するが、結局微分をといて学習をといている、つまりある訓練データあったときに、(嘘を恐れずいえば)
      1. まず現在のパラメータ(重み)を使って損失計算をする
      2. 暫定的にあるパラメータに着目して、ちょっとだけ値を変える(+h)
      3. 損失計算を再計算
      4. 損失関数の変化からそのパラメータ(重み)を大きくしたほうが良いのか小さくした方が良いのか判断する
    • という流れになるが、ここで、(パラメータがかなり多く冗長であるので)あるデータ1に対しては大きくしたほうが良いが、他のデータ2〜10に対しては小さくした方が良いということが多発する。
    • ミニバッチをある程度大きさのデータとすることで、全体としてはパラメータを小さくしたほうが良いという見解が得られる
    • 機械学習の常識はわからないが、少なくともLM法などで数値的に非線形問題を解くときに、冗長性は敵である(解が見つからない!)
  • 勾配法で学習する話

    • 学習が深層学習のコアだが、多分、数学的には深層学習のことを知らない人が想像しているよりも遥かに簡単だと思う
    • 層の設計とかいろいろ難しいことはあるのだろうが、この初期導入および深層学習を始める際の最初の数学的敷居の低さは、今の深層学習ブームに一役買っていると思う
    • 特に、この「ゼロから作るDeep Learning」は本当に解りやすい!おすすめ!
      • 「やってみた」がしやすい←まさに数学が得意でないのに、できそうな気がしてほいほいやっています
    • 大まかにいうと、関数の各パラメータに対する微分偏微分)を計算して、損失関数が小さくなる方にパラメータを更新する。さらに、関数の正解は不明で、解析的な微分はできないので、数値的な微分値を使用する
    • 要するに局所的にf(x + h)を実際に計算しみて、各パラメータの変化にたいするf(損失関数)の変化からどのようにパラメータを変えたら良いか決定する
    • 勾配法なので、更新量を決定する学習率ηが存在する
      • 上の話は、一次近似なのでどこまで更新したらよいかわからないため
      • ガウス・ニュートン的な)2次近似して、学習率ηをなくすというな方法を聞いたことがないのが疑問だが、パラメータが多すぎて解けないため、という理解で良いのだろうか?
  • 理解が正しければ、収束計算なので、一通り訓練データを学習ステップにいれただけでは全然最適解にたどり着いていない

    • 1次近似なのでその効率も全く不明?
    • そこで、ミニバッチの組み合わせを変えながら何回も訓練データを学習の際に使用する
    • 一通りデータを使い終えた(とみなせる)時点で、1エポックという単位が使われる
    • 数エポックで、学習がうまく行っているかどうかちゃんとチェックするのが、実用上は大事
  • 誤差逆伝播

    • 今度またしっかり読むが、読み飛ばした感じでは、深層学習は理論的には勾配法(確率的勾配効果法、SGD)なのは変わらない
    • それを(ほとんど結果を変えずに)高速に算出するのが誤差伝播法

深層学習の超基礎知識を勉強した(パーセプトロンからニューラルネットによる推論まで)

  • ゼロから作るDeep Learningの2〜3章を読んだ
  • ここまでは簡単で、基本的にpythonで手を動かす練習をしているだけ
  • パーセプトロンで、OR, AND, NANDを作れる
    • それを二層にすることで、XOR(非線形)を作れる
  • 深層学習で、層を重ねて非線形の問題を解くためには、活性化関数を非線形にする必要がある
    • 言われてみると当たり前
    • シグモイド関数とかReLU関数とか
    • ReLUの方がよく使われているだろうか?
  • pythonでは、A * Bが行列の内積ではないことに注意。以下のように記述する必要がある。
    • np.dot(A, B)
  • ニューラルネットワークで、実際に推論してみる
    • お馴染みのMNISTデータ
    • 簡単にデータをロードできてよかった
      • 機械学習を使おうとすると、ほとんどこの辺のデータ準備の作業ばかりになりそうで怖い
  • 層の計算は、行ベクトルと行列の内積で算出できる
  • pickleは絶対便利
    • オブジェクトは'wb'で書き込んで、'rb'で読み込む
data = {}
data['name'] = "hoge"
...

with open(file_name, 'wb') as f:
  pickle.dump(data, f)

で保存して、

with open(file_name, 'rb') as f:
   data = pickle.load(f)

で読み込む。

  • 時間測定は、timeをimportすれば良い
start = time.time()
...
end = time.time()
print(str(end - start) + "[sec]"

時間は秒のようだ。

  • batch処理に関して
    • 要するに、1データが行ベクトルだったものを、複数データを行列とすることで、まとめて計算を行って高速化する
    • 簡単に10000テストデータで時間計測したところ、
      • バッチサイズを100とすることで、処理時間が10倍速くなったが、その後、バッチサイズを1000や10000にしてもほぼ同じだった
    • バッチサイズは大きければ大きいほどよいというものでもないようだ

ゼロから作るDeep Learningの一章を読んでみた

概略

  • ゼロから作るDeepLearningの一章を読んだので、そのログを残す
  • 一章は、pythonの話
    • pythonはあまり触ったことがなかったので、素直に手を動かした
    • pythonを使っている人からしてみたら、多分つまらない話

アナコンダのインストール

Anaconda を利用した Python のインストール (Ubuntu Linux) – Python でデータサイエンス

メモ

  • pythonには!がないので、notを使う
  • 配列の長さはa.lengthではなく、len(a)
  • コンストラクトが__init__
  • 階層が、:とインデントで、決まるのがなかなか慣れない気がする。
  • 「str1 + int + str2」みたいにして自動で文字列化するのはできない
    • str関数を使う
  • for文はCになれていると最初ちょっと困りそう
  • NumPyはMATLABみたいだ
    • braodcast計算が賢い
  • 配列は、ポインタ渡し?ではないみたいだ
    • 以下のように書いたときに
A = np.array([[1, 2], [3, 4]])
B = A
B = B.flatten()
print(A)
print(B)
  • 以下のような結果になる
[[1 2]
 [3 4]]
[1 2 3 4]

その他

ビジョン勉強会に行ったけど正直ついていけなかった、けどログを残す

ちゃんとバックボーンを勉強する必要性を痛感して帰ってきた。 日常的に勉強をすることは、本当に大事だと思う。 さらに、正直3本目以降くらいから頭が回らなくなってしまった。。。 普段から頭を使う&食事をとって体調を用意することの必要性も痛感した。

Discriminant Optimization: Theory and Application to Point Cloud Registration

資料

メモ

  • コスト関数を最小化するように座標変換を求めるのでなくて、特徴量から直接座標変換を求める
    • その際に学習を行う(リッジ回帰)
  • ICPよりロバスト
  • DO(discriminant Optimization)の方が初期値によらず寄っている
  • 学習だから仕方ないが、トレーニングのシーン次第に強く依存する気がする
  • 処理速度はICPと同等かちょっと遅い
  • 精度は圧倒的に良い
    • ICPで特徴量を使って、外れ値や欠損点に対するロバスト性の工夫をしたときとの比較はわからない?
  • 確かに、トラッキング(途中で見えなくなるときなど)に強そうだ
  • (関連アルゴリズムで)SDMという方法もある

Learning Cross-modal Embeddings for Cooking Recipes and Food Images

資料

メモ

  • 画像をみて、レシピを決める(Pic2Recipe)
    • レシピをいれると、画像が出てくることも可能
  • よくわかっていない
  • joint embedding spaceで両方からアクセス可?
    • このjpoint embedding spaceから、レシピや画像を決定するステップがわかっていない
  • LSTM
  • (VGG-16) and ResNet-50
    • ResNetは最近本当によく聞く
  • similarity lossで学習
    • レシピと画像が同じが違うかで学習
    • 2:8の、マッチデータ、ミスマッチデータ
  • semantic regularization loss
    • semantic regularization loss
      • 同じカテゴリだったらロスを小さくする?
        • 例えば、チーズバーガーとハンバーガーはロスが小さい?
      • タイトルからカテゴリを推定
  • http;//wednesday.????
  • word2vec math
    • king - man + woman = queenみたいな(適当)

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

資料

メモ

  • CNNを使ったSLAM
  • LSD-SLAM ?
    • 昔あったmono-slamのやつだろうか?
    • 輝度勾配が大きいところを特徴としてもってくる
    • キーフレームで准距離推定?
  • CNNデプス推定
    • MITの研究室で元からあった手法
    • 絶対スケールがわかる
    • こっちの方がコア技術の印象を受けた
  • 概略
    • depth推定(CNNを利用)
      • Depper Depth Prediction with Fully Convolutional Residual Networks
      • またResNet-50
    • LSD-SLMAPのフレームワーク
      • depthの信用度情報を使って、うまくヒュージョン
  • End-to-Endではない
  • orb-slam, lsd-slamについて

Universal adversarial perturbations

資料

メモ

  • 今日のベストプレゼンはこれだと思う
  • Deep Learningモデルをご認識させるような普遍的な摂動ノイズを発見
  • 汎用的なノイズ(Universal)
  • 識別境界への法線ベクトルが結構共通方向を向いている→もっと低次元化できるという見解は超面白い
  • 聞いているのがやっとでメモしている時間がなかった
  • 法線方向(境界への最短方向)を決めてくるところが肝
    • SVMとかと関連があるのだろうか?

Realtime Multi-Person 2D Pose Estimation using Part Affinity Field

資料

メモ

  • CPM (Convorutional Pose Machine)の他の信用できる情報を組み合わせ得る発想はちゃんと勉強する
  • kinectのpose estimatinでも似た感じだったのだろうか?
    • あれはrandom forestだっけ

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

資料

メモ

  • 1枚の画像から、Point Cloudの推定
  • chamfer distanceとearth mover’s distance
  • VAE(Variational Auto-Encoder)?
  • Deconvとは…
  • 非常に面白いけど、厳密なデータとして扱うには限界があるきがする。個人的には将来への発展性を感じた。 こういった漠然とした3D形状を認識するモデルを中間層にもって、分類に活かすのはもちろん類似度?まで考慮するみたいな。。。これはコップじゃないけどコップとして使用できるみたいな物体の本質を理解した上での応用みたいなことをしたくなるとこういった暗黙の推定がいる気がする。何言っているのが良くわからない。

Image Super-Resolution via Deep Recursive Residual Network

資料

メモ

  • DRRN(Deep Recursive Residual Network)
  • global residual learning
  • resursive learnig
    • ウェイトを共有
    • 汎化能力が高くなる(使われるシーンが一つでないので発散しにくくなる)
  • multi-path local residual learning
  • パラメータは少ないけど結構複雑
  • 工夫の一覧
    • Data Augmentation
      • データの水増し
      • 1/3, 1/4をひとつのpathで渡している
    • batch normalization
    • pre-activation
    • gradient clipping
    • Local Residual Learning
    • バッチイメージのストライドサイズが半分でなく、2/3
      • 境界を敢えてまたぐようにする
  • GAN (Generative Adversarial Networks)を使うというのもあるらしい

Person Re-Identification in the wild Joint Detection and Identification Feature Learning for Person Search

資料

メモ

  • Person Re-Identification(人物再同定)という問題
    • 複数のカメラにまたがった人物推定
  • 1本目は、datasetと性能のベースとなるデータを用意した、という話か

  • Joint Detection and Identification Feature Learning for Person Search

    • End-to-Endのアルゴリズムも提唱している
    • 「Faster R-CNN」という単語が今日何回か出てきている
    • クラス分類ではなく類似度問題にすることで、mini batchに含まれる画像の人物だけで、lossが計算できる
      • online instance matchingの方がsoftmaxよりも高精度

Scalable Surface Reconstruction from Point Clouds with Extreme Scale and Density Diversity

資料

メモ

  • 従来法
    • Octreeアプローチ
    • ドロネー網(Graph cut)アプローチ
  • 密度の違うPoint Cloudの統合、表面生成にチャレンジ
  • TX2では、OpenCV3.3が動く
  • メッシュをきるときも視点情報を使うというのはしっくりくる
    • その最たる例が、距離画像
  • 今更だけど、Graph-Cutはいい加減勉強しないといけないな

NVIDIAのGPU付のubuntuにログインしようとしてもできなくなってしまったときの対処メモ

初期症状

  • (明らかに解像度が間違っている)ログイン画面にはなる
  • パスワードをいれると、一瞬エラーが発生しましたみたいな画面になるが、直ぐにログイン画面に戻ってしまう
    • 後からわかったことだが、これらは別の問題で、前者は未解決のまま
  • ubuntu16.04で、GeForce1080を使っている

NVIDIAGPUを使っているときの注意点

ライブCDをいれたときに以下のような確認画面になる(厳密ではない) - run ubuntu without installing - install ubuntu - OEM的な何か - check disk for defect

この画面において以下の操作が必須!

  1. 選択メニューで「e」を押す
  2. quiet splashという単語を探して、nomodesetに置き換える
  3. 起動(私の環境では、F10)

上記の操作を忘れていると色々面倒。

GUIが立ち上がらないときなどの基本事項

  • Alt + Shift + F1でコンソールモードになるのでそこで頑張る
  • さらにGUIをストップする必要があるとき(以下のどれかが、数打てばあたる)

    • sudo sudo service lightdm stop
    • $ sudo service gdm stop
  • GUIのスタート

    • Alt + F7
    • 正し、リブートした方が無難

ディスクチェックをしよう

今回はこれでは直らなかったが、覚えておいた方が良い。 ここで注意点はこの操作の際も、CDのubuntuを、nomodesetで立ち上げる必要があることだ。

ubuntuが動かなくなりました。昨日までは普通に動いたのに急に添付ファイルの画... - Yahoo!知恵袋

まとめると、一度なんとかubuntuを立ち上げて、gpartedを実行して、ディスクをチェックすれば良い。

Ubuntu16.04にNVIDIAのドライバをいれたときのおさらい

結局、ドライバを入れ直す作業が有効だった。 以下のサイトを見て、その操作を行った。

askubuntu.com

操作の具体例は、以下のサイトがわかりやすい。

qiita.com

なお、現時点での最新のドライバは、別のPCで調べるべき。 2017年8月5日時点では、384だったので、

sudo apt-get install nvidia-384

そして、リブートしたら直った。

自分用メモ:「初めてのThree.js」を読む&手を動かす

  • 「初めてのThree.js」を読んだ際のメモ記事
    • 逐次更新

一章

  • ローカルウェブサーバは以下のコマンドだけで立ち上がる
    • cloneしたレポジトリのディレクトリで実行する必要があるらしい
python -m SimpleHTTPServer
  • requestAnimationFrameとはモダンブラウザでサポートされていて、ブラウザによって定義された感覚で呼び出す関数を設定できる
    • setIntervalでは、focusのチェックもしないから裏でも走ってCPU利用率が高くなるとき、setIntervalは画面の再描画と同期されないなどの問題があるらしい。
  • 一章で書かれている内容は、必ず必要になる手順なので、htmlに書いても良いけど、jsでラッピングしても良いよね

二章

  • sceneオブジェクトの重要なプロパティや関数
     説明
add(obejct) シーンに足す
children 追加されたオブジェクトの一覧(配列?)
getObjectByName(name) オブジェクト名からオブジェクトを取得するのだろうが、どうやってオブジェクト名を指定するの?
remove(object)
tranerse(function) すべてのchildrenに関数を適用する

自分用メモ:Emacsの設定

逐次更新します

C-hの挙動をバックスペースに変更

akisute3.hatenablog.com

jsの編集モードをインストール

daifuku-p.org

  • 何も考えず以下の手順でいけた
    1. M-x package-list-packagesでpackageの一覧を取得
    2. js2-modeを選んでiで選択
    3. xでインストールを実行
    4. ~/.emacs.d/init.elを編集(自分はこれを使っているので)

Ctrl-Spaceで選択できるようにする

markdownEmacsで書いて、気軽に確認する

pythonのタブ幅を指定

  • 以下をinit.elに追加
;;python-mode
(add-hook 'python-mode-hook
      '(lambda()
         (setq indent-tabs-mode t)
         (setq indent-level 2)
         (setq python-indent 2)
         (setq tab-width 2)))