# Path: dlearn/models/block.py
# class Block(object):
# 
#     """Construct a base class to represent an input-output black box.
# 
#     Attributes
#     ----------
#     parameters : list of theano.tensor
#         The block parameters. *Read-only*.
#     input : theano.tensor or list of theano.tensor
#         The input symbol(s) of the block. *Read-only*.
#     output : theano.tensor or list of theano.tensor
#         The output symbol(s) of the block. *Read-only*.
#     dropout_input : None, theano.tensor, or list of theano.tensor
#         None if no dropout input symbol is specified, and the `input` will be
#         used as `dropout_input`. *Read-only*.
#     dropout_output : None, theano.tensor, or list of theano.tensor
#         None if no dropout for this layer, and the `output` will be used as
#         `dropout_output`. *Read-only*.
# 
#     Parameters
#     ----------
#     input : theano.tensor or list of theano.tensor
#         The input symbol(s) of the block.
#     dropout_input : None, theano.tensor, or list of theano.tensor, optional
#         None if no dropout input symbol is specified, and the `input` will be
#         used as `dropout_input`. Default is None.
# 
#     """
# 
#     def __init__(self, input, dropout_input=None):
#         super(Block, self).__init__()
# 
#         self._params = []
#         self._input = input
#         self._output = input
# 
#         if dropout_input is None:
#             self._dropout_input = self._input
#         else:
#             self._dropout_input = dropout_input
# 
#         self._dropout_output = self._dropout_input
# 
#     @property
#     def parameters(self):
#         return self._params
# 
#     @property
#     def input(self):
#         return self._input
# 
#     @property
#     def output(self):
#         return self._output
# 
#     @property
#     def dropout_input(self):
#         return self._dropout_input
# 
#     @property
#     def dropout_output(self):
#         return self._dropout_output
# 
# Path: dlearn/utils/actfuncs.py
# def identity(x):
# def relu(x):
# 
# Path: dlearn/utils/math.py
# def create_shared(x):
# def create_empty(p):
# def dropout(x, ratio):


import numpy as np
import theano
import theano.tensor as T
from theano.tensor.signal.downsample import max_pool_2d
    from theano.sandbox.cuda.basic_ops import gpu_contiguous
    from pylearn2.sandbox.cuda_convnet.filter_acts import FilterActs
from .block import Block
from ..utils import actfuncs
from ..utils.math import nprng, dropout
            n_rows = self._input_shape[-2]
            n_cols = self._input_shape[-1]

        self._output_shape = (
            self._filter_shape[0],
            n_rows // self._pool_shape[0],
            n_cols // self._pool_shape[1]
        )
        if flatten:
            self._output_shape = np.prod(self._output_shape)

        satisfy_convnet = use_convnet and \
            self._filter_shape[0] % 16 == 0 and \
            self._filter_shape[2] == self._filter_shape[3] and \
            (self._input_shape[0] <= 4 or self._input_shape[0] % 4 == 0)

        if use_convnet and not satisfy_convnet:
            print "Break the convnet constraints. Fallback to theano conv."

        if not satisfy_convnet and self._border_mode == 'same':
            raise ValueError("Cannot use 'same' border mode when using theano conv")

        # Initialize parameters
        if W is None:
            fan_in = np.prod(self._filter_shape[1:])
            fan_out = self._filter_shape[0] * \
                np.prod(self._filter_shape[2:]) / np.prod(self._pool_shape)

            W_bound = np.sqrt(6.0 / (fan_in + fan_out))


# Path: dlearn/models/block.py
# class Block(object):
# 
#     """Construct a base class to represent an input-output black box.
# 
#     Attributes
#     ----------
#     parameters : list of theano.tensor
#         The block parameters. *Read-only*.
#     input : theano.tensor or list of theano.tensor
#         The input symbol(s) of the block. *Read-only*.
#     output : theano.tensor or list of theano.tensor
#         The output symbol(s) of the block. *Read-only*.
#     dropout_input : None, theano.tensor, or list of theano.tensor
#         None if no dropout input symbol is specified, and the `input` will be
#         used as `dropout_input`. *Read-only*.
#     dropout_output : None, theano.tensor, or list of theano.tensor
#         None if no dropout for this layer, and the `output` will be used as
#         `dropout_output`. *Read-only*.
# 
#     Parameters
#     ----------
#     input : theano.tensor or list of theano.tensor
#         The input symbol(s) of the block.
#     dropout_input : None, theano.tensor, or list of theano.tensor, optional
#         None if no dropout input symbol is specified, and the `input` will be
#         used as `dropout_input`. Default is None.
# 
#     """
# 
#     def __init__(self, input, dropout_input=None):
#         super(Block, self).__init__()
# 
#         self._params = []
#         self._input = input
#         self._output = input
# 
#         if dropout_input is None:
#             self._dropout_input = self._input
#         else:
#             self._dropout_input = dropout_input
# 
#         self._dropout_output = self._dropout_input
# 
#     @property
#     def parameters(self):
#         return self._params
# 
#     @property
#     def input(self):
#         return self._input
# 
#     @property
#     def output(self):
#         return self._output
# 
#     @property
#     def dropout_input(self):
#         return self._dropout_input
# 
#     @property
#     def dropout_output(self):
#         return self._dropout_output
# 
# Path: dlearn/utils/actfuncs.py
# def identity(x):
# def relu(x):
# 
# Path: dlearn/utils/math.py
# def create_shared(x):
# def create_empty(p):
# def dropout(x, ratio):


# Path: dlearn/models/layer.py
import numpy as np
import theano
import theano.tensor as T
from theano.tensor.signal.downsample import max_pool_2d
    from theano.sandbox.cuda.basic_ops import gpu_contiguous
    from pylearn2.sandbox.cuda_convnet.filter_acts import FilterActs
from .block import Block
from ..utils import actfuncs
from ..utils.math import nprng, dropout

            n_rows = self._input_shape[-2]
            n_cols = self._input_shape[-1]

        self._output_shape = (
            self._filter_shape[0],
            n_rows // self._pool_shape[0],
            n_cols // self._pool_shape[1]
        )
        if flatten:
            self._output_shape = np.prod(self._output_shape)

        satisfy_convnet = use_convnet and \
            self._filter_shape[0] % 16 == 0 and \
            self._filter_shape[2] == self._filter_shape[3] and \
            (self._input_shape[0] <= 4 or self._input_shape[0] % 4 == 0)

        if use_convnet and not satisfy_convnet:
            print "Break the convnet constraints. Fallback to theano conv."

        if not satisfy_convnet and self._border_mode == 'same':
            raise ValueError("Cannot use 'same' border mode when using theano conv")

        # Initialize parameters
        if W is None:
            fan_in = np.prod(self._filter_shape[1:])
            fan_out = self._filter_shape[0] * \
                np.prod(self._filter_shape[2:]) / np.prod(self._pool_shape)

            W_bound = np.sqrt(6.0 / (fan_in + fan_out))


            if active_func == actfuncs.sigmoid: