| # pylint: skip-file |
| import sys |
| sys.path.append('../../python/') |
| import mxnet as mx |
| import logging |
| |
| def ConvFactory(data, num_filter, kernel, stride=(1,1), pad=(0, 0), name=None, suffix=''): |
| conv = mx.symbol.Convolution(data=data, num_filter=num_filter, kernel=kernel, stride=stride, pad=pad, name='conv_%s%s' %(name, suffix)) |
| bn = mx.symbol.BatchNorm(data=conv, name='bn_%s%s' %(name, suffix)) |
| act = mx.symbol.Activation(data=bn, act_type='relu', name='relu_%s%s' %(name, suffix)) |
| return act |
| |
| def InceptionFactoryA(data, num_1x1, num_3x3red, num_3x3, num_d3x3red, num_d3x3, pool, proj, name): |
| # 1x1 |
| c1x1 = ConvFactory(data=data, num_filter=num_1x1, kernel=(1, 1), name=('%s_1x1' % name)) |
| # 3x3 reduce + 3x3 |
| c3x3r = ConvFactory(data=data, num_filter=num_3x3red, kernel=(1, 1), name=('%s_3x3' % name), suffix='_reduce') |
| c3x3 = ConvFactory(data=c3x3r, num_filter=num_3x3, kernel=(3, 3), pad=(1, 1), name=('%s_3x3' % name)) |
| # double 3x3 reduce + double 3x3 |
| cd3x3r = ConvFactory(data=data, num_filter=num_d3x3red, kernel=(1, 1), name=('%s_double_3x3' % name), suffix='_reduce') |
| cd3x3 = ConvFactory(data=cd3x3r, num_filter=num_d3x3, kernel=(3, 3), pad=(1, 1), name=('%s_double_3x3_0' % name)) |
| cd3x3 = ConvFactory(data=cd3x3, num_filter=num_d3x3, kernel=(3, 3), pad=(1, 1), name=('%s_double_3x3_1' % name)) |
| # pool + proj |
| pooling = mx.symbol.Pooling(data=data, kernel=(3, 3), stride=(1, 1), pad=(1, 1), pool_type=pool, name=('%s_pool_%s_pool' % (pool, name))) |
| cproj = ConvFactory(data=pooling, num_filter=proj, kernel=(1, 1), name=('%s_proj' % name)) |
| # concat |
| concat = mx.symbol.Concat(*[c1x1, c3x3, cd3x3, cproj], name='ch_concat_%s_chconcat' % name) |
| return concat |
| |
| def InceptionFactoryB(data, num_3x3red, num_3x3, num_d3x3red, num_d3x3, name): |
| # 3x3 reduce + 3x3 |
| c3x3r = ConvFactory(data=data, num_filter=num_3x3red, kernel=(1, 1), name=('%s_3x3' % name), suffix='_reduce') |
| c3x3 = ConvFactory(data=c3x3r, num_filter=num_3x3, kernel=(3, 3), pad=(1, 1), stride=(2, 2), name=('%s_3x3' % name)) |
| # double 3x3 reduce + double 3x3 |
| cd3x3r = ConvFactory(data=data, num_filter=num_d3x3red, kernel=(1, 1), name=('%s_double_3x3' % name), suffix='_reduce') |
| cd3x3 = ConvFactory(data=cd3x3r, num_filter=num_d3x3, kernel=(3, 3), pad=(1, 1), stride=(1, 1), name=('%s_double_3x3_0' % name)) |
| cd3x3 = ConvFactory(data=cd3x3, num_filter=num_d3x3, kernel=(3, 3), pad=(1, 1), stride=(2, 2), name=('%s_double_3x3_1' % name)) |
| # pool + proj |
| pooling = mx.symbol.Pooling(data=data, kernel=(3, 3), stride=(2, 2), pad=(1, 1), pool_type="max", name=('max_pool_%s_pool' % name)) |
| # concat |
| concat = mx.symbol.Concat(*[c3x3, cd3x3, pooling], name='ch_concat_%s_chconcat' % name) |
| return concat |
| |
| def inception(nhidden, grad_scale): |
| # data |
| data = mx.symbol.Variable(name="data") |
| # stage 1 |
| conv1 = ConvFactory(data=data, num_filter=64, kernel=(7, 7), stride=(2, 2), pad=(3, 3), name='conv1') |
| pool1 = mx.symbol.Pooling(data=conv1, kernel=(3, 3), stride=(2, 2), name='pool1', pool_type='max') |
| # stage 2 |
| conv2red = ConvFactory(data=pool1, num_filter=64, kernel=(1, 1), stride=(1, 1), name='conv2red') |
| conv2 = ConvFactory(data=conv2red, num_filter=192, kernel=(3, 3), stride=(1, 1), pad=(1, 1), name='conv2') |
| pool2 = mx.symbol.Pooling(data=conv2, kernel=(3, 3), stride=(2, 2), name='pool2', pool_type='max') |
| # stage 2 |
| in3a = InceptionFactoryA(pool2, 64, 64, 64, 64, 96, "avg", 32, '3a') |
| in3b = InceptionFactoryA(in3a, 64, 64, 96, 64, 96, "avg", 64, '3b') |
| in3c = InceptionFactoryB(in3b, 128, 160, 64, 96, '3c') |
| # stage 3 |
| in4a = InceptionFactoryA(in3c, 224, 64, 96, 96, 128, "avg", 128, '4a') |
| in4b = InceptionFactoryA(in4a, 192, 96, 128, 96, 128, "avg", 128, '4b') |
| in4c = InceptionFactoryA(in4b, 160, 128, 160, 128, 160, "avg", 128, '4c') |
| in4d = InceptionFactoryA(in4c, 96, 128, 192, 160, 192, "avg", 128, '4d') |
| in4e = InceptionFactoryB(in4d, 128, 192, 192, 256, '4e') |
| # stage 4 |
| in5a = InceptionFactoryA(in4e, 352, 192, 320, 160, 224, "avg", 128, '5a') |
| in5b = InceptionFactoryA(in5a, 352, 192, 320, 192, 224, "max", 128, '5b') |
| # global avg pooling |
| avg = mx.symbol.Pooling(data=in5b, kernel=(7, 7), stride=(1, 1), name="global_pool", pool_type='avg') |
| # linear classifier |
| flatten = mx.symbol.Flatten(data=avg, name='flatten') |
| fc1 = mx.symbol.FullyConnected(data=flatten, num_hidden=nhidden, name='fc1') |
| softmax = mx.symbol.SoftmaxOutput(data=fc1, name='softmax') |
| return softmax |
| |
| |
| |
| softmax = inception(1000, 1.0) |
| batch_size = 32 |
| softmax = inception(1000, 1.0) |
| |
| if len(sys.argv) == 2: |
| grad_req = sys.argv[1] |
| else: |
| grad_req = 'write' |
| |
| texec = softmax.simple_bind(ctx=mx.cpu(), |
| data=(batch_size, 3, 224, 224), |
| grad_req=grad_req) |
| # We extract the memory cost from the execution plan |
| print(texec.debug_str().split('\n')[-3]) |