def box_with_connectable(text,
                         box_size,
                         box_loc,
                         node_spacing,
                         hidden_layer_node_num,
                         box_colour='lime',
                         text_pos='right',
                         text_kwargs={}):
    # def box_with_connectable(text, box_size, box_loc, node_spacing, hidden_layer_node_num, box_colour='#55CC77'):
    # the box
    nb = NodeBrush('box', size=size)
    nb.size = box_size
    nb.color = box_colour
    nodes3 = viznet.node_sequence(nb, 1, box_loc, space=node_spacing)
    text_colour = box_colour
    if box_colour == 'lime':
        text_colour = 'green'
    if box_colour == 'grey':
        text_colour = 'black'
    nodes3[0].text(text, text_pos, fontsize=font_size_small, color=text_colour)
    # the connectable-invisible nodes
    nb = NodeBrush('invisible',
                   size=box_size[1])  # box_size[1] is the height of box
    # nb = NodeBrush([
    #         None,
    #         "rectangle",
    #         "none"
    #     ], size=box_size[1])  # box_size[1] is the height of box
    invis = viznet.node_sequence(nb,
                                 hidden_layer_node_num,
                                 box_loc,
                                 space=node_spacing)

    return nodes3, invis
def box_with_connectable(text,
                         box_size,
                         box_loc,
                         node_spacing,
                         hidden_layer_node_num,
                         box_colour='#55CC77'):
    # the box
    nb = NodeBrush('box', size=size)
    nb.size = box_size
    nb.color = box_colour
    nodes3 = viznet.node_sequence(nb, 1, box_loc, space=node_spacing)
    nodes3[0].text(text, 'right', fontsize=font_size_small)
    # the connectable-invisible nodes
    nb = NodeBrush('invisible',
                   size=box_size[1])  # box_size[1] is the height of box
    # nb = NodeBrush([
    #         None,
    #         "rectangle",
    #         "none"
    #     ], size=box_size[1])  # box_size[1] is the height of box
    invis = viznet.node_sequence(nb,
                                 hidden_layer_node_num,
                                 box_loc,
                                 space=node_spacing)

    return nodes3, invis
def draw_feed_forward(ax, num_node_list, size=2):
    '''
    draw a feed forward neural network.

    Args:
        num_node_list (list<int>): number of nodes in each layer.
    '''
    num_hidden_layer = len(num_node_list) - 2
    token_list = ['\sigma^z'] + \
        ['y^{(%s)}' % (i + 1) for i in range(num_hidden_layer)] + ['\psi']
    kind_list = ['nn.input'] + ['nn.hidden'] * num_hidden_layer + ['nn.output']
    radius_list = [0.3] + [0.2] * num_hidden_layer + [0.3]
    y_list = 1.5 * np.arange(len(num_node_list))

    text_list = ['$\phi$'] * 3

    seq_list = []
    for n, kind, radius, y, text in zip(num_node_list, kind_list, radius_list,
                                        y_list, text_list):
        b = NodeBrush(kind)
        _nodes = viznet.node_sequence(b, n, center=(0, y))
        for _n in _nodes:
            _n.text(text, 'center', fontsize=18)
        # print(_nodes)
        seq_list.append(_nodes)

    eb = EdgeBrush('<--')
    for st, et in zip(seq_list[:-1], seq_list[1:]):
        viznet.connecta2a(st, et, eb)

    # viznet.node_sequence(NodeBrush('box', ax, size=size), 1, (0,4))
    #
    node = NodeBrush('box', size=size)
    node.size = (0.5, 0.3)
    viznet.node_sequence(node, 1, (0, ))
Beispiel #4
0
    def draw(self, file=None, size=(10, 6)):
        """
        Draw the network architecture 
        Param:
            - file: The file where the image will be saved. Default: None
            - size: the image size. Default: (10,6)
        """

        with DynamicShow(size, filename=file) as d:

            num_hidden_layer = len(self.architecture) - 2
            token_list = ['\sigma^z'] + [
                'y^{(%s)}' % (i + 1) for i in range(num_hidden_layer)
            ] + ['\psi']
            kind_list = ['nn.input'
                         ] + ['nn.hidden'] * num_hidden_layer + ['nn.output']
            radius_list = [0.1] + [0.2] * num_hidden_layer + [0.3]
            x_list = 1.5 * np.arange(len(self.architecture)) + 1.5

            seq_list = []

            # Input pins
            inputPins = NodeBrush('qc.C', d.ax)
            seq_list.append(
                node_sequence(inputPins,
                              self.inputs,
                              center=(0, 0),
                              space=(0, 1)))

            # Network and connections
            for n, kind, radius, y in zip(self.architecture, kind_list,
                                          radius_list, x_list):
                b = NodeBrush(kind, d.ax)
                seq_list.append(
                    node_sequence(b, n, center=(y, 0), space=(0, 1)))

            for st, et in zip(seq_list[:-1], seq_list[1:]):
                connecta2a(st, et, EdgeBrush('-->', d.ax))

            # Output pins
            outputEdge = EdgeBrush('---', d.ax)
            outputPins = NodeBrush('qc.C', d.ax)
            seq_list.append(
                node_sequence(outputPins,
                              self.architecture[-1],
                              center=(x_list[-1] + 1.5, 0),
                              space=(0, 1)))
            connect121(seq_list[-2], seq_list[-1], outputEdge)
Beispiel #5
0
def draw_feed_forward(ax, num_node_list):
    '''
    draw a feed forward neural network.

    Args:
        num_node_list (list<int>): 每层节点数组成的列表
    '''
    num_hidden_layer = len(num_node_list) - 2  # 隐藏层数
    token_list = ['\sigma^z'] + \
        ['y^{(%s)}' % (i + 1) for i in range(num_hidden_layer)] + ['\psi']
    kind_list = ['nn.input'] + ['nn.hidden'] * num_hidden_layer + ['nn.output']
    radius_list = [0.3] + [0.2] * num_hidden_layer + [0.3]  # 半径大小
    y_list = -1.5 * np.arange(
        len(num_node_list))  # 每一层节点所在的位置的纵轴坐标,全取负值说明网络是自顶而下的

    seq_list = []
    for n, kind, radius, y in zip(num_node_list, kind_list, radius_list,
                                  y_list):
        b = NodeBrush(kind, ax)
        seq_list.append(node_sequence(b, n, center=(0, y)))
    print("!")
    eb = EdgeBrush('-->', ax)
    for st, et in zip(seq_list[:-1], seq_list[1:]):
        connecta2a(st, et, eb)
    #for i, layer_nodes in enumerate(seq_list):
    #[node.text('$z_%i^{(%i)}$'%(j, i), 'center', fontsize=16) for j, node in enumerate(layer_nodes)]
    return seq_list
def block_2(inputs,
            text1,
            output_text,
            hidden_layer_text="$h_{2M \\times Q}$",
            no_box=False,
            use_121=False,
            offset=0,
            x_offset=0,
            box_colour='grey'):
    hidden_layer_node_num = 3
    node_spacing = (1.2 * size, 0)

    # hidden layers 1
    nb = NodeBrush(['lime', 'circle', 'none'], size=size * .5)
    xys = custom_node_seq(hidden_layer_node_num,
                          (x_offset, offset + -1 * step),
                          space=node_spacing)
    __nb = NodeBrush('invisible', size=size * .5)
    _inner_block_1 = [
        nb >> xys[0],
        __nb >> xys[1],
        nb >> xys[2],
    ]
    _inner_block_1[0].text("$h_{1}$", 'center', fontsize=font_size_small)
    _inner_block_1[1].text("$\cdots$", 'center', fontsize=font_size_small)
    _inner_block_1[1].brush.style = "invisible"

    _inner_block_1[2].text(hidden_layer_text,
                           'center',
                           fontsize=font_size_small)
    if use_121:
        viznet.connect121(pin_bot(inputs), _inner_block_1, eb)
    else:
        viznet.connecta2a(pin_bot(inputs), pin_top(_inner_block_1), eb)

    if not no_box:
        # hidden layers 1 Act
        _inner_block_2, _inner_block_2_connectable = box_with_connectable(
            text=text1,
            node_spacing=node_spacing,
            hidden_layer_node_num=hidden_layer_node_num,
            box_loc=(x_offset, offset + -1.25 * step),
            box_size=(size * 1.8, size / 7.3),
            box_colour=box_colour)
        viznet.connect121(_inner_block_1, _inner_block_2_connectable, eb)

    # output
    nb = NodeBrush('nn.output', size=size * .5)
    output = viznet.node_sequence(nb,
                                  1, (x_offset, offset + -1.6 * step),
                                  space=node_spacing)
    output[0].text(output_text, 'center', fontsize=font_size)

    if not no_box:
        viznet.connecta2a(pin_bot(_inner_block_2_connectable), pin_top(output),
                          eb)
        return _inner_block_1, _inner_block_2, _inner_block_2_connectable, output
    else:
        viznet.connecta2a(pin_bot(_inner_block_1), pin_top(output), eb)
        return _inner_block_1, output
Beispiel #7
0
def draw_feed_forward(ax, num_node_list):
    '''
    draw a feed forward neural network.

    Args:
        num_node_list (list<int>): number of nodes in each layer.
    '''
    num_hidden_layer = len(num_node_list) - 2
    token_list = ['\sigma^z'] + \
        ['y^{(%s)}' % (i + 1) for i in range(num_hidden_layer)] + ['\psi']
    kind_list = ['nn.input'] + ['nn.hidden'] * num_hidden_layer + ['nn.output']
    radius_list = [0.3] + [0.2] * num_hidden_layer + [0.3]
    y_list = 1.5 * np.arange(len(num_node_list))

    seq_list = []
    for n, kind, radius, y in zip(num_node_list, kind_list, radius_list,
                                  y_list):
        b = NodeBrush(kind, ax)
        seq_list.append(node_sequence(b, n, center=(0, y)))

    eb = EdgeBrush('-->', ax)
    for st, et in zip(seq_list[:-1], seq_list[1:]):
        connecta2a(st, et, eb)
def block_1(inputs, text1, text2, use_121=False, offset=0, box_colour='grey'):
    # hidden layers 1
    nb = NodeBrush('nn.hidden', size=size * .5)
    _inner_block_1 = viznet.node_sequence(nb,
                                          hidden_layer_node_num,
                                          (0, offset + -1 * step),
                                          space=node_spacing)
    for i, n in enumerate(_inner_block_1):
        if i > len(_inner_block_1) // 2:
            i = 500 - (len(_inner_block_1) - i)
        _t = f"$h_{{{i+1}}}$"
        if i == len(_inner_block_1) // 2:
            _t = "$h_{...}$"
        n.text(_t, 'center', fontsize=font_size_small)
    if use_121:
        viznet.connect121(pin_bot(inputs), _inner_block_1, eb)
    else:
        viznet.connecta2a(pin_bot(inputs), pin_top(_inner_block_1), eb)

    # hidden layers 1 Act
    _inner_block_2, _inner_block_2_connectable = box_with_connectable(
        text=text1,
        box_loc=(0, offset + -1.4 * step),
        box_size=(size * 9, size / 2.8))
    viznet.connect121(_inner_block_1, _inner_block_2_connectable, eb)

    # hidden layers 1 BN
    _inner_block_3, _inner_block_3_connectable = box_with_connectable(
        text=text2,
        box_loc=(0, offset + -1.7 * step),
        box_size=(size * 9, size / 2.8),
        box_colour=box_colour)
    viznet.connect121(_inner_block_2_connectable, _inner_block_3_connectable,
                      eb)

    return _inner_block_1, _inner_block_2, _inner_block_2_connectable, _inner_block_3, _inner_block_3_connectable
    #         "rectangle",
    #         "none"
    #     ], size=box_size[1])  # box_size[1] is the height of box
    invis = viznet.node_sequence(nb,
                                 hidden_layer_node_num,
                                 box_loc,
                                 space=node_spacing)

    return nodes3, invis


eb = EdgeBrush('-->>', lw=size)

# input
nb = NodeBrush('nn.input', size=size)
nodes1 = viznet.node_sequence(nb, 1, (0, -0.2), space=node_spacing)
nodes1[0].text("$\phi$", 'center', fontsize=font_size)


def pin_top(iterable):
    return [_.pin("top") for _ in iterable]


def pin_bot(iterable):
    return [_.pin("bottom") for _ in iterable]


def block_1(inputs, text1, text2, use_121=False, offset=0, box_colour='grey'):
    # hidden layers 1
    nb = NodeBrush('nn.hidden', size=size * .5)
    _inner_block_1 = viznet.node_sequence(nb,
Beispiel #10
0
def draw_feed_forward(ax,
                      num_node_list,
                      node_labels=None,
                      weights=None,
                      biases=None):
    '''
    draw a feed forward neural network.

    Args:
        num_node_list (list<int>): number of nodes in each layer.
    '''
    num_hidden_layer = len(num_node_list) - 2
    token_list = ['\sigma^z'] + \
        ['y^{(%s)}' % (i + 1) for i in range(num_hidden_layer)] + ['\psi']
    kind_list = ['nn.input'] + ['nn.hidden'] * num_hidden_layer + ['nn.output']
    radius_list = [0.3] + [0.2] * num_hidden_layer + [0.3]
    y_list = 1.5 * np.arange(len(num_node_list))

    theme.NODE_THEME_DICT['nn.input'] = ["#E65933", "circle", "none"]
    theme.NODE_THEME_DICT['nn.hidden'] = ["#B9E1E2", "circle", "none"]
    theme.NODE_THEME_DICT['nn.output'] = ["#579584", "circle", "none"]

    seq_list = []
    for n, kind, radius, y in zip(num_node_list, kind_list, radius_list,
                                  y_list):
        b = NodeBrush(kind, ax)
        seq_list.append(node_sequence(b, n, center=(0, y)))

    # add labels
    if node_labels:
        for i, st in enumerate(seq_list):
            for j, node in enumerate(st):
                lab = node_labels[i][j]
                if isinstance(lab, float):
                    lab = f'{lab:.2f}'
                node.text(f'{lab}', fontsize=8)

    # add biases
    if biases:
        for i, st in enumerate(seq_list[1:]):
            for j, node in enumerate(st):
                x, y = node.pin(direction='right')
                lab = biases[i][j]
                if isinstance(lab, float):
                    lab = f'{lab:.2f}'
                ax.text(x + 0.05, y, lab, fontsize=6)

    eb = EdgeBrush('-->', ax, color='#58595b')
    layer = 0
    for st, et in zip(seq_list[:-1], seq_list[1:]):
        c = connecta2a(st, et, eb)
        if weights:
            w = weights[layer]
            if isinstance(w, np.ndarray):
                w = w.flatten()

            for k, cc in enumerate(c):
                factor = 1
                if k % 2:
                    factor = -1

                lab = w[k]
                if isinstance(lab, float):
                    lab = f'{lab:.2f}'

                cc.text(lab,
                        fontsize=6,
                        text_offset=0.075 * factor,
                        position='top')

        layer += 1
Beispiel #11
0
def draw_feed_forward(ax, num_node_list, node_labels=None, weights=None,biases=None, zero_index=False, 
                     weight_thickness=False):
    '''
    draw a feed forward neural network.

    Args:
        num_node_list (list<int>): number of nodes in each layer.
    '''
    num_hidden_layer = len(num_node_list) - 2
    token_list = ['\sigma^z'] + \
        ['y^{(%s)}' % (i + 1) for i in range(num_hidden_layer)] + ['\psi']
    kind_list = ['nn.input'] + ['nn.hidden'] * num_hidden_layer + ['nn.output']
    radius_list = [0.3] + [0.2] * num_hidden_layer + [0.3]
    y_list = 1.5 * np.arange(len(num_node_list))
    
    theme.NODE_THEME_DICT['nn.input'] = ["#E65933","circle","none"]
    theme.NODE_THEME_DICT['nn.hidden'] = ["#B9E1E2","circle","none"]
    theme.NODE_THEME_DICT['nn.output'] = ["#579584","circle","none"]
    
    shift = not zero_index

    # generate some default node labels
    if node_labels is None:
        node_labels = []
        for ℓ,nℓ in enumerate(num_node_list):
            if ℓ == 0:
                node_labels.append([f'$x_{j+shift}$' for j in range(nℓ)])
            else:
                node_labels.append([r'$a^{' + f'{ℓ}' + r'}_{' + f'{j+shift}' + r'}$' for j in range(nℓ)])
                
    # generate default bias labels
    if weights is None:
        weights = []
        for ℓ,nℓ in enumerate(num_node_list):
            if ℓ > 0:
                nℓm1 = num_node_list[ℓ-1]
                w_lab = np.zeros([nℓm1,nℓ],dtype='<U32')
                for k in range(nℓm1):
                    for j in range(nℓ):
                        w_lab[k,j] = r'$w^{' + f'{ℓ}' + r'}_{' + f'{k+shift}{j+shift}' + r'}$'
                weights.append(w_lab)
                    
    # generate some default weight labels
    if biases is None:
        biases = []
        for ℓ,nℓ in enumerate(num_node_list):
            if ℓ > 0:
                biases.append([r'$b^{' + f'{ℓ}' + r'}_{' + f'{j+shift}' + r'}$' for j in range(nℓ)])

    seq_list = []
    for n, kind, radius, y in zip(num_node_list, kind_list, radius_list, y_list):
        b = NodeBrush(kind, ax)
        seq_list.append(node_sequence(b, n, center=(0, y)))

    # add labels
    if node_labels:
        for i,st in enumerate(seq_list):
            for j,node in enumerate(st):
                lab = node_labels[i][j]
                if isinstance(lab, float):
                    lab = f'{lab:.2f}'
                node.text(f'{lab}',fontsize=8)

    # add biases
    if biases:
        for i,st in enumerate(seq_list[1:]):
            for j,node in enumerate(st):
                x,y = node.pin(direction='right')
                lab = biases[i][j]
                if isinstance(lab, np.floating) or isinstance(lab,float):
                    lab = f'{lab:.2f}'
                ax.text(x+0.05,y,lab,fontsize=6)
       
    eb = EdgeBrush('-->', ax,color='#58595b')
    ℓ = 0
    for st, et in zip(seq_list[:-1], seq_list[1:]):
        
        if not weight_thickness:
            c = connecta2a(st, et, eb)
            if weights:

                w = weights[ℓ]

                if isinstance(w,np.ndarray):
                    w = w.flatten()

                for k,cc in enumerate(c):

                    factor = 1

                    # get the input and output neuron indices
                    idx = np.unravel_index(k,weights[ℓ].shape)
                    if idx[0]%2:
                        factor = -1

                    lab = w[k]
                    if isinstance(lab, np.floating) or isinstance(lab,float):
                        lab = f'{lab:.2f}' 

                    wtext = cc.text(lab,fontsize=6,text_offset=0.08*factor, position='top')
                    wtext.set_path_effects([path_effects.withSimplePatchShadow(offset=(0.5, -0.5),shadow_rgbFace='white', alpha=1)])
        
        else:
            # this is to plot individual edges with a thickness dependent on their weight
            # useful for convolutional networks where many weights are "zero"
            for i,cst in enumerate(st):
                for j,cet in enumerate(et):
                    if weights:
                        w = weights[ℓ]
                        
                        if np.abs(w[i,j]) > 1E-2:
                            eb = EdgeBrush('-->', ax,color='#58595b', lw=np.abs(w[i,j]))
                            e12 = eb >> (cst, cet)
                        
                            factor = 1
                            if i%2:
                                factor = -1
                            wtext = e12.text(f'{w[i,j]:.2f}',fontsize=6,text_offset=0.08*factor, position='top')
                            wtext.set_path_effects([path_effects.withSimplePatchShadow(offset=(0.5, -0.5),shadow_rgbFace='white', alpha=1)])

        ℓ += 1