From 11764198a3f33ce7142c72124fbd3b7b5207a62c Mon Sep 17 00:00:00 2001 From: aliakbar Date: Wed, 22 Jan 2020 16:52:56 -0500 Subject: [PATCH] This change uses tensorflow directly --- ann_visualizer/visualize.py | 300 ++++++++++++++++++------------------ 1 file changed, 153 insertions(+), 147 deletions(-) diff --git a/ann_visualizer/visualize.py b/ann_visualizer/visualize.py index 72a9a7c..5941063 100644 --- a/ann_visualizer/visualize.py +++ b/ann_visualizer/visualize.py @@ -27,180 +27,186 @@ def ann_viz(model, view=True, filename="network.gv", title="My Neural Network"): title: A title for the graph """ - from graphviz import Digraph; - import keras; - from keras.models import Sequential; - from keras.layers import Dense, Conv2D, MaxPooling2D, Dropout, Flatten; - import json; - input_layer = 0; - hidden_layers_nr = 0; - layer_types = []; - hidden_layers = []; - output_layer = 0; + from graphviz import Digraph + from tensorflow.python.keras.layers import Conv2D, MaxPooling2D, Activation, Dense + from tensorflow.python.keras.layers.core import Dropout, Flatten + # import keras + input_layer = 0 + hidden_layers_nr = 0 + layer_types = [] + hidden_layers = [] + output_layer = 0 for layer in model.layers: - if(layer == model.layers[0]): - input_layer = int(str(layer.input_shape).split(",")[1][1:-1]); - hidden_layers_nr += 1; - if (type(layer) == keras.layers.core.Dense): - hidden_layers.append(int(str(layer.output_shape).split(",")[1][1:-1])); - layer_types.append("Dense"); + if layer == model.layers[0]: + input_layer = int(str(layer.input_shape).split(",")[1][1:-1]) + hidden_layers_nr += 1 + if type(layer) == Dense: + hidden_layers.append(int(str(layer.output_shape).split(",")[1][1:-1])) + layer_types.append("Dense") else: - hidden_layers.append(1); - if (type(layer) == keras.layers.convolutional.Conv2D): - layer_types.append("Conv2D"); - elif (type(layer) == keras.layers.pooling.MaxPooling2D): - layer_types.append("MaxPooling2D"); - elif (type(layer) == keras.layers.core.Dropout): - layer_types.append("Dropout"); - elif (type(layer) == keras.layers.core.Flatten): - layer_types.append("Flatten"); - elif (type(layer) == keras.layers.core.Activation): - layer_types.append("Activation"); + hidden_layers.append(1) + if type(layer) == Conv2D: + layer_types.append("Conv2D") + elif type(layer) == MaxPooling2D: + layer_types.append("MaxPooling2D") + elif type(layer) == Dropout: + layer_types.append("Dropout") + elif type(layer) == Flatten: + layer_types.append("Flatten") + elif type(layer) == Activation: + layer_types.append("Activation") else: - if(layer == model.layers[-1]): - output_layer = int(str(layer.output_shape).split(",")[1][1:-1]); + if (layer == model.layers[-1]): + output_layer = int(str(layer.output_shape).split(",")[1][1:-1]) else: - hidden_layers_nr += 1; - if (type(layer) == keras.layers.core.Dense): - hidden_layers.append(int(str(layer.output_shape).split(",")[1][1:-1])); - layer_types.append("Dense"); + hidden_layers_nr += 1 + if (type(layer) == Dense): + hidden_layers.append(int(str(layer.output_shape).split(",")[1][1:-1])) + layer_types.append("Dense") else: - hidden_layers.append(1); - if (type(layer) == keras.layers.convolutional.Conv2D): - layer_types.append("Conv2D"); - elif (type(layer) == keras.layers.pooling.MaxPooling2D): - layer_types.append("MaxPooling2D"); - elif (type(layer) == keras.layers.core.Dropout): - layer_types.append("Dropout"); - elif (type(layer) == keras.layers.core.Flatten): - layer_types.append("Flatten"); - elif (type(layer) == keras.layers.core.Activation): - layer_types.append("Activation"); - last_layer_nodes = input_layer; - nodes_up = input_layer; - if(type(model.layers[0]) != keras.layers.core.Dense): - last_layer_nodes = 1; - nodes_up = 1; - input_layer = 1; + hidden_layers.append(1) + if (type(layer) == Conv2D): + layer_types.append("Conv2D") + elif (type(layer) == MaxPooling2D): + layer_types.append("MaxPooling2D") + elif (type(layer) == Dropout): + layer_types.append("Dropout") + elif (type(layer) == Flatten): + layer_types.append("Flatten") + elif (type(layer) == Activation): + layer_types.append("Activation") + last_layer_nodes = input_layer + nodes_up = input_layer + if type(model.layers[0]) != Dense: + last_layer_nodes = 1 + nodes_up = 1 + input_layer = 1 - g = Digraph('g', filename=filename); - n = 0; - g.graph_attr.update(splines="false", nodesep='1', ranksep='2'); - #Input Layer + g = Digraph('g', filename=filename) + n = 0 + g.graph_attr.update(splines="false", nodesep='1', ranksep='2') + # Input Layer with g.subgraph(name='cluster_input') as c: - if(type(model.layers[0]) == keras.layers.core.Dense): - the_label = title+'\n\n\n\nInput Layer'; - if (int(str(model.layers[0].input_shape).split(",")[1][1:-1]) > 10): - the_label += " (+"+str(int(str(model.layers[0].input_shape).split(",")[1][1:-1]) - 10)+")"; - input_layer = 10; + if type(model.layers[0]) == Dense: + the_label = title + '\n\n\n\nInput Layer' + if int(str(model.layers[0].input_shape).split(",")[1][1:-1]) > 10: + the_label += " (+" + str(int(str(model.layers[0].input_shape).split(",")[1][1:-1]) - 10) + ")" + input_layer = 10 c.attr(color='white') for i in range(0, input_layer): - n += 1; - c.node(str(n)); + n += 1 + c.node(str(n)) c.attr(label=the_label) - c.attr(rank='same'); - c.node_attr.update(color="#2ecc71", style="filled", fontcolor="#2ecc71", shape="circle"); + c.attr(rank='same') + c.node_attr.update(color="#2ecc71", style="filled", fontcolor="#2ecc71", shape="circle") - elif(type(model.layers[0]) == keras.layers.convolutional.Conv2D): - #Conv2D Input visualizing - the_label = title+'\n\n\n\nInput Layer'; - c.attr(color="white", label=the_label); - c.node_attr.update(shape="square"); - pxls = str(model.layers[0].input_shape).split(','); - clr = int(pxls[3][1:-1]); + elif (type(model.layers[0]) == Conv2D): + # Conv2D Input visualizing + the_label = title + '\n\n\n\nInput Layer' + c.attr(color="white", label=the_label) + c.node_attr.update(shape="square") + pxls = str(model.layers[0].input_shape).split(',') + clr = int(pxls[3][1:-1]) if (clr == 1): - clrmap = "Grayscale"; - the_color = "black:white"; + clrmap = "Grayscale" + the_color = "black:white" elif (clr == 3): - clrmap = "RGB"; - the_color = "#e74c3c:#3498db"; + clrmap = "RGB" + the_color = "#e74c3c:#3498db" else: - clrmap = ""; - c.node_attr.update(fontcolor="white", fillcolor=the_color, style="filled"); - n += 1; - c.node(str(n), label="Image\n"+pxls[1]+" x"+pxls[2]+" pixels\n"+clrmap, fontcolor="white"); + clrmap = "" + c.node_attr.update(fontcolor="white", fillcolor=the_color, style="filled") + n += 1 + c.node(str(n), label="Image\n" + pxls[1] + " x" + pxls[2] + " pixels\n" + clrmap, fontcolor="white") else: - raise ValueError("ANN Visualizer: Layer not supported for visualizing"); + raise ValueError("ANN Visualizer: Layer not supported for visualizing") for i in range(0, hidden_layers_nr): - with g.subgraph(name="cluster_"+str(i+1)) as c: + with g.subgraph(name="cluster_" + str(i + 1)) as c: if (layer_types[i] == "Dense"): - c.attr(color='white'); - c.attr(rank='same'); - #If hidden_layers[i] > 10, dont include all - the_label = ""; + c.attr(color='white') + c.attr(rank='same') + # If hidden_layers[i] > 10, dont include all + the_label = "" if (int(str(model.layers[i].output_shape).split(",")[1][1:-1]) > 10): - the_label += " (+"+str(int(str(model.layers[i].output_shape).split(",")[1][1:-1]) - 10)+")"; - hidden_layers[i] = 10; - c.attr(labeljust="right", labelloc="b", label=the_label); + the_label += " (+" + str(int(str(model.layers[i].output_shape).split(",")[1][1:-1]) - 10) + ")" + hidden_layers[i] = 10 + c.attr(labeljust="right", labelloc="b", label=the_label) for j in range(0, hidden_layers[i]): - n += 1; - c.node(str(n), shape="circle", style="filled", color="#3498db", fontcolor="#3498db"); - for h in range(nodes_up - last_layer_nodes + 1 , nodes_up + 1): - g.edge(str(h), str(n)); - last_layer_nodes = hidden_layers[i]; - nodes_up += hidden_layers[i]; + n += 1 + c.node(str(n), shape="circle", style="filled", color="#3498db", fontcolor="#3498db") + for h in range(nodes_up - last_layer_nodes + 1, nodes_up + 1): + g.edge(str(h), str(n)) + last_layer_nodes = hidden_layers[i] + nodes_up += hidden_layers[i] elif (layer_types[i] == "Conv2D"): - c.attr(style='filled', color='#5faad0'); - n += 1; - kernel_size = str(model.layers[i].get_config()['kernel_size']).split(',')[0][1] + "x" + str(model.layers[i].get_config()['kernel_size']).split(',')[1][1 : -1]; - filters = str(model.layers[i].get_config()['filters']); - c.node("conv_"+str(n), label="Convolutional Layer\nKernel Size: "+kernel_size+"\nFilters: "+filters, shape="square"); - c.node(str(n), label=filters+"\nFeature Maps", shape="square"); - g.edge("conv_"+str(n), str(n)); - for h in range(nodes_up - last_layer_nodes + 1 , nodes_up + 1): - g.edge(str(h), "conv_"+str(n)); - last_layer_nodes = 1; - nodes_up += 1; + c.attr(style='filled', color='#5faad0') + n += 1 + kernel_size = str(model.layers[i].get_config()['kernel_size']).split(',')[0][1] + "x" + \ + str(model.layers[i].get_config()['kernel_size']).split(',')[1][1: -1] + filters = str(model.layers[i].get_config()['filters']) + c.node("conv_" + str(n), + label="Convolutional Layer\nKernel Size: " + kernel_size + "\nFilters: " + filters, + shape="square") + c.node(str(n), label=filters + "\nFeature Maps", shape="square") + g.edge("conv_" + str(n), str(n)) + for h in range(nodes_up - last_layer_nodes + 1, nodes_up + 1): + g.edge(str(h), "conv_" + str(n)) + last_layer_nodes = 1 + nodes_up += 1 elif (layer_types[i] == "MaxPooling2D"): - c.attr(color="white"); - n += 1; - pool_size = str(model.layers[i].get_config()['pool_size']).split(',')[0][1] + "x" + str(model.layers[i].get_config()['pool_size']).split(',')[1][1 : -1]; - c.node(str(n), label="Max Pooling\nPool Size: "+pool_size, style="filled", fillcolor="#8e44ad", fontcolor="white"); - for h in range(nodes_up - last_layer_nodes + 1 , nodes_up + 1): - g.edge(str(h), str(n)); - last_layer_nodes = 1; - nodes_up += 1; + c.attr(color="white") + n += 1 + pool_size = str(model.layers[i].get_config()['pool_size']).split(',')[0][1] + "x" + \ + str(model.layers[i].get_config()['pool_size']).split(',')[1][1: -1] + c.node(str(n), label="Max Pooling\nPool Size: " + pool_size, style="filled", fillcolor="#8e44ad", + fontcolor="white") + for h in range(nodes_up - last_layer_nodes + 1, nodes_up + 1): + g.edge(str(h), str(n)) + last_layer_nodes = 1 + nodes_up += 1 elif (layer_types[i] == "Flatten"): - n += 1; - c.attr(color="white"); - c.node(str(n), label="Flattening", shape="invtriangle", style="filled", fillcolor="#2c3e50", fontcolor="white"); - for h in range(nodes_up - last_layer_nodes + 1 , nodes_up + 1): - g.edge(str(h), str(n)); - last_layer_nodes = 1; - nodes_up += 1; + n += 1 + c.attr(color="white") + c.node(str(n), label="Flattening", shape="invtriangle", style="filled", fillcolor="#2c3e50", + fontcolor="white") + for h in range(nodes_up - last_layer_nodes + 1, nodes_up + 1): + g.edge(str(h), str(n)) + last_layer_nodes = 1 + nodes_up += 1 elif (layer_types[i] == "Dropout"): - n += 1; - c.attr(color="white"); - c.node(str(n), label="Dropout Layer", style="filled", fontcolor="white", fillcolor="#f39c12"); - for h in range(nodes_up - last_layer_nodes + 1 , nodes_up + 1): - g.edge(str(h), str(n)); - last_layer_nodes = 1; - nodes_up += 1; + n += 1 + c.attr(color="white") + c.node(str(n), label="Dropout Layer", style="filled", fontcolor="white", fillcolor="#f39c12") + for h in range(nodes_up - last_layer_nodes + 1, nodes_up + 1): + g.edge(str(h), str(n)) + last_layer_nodes = 1 + nodes_up += 1 elif (layer_types[i] == "Activation"): - n += 1; - c.attr(color="white"); - fnc = model.layers[i].get_config()['activation']; - c.node(str(n), shape="octagon", label="Activation Layer\nFunction: "+fnc, style="filled", fontcolor="white", fillcolor="#00b894"); - for h in range(nodes_up - last_layer_nodes + 1 , nodes_up + 1): - g.edge(str(h), str(n)); - last_layer_nodes = 1; - nodes_up += 1; - + n += 1 + c.attr(color="white") + fnc = model.layers[i].get_config()['activation'] + c.node(str(n), shape="octagon", label="Activation Layer\nFunction: " + fnc, style="filled", + fontcolor="white", fillcolor="#00b894") + for h in range(nodes_up - last_layer_nodes + 1, nodes_up + 1): + g.edge(str(h), str(n)) + last_layer_nodes = 1 + nodes_up += 1 with g.subgraph(name='cluster_output') as c: - if (type(model.layers[-1]) == keras.layers.core.Dense): + if (type(model.layers[-1]) == Dense): c.attr(color='white') - c.attr(rank='same'); - c.attr(labeljust="1"); - for i in range(1, output_layer+1): - n += 1; - c.node(str(n), shape="circle", style="filled", color="#e74c3c", fontcolor="#e74c3c"); - for h in range(nodes_up - last_layer_nodes + 1 , nodes_up + 1): - g.edge(str(h), str(n)); + c.attr(rank='same') + c.attr(labeljust="1") + for i in range(1, output_layer + 1): + n += 1 + c.node(str(n), shape="circle", style="filled", color="#e74c3c", fontcolor="#e74c3c") + for h in range(nodes_up - last_layer_nodes + 1, nodes_up + 1): + g.edge(str(h), str(n)) c.attr(label='Output Layer', labelloc="bottom") - c.node_attr.update(color="#2ecc71", style="filled", fontcolor="#2ecc71", shape="circle"); + c.node_attr.update(color="#2ecc71", style="filled", fontcolor="#2ecc71", shape="circle") - g.attr(arrowShape="none"); - g.edge_attr.update(arrowhead="none", color="#707070"); + g.attr(arrowShape="none") + g.edge_attr.update(arrowhead="none", color="#707070") if view == True: - g.view(); + g.view() +