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 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, ))
def block_1(inputs, text1, text2, use_121=False, offset=0, box_colour='grey'): # hidden layers 1 nb = NodeBrush(['grey', 'circle', 'none'], size=size * .1) # _inner_block_1 = viznet.node_sequence(nb, hidden_layer_node_num, (0, offset + -1*step), space=node_spacing) xys = custom_node_seq(hidden_layer_node_num, (0, offset + -1 * step), space=node_spacing) _inner_block_1 = [] for i, xy in enumerate(xys): if i == len(xys) // 2: __nb = NodeBrush('invisible', size=size * .1) _inner_block_1.append(__nb >> xy) _inner_block_1[-1].text("$\cdots\cdots$", 'center', fontsize=font_size_small) else: _inner_block_1.append(nb >> xy) if i == len(xys) - 1: _inner_block_1[-1].text(f"$h_{1} \sim h_{{500}}$", 'right', 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, node_spacing=node_spacing, hidden_layer_node_num=hidden_layer_node_num, text_pos='left', box_loc=(0, offset + -1.04 * step), box_size=(size * 4.5, size * .05), # text_kwargs={'color' : 'red'} ) 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, node_spacing=node_spacing, hidden_layer_node_num=hidden_layer_node_num, box_loc=(0, offset + -1.06 * step), box_size=(size * 4.5, size * .05), 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
def block_1(inputs, text1, text2, use_121=False, offset=0, box_colour='grey'): # hidden layers 1 nb = NodeBrush(['lime', 'circle', 'none'], size=size * .5) # _inner_block_1 = viznet.node_sequence(nb, hidden_layer_node_num, (0, offset + -1*step), space=node_spacing) xys = custom_node_seq(hidden_layer_node_num, (0, offset + -1 * step), space=node_spacing) _inner_block_1 = [] for i, xy in enumerate(xys): if i == len(xys) // 2: __nb = NodeBrush('invisible', size=size * .5) _inner_block_1.append(__nb >> xy) _inner_block_1[-1].text("$\cdots$", 'center', fontsize=font_size_small) else: if i > len(xys) // 2: i = 500 - (len(xys) - i) _inner_block_1.append(nb >> xy) _inner_block_1[-1].text(f"$h_{{{i+1}}}$", '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, node_spacing=node_spacing, hidden_layer_node_num=hidden_layer_node_num, box_loc=(0, offset + -1.25 * step), box_size=(size * 6.6, size / 7.3), ) 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, node_spacing=node_spacing, hidden_layer_node_num=hidden_layer_node_num, box_loc=(0, offset + -1.38 * step), box_size=(size * 6.6, size / 7.3), 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
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)
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
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
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
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