2017-01-19 5 views
3

私は機械学習とPythonでいくつかの背景を持っていますが、私はTensorFlowを学んでいます。私はtutorial on deep convolutional neural netsを使って画像分類に使用する方法を教えています。道に沿って、私は完了するのに苦労している運動があります。TensorFlow CNNチュートリアル:最上位レイヤーをローカルに接続する方法を教えてください。

演習:推論()のモデルアーキテクチャは、cuda-convnetで指定されたCIFAR-10モデルとは少し異なります。特に、アレックスのオリジナルモデルの最上位層は、ローカルに接続されており、完全には接続されていません。最上位層にローカルに接続されたアーキテクチャを正確に再現するようにアーキテクチャを編集してみてください。

練習問題は、cifar10.py modelのinference()関数を参照しています。 2番目から最後のレイヤー(local4と呼ばれます)はshape = [384,192]で、トップレイヤーはshape = [192、NUM_CLASSES]です。NUM_CLASSES = 10です。私たちは編集することが求められているコードは、トップ層を定義するコードのどこかにあると思う:

with tf.variable_scope('softmax_linear') as scope: 
    weights = _variable_with_weight_decay('weights', [192, NUM_CLASSES], 
             stddev=1/192.0, wd=0.0) 
    biases = _variable_on_cpu('biases', [NUM_CLASSES], 
          tf.constant_initializer(0.0)) 
    softmax_linear = tf.add(tf.matmul(local4, weights), biases,name=scope.name 
    _activation_summary(softmax_linear) 

しかし、私は、層間の接続の確率を決定任意のコードが表示されないので、私は知りません完全に接続されたモデルからローカルに接続されたモデルに変更する方法誰かがこれを行う方法を知っていますか?

答えて

2

私はこの演習でも取り組んでいます。解決策を提示するのではなく、私のアプローチを正しく説明しようとします。完全に接続された層(https://www.tensorflow.org/get_started/mnist/beginners)の数学を振り返る価値があります。

だから完全に接続された層のための線形代数である:XがBNであり、n次元の入力ベクトルである

YはW * X + B

を=バイアスの次元ベクトルであり、Wは、n -by-nの重み行列です。YI番目の要素は、W乗算要素単位XとのI番目の行の合計です。だから、

....あなただけyとしたい場合は、[i]はX [I-1]Xに接続されている[i]を、およびX [I + 1]、あなたは、単に設定離れ(I-1)番目、I番目とその行の(I + 1)番目の列からゼロへWI番目の行のすべての値、。したがって、ローカルに接続されたレイヤーを作成するには、Wをバンドルマトリックス(https://en.wikipedia.org/wiki/Band_matrix)にするだけです(バンドのサイズは、ローカルに接続されている近隣のサイズと同じです)。 Tensorflowには、行列を束縛するように設定する関数があります(tf.batch_matrix_band_part(input, num_lower, num_upper, name=None))。

これは、私が運動の最も単純な数学的解決策に思えます。

+0

この回答は、この課題を解決するものではありません。 W行列は「マルチバンド」でなければならない。たとえば、フィルタが3x3の場合、3つの対角バンド、それぞれ3つの要素幅が必要です。 tf.matrix_band_part()は1つのバンドのみを許可します。 また、Wの次元が変化するため、元のWを取り、いくつかの要素をゼロに設定することはできません。特に、Wの行数は、フラット化された出力フィーチャマップの長さと等しくなければなりません。 私はXyandの答えがより良いアプローチだと考えています:画像パッチを抽出し、それ自身のカーネルでそれぞれを掛けるので、テンソルは2つの余分な次元(6Dになります)を得ます。 – MichaelSB

+0

十分に公正です。これは、私がこの運動を解決する方法の手がかりを与える数学の何らかの理解を得ることを試みているちょうど私でした。私は彼らが演習を与える理由は、人々が自分自身のために考えさせることだと思うので、私は実際にコピー/貼り付けできるコードを与えるだけではなく、理論的にどのようにアプローチできるかを理解するのに役立つ。エンジニアリングだけでなく、神経網を扱うときに線形代数のいくつかを理解することは有益です。 –

+0

私はこのローカルに接続されたレイヤーを処理して以来、しばらくしています。しかし、@DavidPickupによるアプローチは、完全な行列に定数指標行列を乗算したマルチバンド行列をシミュレートすることで実際に動作します。Wのサイズは(w_out * h_out)X(w_in * h_in * d_in)でなければなりません。しかし、それはかなり無駄に思われる。何か不足していますか? – Xyand

2

私は100%ではありませんが、私はあなたの質問に答えようとします。

cuda-convnetを見ると、TensorFlowとcuda-convnetの実装は、2番目のプール層の後で異なることがわかります。

TensorFlowの実装では、2つの完全に接続されたレイヤーとsoftmaxクラシファイアが実装されています。

cuda-convnetは、ローカルに接続された2つのレイヤー(完全に接続されたレイヤーとsoftmaxクラシファイア)を実装しています。

含まれているコードスニペットはsoftmaxクラシファイアのみを参照し、実際には2つの実装間で共有されています。 TensorFlowを使用してcuda-convnetの実装を再現するには、既存の完全に接続されたレイヤーを、ローカルに接続された2つのレイヤーと完全に接続されたレイヤーに置き換える必要があります。

TensorはSDKの一部としてローカルに接続されたレイヤーを持っていないので、既存のツールを使用して実装する方法を見つけなければなりません。

with tf.variable_scope('local3') as scope: 
    shape = pool2.get_shape() 
    h = shape[1].value 
    w = shape[2].value 

    sz_local = 3 # kernel size 
    sz_patch = (sz_local**2)*shape[3].value 
    n_channels = 64 

    # Extract 3x3 tensor patches 
    patches = tf.extract_image_patches(pool2, [1,sz_local,sz_local,1], [1,1,1,1], [1,1,1,1], 'SAME') 
    weights = _variable_with_weight_decay('weights', shape=[1,h,w,sz_patch, n_channels], stddev=5e-2, wd=0.0) 
    biases = _variable_on_cpu('biases', [h,w,n_channels], tf.constant_initializer(0.1)) 

    # "Filter" each patch with its own kernel 
    mul = tf.multiply(tf.expand_dims(patches, axis=-1), weights) 
    ssum = tf.reduce_sum(mul, axis=3) 
    pre_activation = tf.add(ssum, biases) 
    local3 = tf.nn.relu(pre_activation, name=scope.name) 
+0

hおよびwの寸法は、入力フィーチャマップではなく、出力フィーチャマップの高さと幅を参照する必要があります。 – MichaelSB

関連する問題