Source code for elektronn.net.pooling

# -*- coding: utf-8 -*-
# ELEKTRONN - Neural Network Toolkit
#
# Copyright (c) 2014 - now
# Max-Planck-Institute for Medical Research, Heidelberg, Germany
# Authors: Marius Killinger, Gregor Urban

import numpy as np
import theano
from theano import tensor as T


[docs]def maxabs(t1, t2): pos = T.where(t1 > t2, t1, t2) neg = T.where(-t1 > -t2, t1, t2) ret = T.where(pos >= -neg, pos, neg) return ret
[docs]def my_max_pool_3d(sym_input, pool_shape=(2, 2, 2)): """ this one is pure theano. Hence all gradient-related stuff is working! No dimshuffling""" s = None if pool_shape[2] > 1: for i in xrange(pool_shape[2]): t = sym_input[:, :, :, :, i::pool_shape[2]] if s is None: s = t else: s = T.maximum(s, t) else: s = sym_input if pool_shape[0] > 1: temp = s s = None for i in xrange(pool_shape[0]): t = temp[:, i::pool_shape[0], :, :, :] if s is None: s = t else: s = T.maximum(s, t) if pool_shape[1] > 1: temp = s s = None for i in xrange(pool_shape[1]): t = temp[:, :, :, i::pool_shape[1], :] if s is None: s = t else: s = T.maximum(s, t) sym_ret = s return sym_ret
[docs]def maxout(conv_out, factor=2, mode='max', axis=1): """ Pools axis 1 (the channels) of ``conv_out`` by ``factor``. I.e. the number of channels is decreased by this factor. The pooling can either be done as ``max`` or ``maxabs``. Spatial dimensions are unchanged """ assert factor > 1 if mode == 'max': compare = T.maximum elif mode == 'maxabs': compare = maxabs if axis == 1: ret = conv_out[:, 0::factor] for i in xrange(1, factor): t = conv_out[:, i::factor] ret = compare(ret, t) elif axis == 2: ret = conv_out[:, :, 0::factor] for i in xrange(1, factor): t = conv_out[:, :, i::factor] ret = compare(ret, t) return ret
[docs]def pooling2d(conv_out, pool_shape=(2, 2), mode='max'): """ Pools axis 2,3 (x,y) of ``conv_out`` by respective ``pool_shape``. I.e. the spatial extent is decreased by this factor. The pooling can either be done as ``max`` or ``maxabs``. """ if mode == 'max': compare = T.maximum elif mode == 'maxabs': compare = maxabs ret = conv_out if pool_shape[1] > 1: ret = conv_out[:, :, :, 0::pool_shape[1]] for i in xrange(1, pool_shape[1]): t = conv_out[:, :, :, i::pool_shape[1]] ret = compare(ret, t) if pool_shape[0] > 1: accum = ret[:, :, 0::pool_shape[0], :] for i in xrange(1, pool_shape[0]): t = ret[:, :, i::pool_shape[0], :, ] accum = compare(accum, t) ret = accum return ret
[docs]def pooling3d(conv_out, pool_shape=(2, 2, 2), mode='max'): """ Pools axis 2,3 (x,y) of ``conv_out`` by respective ``pool_shape``. I.e. the spatial extent is decreased by this factor. The pooling can either be done as ``max`` or ``maxabs``. """ if mode == 'max': compare = T.maximum elif mode == 'maxabs': compare = maxabs ret = conv_out #(1,4,1,4,4) if pool_shape[2] > 1: ret = conv_out[:, :, :, :, 0::pool_shape[2]] for i in xrange(1, pool_shape[2]): t = conv_out[:, :, :, :, i::pool_shape[2]] ret = compare(ret, t) if pool_shape[0] > 1: accum = ret[:, 0::pool_shape[0], :, :, :] for i in xrange(1, pool_shape[0]): t = ret[:, i::pool_shape[0], :, :, :] accum = compare(accum, t) ret = accum if pool_shape[1] > 1: accum = ret[:, :, :, 0::pool_shape[1], :] for i in xrange(1, pool_shape[1]): t = ret[:, :, :, i::pool_shape[1], :] accum = compare(accum, t) ret = accum return ret
if __name__ == "__main__": import sys, os sys.path.append(os.path.expanduser("~/devel/ELEKTRONN/")) from elektronn.training.trainutils import timeit sym_input = T.TensorType(dtype='float32', broadcastable=[False] * 5)() pool = (2, 2, 2) sym_ret = my_max_pool_3d(sym_input, pool) #my_max_pool_3d_stupid(sym_input) f_maxp_3d_ref = timeit(theano.function([sym_input], sym_ret), 4) sym_ret = pooling3d(sym_input, pool, 'max') #my_max_pool_3d_stupid(sym_input) f_maxp_3d = timeit(theano.function([sym_input], sym_ret), 4) sym_ret = pooling3d(sym_input, pool, 'maxabs') #my_max_pool_3d_stupid(sym_input) f_maxp_3d_new = timeit(theano.function([sym_input], sym_ret), 4) # sym_ret = maxabsPool3d(sym_input, pool)#my_max_pool_3d_stupid(sym_input) # f_maxabsp_3d= timeit(theano.function([sym_input],sym_ret), 4) for i in range(0, 10, 2): inp = np.random.rand(1, 16 + 32 * i, 1, 16 + 32 * i, 16 + 32 * i).astype('float32') - 0.5 print inp.shape a0 = f_maxp_3d_ref(inp) a1 = f_maxp_3d(inp) a2 = f_maxp_3d_new(inp) #a3 = f_maxabsp_3d(inp) assert np.all(np.equal(a1, a0)) #print a1.shape r1 = a1[0, :, 0] r2 = a2[0, :, 0] #r3 = a3[0,:,0] r0 = inp[0, :, 0] #d = r3 - r4