def conc(name, prev, offset=(1, 0, 0), conn=True): layer = tikz.concatenate(name='{}'.format(name), to='{}'.format(prev), offset='{}'.format(offset)) if conn: tikz.short_connection('{}'.format(prev), '{}'.format(name)) return layer
def res(num, name, bottom, top, start_no=0, z_label='', n_filter=64, offset=(0, 0, 0), size=(32, 32, 3.5), opacity=0.5): layers = [] layer_names = [*['{}_{}'.format(name, i) for i in range(num - 1)], top] for name in layers: layer = [ tikz.conv(name='{}'.format(name), offset=offset, to='{}-east'.format(bottom), z_label=z_label, n_filter=str(n_filter), width=size[2], height=size[0], depth=size[1]), tikz.short_connection('{}'.format(bottom), '{}'.format(name)) ] bottom = name layers += layer layers += [ tikz.skip(of=layer_names[1], to=layer_names[-2], pos=1.25), ] return layers
def mult(name, prev, offset=(1, 0, 0), conn=True): layer = tikz.multiply(name='{}'.format(name), to='{}'.format(prev), offset='{}'.format(offset)) if conn: layer += tikz.short_connection('{}'.format(prev), '{}'.format(name)) return layer
def upsample(name, prev='', z_label='', n_filter=64, offset=(1, 0, 0), size=(32, 32), width=0, opacity=0.5, caption='', conn=True, anchor='-east', anchor_of='-west'): """ Generate upsampling layer Arguments: name {str} -- layer name Keyword Arguments: prev {string} -- name of previous layer z_label {str} -- label along the z axis of the layer (default: '') n_filter {int} -- number of filters (default: {64}) offset {str} -- offset between layers (default: {(1,0,0)}) size {tuple} -- size (default: {(32,32)}) width {int} -- width of layers in graph (default: {0}) opacity {float} -- opacity (default: {0.5}) caption {str} -- layer caption (default: {''}) opacity {float} -- opacity (default: {0.5}) conn {bool} -- draw short connection from prev layer (default: {False}) anchor {str} -- position of anchor (default: {'-east'}) Returns: layer {list} -- list of graph elements """ # if names are equal with incrementing numbers, assume name if not prev: prev_s = name.split('_') prev = '{}_{}'.format(prev_s[0], str(int(prev_s[1]) - 1)) if not width: width = log(n_filter, 4) if not isinstance(size, tuple): size = (size, size) layer = tikz.upsample( name='{}'.format(name), z_label=z_label, n_filter=(n_filter), offset=offset, caption=caption, to='{}{}'.format(prev, anchor), width=width, size_1=size, size_2=(2 * size[0], 2 * size[1]), ) if conn: layer += tikz.short_connection(of=prev, to='{}_0'.format(name), anchor_of=anchor_of) return layer
def conv_pool(name, prev='', z_label='', n_filter=64, offset=(1, 0, 0), size=(32, 32), width=0, caption='', conn=True, opacity=0.5, anchor='-east'): """ Generate a convolution layer together with relu activation and pooling Arguments: name {str} -- layer name Keyword Arguments: prev {str} -- name of previous layer (default: {''}) z_label {str} -- label along the z axis of the layer (default: '') n_filter {int} -- number of filters (default: {64}) offset {tuple} -- offset to previous layer (default: {(1,0,0)}) size {tuple} -- size (default: {(32,32)}) width {str} -- width of layers in graph (default: {'0'}) caption {str} -- layer caption (default: {''}) conn {bool} -- draw short connection from prev layer (default: {False}) anchor {str} -- position of anchor (default: {'-east'}) Returns: layer {list} -- list of graph elements """ if not isinstance(size, tuple): size = (size, size) layer = tikz.conv_relu( name='{}'.format(name), z_label=z_label, n_filter=(n_filter), offset=offset, caption=caption, to='{}{}'.format(prev, anchor), width=width, size=size, ) layer += tikz.pool(name='{}'.format(name), offset=(0, 0, 0), to='{}-east'.format(name), width=1, height=size[0] - int(size[0] / 4), depth=size[1] - int(size[0] / 4), opacity=opacity) if conn: layer += tikz.short_connection('{}'.format(prev), '{}'.format(name)) return layer
def block_unconv(name, bottom, top, z_label='', n_filter=64, offset=(1, 0, 0), size=(32, 32, 3.5), opacity=0.5): layers = tikz.unpool(name='unpool_{}'.format(name), offset=offset, to='({}-east)'.format(bottom), width=1, height=size[0], depth=size[1], opacity=opacity) layers += tikz.conv_res(name='ccr_res_{}'.format(name), offset='(0,0,0)', to='(unpool_{}-east)'.format(name), z_label=z_label, n_filter=str(n_filter), width=size[2], height=size[0], depth=size[1], opacity=opacity) layers += tikz.conv(name='ccr_{}'.format(name), offset='(0,0,0)', to='(ccr_res_{}-east)'.format(name), z_label=z_label, n_filter=str(n_filter), width=size[2], height=size[0], depth=size[1]) layers += tikz.conv_res(name='ccr_res_c_{}'.format(name), offset='(0,0,0)', to='(ccr_{}-east)'.format(name), z_label=z_label, n_filter=str(n_filter), width=size[2], height=size[0], depth=size[1], opacity=opacity) layers += tikz.conv(name='{}'.format(top), offset='(0,0,0)', to='(ccr_res_c_{}-east)'.format(name), z_label=z_label, n_filter=str(n_filter), width=size[2], height=size[0], depth=size[1]) layers += tikz.short_connection('{}'.format(bottom), 'unpool_{}'.format(name)) return layers
def conv(name, prev='', z_label='', n_filter=64, offset=(1, 0, 0), size=(32, 32), width=0, caption=' ', conn=True, anchor='-east'): """ Generate a convolution layer Arguments: name {str} -- layer name Keyword Arguments: prev {str} -- name of previous layer (default: {''}) z_label {str} -- label along the z axis of the layer (default: '') n_filter {int} -- number of filters (default: {64}) offset {tuple} -- offset to previous layer (default: {(1,0,0)}) size {tuple} -- size (default: {(32,32)}) width {str} -- width of layers in graph (default: {'0'}) caption {str} -- layer caption (default: {''}) conn {bool} -- draw short connection from prev layer (default: {False}) anchor {str} -- position of anchor (default: {'-east'}) Returns: layer {list} -- list of graph elements """ if not isinstance(size, tuple): size = (size, size) if not prev: # assuming that layer names are given in a uniform way with incrementing numbers prev_s = name.split('_') prev = '{}_{}'.format(prev_s[0], str(int(prev_s[1]) - 1)) if not width: width = log(n_filter, 4) layer = tikz.conv( name='{}'.format(name), z_label=z_label, n_filter=(n_filter), offset=offset, caption=caption, to='{}{}'.format(prev, anchor), width=width, size=size, ) if conn: layer += tikz.short_connection('{}'.format(prev), '{}'.format(name)) return layer
def shortcut(name, prev, offset=(1, 0, 0), size=[40, 40], anchor='-east', caption='', z_label='', conn=True): layer = tikz.shortcut(name='{}'.format(name), z_label=z_label, to='{}{}'.format(prev, anchor), offset='{}'.format(offset), caption=caption, size=size) if conn: layer += tikz.short_connection(of=prev, to=name) return layer
def yolo(name, prev='', z_label='', n_filter=64, offset='(-1,0,4)', size=[32, 32], width=1, scale=32, caption=' ', conn=True, anchor='-east', image=False, path='\\input_image', grid=False, steps=1): if not prev: # if names are equal with incrementing numbers, assume name prev_s = name.split('_') prev = '{}_{}'.format(prev_s[0], str(int(prev_s[1]) - 1)) if not width: width = log(n_filter, 4) layer = tikz.detect(name='{}'.format(name), z_label=z_label, n_filter=(n_filter), offset=offset, caption=caption, to='{}{}'.format(prev, anchor), width=width, size=size) if image: layer += tikz.image('image_{}'.format(name), path, to=(name + anchor), size=[(size[0] / 5), (size[1] / 5)]) if grid: layer += tikz.grid('grid_{}'.format(name), 'image_{}'.format(name), size=[(size[0] / 5), (size[1] / 5)], steps=steps) if conn: layer += tikz.short_connection('{}'.format(prev), '{}'.format(name), anchor_of='-near', anchor_to='-far') return layer
def create_architecture(): input = 40 arch = [] arch += tikz.start() arch += tikz.image(name='image_0', file='\\input_image', to=('-4,0,0'), size=(10, 10)) arch += blocks.conv_relu(name='conv_0', prev='0,0,0', s_filter='I', size=(input, input), caption='0', n_filter=32, anchor='') arch += tikz.short_connection(of='image_0', to='conv_0', anchor_of='', anchor_to='-west') arch += [ *blocks.multi_conv_relu(num=3, name='conv', prev='conv_0', layer_num=1, name_start=1, n_filter=[64, 32, 64], s_filter='I/2', offset='(3,0,0)', size=(input / 2, input / 2), conn=True) ] arch += tikz.resample('conv_0', 'conv_1') # shortcut1 arch += [ *blocks.shortcut(name='short_4', prev='conv_3', offset='(1.75,0,0)', size=(input / 2, input / 2), caption='4'), tikz.short_connection(of='conv_3', to='short_4'), tikz.long_connection('conv_1', 'short_4', pos=1.3, anchor_to='-northwest') ] arch += blocks.multi_conv_relu(num=3, name='conv', prev='short_4', layer_num=5, name_start=5, n_filter=[128, 64, 128], size=(input / 4, input / 4), conn=True, offset='(1.5,0,0)') # downsample arch += tikz.resample(of='short_4', to='conv_5') arch += [ *blocks.shortcut(name='short_8', prev='conv_7', size=(input / 4, input / 4), caption='8', s_filter='I/4'), tikz.long_connection('conv_5', 'short_8', pos=1.5), tikz.short_connection(of='conv_7', to='short_8') ] arch += [ *blocks.shortcut(name='short_11', prev='short_8', size=(input / 8, input / 8), caption='11', s_filter='I/8') ] arch += tikz.ellipsis(of='short_8', to='short_11') arch += [ *blocks.shortcut(name='short_36', prev='short_11', size=(input / 16, input / 16), caption='36') ] arch += tikz.ellipsis(of='short_11', to='short_36') arch += [ *blocks.shortcut(name='short_61', prev='short_36', size=(input / 32, input / 32), caption='61') ] arch += tikz.ellipsis(of='short_36', to='short_61') # first yolo layer arch += [ *blocks.conv_relu(name='conv_79', prev='short_61', n_filter=(512), size=(input / 32, input / 32), caption='79') ] arch += tikz.ellipsis(of='short_61', to='conv_79') arch += [ *blocks.multi_conv_relu_z(num=3, name='conv', prev='conv_79', layer_num=80, name_start=80, n_filter=[512, 1024, 256], s_filter='I/32', size=(input / 32, input / 32), conn=True, offset=3) ] arch += [ *blocks.yolo(name='yolo_83', prev='conv_82', n_filter=(256), size=(input / 32, input / 32), caption='83', offset='(-0.75, 0, 3)', image=True, conn=True, grid=True) ] # resample arch += [ *blocks.conv_relu(name='conv_85', prev='conv_79', n_filter=(256), size=(input / 32, input / 32), caption='85', conn=True) ] arch += [ *blocks.upsample(name='conv_86', prev='conv_85', s_filter='I/16', n_filter=(256), size=(input / 32, input / 32), caption='86', conn=True) ] arch += [*blocks.conc(name='conc_87', prev='conv_86', offset='(1.25,0,0)')] arch += tikz.long_connection(of='short_61', to='conc_87', pos=3) # second yolo layer arch += [ *blocks.conv_relu(name='conv_90', prev='conc_87', n_filter=(512), size=(input / 16, input / 16), caption='90') ] arch += tikz.ellipsis(of='conc_87', to='conv_90') arch += [ *blocks.multi_conv_relu_z(num=3, name='conv', prev='conv_90', layer_num=91, name_start=91, n_filter=[256, 512, 256], s_filter='I/16', size=(input / 16, input / 16), conn=True, offset=3) ] arch += [ *blocks.yolo(name='yolo_94', prev='conv_93', n_filter=(256), size=(input / 16, input / 16), caption='94', offset='(-0.75, 0, 3)', image=True, conn=True, grid=True) ] # resample arch += [ *blocks.conv_relu(name='conv_96', prev='conv_90', n_filter=(128), size=(input / 16, input / 16), caption='96', conn=True) ] arch += [ *blocks.upsample(name='conv_97', prev='conv_96', s_filter='I/8', n_filter=(128), size=(input / 16, input / 16), caption='97', conn=True) ] arch += [*blocks.conc(name='conc_98', prev='conv_97', offset=(1.25, 0, 0))] arch += tikz.long_connection(of='short_36', to='conc_98', pos=3.25) # third yolo layer arch += [ *blocks.conv_relu(name='conv_102', prev='conc_98', n_filter=(512), size=(input / 8, input / 8), caption='103') ] arch += tikz.ellipsis(of='conc_98', to='conv_102') arch += [ *blocks.multi_conv_relu_z(num=3, name='conv', prev='conv_102', layer_num=103, name_start=103, n_filter=[128, 256, 256], s_filter='I/8', size=(input / 8, input / 8), conn=True, offset=4) ] arch += [ *blocks.yolo(name='yolo_106', prev='conv_105', n_filter=(256), size=(input / 8, input / 8), caption='106', offset='(-1, 0, 4)', image=True, conn=True, grid=True) ] # resample arch += [ *blocks.conv_relu(name='conv_108', prev='conv_102', n_filter=(128), size=(input / 8, input / 8), caption='108', conn=True) ] arch += [ *blocks.upsample(name='conv_109', prev='conv_108', s_filter='I/4', n_filter=(128), size=(input / 8, input / 8), caption='109', conn=True) ] arch += [ *blocks.conc(name='conc_110', prev='conv_109', offset=(1.25, 0, 0)) ] arch += tikz.long_connection(of='short_11', to='conc_110', pos=3) # forth yolo layer arch += [ *blocks.conv_relu(name='conv_114', prev='conc_110', n_filter=(512), size=(input / 4, input / 4), caption='114') ] arch += tikz.ellipsis(of='conc_110', to='conv_114') arch += [ *blocks.multi_conv_relu_z(num=3, name='conv', prev='conv_114', layer_num=115, name_start=115, n_filter=[64, 128, 256], s_filter='I/4', size=(input / 4, input / 4), conn=True, offset=6) ] arch += [ *blocks.yolo(name='yolo_4', prev='conv_117', n_filter=(256), size=(input / 4, input / 4), caption='118', offset='(-0.75, 0, 6)', image=True, conn=True, grid=True, steps=13) ] # resample arch += [ *blocks.conv_relu(name='conv_120', prev='conv_114', n_filter=(128), size=(input / 4, input / 4), caption='120', conn=True) ] arch += [ *blocks.upsample(name='conv_121', prev='conv_120', s_filter='I/2', n_filter=(128), size=(input / 4, input / 4), caption='121', conn=True) ] arch += [ *blocks.conc(name='conc_122', prev='conv_121', offset=(1.5, 0, 0)) ] arch += tikz.long_connection(of='short_4', to='conc_122', pos=1.5, anchor_of_1='-southeast', anchor_of_2='-northeast') # fith yolo layer arch += [ *blocks.conv_relu(name='conv_126', prev='conc_122', n_filter=(128), size=(input / 2, input / 2), caption='126', offset='(2,0,0)') ] arch += tikz.ellipsis(of='conc_122', to='conv_126') arch += [ *blocks.multi_conv_relu_z(num=3, name='conv', prev='conv_126', layer_num=127, name_start=127, n_filter=[32, 64, 256], s_filter='I/2', size=(input / 2, input / 2), conn=True, offset=8) ] arch += [ *blocks.yolo(name='yolo_130', prev='conv_129', n_filter=(256), size=(input / 2, input / 2), caption='130', offset='(-0.5, 0, 8)', image=True, conn=True, grid=True, steps=20) ] arch += tikz.legend() arch += tikz.env_end() return arch
def multi_conv_relu_z(num, name, prev, layer_num=0, z_label='', n_filter='', name_start=0, offset=(1, 0, 0), width='0', size=(32, 32), opacity=0.5, conn=True, anchor='-east'): """Generate multiple convolution layers with relu activation along the z axis Arguments: num {int} -- number of layers name {string} -- block name prev {string} -- name of previous layer Keyword Arguments: layer_num {int} -- layer number in the network (default: {0}) z_label {str} -- label along the z axis of the layer (default: '') n_filter {int} -- number of filters (default: {64}) name_start {int} -- number of the first layer, succeeding layers get incrementing numbers (default: {0}) offset {str} -- offset between layers (default: {(1,0,0)}) width {str} -- width of layers in graph (default: {'0'}) size {tuple} -- [description] (default: {(32,32)}) opacity {float} -- [description] (default: {0.5}) conn {bool} -- [description] (default: {False}) anchor {str} -- [description] (default: {'-east'}) Returns: layers {list} -- list of graph elements """ layers = [] j = 0 layer_names = [ *[ '{}_{}'.format(name, i) for i in range(name_start, num + name_start) ] ] if not isinstance(n_filter, list): n_filter = [n_filter] * num if isinstance(offset, int): offset_str = '({},{},{})'.format(-(4 / offset), 0, offset) else: offset_str = offset if not isinstance(size, tuple): size = (size, size) # first layer layer = [ tikz.conv_relu(name='{}'.format(layer_names[0]), offset=offset_str, to='{}{}'.format(prev, anchor), size=size, width=log(n_filter[j], 4)) ] j += 1 layers = layer if conn: layers += tikz.short_connection(of=prev, to=layer_names[0], anchor_of='-near', anchor_to='-far') prev = layer_names[0] # middle layers for l_name in layer_names[1:-1]: layer = [ tikz.conv_relu(name='{}'.format(l_name), offset=offset_str, to='{}{}'.format(prev, anchor), size=size, width=log(n_filter[j], 4)) ] layers += layer j += 1 if conn: layers += tikz.short_connection(of=prev, to=l_name, anchor_of='-near', anchor_to='-far') prev = l_name # last layer layer = [ tikz.conv_relu(name='{}'.format(layer_names[-1]), caption=str(layer_num + j), offset=offset_str, to='{}{}'.format(prev, anchor), z_label=z_label, n_filter=n_filter[j], size=size, width=log(n_filter[j], 4)) ] layers += layer if conn: layers += tikz.short_connection(of=prev, to=layer_names[-1], anchor_of='-near', anchor_to='-far') return layers
def bottleneck(num, name, prev, layer_num=0, z_label='', n_filter=64, name_start=0, offset=(1, 0, 0), width=0, size=(32, 32), opacity=0.5, conn=True, anchor='-east', ellipsis=False, pos=1.5): """Generate multiple convolution layers with relu activation Arguments: num {int} -- number of layers name {string} -- block name prev {string} -- name of previous layer Keyword Arguments: layer_num {int} -- layer number in the network (default: {0}) z_label {str} -- label along the z axis of the layer (default: '') n_filter {int} -- number of filters (default: {64}) name_start {int} -- number of the first layer, succeeding layers get incrementing numbers (default: {0}) offset {tuple} -- offset between layers (default: {(1,0,0)}) width {int} -- width of layers in graph (default: {0}) size {tuple} -- size (default: {(32,32)}) opacity {float} -- opacity (default: {0.5}) conn {bool} -- draw short connection from prev layer (default: {True}) anchor {str} -- position of anchor (default: {'-east'}) ellipsis {bool} -- draw an ellipsis before the first layer (default: {False}) pos {int} -- position of the long connection (default: {1.5}) Returns: layers {list} -- list of graph elements """ layers = [] j = 0 prev_layer = prev layer_names = [ *[ '{}_{}'.format(name, i) for i in range(name_start, num + name_start) ] ] if not isinstance(n_filter, list): n_filter = [n_filter] * num if not isinstance(size, tuple): size = (size, size) # first layer layer = [ tikz.conv_relu(name='{}'.format(layer_names[0]), caption=str(layer_num + j), offset=offset, to='{}{}'.format(prev, anchor), n_filter=n_filter[j], size=size, width=log(n_filter[j], 4)) ] j += 1 layers = layer if conn: layers += tikz.short_connection(prev, layer_names[0], name='({}_connection)'.format(name), options='pos=0.55') if ellipsis: layers += tikz.ellipsis(prev, layer_names[0]) layers += r''' \coordinate [shift={(-0.25,0,0)}] (''' + name + '''_connection) at (''' + layer_names[ 0] + '''-west); ''' prev = layer_names[0] # middle layers for l_name in layer_names[1:-1]: layer = [ tikz.conv_relu(name='{}'.format(l_name), caption=str(layer_num + j), offset='(0,0,0)', to='{}{}'.format(prev, anchor), n_filter=n_filter[j], size=size, width=log(n_filter[j], 4)) ] prev = l_name layers += layer j += 1 # last layer layer = [ tikz.conv_relu(name='{}'.format(layer_names[-1]), caption=str(layer_num + j), offset='(0,0,0)', to='{}{}'.format(prev, anchor), z_label=z_label, n_filter=n_filter[j], size=size, width=log(n_filter[j], 4)) ] layers += layer prev = layer_names[-1] # layers += tikz.relu( # name='{}_relu'.format(layer_names[-1]), # to='{}{}'.format(prev, anchor), # offset=(1, 0, 0), # size=size) # layers += tikz.short_connection('{}'.format(layer_names[-1]), '{}_relu'.format(layer_names[-1])) layers += tikz.long_connection_reversed('{}'.format(layer_names[-1]), '{}_connection'.format(name), pos=pos, anchor_to='') return layers
def multi_conv_relu(num, name, prev, layer_num=0, z_label='', n_filter=64, name_start=0, offset=(1, 0, 0), width=0, size=(32, 32), opacity=0.5, conn=True, anchor='-east'): """Generate multiple convolution layers with relu activation Arguments: num {int} -- number of layers name {string} -- block name prev {string} -- name of previous layer Keyword Arguments: layer_num {int} -- layer number in the network for the caption (default: {0}) z_label {str} -- label along the z axis of the layer (default: '') n_filter {int} -- number of filters (default: {64}) name_start {int} -- number of the first layer, succeeding layers get incrementing numbers (default: {0}) offset {tuple} -- offset between layers (default: {(1,0,0)}) width {int} -- width of layers in graph (default: {0}) size {tuple} -- size (default: {(32,32)}) opacity {float} -- opacity (default: {0.5}) conn {bool} -- draw short connection from prev layer (default: {False}) anchor {str} -- position of anchor (default: {'-east'}) Returns: layers {list} -- list of graph elements """ layers = [] j = 0 layer_names = [ *[ '{}_{}'.format(name, i) for i in range(name_start, num + name_start) ] ] if not isinstance(n_filter, list): n_filter = [n_filter] * num if not isinstance(size, tuple): size = (size, size) # first layer layer = [ tikz.conv_relu(name='{}'.format(layer_names[0]), caption=str(layer_num + j) if layer_num else '', offset=offset, to='{}{}'.format(prev, anchor), n_filter=n_filter[j], size=size, width=log(n_filter[j], 4)) ] j += 1 layers = layer if conn: layers += tikz.short_connection(prev, layer_names[0]) prev = layer_names[0] # middle layers for l_name in layer_names[1:-1]: layer = [ tikz.conv_relu(name='{}'.format(l_name), caption=str(layer_num + j) if layer_num else '', offset='(0,0,0)', to='{}{}'.format(prev, anchor), n_filter=n_filter[j], size=size, width=log(n_filter[j], 4)) ] prev = l_name layers += layer j += 1 # last layer layer = [ tikz.conv_relu(name='{}'.format(layer_names[-1]), caption=str(layer_num + j) if layer_num else '', offset='(0,0,0)', to='{}{}'.format(prev, anchor), z_label=z_label, n_filter=n_filter[j], size=size, width=log(n_filter[j], 4)) ] layers += layer return layers
def conv_relu(name, prev='', z_label='', n_filter=64, offset=(1, 0, 0), size=(32, 32), width=0, caption='', conn=True, anchor='-east', anchor_to='-west', rtl=False): """Generate convolution layer with relu activation Arguments: name {string} -- layer name Keyword Arguments: prev {str} -- name of previous layer (default: {''}) z_label {str} -- label along the z axis of the layer (default: '') n_filter {int} -- number of filters (default: {64}) offset {tuple} -- offset to previous layer (default: {(1,0,0)}) size {int|tuple} -- [description] (default: {(32,32)}) width {str} -- width of layers in graph (default: {'0'}) caption {str} -- layer caption (default: {''}) conn {bool} -- draw short connection from prev layer (default: {False}) anchor {str} -- position of anchor (default: {'-east'}) Returns: layer {list} -- list of graph elements """ # if names are equal with incrementing numbers, assume name if not prev: prev_s = name.split('_') prev = '{}_{}'.format(prev_s[0], str(int(prev_s[1]) - 1)) if not width: width = log(n_filter, 4) if not isinstance(size, tuple): size = (size, size) if rtl: layer = tikz.rtl_conv_relu(name='{}'.format(name), z_label=z_label, n_filter=(n_filter), offset=offset, caption=caption, to='{}{}'.format(prev, anchor), width=width, size=size) else: layer = tikz.conv_relu(name='{}'.format(name), z_label=z_label, n_filter=(n_filter), offset=offset, caption=caption, to='{}{}'.format(prev, anchor), width=width, size=size) if conn: layer += tikz.short_connection('{}'.format(prev), '{}'.format(name), anchor_of=anchor, anchor_to=anchor_to) return layer
def multi_conv(num, name, prev, layer_num=0, z_label='', n_filter=64, scale=32, name_start=0, offset=(1, 0, 0), width='0', size=(32, 32), opacity=0.5, conn=True, anchor='-east'): """ Generate a block of multiple convolution layers Arguments: num {[type]} -- [description] name {[type]} -- [description] prev {[type]} -- [description] Keyword Arguments: layer_num {int} -- [description] (default: {0}) z_label {str} -- [description] (default: {256}) n_filter {int} -- [description] (default: {64}) scale {int} -- [description] (default: {32}) name_start {int} -- [description] (default: {0}) offset {tuple} -- [description] (default: {(1, 0, 0)}) width {str} -- [description] (default: {'0'}) size {tuple} -- [description] (default: {(32, 32)}) opacity {float} -- [description] (default: {0.5}) conn {bool} -- [description] (default: {False}) anchor {str} -- [description] (default: {'-east'}) Returns: [type] -- [description] """ layers = [] j = 0 layer_names = [ *[ '{}_{}'.format(name, i) for i in range(name_start, num + name_start) ] ] if not isinstance(n_filter, list): n_filter = [n_filter] * num if not isinstance(size, tuple): size = (size, size) # first layer layer = [ tikz.conv(name='{}'.format(layer_names[0]), caption=str(layer_num + j), offset=offset, to='{}{}'.format(prev, anchor), n_filter=n_filter[j], size=size, width=log(n_filter[j], 4)) ] j += 1 layers = layer if conn: layers += tikz.short_connection(prev, layer_names[0]) prev = layer_names[0] # middle layers for l_name in layer_names[1:-1]: layer = [ tikz.conv(name='{}'.format(l_name), caption=str(layer_num + j), offset='(0,0,0)', to='{}{}'.format(prev, anchor), n_filter=n_filter[j], size=size, width=log(n_filter[j], 4)) ] prev = l_name layers += layer j += 1 # last layer layer = [ tikz.conv(name='{}'.format(layer_names[-1]), caption=str(layer_num + j), offset='(0,0,0)', to='{}{}'.format(prev, anchor), z_label=z_label, n_filter=n_filter[j], size=size, width=log(n_filter[j], 4)) ] layers += layer return layers
def create_architecture(): input = 40 base_width = 64 arch = [] arch += tikz.start() arch += tikz.image(name='image_0', file='\\input_image', to=('-3,0,0'), size=(10, 10)) arch += blocks.conv_relu(name='conv_0_0', prev='0,0,0', z_label='I', size=(input, input), n_filter=64, anchor='', conn=False) arch += tikz.short_connection(of='image_0', to='conv_0_0', anchor_of='', fill='') arch += blocks.conv_relu(name='conv_0_1', prev='conv_0_0', z_label='I/2', size=(input / 2, input / 2), n_filter=64, offset=(2, 0, 0), conn=False) arch += tikz.short_connection(of='conv_0_0', to='conv_0_1', fill='') arch += tikz.resample('conv_0_0', 'conv_0_1') arch += blocks.conv_relu(name='conv_1_0', prev='conv_0_1', z_label='I/4', size=(input / 4, input / 4), n_filter=64, offset=(1, 0, 0), conn=False) arch += tikz.short_connection(of='conv_0_1', to='conv_1_0', fill='') arch += tikz.resample('conv_0_1', 'conv_1_0') arch += tikz.pool(name='pool_0', width=2, to='conv_1_0', size=(input / 4, input / 4), offset=(1, 0, 0)) arch += tikz.short_connection(of='conv_1_0', to='pool_0', fill='') # arch += blocks.multi_conv_relu(num=3, name='conv_1', prev='conv_1_0', name_start=1, # n_filter=[64, 64, 256], size=(input / 4, input / 4), # offset=(1.5, 0, 0)) # arch += blocks.tikz.long_connection('conv_1_0', 'conv_1_3', pos=1.5, anchor_to='-northeast') arch += blocks.bottleneck(3, 'bottleneck_1', prev='pool_0', size=(input / 4, input / 4), n_filter=[64, 64, 256], offset=(1.5, 0, 0), layer_num=5) arch += blocks.bottleneck(3, 'bottleneck_2', prev='bottleneck_1_2', size=(input / 4, input / 4), n_filter=[64, 64, 256], offset=(1.5, 0, 0), layer_num=8) arch += blocks.bottleneck(3, 'bottleneck_3', prev='bottleneck_2_2', size=(input / 4, input / 4), n_filter=[64, 64, 256], offset=(1.5, 0, 0), layer_num=11) arch += blocks.bottleneck(3, 'bottleneck_4', prev='bottleneck_3_2', size=(input / 8, input / 8), n_filter=[128, 128, 512], offset=(3, 0, 0), layer_num=14) arch += blocks.bottleneck(3, 'bottleneck_7', prev='bottleneck_4_2', size=(input / 8, input / 8), n_filter=[128, 128, 512], offset=(1.5, 0, 0), conn=False, ellipsis=True, layer_num=24) arch += blocks.bottleneck(3, 'bottleneck_8', prev='bottleneck_7_2', size=(input / 16, input / 16), n_filter=[256, 256, 1024], offset=(1.5, 0, 0), pos=2, layer_num=27) arch += blocks.bottleneck(3, 'bottleneck_13', prev='bottleneck_8_2', size=(input / 16, input / 16), n_filter=[256, 256, 1024], offset=(1.5, 0, 0), pos=2, conn=False, ellipsis=True, layer_num=43) arch += blocks.bottleneck(3, 'bottleneck_14', prev='bottleneck_13_2', size=(input / 32, input / 32), n_filter=[512, 512, 2048], offset=(1.5, 0, 0), pos=3, layer_num=46) arch += blocks.bottleneck(3, 'bottleneck_16', prev='bottleneck_14_2', size=(input / 32, input / 32), layer_num=53, n_filter=[512, 512, 2048], offset=(1.5, 0, 0), pos=3, conn=False, ellipsis=True) arch += tikz.coordinate('resnet_last_dummy', of='bottleneck_16_2-east', offset=(3, 0, 0)) arch += tikz.coordinate('resnet_connection_dummy', of='resnet_last_dummy', offset=(0, 0, 6)) arch += tikz.short_connection(of='bottleneck_16_2', to='resnet_last_dummy', anchor_to='') arch += tikz.short_connection(to='resnet_connection_dummy', of='resnet_last_dummy', anchor_to='', anchor_of='') arch += tikz.pool(name='pool_1', width=2, to='bottleneck_16_2', size=(input / 4, input / 4), offset=(0, -5, 0), anchor='-center', caption='$1 \\times 1$') arch += blocks.conv_relu(name='conv_pool_1', prev='pool_1', offset=(-2.5, 0, 0), size=(input / 32, input / 32), n_filter=512, anchor='-west', conn=False, rtl=True) arch += tikz.short_connection(of='pool_1', to='conv_pool_1', anchor_of='-west', anchor_to='-east', options='pos=0.75') arch += tikz.pool(name='pool_2', width=2, to='pool_1', size=(input / 4, input / 4), offset=(0, 0, 6), anchor='-center', caption='$2 \\times 2$') arch += tikz.grid(name='grid_2', at='pool_2', steps=2) arch += blocks.conv_relu(name='conv_pool_2', prev='pool_2', offset=(-2.5, 0, 0), size=(input / 32, input / 32), n_filter=512, anchor='-west', conn=False, rtl=True) arch += tikz.short_connection(of='pool_2', to='conv_pool_2', anchor_of='-west', anchor_to='-east', options='pos=0.75') arch += tikz.pool(name='pool_3', width=2, to='pool_2', size=(input / 4, input / 4), offset=(0, 0, 6), anchor='-center', caption='$4 \\times 4$') arch += tikz.grid(name='grid_3', at='pool_3', steps=4) arch += blocks.conv_relu(name='conv_pool_3', prev='pool_3', offset=(-2.5, 0, 0), size=(input / 32, input / 32), n_filter=512, anchor='-west', conn=False, rtl=True) arch += tikz.short_connection(of='pool_3', to='conv_pool_3', anchor_of='-west', anchor_to='-east', options='pos=0.75') arch += tikz.pool(name='pool_4', width=2, to='pool_3', size=(input / 4, input / 4), offset=(0, 0, 6), anchor='-center', caption='$8 \\times 8$') arch += tikz.grid(name='grid_4', at='pool_4', steps=8) arch += blocks.conv_relu(name='conv_pool_4', prev='pool_4', offset=(-2.5, 0, 0), size=(input / 32, input / 32), n_filter=512, anchor='-west', conn=False, rtl=True) arch += tikz.short_connection(of='pool_4', to='conv_pool_4', anchor_of='-west', anchor_to='-east', options='pos=0.75') arch += blocks.conc(name='conc_1', prev='pool_2', offset=(-5, 0, 2.5), conn=False) arch += tikz.coordinate('dummy_pool_1', 'pool_1-east', (5, 0, 0)) arch += tikz.coordinate('dummy_pool_2', 'pool_2-east', (5, 0, 0)) arch += tikz.coordinate('dummy_pool_3', 'pool_3-east', (5, 0, 0)) arch += tikz.coordinate('dummy_pool_4', 'pool_4-east', (5, 0, 0)) arch += tikz.short_connection('dummy_pool_1', 'pool_1', anchor_of='', anchor_to='-east') arch += tikz.double_connection('dummy_pool_1', 'dummy_pool_2', 'pool_2', anchor_of='', anchor_to='-east') arch += tikz.double_connection('dummy_pool_2', 'dummy_pool_3', 'pool_3', anchor_of='', anchor_to='-east') arch += tikz.double_connection('dummy_pool_3', 'dummy_pool_4', 'pool_4', anchor_of='', anchor_to='-east') arch += tikz.z_connection(of='resnet_last_dummy', to='dummy_pool_1', anchor_to='', shift=(6, 0, 0), anchor_of='') # arch += tikz.z_connection(of='conv_5_0_1', to='pool_2', anchor_of='-anchor', anchor_to='-east', shift=(-1, -1.5, 2)) # arch += tikz.short_connection(of='conv_5_0_1', to='pool_3', anchor_of='-west', anchor_to='-south') # arch += tikz.z_connection(of='conv_5_0_1', to='pool_4', anchor_of='-west', anchor_to='-north', shift=(0, 0, 0)) arch += tikz.z_connection('conv_pool_1', 'conc_1', anchor_of='-west', anchor_to='-northeast', shift=(-2, 0, 0)) arch += tikz.z_connection('conv_pool_2', 'conc_1', anchor_of='-west', anchor_to='-east', shift=(0, 0, 0)) arch += tikz.z_connection('conv_pool_3', 'conc_1', anchor_of='-west', anchor_to='-southeast', shift=(-0, 0, 0)) arch += tikz.z_connection('conv_pool_4', 'conc_1', anchor_of='-west', anchor_to='-southwest', shift=(-2, 0, 0)) arch += tikz.z_connection('resnet_connection_dummy', 'conc_1', anchor_of='', anchor_to='-northwest', shift=(-4.5, 0, 0)) arch += blocks.conv_relu(name='conv_60', prev='conc_1', offset=(-2.5, 0, 0), size=(input / 32, input / 32), n_filter=512, anchor='-west', conn=False) arch += tikz.short_connection(of='conc_1', to='conv_60', anchor_of='-west', anchor_to='-east', options='pos=0.75') arch += blocks.conv_relu(name='conv_60', prev='conc_1', offset=(-2.5, 0, 0), size=(input / 32, input / 32), n_filter=512, anchor='-west', conn=False, rtl=True) arch += tikz.z_conv_relu(name='conv_61', to='bottleneck_14_connection', offset=(0, 0, 8), size=(input / 16, input / 16), n_filter=512) arch += tikz.short_connection('bottleneck_14_connection', 'conv_61', anchor_of='', anchor_to='-far') arch += blocks.sum( name='sum_1', prev='conv_60', offset=(-3, 2, 0), conn=False, ) arch += tikz.short_connection('conv_61', 'sum_1', anchor_of='-near', anchor_to='-northeast') arch += blocks.upsample(name='up_1', prev='sum_1', offset=(-2.5, 0, 0), size=(input / 16, input / 16), n_filter=512, anchor='-west', anchor_of='-west', conn=True) arch += blocks.conv_relu(name='conv_62', prev='conv_60', offset=(-5, 0, 9.4), size=(input / 16, input / 16), n_filter=512, anchor='-west', conn=False, rtl=True) arch += tikz.z_connection(of='conv_60', to='sum_1', anchor_of='-farwest', anchor_to='-east', shift=(-0.3, 0, -5)) arch += tikz.z_conv_relu(name='conv_63', to='bottleneck_8_connection', offset=(0, 0, 8), size=(input / 8, input / 8), n_filter=512) arch += tikz.short_connection('bottleneck_8_connection', 'conv_63', anchor_of='', anchor_to='-far') arch += blocks.sum(name='sum_2', prev='up_1', offset=(-3, 0, 0), conn=False) arch += tikz.short_connection('conv_63', 'sum_2', anchor_of='-near', anchor_to='-northeast') arch += tikz.short_connection('up_1', 'sum_2', anchor_of='-west', anchor_to='-east') arch += blocks.upsample(name='up_2', prev='sum_2', offset=(-2.5, 0, 0), size=(input / 8, input / 8), n_filter=512, anchor='-west', anchor_of='-west') arch += tikz.z_conv_relu(name='conv_64', to='up_1-south', offset=(-0.2, 0, 5), size=(input / 8, input / 8), n_filter=512) arch += tikz.short_connection(of='up_1', to='conv_64', anchor_of='-nearsouthwest', anchor_to='-far') arch += tikz.z_conv_relu(name='conv_65', to='bottleneck_4_connection', offset=(-0.25, 0, 10), size=(input / 4, input / 4), n_filter=512) arch += tikz.short_connection('bottleneck_4_connection', 'conv_65', anchor_of='', anchor_to='-far', options='pos=0.6') arch += blocks.sum(name='sum_3', prev='up_2', offset=(-3, 0, 0), conn=False) arch += tikz.short_connection('conv_65', 'sum_3', anchor_of='-near', anchor_to='-northeast') arch += tikz.short_connection('up_2', 'sum_3', anchor_of='-west', anchor_to='-east') arch += tikz.z_conv_relu(name='conv_66', to='up_2-nearsouthwest', offset=(-0.65, 0, 3), size=(input / 4, input / 4), n_filter=512) arch += tikz.short_connection(of='up_2', to='conv_66', anchor_of='-nearsouthwest', anchor_to='-far', fill='') arch += tikz.z_conv_relu(name='up_3', to='sum_3-southwest', offset=(-0.75, 0, 6), size=(input / 4, input / 4), n_filter=512) arch += tikz.short_connection(of='sum_3', to='up_3', anchor_of='-southwest', anchor_to='-far', fill='') arch += blocks.conc(name='conc_2', prev='conv_62', offset=(-11, 0.5, 0), conn=False) arch += tikz.z_connection(of='conv_60', to='conv_62', anchor_of='-nearwest', anchor_to='-east', shift=(-1, -2, 4)) arch += tikz.z_connection(of='conv_64', to='conc_2', anchor_of='-near', anchor_to='-east', shift=(-1, -1.45, 2.75)) arch += tikz.short_connection(of='conv_62', to='conc_2', anchor_of='-east', anchor_to='-south') arch += tikz.z_connection(of='conv_66', to='conc_2', anchor_of='-near', anchor_to='-northeast', shift=(0, 0, 0)) arch += tikz.z_connection(of='up_3', to='conc_2', anchor_of='-near', anchor_to='-west', shift=(0, 0, 6)) arch += blocks.conv_relu(name='conv_67', prev='conc_2', n_filter=512, size=(input / 4, input / 4), rtl=True, offset=(-4, 0, 8), conn=False) arch += tikz.z_connection(of='conc_2', to='conv_67', anchor_of='-southwest', anchor_to='-east', shift=(0, 0, 7.1)) arch += blocks.conv_relu(name='conv_68', prev='conv_67', n_filter='27', width=2, size=(input / 4, input / 4), rtl=True, offset=(-3.5, 0, 0), anchor='-west', anchor_to='-east') arch += tikz.soft_max('soft_max', offset=(-2, 0, 0), to='conv_68', size=(input / 4, input / 4), n_filter=1, anchor_to='-west') arch += tikz.short_connection('conv_68', 'soft_max', anchor_of='-west', anchor_to='-east') arch += tikz.results_upsampling() arch += tikz.spatial_mask() arch += tikz.legend() # arch += tikz.resample('image_1', 'image_2') # arch += tikz.short_connection(of='conv_61', to='sum_1', anchor_of='-east', # anchor_to='-west') # arch += tikz.resample('image_1', 'image_2') # Close environment arch += tikz.env_end() return arch