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.]]]]
"""

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM