pit-rayの備忘録

知識のあうとぷっと

DropConnectを理解したかった


はじめに

ディープラーニングを行う上で、過学習(overfitting)対策は欠かせません。実際にディープラーニングを行う際、データセットを訓練データ、検証データ、テストデータ等に分割するハズです。ここで、ある場合においてはモデルが訓練データに大きく依存したものになる可能性があります。その結果として訓練データの精度が非常に高くなり、検証データ・テストデータの精度が停滞してしまいます。以下、文献[1]からの引用です。

過学習が起きる原因として、主に次の2つが挙げられます 。

・パラメータを大量に持ち、表現力が高いモデルであること
・訓練データが少ないこと

出典:文献[1]

表現力はレイヤを多層化すればするほど高くなります。より性能が良いモデルを得ようとして多層化したはいいものの、学習が停滞してしまうのでは元も子もありません。過学習を抑制するための手法としては、Weight decayやDropoutなどがあります。また、Dropoutベースの正規化は、DropConnectや変分Dropoutなどがあります。
因みに、Weight decayとは、ネットワークにl2ペナルティを課すという単純な手法ですが、大抵よりよい結果が得られます。しかし、巨大なネットワークには向きません。


全結合ネットワーク(No-Drop)

f:id:pit-ray:20190629144906j:plain
Standard Neural Network

それぞれのノードは、簡単化してAffneレイヤ(Linearレイヤ)のように振舞い、何かしらの活性化関数を通るとします。(これが他であっても(例えばLSTMレイヤなど)入力と出力を考えれば同様に考えられます。ただし、全結合に限ります。)

前提として、今後扱っていく変数の概要を次に示します。

変数名 概要 形状
x 入力 N×1
W 重み N×D
u=Wx Affine(Linear)の結果(行列積) D×1
r=a(u) 活性化関数 a の出力 D×1

上に示す基本的な全結合レイヤは次のように表せます。

        r=a(u)=a(Wx)


それでは、この全結合のニューラルネットワークに対し、それぞれの手法を適用した場合を見ていきたいと思います。

Dropout

Dropoutは、G. Hinton先生らによって2012年に考案された正規化手法です。
意味としては、出力に対してDrop処理を行います。ここでいうDrop処理とは、データを確率的に削減することを指します。
グラフとして表すと下のようになります。

f:id:pit-ray:20190630005101j:plain
Dropout

ここで、削減されるデータの確率(割合)を p とすると、出力として残す確率は ( 1-p ) となります。
この確率にしたがって残す部分を1、無視する部分を0としたバイナリマスクを m とすると、Dropoutを導入した全結合層は次のように表されます。

        r=m*a(Wx)

ただし、* はアダマール積(Hadamard product)を表しています。アダマール積はシューア積(Schur product)や要素ごとの積(element-wise product)とも言われます。

上で述べたように、残したいものだけ残るような形になります。

シンプルなしくみでありつつ、これにて過学習に対して絶大なる効果を発揮します。

実装手法は様々なものが考案されていますので、ChainerやTensorFlowなどのソースコードを参考にするとよいでしょう。分かりやすい実装例を次に示します。(文献[1]p196参照)

import numpy as np

def dropout( y, dropout_ratio = 0.5 ):
    mask = np.random.rand( *y.shape ) > dropout_ratio
    r = mask * y
    return r

numpyのrandom.randは、0.0から1.0の一様なランダム行列を返します。
一様という点から、dropout_ratioと比較した結果はバイナリマスクを作ることと同等になります。
また、*y.shapeは、タプル自体を渡しています。仮にy.shapeのまま渡してしまうと、y.shapeを一つの要素として、( ( x, y, z ), )のように渡されてしまいます。



DropConnect

DropConnectは、Li Wan先生らが2013年に発表した手法であり、Dropoutの一般化したものであるとされています(文献[2]Abstract参照)。

Dropoutと同じようにバイナリマスクを用います。
DropConnectは、上で示した(下に再掲)、Dropoutを適用した全結合レイヤを変形することで求められます。

        r=m*a(Wx)

活性化関数  a によく用いられるものとしては、tanh、Relu、sigmoid等が挙げられます。
ここで、a(0)=0 を満たすものであれば、上の式を変形することができます。

        r=a(m*Wx)

次にバイナリマスクとして異なる形状のものを新たに用意します。

バイナリマスク 形状
m D×1
M N×D

すると次のように変形できます。

        r=a((M*W)x)

この式は、出力をDropするのではなく、重みをDropすることを表しています。
重みをDropするということは、なんぞ?となると思いますが、図に表すとスグ理解できるハズです。

f:id:pit-ray:20190630010842j:plain
DropConnect①

Dropしたものを赤で示しています。赤を取り除くと次のようになります。

f:id:pit-ray:20190630010858j:plain
DropConnect②

このように、出力よりもむしろ、接続を断つというのがDropConnectの手法なのです。
outが出力で、Connectが接続という観点からみても分かるでしょう。

簡単な実装では、重みと同じ形状のバイナリマスクを作り、アダマール積を行えばよいです。実装上、重みやバイアスを含むことから、文献[2]の2.2ではDropConnectをa sparsely connected layerと呼んでいます。レイヤとして一体化させたほうが扱いやすいかもしれません。
オリジナルの実装は、活性化関数を渡す前にガウス分布によるサンプリングを行います。
簡単な実装は、上で示したDropoutの例を応用すればよいです。

DropoutとDropConnectの比較

詳細な結果としての比較は、文献[2]のsection. 6をご覧ください。ここでは、簡単な比較と特徴を述べます。

ここで考えられる最も大きな違いは、バイナリマスクの表現力です。バイナリマスクを二値画像で表すと下のようになります。

f:id:pit-ray:20190630014301j:plain
binary mask

集合体恐怖症の方は大変申し訳ありません。雑いですが、元の論文を参考に作りました。
これをみると分かるように、DropConnectはより複雑な正規化を行うことができます。
ニューラルネットワークのデザインにも寄りますが、大抵の場合、Dropoutよりも良い結果になります。その反面、Dropoutよりも僅かに遅いという欠点があります。また、その実装のコストが高いこともデメリットとして挙げられます。仮にChainerにてLinearレイヤ(線形全結合レイヤ)にDropConnectを導入するとします。その場合、重みに対してDrop機構を備えた線形なレイヤに入れ替えるだけで済みます。Chainerでは SimplifiedDropconnectとして用意されています。これに対して、LSTMレイヤなどに適用するとなると自前でDropConnect機構を備えたLSTMレイヤを作らなくてはいけません。逆伝播(back propagation, backward)はDropのさせ方によって簡単化することも可能なので、実装次第ですが。このように元のレイヤやコストを考慮しなくてはいけません。



以上です。
どのような手段でも構いませんので、気づいた点やご質問等ありましたら、お気軽にお寄せください。



参考文献



[1] 斎藤 康毅 (2018) 『ゼロから作るDeep Learning -Pythonで学ぶディープラーニングの理論と実装』 株式会社オライリー・ジャパン.

[2] Li Wan, Matthew Zeiler, Sixin Zhang, Yann Le Cun, Rob Fergus "Regularization of Neural Networks using DropConnect" Proceedings of the 30th International Conference on Machine Learning, PMLR 28(3):1058-1066, 2013.

【iPhone】復元(初期化)後にアクティベートできない

本記事の内容は、知恵袋で同様の質問をし、自己解決した内容です。
そのまとめを詳細に記事にすることで、アクセス数を稼ごうという次第です。

iPhoneの調子が悪く、バックアップをしたうえで初期化を行うというケースは少なくないと思います。

その際、iPhoneがアクティベートできない症状に見舞われるかもしれません。
原因としていくつか挙げられますが、次に挙げる症状がある場合は同様の解決策が最適かもしれません。


現在契約中のiPhoneを、iTunesの「復元」にて初期化を行い、その後の再起動で次の文章が表示される

アクティベートできません
アクティベーションサーバにアクセスできないため、このiPhoneをアクティベートできませんでした。iPhoneをiTunesに接続してアクティベートしてみるか、数分後にやり直してください。
この問題が解決しない場合は、Appleのサポートに問い合わせてください: apple.com/jp/support


解決策は次の通りです。
上から順番に試してみてください。
ただし、当サイトで紹介した方法を試す場合は、自己責任でよろしくお願いいたします。こちらは一切の責任を負いません。

■ アクティベーション中にSIMカードを抜く

この方法に関するソースは分かりませんが、巷で解決しているケースもあるようです。お試しください。


■ iTunesに接続し、アクティベーションを開始してみる

この際に次のようにエラーが出た場合は、他の解決策をお試しください。

デバイスからアクティベーション情報が取得できなかったため、iPhone "iPhone"をアクティブにできませんでした。
iPhoneを取り外し、SIMカードが正しくセットされていることを確認します。SIM PINを使用している場合は"ロック解除"をタップしてSIM PINを入力します。次に、iPhoneを接続し直します。

■ リカバリモードを用いてアップデートまたは復元を行う

リカバリモードを用いて、iOSの再インストールを行います。ここでは、初期化したiPhoneを対象に説明をしていますので、アップデートと復元はどちらでも構いません。
Apple公式ページを参考にするといいと思います。


■ SIMカードに異状があるかどうか確認する

 身内等に同じキャリアの同機種をお持ちの方限定の方法です。自分のiPhoneのSIMカードと、他方のiPhoneのSIMカードを交換し、正常に動作するか確認します。
 自分のSIMカードを入れたiPhoneが正常に動作しなかった場合は、SIMカードに原因がある可能性があるため、キャリアさんにSIMカード交換をお願いするとよいでしょう。
キャリアによっては同様の確認をしていただける場合もあるので、お問い合わせしてみましょう。

■ 他のWi-Fiを用いてアクティベーションを行う

 これはフリーでもよいので試してみてください。私がAppleサポートセンターにお問い合わせしたところ、試してみるようにとのことでした。
スマホだけの場合とiTunesを使用した場合を試すのが確実でしょう。


■ Appleストア、あるいはApple正規サービスプロバイダに持ち込み、無償交換してもらう

 解決方法というか最後の手段ですが、ここまでの解決策で改善しない場合は本体異常の可能性が高いです。それまで正常に使用できていた場合でも同様です。
まずお近くのAppleサポートが受けれる店舗で修理を依頼してください。近辺にない場合は、輸送でサポートを受けることもできます。ただし、持ち込みの際は必ず予約を行うようにしてください。
 また、現在故障中の機種がApple Care対象か確認してからサポートを受けるようにしましょう。本体に故意的な異常が見られない場合、その場での無償交換をしていただけますが、そうでない場合は修理費としてお金が発生します。

Apple Care Servicesに加入しているか確認するには次の手順を踏んでください。
現在故障中のiPhoneで、右下のマークからシリアルナンバー(SN)を確認します。
その番号をApple公式ページに入力することで確認が可能です。


以上です。
ご不明な点があればコメントください。なるべく早めに返答いたします。