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_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 petersenijk(self, tp='pdf'): colored = False size = 'normal' node = NodeBrush('basic', size=size) edge = EdgeBrush('---', lw=2.) label_count = [0] def assign_label(): label_count[0] += 1 return "%c" % (96 + label_count[0]) with DynamicShow((4, 4), filename='_petersenijk.%s' % tp) as ds: x = [0, 1] y = [0, 2] ys = [] xs = [] for i in range(5): xi = node >> rotate(x, np.pi / 5 * 2 * i) yi = node >> rotate(y, np.pi / 5 * 2 * i) xi.text("%d" % (i + 1)) yi.text("%d" % (i + 6)) xs.append(xi) ys.append(yi) c = 'r' if (i == 0 and colored) else 'k' withcolor(c, edge, (xi, yi)).text(assign_label()) for i in range(5): c = 'g' if i == 0 else ('b' if i == 4 else 'k') if not colored: c = 'k' withcolor(c, edge, (xs[i], xs[(i + 2) % 5])).text(assign_label()) (edge >> (ys[i], ys[(i + 1) % 5])).text(assign_label())
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 framework(self): with viznet.DynamicShow(figsize=(6, 4), filename="framework.png") as dp: grid = viznet.Grid((3.0, 1.5), offset=(2, 2)) edge = EdgeBrush('->', lw=2., color='r') # define an mpo mpo = NodeBrush('box', color='cyan', roundness=0.2, size=(1.0, 0.4)) # generate two mpos Const = mpo >> grid[0:2, 0:1] Const.text('LuxurySparse') Intrinsics = mpo >> grid[3:5, 0:1] Intrinsics.text('Binary Op') Intrinsics = mpo >> grid[6:8, 0:1] Intrinsics.text('Cache Server') Register = mpo >> grid[3:5, 2:3] Register.text('Register') Block = mpo >> grid[0:8, 4:5] Block.text('Blocks (Operator Tree)') Extensions = mpo >> grid[4.5:8, 6:7] Extensions.text('Boost & Extensions') Interface = mpo >> grid[0:3.5, 6:7] Interface.text('Interface') Applications = mpo >> grid[0:8, 8:9] Applications.text('Applications')
def _petersen(self, colored, tp='pdf'): size = 'normal' node = NodeBrush('basic', size=size) edge = EdgeBrush('---', lw=2.) with DynamicShow( (4, 4), filename='%spetersen.%s' % ('c' if colored else '', tp)) as ds: x = [0, 1] y = [0, 2] ys = [] xs = [] for i in range(5): xi = node >> rotate(x, np.pi / 5 * 2 * i) yi = node >> rotate(y, np.pi / 5 * 2 * i) xi.text("%d" % (i + 6)) yi.text("%d" % (i + 1)) xs.append(xi) ys.append(yi) c = 'r' if (i == 0 and colored) else 'k' withcolor(c, edge, (xi, yi)) for i in range(5): c = 'g' if i == 0 else ('b' if i == 3 else 'k') if not colored: c = 'k' withcolor(c, edge, (xs[i], xs[(i + 2) % 5])) edge >> (ys[i], ys[(i + 1) % 5])
def visualize_network(network: AcyclicNetwork): num_layers = len(network.layer_info) nodes_per_layer = [ (network.layer_info[i + 1][0] - network.layer_info[i][0]) + 1 for i in range(num_layers - 1) ] nodes_per_layer = [network.layer_info[0][0]] + nodes_per_layer max_num_nodes = max(nodes_per_layer) vertical_gap_size = 1.0 / (num_layers + 1) radius = 5 with DynamicShow((10, 10), 'test.png') as d: brush = NodeBrush('nn.input', ax=d.ax) edge_brush = EdgeBrush('-', ax=d.ax, lw=2) nodes = [] for y in range(num_layers): for x in range(nodes_per_layer[y]): horizontal_gap = 1.0 / (nodes_per_layer[y] + 1) nodes.append(brush >> ( (x + 1) * horizontal_gap, vertical_gap_size * (y + 1))) conn_idx = 0 for layer in network.layer_info: _, end_connection_idx = layer for idx in range(con_idx, end_connection_idx): from_id, to_id, _ = network.connections[idx] edge_brush >> (nodes[from_id], nodes[to_id]) con_idx = end_connection_idx
def draw_prodnet2(ax, num_node_visible): '''CNN to achieve MSR''' handler = Layerwise() # brush conv = NodeBrush('nn.convolution', ax) input = NodeBrush('nn.input', ax) output = NodeBrush('nn.output', ax) op = NodeBrush('basic', ax, size='small') de = EdgeBrush('-->', ax) ude = EdgeBrush('---', ax) da = 0.6 db = 0.8 y = 0 # visible layers handler.node_sequence('\sigma', num_node_visible, input, offset=(0, y)) y += da # log handler.node_sequence('\log', num_node_visible, op, offset=(0, y)) y += db # hidden layers handler.node_sequence('h', num_node_visible, conv, (0, y)) y += da # exp handler.node_sequence('\exp', num_node_visible, op, offset=(0, y)) # psi plt.text(0, 2.7, r'$\ldots$', va='center', ha='center', fontsize=22) handler.node_sequence(r'\psi', 1, output, (0, 3.5)) # annotate nodes handler.text('\sigma') handler.text('h') handler.text(r'\psi', text_list=[r'$\psi$']) handler.text(r'\log', text_list=[r'$\log$'], position='left') handler.text(r'\exp', text_list=[r'$\exp$'], position='left') # connect them handler.connect121('\sigma', '\log', de) handler.connecta2a('\log', 'h', de) handler.connect121('h', '\exp', de)
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 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 test_draw_bm(): '''Draw a Boltzmann Machine''' num_node_visible = 6 with DynamicShow((5, 4), '_bm.png') as d: # define brushes node = NodeBrush('nn.backfed', d.ax, size='normal') edge = EdgeBrush('---', d.ax) node_list = add_circled_node_sequence(num_node_visible, node, radius=1.0, offset=(0, 0)) # connect all for i, nodei in enumerate(node_list): # add text nodei.text(r'$\sigma_%d$' % i) for nodej in node_list: if nodei is not nodej: edge >> (nodei, nodej)
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 contract(self, tp="gif"): steper = NodeBrush("basic") dbl = EdgeBrush('=', lw=2) with DynamicShow(figsize=(5, 4), filename="contract.%s" % tp) as ds: st = steper >> (3, 3) t = st.text("") xs = [0, 0, -1, 1, -2, 0, 2.0] ys = [3, 2, 1, 1, 0, 0, 0.0] locs = zip(xs, ys) nds = [nbrush >> loc for loc in locs] A, B, C, D, E, F, G = nds for obj, x in zip([A, B, C, D, E, F, G], ["A", "B", "C", "D", "E", "F", "G"]): obj.text(x) obj.edges = [] obj.label = x pairs = [(A, B), (B, C), (B, D), (C, E), (C, F), (D, F), (D, G), (E, F), (F, G)] _pairs = [(A, B), (B, C), (B, D), (C, E), (C, F), (D, F), (D, G), (E, F), (F, G)] corder = [0, 2, 6, 5, 8, 1, 4, 7, 3] edges = [] for (ip, pair) in enumerate(pairs): e = edge >> pair e.vertices = pair pair[0].edges.append(ip) pair[1].edges.append(ip) edges.append(e) removed_list = [] sl = [] def update(i): ip = corder[i] X, Y = pairs[ip] _X, _Y = _pairs[ip] st.objs[-1].remove() t = st.text(_X.label + _Y.label) if pairs[ip] in removed_list: sl[-1].remove() return removed_list.append(pairs[ip]) print(X.label, Y.label) res = edges[ip].remove() nnode = nbrush >> edges[ip].position nnode.edges = [] nnode.label = X.label + Y.label nnode.text(nnode.label) if i in [3, 5, 7]: sl.append(selfloop >> nnode.pin("top")) # special cases vl = [] for ie in X.edges + Y.edges: res = edges[ie].remove() for v in edges[ie].vertices: if v not in (X, Y): if v in vl: #e = dbl >> (v, nnode) e = next( filter(lambda e: e.vertices == (v, nnode), edges)) e.obj.set_linewidth(e.obj.get_linewidth() + 2) else: e = edge >> (v, nnode) nnode.edges.append(ie) e.vertices = (v, nnode) edges[ie] = e print(ie, e.vertices[0].label, e.vertices[1].label) pairs[ie] = e.vertices vl.append(v) try: v.edges.remove(ie) except: pass X.remove() Y.remove() ds.steps = [lambda j=i: update(j) for i in range(len(corder))]
GRAY = '#D4D4D4' RED = '#F0201C' BLUE = '#1072B6' GREEN = '#00B122' YELLOW = '#FF9223' LAKE = '#00A79B' VIOLET = '#6611CC' PINK = '#DF678C' GRASS = '#CCF381' LW = 3 setting.node_setting['lw'] = LW setting.node_setting['inner_lw'] = LW blue = NodeBrush('basic', size=0.2, color=BLUE) yellow = NodeBrush('basic', size=0.2, color=YELLOW) red = NodeBrush('basic', size=0.2, color=RED) green = NodeBrush('basic', size=0.2, color=GREEN) lake = NodeBrush('basic', size=0.2, color=LAKE) gray = NodeBrush('basic', size=0.25, color=GRAY) violet = NodeBrush('basic', size=0.2, color=VIOLET) pink = NodeBrush('basic', size=0.2, color=PINK) grass = NodeBrush('basic', size=0.2, color=GRASS) # edges edge = EdgeBrush('-', lw=LW) def plot_ctmrg(): with DynamicShow(figsize=(6, 4), filename="_ctmrg.png") as pl:
import pdb, fire from viznet import theme, EdgeBrush, DynamicShow, Grid, NodeBrush import matplotlib.pyplot as plt import numpy as np import time nbrush = NodeBrush("tn.mps", color="#31e0cf") selfloop = NodeBrush("basic", size="small", zorder=-10) e2v = NodeBrush("tn.mps", size="tiny", color="r", zorder=2) edge = EdgeBrush("-", color="#333333", lw=2) edge2 = EdgeBrush(".", color="#DD7722", lw=2) class TW(object): def origin(self, tp="png"): with DynamicShow(figsize=(5, 4), filename="origin.%s" % tp) as ds: xs = [0, 0, -1, 1, -2, 0, 2.0] ys = [3, 2, 1, 1, 0, 0, 0.0] locs = zip(xs, ys) A, B, C, D, E, F, G = [nbrush >> loc for loc in locs] for x in ["A", "B", "C", "D", "E", "F", "G"]: eval("%s.text('%s')" % (x, x)) pairs = [(A, B), (B, C), (B, D), (C, E), (C, F), (D, F), (D, G), (E, F), (F, G)] edges = [edge >> pair for pair in pairs] def mapping(self, tp="gif"): with DynamicShow(figsize=(5, 4), filename="mapping.%s" % tp) as ds: xs = [0, 0, -1, 1, -2, 0, 2.0] ys = [3, 2, 1, 1, 0, 0, 0.0]
def block_2(inputs, text1, output_text, hidden_layer_text="$h_1 \sim 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 = (.65 * size, 0) # hidden layers 1 nb = NodeBrush(['grey', 'circle', 'none'], size=size * .1) xys = custom_node_seq(hidden_layer_node_num, (x_offset, offset + -1 * step), space=node_spacing) __nb = NodeBrush('invisible', size=size * .1) _inner_block_1 = [ nb >> xys[0], __nb >> xys[1], nb >> xys[2], ] _inner_block_1[1].text("$\cdots\cdots$", 'center', fontsize=font_size_small) _inner_block_1[1].brush.style = "invisible" _inner_block_1[2].text(hidden_layer_text, '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) 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.04 * step), box_size=(size * .9, size * .05), box_colour=box_colour) viznet.connect121(_inner_block_1, _inner_block_2_connectable, eb) # output nb = NodeBrush(['grey', 'circle', 'none'], size=size * .3) output = viznet.node_sequence(nb, 1, (x_offset, offset + -1.1 * step), space=node_spacing) output[0].text(output_text, 'right', fontsize=font_size * 2) 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 plot_ctmrg(): with DynamicShow(figsize=(6, 4), filename="_ctmrg.png") as pl: grid = Grid(([1.0, 0], [0.5, 0.8])) box = NodeBrush('box', size=(0.5, 0.2), color="#333333", roundness=0.1, edgecolor="#333333") redline = EdgeBrush('-', lw=LW, color="#000000", zorder=100) blueline = EdgeBrush('-', lw=LW, color="#999999", zorder=-2) iedge = copy.copy(edge) iedge.zorder = -1 def ket(isbra=False): X2 = 2 X1 = 1 Y = 1 E1 = red >> grid[-X1, Y] E3 = red >> grid[-X1, -Y] E4 = red >> grid[X1, -Y] E6 = red >> grid[X1, Y] E2 = red >> grid[-X2, 0] E5 = red >> grid[X2, 0] ES = [E1, E2, E3, E4, E5, E6] C1 = blue >> grid[-X2, Y] C2 = blue >> grid[-X2, -Y] C4 = blue >> grid[X2, Y] C3 = blue >> grid[X2, -Y] dYa = 0.3 * (1 if isbra else -1) bl = copy.copy(grass) A1 = bl >> grid[-X1, 0] + [0, dYa] A2 = bl >> grid[X1, 0] + [0, dYa] QUEUE = [E1, C1, E2, C2, E3, E4, C3, E5, C4, E6] NQ = 10 for i in range(NQ): iedge >> (QUEUE[i], QUEUE[(i + 1) % NQ]) eg = redline if isbra else blueline eg >> (E2, A1) eg >> (E1, A1) eg >> (E3, A1) eg >> (E4, A2) eg >> (E5, A2) eg >> (E6, A2) eg >> (A1, A2) return A1, A2, ES A1, A2, ES = ket(True) A1_, A2_, ES_ = ket() c = box >> grid[0, 0] c.text("$\hat{H}$", fontsize=16, color='w') redline >> (c, A1) blueline >> (c, A1_) redline >> (c, A2) blueline >> (c, A2_) plt.axis("equal") plt.axis("off") plt.tight_layout()
import numpy as np import matplotlib.pyplot as plt import viznet from viznet import NodeBrush, EdgeBrush, Pin, DynamicShow RED = '#FF2200' BLUE = '#333333' YELLOW = '#BBBBBB' viznet.setting.node_setting["inner_lw"] = 3 topc = NodeBrush('qc.cross', color=RED, size=0.1, lw=0, zorder=101) leaf = NodeBrush('basic', color=BLUE, size='tiny', lw=0, edgecolor=BLUE) base = NodeBrush('basic', color=YELLOW, size='normal', lw=4) hedge = EdgeBrush('-', lw=5, color=BLUE, zorder=-1, solid_capstyle='round') vedge = EdgeBrush('-', lw=3, color=RED, zorder=100) dz = 0.6 def grow(brush, nodes, dr, angle, vbar, size): """grow one more layer.""" nnodes = [] brush.size = size for node in nodes: x, y = node.position angle0 = np.angle(x + 1j * y) for nangle in [angle / 2 + angle0, -angle / 2 + angle0]: nx, ny = x + dr * np.cos(nangle), y + dr * np.sin(nangle) brush.rotate = nangle + np.pi + np.pi / 6 nnode = brush >> (nx, ny) nnodes.append(nnode) hedge >> (nnode, node)
import numpy as np def _plotinit(): plt.axis("equal") plt.axis("off") # define a grid with grid space dx = 1, and dy = 1. GRAY = '#CCCCCC' setting.node_setting['lw'] = 2 setting.node_setting['inner_lw'] = 2 C.zorder = 10 size = "normal" mps = NodeBrush('tn.mps', size=size) basic2 = NodeBrush('basic', size="small", color="w", zorder=10) basic = NodeBrush('basic', size="small", color="k") box = NodeBrush('box', size=size, color=GRAY, zorder=100, roundness=0.2, lw=0) hbox = NodeBrush('box', size=(0.25, 0.12), color=GRAY, zorder=100, roundness=0.06, lw=0) obox = NodeBrush("box", ls="-", roundness=0.2, color=GRAY, zorder=-1, lw=0) tri = NodeBrush('tn.tri', size=0.35, color="#66CCAA", rotate=-np.pi / 6, lw=0) sq = NodeBrush('tn.mpo', size=0.3, color='#EEBB44', lw=0) sqr = NodeBrush('tn.mpo', size=0.3, color='#EE3344', lw=0) sq2 = NodeBrush('box', size=(0.25, 0.15), color='red', zorder=103, lw=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
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
# 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 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)