2016-07-14 4 views
0

私はTensorFlowで単純な畳み込みニューラルネットワークを作成しようとしています。下のコードを実行すると、すべてうまくいくように見えます。私はSpyder IDEでそれを実行し、メモリの使用状況を監視する - それは私のラップトップで64から65%に成長し、それ以上は行っていない。TensorFlow - nn.max_poolingはメモリ使用量を大幅に増加させます

batch_size = 16 
patch_size = 5 
depth = 16 
num_hidden = 64 

graph = tf.Graph() 

with graph.as_default(): 

    # Input data. 
    tf_train_dataset = tf.placeholder(
    tf.float32, shape=(batch_size, image_size, image_size, num_channels)) 
    tf_train_labels = tf.placeholder(tf.float32, shape=(batch_size, num_labels)) 
    tf_valid_dataset = tf.constant(valid_dataset) 
    tf_test_dataset = tf.constant(test_dataset) 

    # Variables. 
    layer1_weights = tf.Variable(tf.truncated_normal(
     [patch_size, patch_size, num_channels, depth], stddev=0.1)) 
    layer1_biases = tf.Variable(tf.zeros([depth])) 
    layer2_weights = tf.Variable(tf.truncated_normal(
     [patch_size, patch_size, depth, depth], stddev=0.1)) 
    layer2_biases = tf.Variable(tf.constant(1.0, shape=[depth])) 
    layer3_weights = tf.Variable(tf.truncated_normal(
     [image_size // 4 * image_size // 4 * depth, num_hidden], stddev=0.1)) 
    layer3_biases = tf.Variable(tf.constant(1.0, shape=[num_hidden])) 
    layer4_weights = tf.Variable(tf.truncated_normal(
     [num_hidden, num_labels], stddev=0.1)) 
    layer4_biases = tf.Variable(tf.constant(1.0, shape=[num_labels])) 

    # Model. 
    #Now instead of using strides = 2 for convolutions we will use maxpooling with 
    #same convolution sizes 
    def model(data): 
    conv = tf.nn.conv2d(data, layer1_weights, [1, 2, 2, 1], padding='SAME') 
    hidden = tf.nn.relu(conv + layer1_biases) 
    conv = tf.nn.conv2d(hidden, layer2_weights, [1, 2, 2, 1], padding='SAME') 
    hidden = tf.nn.relu(conv + layer2_biases) 
    shape = hidden.get_shape().as_list() 
    reshape = tf.reshape(hidden, [shape[0], shape[1] * shape[2] * shape[3]]) 
    hidden = tf.nn.relu(tf.matmul(reshape, layer3_weights) + layer3_biases) 
    return tf.matmul(hidden, layer4_weights) + layer4_biases 

    # Training computation. 
    logits = model(tf_train_dataset) 
    loss = tf.reduce_mean(
    tf.nn.softmax_cross_entropy_with_logits(logits, tf_train_labels)) 

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

    # Predictions for the training, validation, and test data. 
    train_prediction = tf.nn.softmax(logits) 
    valid_prediction = tf.nn.softmax(model(tf_valid_dataset)) 
    test_prediction = tf.nn.softmax(model(tf_test_dataset)) 

num_steps = 1001 

with tf.Session(graph=graph) as session: 
    tf.initialize_all_variables().run() 
    print('Initialized') 
    for step in range(num_steps): 
    offset = (step * batch_size) % (train_labels.shape[0] - batch_size) 
    batch_data = train_dataset[offset:(offset + batch_size), :, :, :] 
    batch_labels = train_labels[offset:(offset + batch_size), :] 
    feed_dict = {tf_train_dataset : batch_data, tf_train_labels : batch_labels} 
    _, l, predictions = session.run(
     [optimizer, loss, train_prediction], feed_dict=feed_dict) 
    if (step % 50 == 0): 
     print('Minibatch loss at step %d: %f' % (step, l)) 
     print('Minibatch accuracy: %.1f%%' % accuracy(predictions, batch_labels)) 
     print('Validation accuracy: %.1f%%' % accuracy(
     valid_prediction.eval(), valid_labels)) 
    print('Test accuracy: %.1f%%' % accuracy(test_prediction.eval(), test_labels)) 

[OK]を、その後、私は2のカーネルとmaxpoolingを導入しようとすると、CONV層の代わりにmaxpoolingとデータのサイズを小さくします。以下のようになります。

conv = tf.nn.conv2d(data, layer1_weights, [1, 1, 1, 1], padding='SAME') 
    maxpool = tf.nn.max_pool(conv, [1, 2, 2, 1], [1, 2, 2, 1], padding='SAME') 
    hidden = tf.nn.relu(maxpool + layer1_biases) 
    conv = tf.nn.conv2d(hidden, layer2_weights, [1, 2, 2, 1], padding='SAME') 

他のすべては同じです。しかし、私がこれを行うと(注意して、私はmaxpoolingレイヤーを1つだけ導入しました)、メモリ使用量は100%に増え、iPythonカーネルはちょうど死にます。そのような奇妙な行動のアイデア、なぜメモリ使用量がそれほど大きくなるのでしょうか?私は何か間違っているのですか?メモリ使用量を減らす方法に関する提案はありますか?

答えて

1

1チャネル6x6入力で1つの3x3フィルタを使用しているとします。

ストライド2のストライド畳み込みを実行すると、3x3の結果が生成されます。

入力36ユニット+フィルタ9ユニット+出力9ユニットを効果的に使用します。あなたは非ストライドコンボリューション後に最大のプールを適用しようとしているとき

は今、あなたの畳み込み層を使用すると、3x3の出力を得るためにmaxpoolを適用した上で6x6の出力を生成します。 max poolを適用する前にメモリにあるサイズが6x6の中間結果があることに注意してください。

入力36単位+フィルタ9つの単位+中間結果36単位+出力メモリ

の9つの単位

を使用するので、ここで上にこれは、メモリ使用量を説明するであろう。これは奇妙な動作ではありません。あなたのリソースを完全に使い果たした理由は、イメージサイズ、バッチサイズ、使用しているフィルタの数によって異なります。

+0

画像サイズは28x28、シングルチャンネル、バッチサイズは16 ...奇妙なことに、パッチサイズを1(〜4)でも小さくしてもうまくいきます。そのことについての何らかの考え方 - なぜパッチのサイズに大きな影響があるのですか?私はまた、実行中のメモリ使用量が大きく変動していることに気付きました。ある瞬間、他の登山では97%に50%以下になり、その後に戻ります(4のパッチがあるとき) –

関連する問題