Skip to content

Instantly share code, notes, and snippets.

@stared
Last active January 18, 2017 13:28
Show Gist options
  • Save stared/8411d4e7e457b0f14f39d700afc8511c to your computer and use it in GitHub Desktop.
Save stared/8411d4e7e457b0f14f39d700afc8511c to your computer and use it in GitHub Desktop.
Sequential model in Keras -> ASCII

Sequential model in Keras -> ASCII

by Piotr Migdał from deepsense.io

EDIT: Now at: https://github.com/stared/keras-sequential-ascii, pip-installable.

Usage

from keras_ascii_sequential import sequential_model_to_ascii_printout
sequential_model_to_ascii_printout(model)

Rationale

Both model.summary() and graph export were not enough - I wanted dimensions, numbers of parameters and activation functions in one place. I use it for didactic purpose.

Examples

Proof of principle

      OPERATION           DATA DIMENSIONS   WEIGHTS(N)   WEIGHTS(%)

          Input   #####   (1, 28, 28)
  Convolution2D    \|/  -------------------       100     0.6%
           relu   #####   (10, 26, 26)
   MaxPooling2D   YYYYY -------------------         0     0.0%
                  #####   (10, 13, 13)
        Flatten   ||||| -------------------         0     0.0%
                  #####   (1690,)
          Dense   XXXXX -------------------     16910    98.8%
                  #####   (10,)
        Dropout    | || -------------------         0     0.0%
           relu   #####   (10,)
          Dense   XXXXX -------------------       110     0.6%
        softmax   #####   (10,)

VGG16

      OPERATION           DATA DIMENSIONS   WEIGHTS(N)   WEIGHTS(%)

          Input   #####   (3, 224, 224)
  Convolution2D    \|/  -------------------      1792     0.0%
           relu   #####   (64, 224, 224)
  Convolution2D    \|/  -------------------     36928     0.0%
           relu   #####   (64, 224, 224)
   MaxPooling2D   YYYYY -------------------         0     0.0%
                  #####   (64, 112, 112)
  Convolution2D    \|/  -------------------     73856     0.1%
           relu   #####   (128, 112, 112)
  Convolution2D    \|/  -------------------    147584     0.1%
           relu   #####   (128, 112, 112)
   MaxPooling2D   YYYYY -------------------         0     0.0%
                  #####   (128, 56, 56)
  Convolution2D    \|/  -------------------    295168     0.2%
           relu   #####   (256, 56, 56)
  Convolution2D    \|/  -------------------    590080     0.4%
           relu   #####   (256, 56, 56)
  Convolution2D    \|/  -------------------    590080     0.4%
           relu   #####   (256, 56, 56)
   MaxPooling2D   YYYYY -------------------         0     0.0%
                  #####   (256, 28, 28)
  Convolution2D    \|/  -------------------   1180160     0.9%
           relu   #####   (512, 28, 28)
  Convolution2D    \|/  -------------------   2359808     1.7%
           relu   #####   (512, 28, 28)
  Convolution2D    \|/  -------------------   2359808     1.7%
           relu   #####   (512, 28, 28)
   MaxPooling2D   YYYYY -------------------         0     0.0%
                  #####   (512, 14, 14)
  Convolution2D    \|/  -------------------   2359808     1.7%
           relu   #####   (512, 14, 14)
  Convolution2D    \|/  -------------------   2359808     1.7%
           relu   #####   (512, 14, 14)
  Convolution2D    \|/  -------------------   2359808     1.7%
           relu   #####   (512, 14, 14)
   MaxPooling2D   YYYYY -------------------         0     0.0%
                  #####   (512, 7, 7)
        Flatten   ||||| -------------------         0     0.0%
                  #####   (25088,)
          Dense   XXXXX ------------------- 102764544    74.3%
           relu   #####   (4096,)
        Dropout    | || -------------------         0     0.0%
                  #####   (4096,)
          Dense   XXXXX -------------------  16781312    12.1%
           relu   #####   (4096,)
        Dropout    | || -------------------         0     0.0%
                  #####   (4096,)
          Dense   XXXXX -------------------   4097000     3.0%
                  #####   (1000,)
                  ||||| -------------------         0     0.0%
        softmax   #####   (1000,)
graphics = {
"Convolution2D": " \|/ ",
"Activation": "|||||",
"Flatten": "|||||",
"MaxPooling2D": "YYYYY",
"Dropout": " | ||",
"Dense": "XXXXX",
"ZeroPadding2D": "\|||/"
}
def jsonize(model):
res = []
for layer in model.layers:
x = {}
x["name"] = layer.name
x["kind"] = layer.__class__.__name__
x["input_shape"] = layer.input_shape[1:]
x["output_shape"] = layer.output_shape[1:]
x["n_parameters"] = layer.count_params()
try:
x["activation"] = layer.activation.__name__
except AttributeError:
x["activation"] = ""
res.append(x)
return res
def compress_layers(jsonized_layers):
res = [jsonized_layers[0]]
for each in jsonized_layers[1:]:
if each["kind"] == "Activation" and res[-1]["activation"] in ["", "linear"]:
res[-1]["activation"] = each["activation"]
else:
res.append(each)
return res
# data_template = "{activation:>15s} ##### {shape} = {length}"
data_template = "{activation:>15s} ##### {shape}"
layer_template = "{kind:>15s} {graphics} -------------------{n_parameters:10d} {percent_parameters:5.1f}%"
def product(iterable):
res = 1
for each in iterable:
res *= each
return res
def print_layers(jsonized_layers, sparser=False, simplify=False, header=True):
if simplify:
jsonized_layers = compress_layers(jsonized_layers)
all_weights = sum([each["n_parameters"] for each in jsonized_layers])
if header:
print(" OPERATION DATA DIMENSIONS WEIGHTS(N) WEIGHTS(%)\n")
print(data_template.format(
activation="Input",
shape=jsonized_layers[0]["input_shape"],
# length=product(jsonized_layers[0]["output_shape"])
))
for each in jsonized_layers:
if sparser:
print("")
print(layer_template.format(
kind=each["kind"] if each["kind"] != "Activation" else "",
graphics=graphics.get(each["kind"], "?????"),
n_parameters=each["n_parameters"],
percent_parameters=100 * each["n_parameters"] / all_weights
))
if sparser:
print("")
print(data_template.format(
activation=each["activation"] if each["activation"] != "linear" else "",
shape=each["output_shape"],
# length=product(each["output_shape"])
))
def sequential_model_to_ascii_printout(model, sparser=False, simplify=True, header=True):
print_layers(jsonize(model), sparser=sparser, simplify=simplify, header=header)
@stared
Copy link
Author

stared commented Jan 18, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment