1

I was following along with a sentdex tutorial on writing a constitutional neural network and I got to wondering if I could figure out my own pooling layer. The problem is that as part of this pooling layer I have to perform a tensorflow function using a session.

def customPool(x):
patches = tf.extract_image_patches(x, [1, 2, 2, 1], [1,2,2,1], [1,1,1,1], 'SAME')

tempSess = tf.Session()
bool1 = tempSess.run( tf.greater( tf.reduce_max(patches) , tf.contrib.distributions.percentile(patches, q=75.) ) )
tempSess.close()

if bool1:
    return tf.nn.max_pool(x, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')
else:
    return tf.nn.avg_pool(x, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')

but the problem is, at least I think, that since I start everything out with a place holder

x = tf.placeholder('float', [None, 784])

Basically my question is: How do I compute something using a tensorflow session inside of the neural network model if it is being passed placeholder variables? Help is much appreciated! full code:

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("/tmp/data/", one_hot = True)

n_classes = 10
batch_size = 128

x = tf.placeholder('float', [None, 784])
y = tf.placeholder('float')

keep_rate = 0.8
keep_prob = tf.placeholder(tf.float32)


def conv2d(x, W):
    return tf.nn.conv2d(x, W, strides=[1,1,1,1], padding='SAME')

def maxpool2d(x):
    #                        size of window         movement of window
    return tf.nn.max_pool(x, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')

def customPool(x):
    patches = tf.extract_image_patches(x, [1, 2, 2, 1], [1,2,2,1], [1,1,1,1], 'SAME')

    tempSess = tf.Session()
    bool1 = tempSess.run( tf.greater( tf.reduce_max(patches) , tf.contrib.distributions.percentile(patches, q=75.) ) )
    tempSess.close()

    if bool1:
        return tf.nn.max_pool(x, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')
    else:
        return tf.nn.avg_pool(x, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')

def convolutional_neural_network(x):
    weights = {'W_conv1':tf.Variable(tf.random_normal([5,5,1,32])),
           'W_conv2':tf.Variable(tf.random_normal([5,5,32,64])),
           'W_fc':tf.Variable(tf.random_normal([7*7*64,1024])),
           'out':tf.Variable(tf.random_normal([1024, n_classes]))}

    biases = {'b_conv1':tf.Variable(tf.random_normal([32])),
           'b_conv2':tf.Variable(tf.random_normal([64])),
           'b_fc':tf.Variable(tf.random_normal([1024])),
           'out':tf.Variable(tf.random_normal([n_classes]))}

    x = tf.reshape(x, shape=[-1, 28, 28, 1])

    conv1 = tf.nn.relu(conv2d(x, weights['W_conv1']) + biases['b_conv1'])
    #conv1 = maxpool2d(conv1)
    conv1 = customPool(conv1)

    conv2 = tf.nn.relu(conv2d(conv1, weights['W_conv2']) + biases['b_conv2'])
    #conv2 = maxpool2d(conv2)
    conv1 = customPool(conv1)

    fc = tf.reshape(conv2,[-1, 7*7*64])
    fc = tf.nn.relu(tf.matmul(fc, weights['W_fc'])+biases['b_fc'])
    fc = tf.nn.dropout(fc, keep_rate)

    output = tf.matmul(fc, weights['out'])+biases['out']

    return output

def train_neural_network(x):
    prediction = convolutional_neural_network(x)
    cost = tf.reduce_mean( tf.nn.softmax_cross_entropy_with_logits(logits=prediction, labels=y) )
    optimizer = tf.train.AdamOptimizer().minimize(cost)


    hm_epochs = 1
    with tf.Session() as sess:
        sess.run(tf.initialize_all_variables())

        saver = tf.train.Saver()

        for epoch in range(hm_epochs):
            epoch_loss = 0
            for _ in range(int(mnist.train.num_examples/batch_size)):
            epoch_x, epoch_y = mnist.train.next_batch(batch_size)
            _, c = sess.run([optimizer, cost], feed_dict={x: epoch_x, y: epoch_y})
                epoch_loss += c

    print('Epoch', epoch, 'completed out of',hm_epochs,'loss:',epoch_loss)

    correct = tf.equal(tf.argmax(prediction, 1), tf.argmax(y, 1))

    accuracy = tf.reduce_mean(tf.cast(correct, 'float'))
    print('Accuracy:',accuracy.eval({x:mnist.test.images, y:mnist.test.labels}))

    save_path = saver.save(sess, "/tmp/convnet_maxpool")
    print("Model saved in file: %s" % save_path)


#sess = tf.Session()
train_neural_network(x)
#sess.close()

EDIT: after following Maxim's advice I ran it and it threw the error

_, c = sess.run([optimizer, cost], feed_dict={x: epoch_x, y: epoch_y})
InvalidArgumentError (see above for traceback): logits and labels must be same size: logits_size=[512,10] labels_size=[128,10]
     [[Node: SoftmaxCrossEntropyWithLogits = SoftmaxCrossEntropyWithLogits[T=DT_FLOAT, _device="/job:localhost/replica:0/task:0/device:CPU:0"](Reshape_2, Reshape_3)]]

it was tracing back to:

File "conv net custom test 1.py", line 89, in <module>
   train_neural_network(x)
File "conv net custom test 1.py", line 59, in train_neural_network
   cost=tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=prediction, labels=y) )

1 Answers1

1

Use tf.cond, not session:

def customPool(x):
  patches = tf.extract_image_patches(x, [1, 2, 2, 1], [1,2,2,1], [1,1,1,1], 'SAME')
  pred = tf.greater(tf.reduce_max(patches), 
                    tf.contrib.distributions.percentile(patches, q=75.))
  return tf.cond(pred, 
                 lambda: tf.nn.max_pool(x, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME'),
                 lambda: tf.nn.avg_pool(x, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME'))

Update:

You've also a copy-paste bug: it's conv1 = customPool(conv1) twice in a row, conv2 isn't downsampled, hence the dimensions error.

Maxim
  • 52,561
  • 27
  • 155
  • 209
  • I think that may have done the trick. It is now telling me that I have an unequal amount of logits and labels. This code worked before and the only difference now is that sometimes it performs max pool and sometimes it performs average pool, correct? Do you know how this made it different? – Dean Alvarez Jan 23 '18 at 18:26
  • `tf.cond` doesn't change the dimensions. In fact, it would complain if two branches have different output dimensions. Edit your question and post the stacktrace – Maxim Jan 23 '18 at 18:29
  • yeah, I was thinking that it shouldn't have changed the dimensions at all as it was just deciding which pooling technique to use. okay, edited. – Dean Alvarez Jan 23 '18 at 18:43