如何使用theano在CNN中分离卷积层和池化层?

时间:2016-11-18 23:57:04

标签: deep-learning theano conv-neural-network

在我的项目中,我必须多次使用卷积层,最后才能使用池化层。我在

找到了代码

https://github.com/lisa-lab/DeepLearningTutorials/blob/master/code/convolutional_mlp.py

但是类LeNetConvPoolLayer将卷积层和池层组合在一起。当我尝试将这两个部分分成两个类ConvLayerPoolLayer时,在计算新构建的卷积层中的参数梯度以及汇集时会出现一个名为DisconnectedInputError的错误层。

这是我的代码。谢谢你的帮助!

class ConvLayer(object):
"""Conv Layer of a convolutional network without Pooling """

def __init__(self, rng, input, filter_shape, image_shape):
    """
    Allocate a LeNetConvPoolLayer with shared variable internal parameters.

    :type rng: numpy.random.RandomState
    :param rng: a random number generator used to initialize weights

    :type input: theano.tensor.dtensor4
    :param input: symbolic image tensor, of shape image_shape

    :type filter_shape: tuple or list of length 4
    :param filter_shape: (number of filters, num input feature maps,
                          filter height, filter width)

    :type image_shape: tuple or list of length 4
    :param image_shape: (batch size, num input feature maps,
                         image height, image width)

    :type poolsize: tuple or list of length 2
    :param poolsize: the downsampling (pooling) factor (#rows, #cols)
    """

    assert image_shape[1] == filter_shape[1]
    self.input = input

    # there are "num input feature maps * filter height * filter width"
    # inputs to each hidden unit
    fan_in = numpy.prod(filter_shape[1:])
    # each unit in the lower layer receives a gradient from:
    # "num output feature maps * filter height * filter width" /
    #   pooling size
    fan_out = (filter_shape[0] * numpy.prod(filter_shape[2:]))
    # initialize weights with random weights
    W_bound = numpy.sqrt(6. / (fan_in + fan_out))
    self.W = theano.shared(
        numpy.asarray(
            rng.uniform(low=-W_bound, high=W_bound, size=filter_shape),
            dtype=theano.config.floatX
        ),
        borrow=True
    )

    # the bias is a 1D tensor -- one bias per output feature map
    b_values = numpy.zeros((filter_shape[0],), dtype=theano.config.floatX)
    self.b = theano.shared(value=b_values, borrow=True)

    # convolve input feature maps with filters
    conv_out = conv2d(
        input=input,
        filters=self.W,
        filter_shape=filter_shape,
        input_shape=image_shape
    )
    '''
    # pool each feature map individually, using maxpooling
    pooled_out = pool.pool_2d(
        input=conv_out,
        ds=poolsize,
        ignore_border=True
    )
    '''

    self.output = conv_out

    # store parameters of this layer
    self.params = [self.W, self.b]

    # keep track of model input
    self.input = input


class PoolLayer(object):
"""Pool Layer after a convolutional network """

def __init__(self, rng, input, filter_shape=(3, 3), poolsize=(2, 2)):
    """
    Allocate a LeNetConvPoolLayer with shared variable internal parameters.

    :type rng: numpy.random.RandomState
    :param rng: a random number generator used to initialize weights

    :type input: theano.tensor.dtensor4
    :param input: symbolic image tensor, of shape image_shape

    :type filter_shape: tuple or list of length 4
    :param filter_shape: (number of filters, num input feature maps,
                          filter height, filter width)

    :type image_shape: tuple or list of length 4
    :param image_shape: (batch size, num input feature maps,
                         image height, image width)

    :type poolsize: tuple or list of length 2
    :param poolsize: the downsampling (pooling) factor (#rows, #cols)
    """

    self.input = input

    # there are "num input feature maps * filter height * filter width"
    # inputs to each hidden unit
    fan_in = numpy.prod(filter_shape[1:])
    # each unit in the lower layer receives a gradient from:
    # "num output feature maps * filter height * filter width" /
    #   pooling size
    fan_out = (filter_shape[0] * numpy.prod(filter_shape[2:]) //
               numpy.prod(poolsize))
    # initialize weights with random weights
    W_bound = numpy.sqrt(6. / (fan_in + fan_out))
    self.W = theano.shared(
        numpy.asarray(
            rng.uniform(low=-W_bound, high=W_bound, size=filter_shape),
            dtype=theano.config.floatX
        ),
        borrow=True
    )

    # the bias is a 1D tensor -- one bias per output feature map
    b_values = numpy.zeros((filter_shape[0],), dtype=theano.config.floatX)
    self.b = theano.shared(value=b_values, borrow=True)

    # pool each feature map individually, using maxpooling
    pooled_out = pool.pool_2d(
        input=input,
        ds=poolsize,
        ignore_border=True
    )

    # add the bias term. Since the bias is a vector (1D array), we first
    # reshape it to a tensor of shape (1, n_filters, 1, 1). Each bias will
    # thus be broadcasted across mini-batches and feature map
    # width & height
    self.output = T.nnet.relu(pooled_out)

    # store parameters of this layer
    self.params = [self.W, self.b]

    # keep track of model input
    self.input = input

1 个答案:

答案 0 :(得分:0)

这是我正在使用的类的一部分。您可以修改零件以适合您的模型

 class ConvLayer(object):
        """Pool Layer of a convolutional network """

        def __init__(self, rng, input, image_shape, filter_shape, subsample=(1,1), poolsize=(2, 2), border_mode = 'valid'):
            assert image_shape[1] == filter_shape[1]
            self.input = input

            fan_in = numpy.prod(filter_shape[1:])
            fan_out = filter_shape[0] * numpy.prod(filter_shape[2:])

            w_values, b_values = generate_weights(rng, filter_shape, fan_in, fan_out, 'relu', filter_shape[0])

            self.W = theano.shared(w_values, borrow=True )

            self.b = theano.shared(value=b_values, borrow=True)

            # convolve input feature maps with filters
            conv_out = conv2d(
                input=input,
                filters=self.W,
                input_shape=image_shape,
                filter_shape=filter_shape,
                subsample=subsample,
                border_mode=border_mode
            )
            self.rectified_conv_out = T.nnet.relu(conv_out + self.b.dimshuffle('x', 0, 'x', 'x'))
            self.output = self.rectified_conv_out


    class PoolLayer(object):
        """Pool Layer of a convolutional network """

        def __init__(self, input, poolsize=(2, 2), stride=None, ig_border = True, mode='max', same=False ):

            self.input = input

            if same:
                pooled_out = pool.max_pool_2d_same_size(
                    input=self.input,
                    patch_size=poolsize
                )
            else:
                # downsample each feature map individually
                pooled_out = pool.pool_2d(
                    input= self.input,
                    ws=poolsize,
                    ignore_border=ig_border,
                    stride= stride,
                    mode= mode
                )
            self.output = pooled_out