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

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

深層学習の超基礎知識を勉強した(学習に関するテクニック)

本当に久しぶりですが、ゼロから作るDeepLearningの6章、学習に関するテクニックを読んだときのメモを残します。 今年は継続的な勉強を頑張りたいです。継続は力なり。

  • SGDとは、確率的勾配降下法のこと
    • 勾配方向に向かう一番単純な方法
    • stochastic gradient descent
  • SGDは解く関数の形状が等方的でないと収束がうまくいかない
    • x方向の勾配は急だけど、y方向の勾配が非常に緩い場合など
    • このとき、勾配の方向が本来の最小値の方向を指しているとは限らない
      • この辺が、ガウス・ニュートンだと解決されているのか?
        • 自分の理解が正しければ、方向というよりは、収束点がわかっているイメージ
          • 勾配降下法は学習率のパラメータが必要だけど、いらないということ
  • Momentum
    • 収束に慣性を持たせる
  • AdaGrad
    • パラメータ毎に適応的に学習係数を調整する
    • 各パラメータの勾配の二乗和(スカラー)を逐次的に足し合わせてその分だけ学習係数を小さくする
    • 一回でも間違って大きく更新されてしまうとその後戻るステップが遅くなるみたいな性質を想像すると、結構イマイチな気がする
    • RMSPropという方法の方が良さそう
  • Adam
    • MomentumとAdaGradの融合
    • Qiitaなどをみていても、未だにAdamが鉄板だと思う。ライブラリでAdamを使えば良い
  • 初期値はとりあえずランダムで良い?←あとから、ダメという話がある
    • 何か学習済みのパラメータがあればそれを流用するのが良い
  • 勾配消失問題
    • 微分値が0になってしまうと、重みパラメータが更新できないという話
    • シグモイドならば0付近と1付近
  • 「表現力の制限」の問題は、逆にニューラルネットをコンパクトにしたい際に使用されている気がする
    • ニューロンが違う挙動しないと、ニューロンがたくさんある意味がないという話なので、逆に性能が出ているのに同一挙動のニューロンがあればそれは減らせる、みたいな
  • 初期値について
    • Xavierの初期値という考え方がある
      • できるだけ偏りなく勾配消失しない形でアクティベーションされることを目指したのかな
      • ところで、活性化関数に用いる関数は、原点対象であることが望ましい性質として知られているらしい
    • 活性化関数にReLUを使う場合は、「Heの初期値」を用いると良い
      • 考え方はほとんどXavierと変わらない
  • Batch Nomalization
    • 恥ずかしいことに、バッチノーマライゼーションとミニバッチ学習を混同していたが、全然違う
    • ミニバッチ学習
      • (ちょっとまだ自信がないが)ミニバッチ学習をせずに一つのデータだけで勾配を計算してしまうと、勾配方法が信用できなくなってしまうという話だと思う
      • 100個とか適当にサンプリングしたデータの塊を全データの近似とみなすということは、勾配方向がそこそこだ正しいとみなすことかな?
      • なので、ミニバッチ学習のサンプリング数は小さぎてはいけないと思う
    • Batch Normalizationは、ニューラルネットにBatch Nomaizationレイヤを挿入する
    • 角層でのアクティベーションの分布を適度な広がりになるように調整する専用の層を設計するということ
      • ミニバッチごとに正規化を行う
      • データの分布が平均が0で分散が1になるように正規化
      • 逆伝播の解説は省略されていたが、定性的な理解をしたうえで、基本的にライブラリを信じれば良いだろう
  • 過学習を抑制する手段として下の手法が有名
    • Weidht decay
      • 重みパラメータにペナルティをつける
      • 割と昔からある考え方
    • Dropout
      • 訓練時に、わざとランダムに使用しないニューロンを設定する
      • 擬似的に、アンサンブル学習を行っているという解釈になる
  • 最近はBatch Normalizationの方が有力ということなんだろうか
  • ハイパーパラメータの最適化
    • 今後重要な領域だろうが、今は興味外なので省略
    • ハイパーパラメータを遺伝的アルゴリズムで最適化とかあった気がする

すごい久々だけど大したことは書けない

すごいどうでも良い話だけど、久々に勉強しようとした際にメモをどこに残そう?と少し悩んだ。 要求仕様としては、

  • 基本的にはweb上に残したい
    • DesktopとノートPCの両方でアクセスしたいので
  • いざというときに、オフラインでローカルで編集したい

これだけ。そこで、以下の記事を見つけた。

d.hatena.ne.jp

要するに、全部GitHubで管理すれば良しちゃえということ。 これは凄く良いと思うので、早速レポジトリを作った。

とにかくここにメモをマークダウンで残してある程度まとまったら、記事にするとかありかもしれない。

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

  • 「ゼロから作る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

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