2017-08-25 10 views
0

私はテンソルフローの分類モデルを2つの方法で定義しました。私は同じ効果があると考えていました。しかし、実際に私は別の結果を得ました。次いでテンソルフローでモデルを定義する方法は?

def network(x, mode_name): 
    conv1 = conv_layer(x, conv_size=[13, 13, 1, 32], stride_size=[1, 1, 1, 1], name=mode_name + "conv1") 
    maxp1 = pooling_layer(conv1, ksize=[1, 4, 4, 1], stride_size=[1, 4, 4, 1]) 
    conv2 = conv_layer(maxp1, conv_size=[7, 7, 32, 64], stride_size=[1, 1, 1, 1], name=mode_name + "conv2") 
    maxp2 = pooling_layer(conv2, ksize=[1, 2, 2, 1], stride_size=[1, 2, 2, 1]) 
    conv3 = conv_layer(maxp2, conv_size=[3, 3, 64, 256], stride_size=[1, 1, 1, 1], name=mode_name + "conv3") 
    maxp3 = pooling_layer(conv3, ksize=[1, 2, 2, 1], stride_size=[1, 2, 2, 1]) 
    shape = maxp3.get_shape().as_list() 
    reshape = tf.reshape(maxp3, [shape[0], shape[1] * shape[2] * shape[3]]) 
    fc = fc_layer(reshape, label_number, name=mode_name + "fc") 
    return fc 

def fc_layer(prev_layer, n_weight, name): 
    n_prev_weight = prev_layer.get_shape()[1] 
    initer = tf.truncated_normal_initializer(stddev=0.0001) 
    W = tf.get_variable(name + 'W', dtype=tf.float32, shape=[n_prev_weight, n_weight], initializer=initer) 
    b = tf.get_variable(name + "b", dtype=tf.float32, 
        initializer=tf.constant(0.0001, shape=[n_weight], dtype=tf.float32)) 
    fc = tf.nn.bias_add(tf.matmul(prev_layer, W), b) 
    return fc 


def conv_layer(prev_layer, conv_size, stride_size, name): 
    initer = tf.truncated_normal_initializer(stddev=0.0001) 
    W = tf.get_variable(name + 'W', dtype=tf.float32, shape=conv_size, 
        initializer=initer) 
    b = tf.get_variable(name + 'b', dtype=tf.float32, 
        initializer=tf.constant(0.0001, shape=[conv_size[3]], dtype=tf.float32)) 

    return tf.nn.relu(tf.nn.conv2d(prev_layer, W, stride_size, padding='VALID') + b) 

def pooling_layer(prev_layer, ksize, stride_size): 
    return tf.nn.max_pool(prev_layer, ksize=ksize, strides=stride_size, padding='VALID') 

mainこれらの関数を使用する:

graph = tf.Graph() 

with graph.as_default(): 
    # input data 
    tf_train_dataset = tf.placeholder(tf.float32, 
             shape=(batch_size, image_size, image_size, image_channel)) 
    tf_train_labels = tf.placeholder(tf.float32, 
            shape=(batch_size, label_number)) 
    tf_test_dataset = tf.constant(test_dataset) 

    with tf.variable_scope("simple_cnn") as scope: 
     logits = network(tf_train_dataset, "simple_cnn") 

    loss = tf.reduce_mean(
     tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=tf_train_labels)) 

    optimizer = tf.train.GradientDescentOptimizer(0.05).minimize(loss) 

    train_prediction = tf.nn.softmax(logits=logits) 

    with tf.variable_scope("simple_cnn") as scope: 
     scope.reuse_variables() 
     test_prediction = tf.nn.softmax(network(tf_test_dataset, "simple_cnn")) 

他の方法は、すべての変数を割り当て、mainモデルを定義することである。

機能を通じてモデルを定義して 第方法
graph = tf.Graph() 

with graph.as_default(): 
    # input data 
    tf_train_dataset = tf.placeholder(tf.float32, 
             shape=(batch_size, image_size, image_size, image_channel)) 
    tf_train_labels = tf.placeholder(tf.float32, 
            shape=(batch_size, label_number)) 
    tf_test_dataset = tf.constant(test_dataset) 

    initer = tf.truncated_normal_initializer(stddev=0.01) 
    conv_w1 = tf.get_variable(name="conv_w1", dtype=tf.float32, shape=[13, 13, 1, 32], initializer=initer) 
    conv_b1 = tf.get_variable(name="conv_b1", dtype=tf.float32, 
           initializer=tf.constant(0.01, shape=[32, ], dtype=tf.float32)) 
    conv_w2 = tf.get_variable(name="conv_w2", dtype=tf.float32, shape=[7, 7, 32, 64], initializer=initer) 
    conv_b2 = tf.get_variable(name="conv_b2", dtype=tf.float32, 
           initializer=tf.constant(0.01, shape=[64, ], dtype=tf.float32)) 
    conv_w3 = tf.get_variable(name="conv_w3", dtype=tf.float32, shape=[3, 3, 64, 256], initializer=initer) 
    conv_b3 = tf.get_variable(name="conv_b3", dtype=tf.float32, 
           initializer=tf.constant(0.01, shape=[256, ], dtype=tf.float32)) 
    fc_w = tf.get_variable(name='fc_w', dtype=tf.float32, shape=[2304, label_number], initializer=initer) 
    fc_b = tf.get_variable(name="fc_b", dtype=tf.float32, 
          initializer=tf.constant(0.0001, shape=[label_number, ], dtype=tf.float32)) 


    def model(x): 
     conv1 = tf.nn.conv2d(x, conv_w1, strides=[1, 1, 1, 1], padding='VALID') + conv_b1 
     relu1 = tf.nn.relu(conv1) 
     maxp1 = tf.nn.max_pool(relu1, ksize=[1, 4, 4, 1], strides=[1, 4, 4, 1], padding='VALID') 

     conv2 = tf.nn.conv2d(maxp1, conv_w2, strides=[1, 1, 1, 1], padding="VALID") + conv_b2 
     relu2 = tf.nn.relu(conv2) 
     maxp2 = tf.nn.max_pool(relu2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='VALID') 

     conv3 = tf.nn.conv2d(maxp2, conv_w3, strides=[1, 1, 1, 1], padding='VALID') 
     relu3 = tf.nn.relu(conv3) 
     maxp3 = tf.nn.max_pool(relu3, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='VALID') 

     shape = maxp3.get_shape().as_list() 

     reshape = tf.reshape(maxp3, [shape[0], shape[1] * shape[2] * shape[3]]) 
     fc = tf.nn.bias_add(tf.matmul(reshape, fc_w), fc_b) 
     return fc 

    logits = model(tf_train_dataset) 
    loss = tf.reduce_mean(
     tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=tf_train_labels)) 

    optimizer = tf.train.GradientDescentOptimizer(0.1).minimize(loss) 

    train_prediction = tf.nn.softmax(logits=logits) 

    test_prediction = tf.nn.softmax(model(tf_test_dataset)) 

2つの方法が実際に同じモデルを定義していると思います。しかし、私がそれらを訓練したとき、最初の方法がコストを減らすことに何の効果ももたらさなかったのは、failure-resultであり、第2の方法で定義されたモデルは成功したsuccessです。モデルそのものを気にしないで、どうしてこのような違いが生じたのだろうか?入力データは両方とも同じです。

+0

変数を更新していないようです。あなたが言ったように – velikodniy

答えて

0

あなたの変数を見てください。最初のモデルでは

with tf.variable_scope("simple_cnn") as scope: 
    scope.reuse_variables() 
    test_prediction = tf.nn.softmax(network(tf_test_dataset, "simple_cnn")) 

、テスト変数名は、余分なsimple_cnn/を持っている必要があります。だからあなたはあなたのテストに学習された変数を使用していません。

Sharing Variableを参照して、変数を共有する方法を理解してください。あなたの場合は、すべてを同じスコープに入れてください(つまり、with tf.variable_scope("simple_cnn") ...もトレーニングモデルの前に置く必要があります)。

+0

ただ、私は次のようにコードを変更:スコープとしてtf.variable_scopeと ( "simple_cnn"): logits =ネットワーク(tf_train_dataset) scope.reuse_variables() test_prediction = tf.nn.softmax(ネットワークを(tf_test_dataset))= tf.reduce_mean 損失( tf.nn.softmax_cross_entropy_with_logits(logitsの=のlogits、 ラベル= tf_train_labels)) は、それが動作します。しかし、私はまだなぜか分からない。 [チュートリアル](https://www.tensorflow.org/versions/r0.12/how_tos/variable_scope/index.html)を読んで、テスト変数がトレーニング変数とまったく同じだと思います。 tf.variable_scopeと V = tf.get_variable( "V"、[1]) ( "FOO"、=真を再利用): – Jermmy

+0

公式例:tf.variable_scopeと ( "FOO") V1 = TF .get_variable( "v"、[1]) アサートv1がv の場合は、最初のモデルで使用したのとまったく同じです。トレーニングモデルの前にスコープを入れただけなのかもしれませんか? – Jermmy

+0

'tf.variable_scope(" simple_cnn ")を使うと、変数のすべての名前に' simple_cnn'が追加されます。これはあなたの2つのコードの唯一の違いでした。テンソルフローが変数を再利用するときは、その名前を使用します。テストで同じスコープを追加すると、ランダムな値を使用する前に、同じ訓練された変数を使用するようになります。 –

関連する問題