Caffeでは、convolution
レイヤーは1つのボトムブロブを取り、学習タイプのフィルタ(「Xavier」、「MSRA」などのウェイトタイプを使用して初期化されています)で畳み込みます。しかし、私の質問は、単に2つのボトムブロブを畳み込み、トップブロブを生成できるかどうかです。これを行う最もエレガントな方法は何でしょうか?これは、下部のブロブの1つがdata
になり、もう1つは前のレイヤーで生成された動的フィルタ(に応じて変更)になります(私はdynamic convolutionを実装しようとしています)。Caffeで2つのブロブを畳み込む方法
私の試み:私の心に来た
一つの方法は、filler.hpp
を変更し、(代わりに「ザビエル」、「MSRA」などの)filler
マトリックス自体として下ブロブを割り当てることでした。それから畳み込みレイヤーがそこから拾い上げると思った。 lr = 0
を設定して、カスタムフィラーによって初期化された重量を変更しないことを示すことができます。しかし、私がソースコードを見ても、それをやる方法はまだ分かりません。一方、私はcaffeのワークフローを破りたくはありません。私は、convレイヤーが正常に機能するようにしたいと思っています。
明らかに、より退屈な方法は、文字通り畳み込みを実装するためにSlice
、tile
および/またはScale
レイヤの組み合わせを使用することです。私はそれがうまくいくと思うが、それは乱雑になるだろう。他の考え?
編集1:
私はカフェの畳み込み層を変更することによって、新しいレイヤーを書きました。特に、src/caffe/layers/conv_layer.cpp
の27行目では、filler
で定義された重みをとり、それを下のブロブと畳み込んでいます。だから、filler
からブロブを取り込む代わりに、レイヤーを2つのボトムに変更しました。ボトムの1つがフィラーに直接割り当てられます。
weight
ブロブは、すべてのサンプルに対して同じ値を持っている:今、私のような他のいくつかの変更をしなければなりませんでした。ここでは、サンプルごとに異なる値が設定されます。
this->forward_cpu_gemm(
bottom_data + n * this->bottom_dim_,
weight,
top_data + n * this->top_dim_);
へ:だから私はからライン32を変更し、物事を簡単にするために
this->forward_cpu_gemm(
bottom_data + n * bottom[1]->count(1),
bottom[0]->cpu_data() + n * bottom[0]->count(1),
top_data + n * this->top_dim_);
私は関与なしバイアス項が存在しないと仮定し、ストライドは常に1である、パディングは常に0にすることができますしかし、私はフォワードパスをテストしたとき、それは私に奇妙な答えを与えました(単純な畳み込みカーネル= np.ones((1,1,3,3))
)。このカーネルの学習率はゼロに設定されています。しかし、私は正しい答えを得ることができません。どんな提案もありがとうございます。
Slice, Eltwise, Crop
などの既存のレイヤーを使用してソリューションを提案しないでください。私はすでに実装しています - それは動作しますが、それは信じられない複雑さとメモリ非効率です。
私はそれを読んで "2つのブロンドをカフェで納得させる":\ – Elazar
@エラザールだから、あなたはダウン投票したのですか? (ちょうど冗談です):P –