web-dev-qa-db-ja.com

なぜ畳み込みニューラルネットワークはこれほど多くのメモリを使用するのですか?

高解像度画像に ニューラルスタイル を適用する場合の主な問題の1つは、使用するメモリの量が膨大であると聞きました。

また、私は configuredtiny-cnn を使用するネットワーク

これは、私の例の重みの数とレイヤーあたりのニューロンの数の計算です:

conv_layer_# height width depth filter_height filter_width neurons_(h*w*d) weights
1            512    512   3     3             3            786432          108    
2            256    256   6     3             3            393216          216    
3            128    128   12    3             3            196608          432    
4            64     64    24    3             3            98304           864    
5            32     32    48    3             3            49152           1728   
6            16     16    96    3             3            24576           3456   
7            8      8     192   3             3            12288           6912   

                                                           1560576         13716  

8バイト(単精度浮動小数点形式)を格納する必要があるすべての値を指定すると、6297168バイト、つまり約12 MBになります。しかし、ネットは、1GBを超えるRAMをトレーニングすると割り当てます。メモリは何に必要ですか?

3
Tobias Hermann

効果に寄与している可能性のある要因をいくつか見つけました。

1)少なくともtiny-cnnでは、一部のバッファは1回ではなく、ワーカースレッドごとに1回割り当てられます。 8 CPUスレッドを備えたマシンでは、これによりメモリ使用量が大幅に増加する可能性があります。 MS VC++ 2015を使用するデバッグモードでは、コードベースの次の2行が大きなチャンクを割り当てます。どちらもワーカースレッドに関連しています: ith_in_node(i)->set_worker_size(worker_count); および ith_out_node(i)->set_worker_size(worker_count);

2)私の質問にリストされているニューロンと重みの値に加えて、勾配や、バックワードパスと最適化のためのその他の要素も保存する必要があります。

3)これがtiny-cnnに関連しているかどうかはわかりませんが、多くのフレームワークはim2colと呼ばれる操作を使用しているようです。これにより、たたみ込みを行列の乗算として表現することで、たたみ込みがはるかに速くなります。ただし、高さと幅が3 * 3のフィルターの場合、これは入力から畳み込みまでの値の数を9倍に拡大します。 Justin Johnsonが講演でそれを説明します "S231n Winter 2016 Lecture 11 ConvNets in実際" 36:22に開始。

4)私の最初の計算でエラーがありました。 512 * 512 * 3のボリュームが6つの3 * 3フィルターで畳み込まれ、平均的なプーリングレイヤーに送信されると、結果のボリュームは256 * 256 * 6になりますが、その間に512 * 512 * 6があり、 2の因数。

5)私の最初の計算で別のエラーがありました。最後の変換レイヤー(7)でそれを示します。サイズは3 * 3のフィルターで、16 * 16 * 96から8 * 8 * 192のボリュームになります。これは、すべてのフィルターに3 * 3 * 96の重みがあり、それらが192個あることを意味し、6912ではなく、このレイヤー全体で165888(3 * 3 * 96 * 192)の重みになります。

したがって、最初の3つの要素(8、9、2)のみを数学的に乗算すると、144の要素になります。これは、高いメモリ消費を説明するのに十分なようです。

1
Tobias Hermann

使用されるメモリ量の計算は、ネットワーク内のニューロンの数とそれぞれのdoubleの格納に関連しているようですが、必要なストレージはそれだけではありません。各ニューロンには、重みの数。各重みには少なくともfloatが必要になる可能性があります。これは出力の最後の列であり、(少なくとも私が正しく使用しているプログラムを理解している場合は)保存されている重みの数ニューロンごとです。それぞれの重みがfloatであるとすると、これは合計で2GB強になります。

1
Jules