<p>In a classification task improving the accuracy is the goal.</p>

<p>However, pooling allows you to:</p>

<ol>
<li>Reduce the input dimensionality</li>
<li>Force the network to learn particular features, depending on the type of pooling you apply.</li>
</ol>

<p>Reducing the input dimensionality is something you want because it forces the network to project its learned representations in a different and with lower dimensionality space. This is good computationally speaking because you have to allocate less memory and thus you can have bigger batches. But it's also something desirable because usually high-dimensional spaces have a lot of redundancy and are spaces in which all abjects appears to be sparse and dissimilar ( see <a href="https://en.wikipedia.org/wiki/Curse_of_dimensionality)" rel="nofollow noreferrer">The curse of dimensionality</a> )</p>

<p>The function you decide to use for the pooling operation, moreover, can force the network to give more importance to some features.</p>

<p>Max-pooling, for instance, is widely used because allow the network to be robust to small variations of the input image.</p>

<p>What happens, in practice, it that only the features with the highest activations pass through the max-pooling gate.
If the input image is shifted by a small amount, then the max-pooling op produces the same output although the input is shifted (the maximum shift is thus equal to the kernel size).</p>

<p>CNN without pooling are also capable of learning this kind of features, but with a bigger cost in term of parameters and computing time (see <a href="https://arxiv.org/abs/1412.6806" rel="nofollow noreferrer">Striving for Simplicity: The All Convolutional Net</a>)</p>
Effect of max_pool in Convolutional Neural Network [tensorflow]
<p>I'm following Udacity Deep Learning video by Vincent Vanhoucke and trying to understand the (practical or intuitive or obvious) effect of max pooling.</p>

<p>Let's say my current model (without pooling) uses convolutions with stride 2 to reduce the dimensionality. </p>

<pre><code>  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
</code></pre>

<p>Now I introduced pooling: Replace the strides by a max pooling operation (nn.max_pool()) of stride 2 and kernel size 2.</p>

<pre><code>  def model(data):
    conv1 = tf.nn.conv2d(data, layer1_weights, [1, 1, 1, 1], padding='SAME')
    bias1 = tf.nn.relu(conv1 + layer1_biases)
    pool1 = tf.nn.max_pool(bias1, [1, 2, 2, 1], [1, 2, 2, 1], padding='SAME')
    conv2 = tf.nn.conv2d(pool1, layer2_weights, [1, 1, 1, 1], padding='SAME')
    bias2 = tf.nn.relu(conv2 + layer2_biases)
    pool2 = tf.nn.max_pool(bias2, [1, 2, 2, 1], [1, 2, 2, 1], padding='SAME')
    shape = pool2.get_shape().as_list()
    reshape = tf.reshape(pool2, [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
</code></pre>

<p>What would be the compelling reason that we use the later model instead of no-pool model, besides the improved accuracy? Would love to have some insights from people who have already used cnn many times!</p>