zoukankan      html  css  js  c++  java
  • Theano 学习四 pool_2d

    池化操作计算如下图所示[图片转自网络]。

         

    Theano的简单使用如下。

    在较早的版本中,可能会使用from theano.tensor.signal.downsample import max_pool_2d。根据运行提示,更新到 from theano.tensor.signal.pool import pool_2d 中了。

    import numpy as np
    import theano
    from theano.tensor.signal.pool import pool_2d
    import theano.tensor as T
    #from theano.tensor.signal.downsample import  max_pool_2d
    
    inputs = T.tensor4(name='input', dtype='float64')
    a = np.array(np.random.randint(1,100,50))
    a = np.reshape(a,(1,2,5,5))
    #pool_out = pool_2d (input=inputs, ds=(3,3), ignore_border=True, padding=(1,1),mode='max')
    pool_out = pool_2d (input=inputs, ds=(2,2),mode='max')   #warning
    f = theano.function([inputs], pool_out)
    y= f(a)
    
    print a
    print y

    函数用给定的因子从输入矩阵(N维)中采样,接受的参数包括:

    • input (N-D theano tensor of input images) – Input images. Max pooling will be done over the 2 last dimensions.
    • ds (tuple of length 2) – Factor by which to downscale (vertical ds, horizontal ds). (2,2) will halve the image in each dimension.
    • ignore_border (bool (default Nonewill print a warning and set to False)) – When True, (5,5) input with ds=(2,2) will generate a (2,2) output. (3,3) otherwise.
    • st (tuple of two ints) – Stride size, which is the number of shifts over rows/cols to get the next pool region. If st is None, it is considered equal to ds (no overlap on pooling regions).
    • padding (tuple of two ints) – (pad_h, pad_w), pad zeros to extend beyond four borders of the images, pad_h is the size of the top and bottom margins, and pad_w is the size of the left and right margins.
    • mode ({'max''sum''average_inc_pad''average_exc_pad'}) – Operation executed on each window. max and sum always exclude the padding in the computation. average gives you the choice to include or exclude it.

    默认 ignore_border=False,如果从5*5 数据中采样大小为2*2,结果将是3*3,最后一行/列从2*1 / 1*2数据中采样。

    只有在 ignore_border=True时,才能使用padding,效果为在输入中(从input [0][0]处) 增加 pad_h, pad_w的数据。

    下面out_shape和theano_pool是从theano源码中复制出来的,稍作修改以能单独运行。

    simple_pool为实现的一个简单版本。

    import numpy as np
    import theano
    from theano.tensor.signal.pool import pool_2d
    import theano.tensor as T
    #from theano.tensor.signal.downsample import  max_pool_2d
    
    
    inputs = T.tensor4(name='input', dtype='float64')
    a = np.array(np.random.randint(1,100,50))
    a = np.reshape(a,(1,2,5,5))
    #pool_out = pool_2d (input=inputs, ds=(3,3), ignore_border=True, padding=(1,1),mode='max')
    pool_out = pool_2d (input=inputs, ds=(2,2),mode='max')   #warning
    f = theano.function([inputs], pool_out)
    y= f(a)
    
    print a
    """
    [[[[37 45 87 87 83]
       [57 72 71 86 51]
       [93 90  3 40 94]
       [67 37 42 68 45]
       [82 13 95 13 28]]
    
      [[85 12 67 23 27]
       [39 72 77 29 77]
       [37 28 82 43 74]
       [16 40  8 19 45]
       [40 57  2 82 57]]]]
    """
    print y
    """
    [[[[ 72.  87.  83.]
       [ 93.  68.  94.]
       [ 82.  95.  28.]]
    
      [[ 85.  77.  77.]
       [ 40.  82.  74.]
       [ 57.  82.  57.]]]]
    """
    
    
    def theano_pool(x, ds,ignore_border,mode):
        # mode : {'max', 'sum', 'average_inc_pad', 'average_exc_pad'}
        if len(x.shape) != 4:
            raise NotImplementedError(
                'Pool requires 4D input for now')
        z_shape = out_shape(x.shape, ds, ignore_border)
        zz = np.empty(z_shape, dtype=x.dtype)
        # number of pooling output rows
        pr = zz.shape[-2]
        # number of pooling output cols
        pc = zz.shape[-1]
        ds0, ds1 = ds
        st0, st1 = ds
        pad_h ,pad_w = 0,0
        img_rows = x.shape[-2] + 2 * pad_h
        img_cols = x.shape[-1] + 2 * pad_w
        inc_pad = mode == 'average_inc_pad'
    
        # pad the image
        y = np.zeros(
                (x.shape[0], x.shape[1], img_rows, img_cols),
                dtype=x.dtype)
        y[:, :, pad_h:(img_rows - pad_h), pad_w:(img_cols - pad_w)] = x
        func = np.max
        if mode == 'sum':
            func = np.sum
        elif mode != 'max':
            func = np.average
    
        for n in xrange(x.shape[0]):
            for k in xrange(x.shape[1]):
                for r in xrange(pr):
                    row_st = r * st0
                    row_end = min(row_st + ds0, img_rows)
                    if not inc_pad:
                        row_st = max(row_st, pad_h)
                        row_end = min(row_end, x.shape[-2] + pad_h)
                    for c in xrange(pc):
                        col_st = c * st1
                        col_end = min(col_st + ds1, img_cols)
                        if not inc_pad:
                            col_st = max(col_st, pad_w)
                            col_end = min(col_end,
                                                   x.shape[-1] + pad_w)
                        zz[n, k, r, c] = func(y[n, k, row_st:row_end, col_st:col_end])
        return zz
                        
    def out_shape(imgshape, ds, ignore_border=False, st=None, padding=(0, 0)):
            """Return the shape of the output from this op, for input of given
            shape and flags.
    
            Parameters
            ----------
            imgshape : tuple of integers or scalar Theano variables
                the shape of a tensor of images. The last two elements are
                interpreted as the number of rows, and the number of cols.
            ds : tuple of two ints
                downsample factor over rows and columns this parameter
                indicates the size of the pooling region
            st : tuple of two ints
                the stride size. This is the distance between the pooling
                regions. If it's set to None, in which case it equlas ds.
            ignore_border : bool
                if ds doesn't divide imgshape, do we include an extra
                row/col of partial downsampling (False) or ignore it
                (True).
            padding : tuple of two ints
                (pad_h, pad_w), pad zeros to extend beyond four borders of
                the images, pad_h is the size of the top and bottom
                margins, and pad_w is the size of the left and right
                margins.
    
            Returns
            -------
            list :
                the shape of the output from this op, for input of given
                shape.  This will have the same length as imgshape, but
                with last two elements reduced as per the downsampling &
                ignore_border flags.
    
            """
            if len(imgshape) < 2:
                raise TypeError('imgshape must have at least two elements '
                                '(rows, cols)')
    
            if st is None:
                st = ds
            r, c = imgshape[-2:]
            r += padding[0] * 2
            c += padding[1] * 2
    
            if ignore_border:
                out_r = (r - ds[0]) // st[0] + 1
                out_c = (c - ds[1]) // st[1] + 1
                if isinstance(r, theano.Variable):
                    nr = max(out_r, 0)
                else:
                    nr = np.maximum(out_r, 0)
                if isinstance(c, theano.Variable):
                    nc = max(out_c, 0)
                else:
                    nc = np.maximum(out_c, 0)
            else:
                if isinstance(r, theano.Variable):
                    nr = T.switch(T.ge(st[0], ds[0]),
                                       (r - 1) // st[0] + 1,
                                       max(0, (r - 1 - ds[0]) //
                                                      st[0] + 1) + 1)
                elif st[0] >= ds[0]:
                    nr = (r - 1) // st[0] + 1
                else:
                    nr = max(0, (r - 1 - ds[0]) // st[0] + 1) + 1
    
                if isinstance(c, theano.Variable):
                    nc = T.switch(T.ge(st[1], ds[1]),
                                       (c - 1) // st[1] + 1,
                                       max(0, (c - 1 - ds[1]) //
                                                      st[1] + 1) + 1)
                elif st[1] >= ds[1]:
                    nc = (c - 1) // st[1] + 1
                else:
                    nc = max(0, (c - 1 - ds[1]) // st[1] + 1) + 1
    
            rval = list(imgshape[:-2]) + [nr, nc]
            return rval
    
    print out_shape((1,2,5,5), ds=(2,2))  # [1, 2, 3, 3]
    print theano_pool(a, ds=(2,2), ignore_border=False, mode='max')
    """
    [[[[72 87 83]
       [93 68 94]
       [82 95 28]]
    
      [[85 77 77]
       [40 82 74]
       [57 82 57]]]]
    """
    
    
    def simple_pool(input,ds=(2,2),mode='max'):
        fun=np.max
        if mode=='sum':
            fun=np.sum
        elif mode=='average':
            fun=np.average
    
        n,m,h,w=np.shape(input)
        d,s=ds
        zh=h/d+h%d
        zw=w/s+w%s
        z=np.zeros((n,m,zh,zw))
    
        for k in range(n):
            for o in range(m):
                for i in range(zh):
                    for j in range(zw):
                        z[k,o,i,j]=fun(input[k,o,d*i:min(d*i+d,h),s*j:min(s*j+s,w)])
    
        return z;
    print simple_pool(a)
    """
    [[[[ 72.  87.  83.]
       [ 93.  68.  94.]
       [ 82.  95.  28.]]
    
      [[ 85.  77.  77.]
       [ 40.  82.  74.]
       [ 57.  82.  57.]]]]
    """
  • 相关阅读:
    acm常见算法及例题
    检测数据库各实例session分布情况的sql
    检测数据库大小的sql
    检测数据库各实例session 阻塞 tree的sql
    Oracle 的自治事务 AUTONOMOUS TRANSACTION
    Oracle的 NULL 与 空字符串''
    数据泵 expdp 参数 consistent=y
    mysql 的列转行
    mysql 的行转列
    jboss 到oracle 数据库连接无效的问题
  • 原文地址:https://www.cnblogs.com/qw12/p/6231110.html
Copyright © 2011-2022 走看看