def max_pool(bc01, pool_shape, pool_stride, image_shape, try_dnn=True):
    mx = None
    r, c = image_shape
    pr, pc = pool_shape
    rs, cs = pool_stride

    assert pr <= r
    assert pc <= c

    name = bc01.name
    if name is None:
        name = 'anon_bc01'

    if try_dnn and bc01.dtype == "float32":
        use_dnn = dnn_available()
    else:
        use_dnn = False

    if pool_shape == pool_stride and not use_dnn:
        mx = max_pool_2d(bc01, pool_shape, False)
        mx.name = 'max_pool(' + name + ')'
        return mx

    # Compute index in pooled space of last needed pool
    # (needed = each input pixel must appear in at least one pool)
    def last_pool(im_shp, p_shp, p_strd):
        rval = int(np.ceil(float(im_shp - p_shp) / p_strd))
        assert p_strd * rval + p_shp >= im_shp
        assert p_strd * (rval - 1) + p_shp < im_shp
        # Catch case where p_strd > p_shp causes pool
        # to be set outside of im_shp.
        if p_strd * rval >= im_shp:
            rval -= 1
        return rval
    # Compute starting row of the last pool
    last_pool_r = last_pool(image_shape[0],
                            pool_shape[0],
                            pool_stride[0]) * pool_stride[0]
    # Compute number of rows needed in image for all indexes to work out
    required_r = last_pool_r + pr

    last_pool_c = last_pool(image_shape[1],
                            pool_shape[1],
                            pool_stride[1]) * pool_stride[1]
    required_c = last_pool_c + pc

    for bc01v in get_debug_values(bc01):
        assert not contains_inf(bc01v)
        assert bc01v.shape[2] == image_shape[0]
        assert bc01v.shape[3] == image_shape[1]

    if (required_r > r) or (required_c > c):
        small_r = min(required_r, r)
        small_c = min(required_c, c)
        assert bc01.dtype.startswith('float')
        wide_infinity = T.alloc(T.constant(-np.inf, dtype=bc01.dtype),
                                bc01.shape[0],
                                bc01.shape[1],
                                required_r,
                                required_c)

        bc01 = T.set_subtensor(wide_infinity[:, :, 0:small_r, 0:small_c],
                               bc01[:, :, 0:small_r, 0:small_c])
        name = 'infinite_padded_' + name

    if use_dnn:
        mx = pool_dnn(bc01, pool_shape, pool_stride, 'max')
    else:
        for row_within_pool in xrange(pool_shape[0]):
            row_stop = last_pool_r + row_within_pool + 1
            for col_within_pool in xrange(pool_shape[1]):
                col_stop = last_pool_c + col_within_pool + 1
                cur = bc01[:,
                           :,
                           row_within_pool:row_stop:rs,
                           col_within_pool:col_stop:cs]
                cur.name = ('max_pool_cur_' + name + '_' +
                            str(row_within_pool) + '_' + str(col_within_pool))
                if mx is None:
                    mx = cur
                else:
                    mx = T.maximum(mx, cur)
                    mx.name = ('max_pool_mx_' + name + '_' +
                               str(row_within_pool) + '_' +
                               str(col_within_pool))

    mx.name = 'max_pool(' + name + ')'

    for mxv in get_debug_values(mx):
        assert isfinite(mxv)

    return mx
Theano's max pooling op only supports pool_stride = pool_shape
dataset/ETHPy150Open lisa-lab/pylearn2/pylearn2/models/mlp.py/max_pool