.. _libdoc_tensor_nnet_conv:

==========================================================
:mod:`conv` -- Ops for convolutional neural nets
==========================================================

.. note::

    Two similar implementation exists for conv2d:

        :func:`signal.conv2d <theano.tensor.signal.conv.conv2d>` and
        :func:`nnet.conv2d <theano.tensor.nnet.conv.conv2d>`.

    The former implements a traditional
    2D convolution, while the latter implements the convolutional layers
    present in convolutional neural networks (where filters are 3D and pool
    over several input channels).

.. module:: conv
   :platform: Unix, Windows
   :synopsis: ops for signal processing
.. moduleauthor:: LISA


TODO: Give examples for how to use these things! They are pretty complicated.

- Conv implemented
    - :func:`signal.conv2d <theano.tensor.signal.conv.conv2d>`.
    - :func:`nnet.conv2d <theano.tensor.nnet.conv.conv2d>`.
    - :func:`conv2d_fft <theano.sandbox.cuda.fftconv.conv2d_fft>`
      This is a GPU-only version of nnet.conv2d that uses an FFT transform
      to perform the work. conv2d_fft should not be used directly as it
      does not implement a grad function. Instead, you should use
       nnet.conv2d and enable the fft optimization by setting
      'THEANO_FLAGS=optimizer_including=conv_fft_valid:conv_fft_full'
      in your environement.  This is not enabled by default because it
      has some restrictions on input and uses more memory.  Also note
      that it requires CUDA >= 5.0, scikits.cuda >= 0.5.0 and PyCUDA to run.
      To desactivate the fft optimization on a specific nnet.conv2d
      while the optimization flags are active, you can set its parameters
      version to 'no_fft'. To enable for just one Theano function:

      .. code-block:: python

          mode = theano.compile.get_default_mode()
          mode = mode.including('conv_fft_valid', 'conv_fft_full')

          f = theano.function(..., mode=mode)

    - :func:`conv3D <theano.tensor.nnet.Conv3D.conv3D>`
      3D Convolution. Doesn't work on the GPU.
    - :func:`conv3d_fft <theano.sandbox.cuda.fftconv.conv3d_fft>`
      GPU-only version of conv3D using FFT transform. conv3d_fft should
      not be call directly as it does not implement a grad function.
      You can enable it by setting THEANO_FLAGS to
      'optimizer_including=conv3d_fft:convgrad3d_fft:convtransp3d_fft'
      It does not support strides.
      This is not enabled by default because it uses more memory.
      Also note that it requires CUDA >= 5.0,
      scikits.cuda >= 0.5.0 and PyCUDA to run.
      To enable for just one Theano function:

      .. code-block:: python

          mode = theano.compile.get_default_mode()
          mode = mode.including('conv3d_fft', 'convgrad3d_fft', 'convtransp3d_fft')

          f = theano.function(..., mode=mode)

    - :func:`conv3d2d <theano.tensor.nnet.conv3d2d.conv3d>`
      Another conv3d implementation that uses the conv2d with data reshaping.
      It is faster in some cases than conv3d, specifically on the GPU.
    - `Faster conv2d <http://deeplearning.net/software/pylearn2/library/alex.html>`_

      This is in Pylearn2, not very documented and uses a different
      memory layout for the input. It is important to have the input
      in the native memory layout, and not use dimshuffle on the
      inputs, otherwise you lose most of the speed up. So this is not
      a drop in replacement of conv2d.

      Normally those are called from the `linear transform
      <http://deeplearning.net/software/pylearn2/library/linear.html>`_
      implementation.

      Also, there is restrictions on which shape are supported.
    - :func:`GpuCorrMM <theano.sandbox.cuda.blas.GpuCorrMM>`
      This is a GPU-only version of a correlation that computes correlations
      as `caffe <https://github.com/BVLC/caffe/blob/master/src/caffe/layers/conv_layer.cu>`_.
      For each element in a batch, it first creates a 
      `Toeplitz <http://en.wikipedia.org/wiki/Toeplitz_matrix>`_ matrix in a cuda kernel.
      Then, it performs a ``gemm`` call to multiply this Toeplitz matrix and the kernel.
      It need extra memory equal to the size of the Toeplitz matrix. Precisely, 
      the dimensions of this 2D Toeplitz matrix is equal to
      ``(no of channels * filter width * filter height, output width * output height)``.
      You can enable it for call to conv2d 2d by setting ``THEANO_FLAGS=optimizer_including=conv_gemm``
      in your environment. This is not enabled by default because it
      uses some extra memory. MM mean matrix multiply.

.. autofunction:: theano.tensor.nnet.conv.conv2d
.. autofunction:: theano.tensor.nnet.Conv3D.conv3D
.. autofunction:: theano.tensor.nnet.conv3d2d.conv3d
.. autofunction:: theano.sandbox.cuda.fftconv.conv2d_fft
