1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
|
#!/usr/bin/env python3
import pickle
import math
import numpy as np
import re
import sys
model_file = sys.argv[1]
trim_trailing_zeros = re.compile('0+p')
def small_hex(f):
hf = float(f).hex()
return trim_trailing_zeros.sub('p', hf)
def process_column(v, pad):
""" process and pad """
return [small_hex(f) for f in v] + [small_hex(0.0)] * pad
def cformatM(fh, name, X):
nrq = int(math.ceil(X.shape[1] / 4.0))
pad = nrq * 4 - X.shape[1]
lines = map(lambda v: ', '.join(process_column(v, pad)), X)
fh.write('float {}[] = {}\n'.format('__' + name, '{'))
fh.write('\t' + ',\n\t'.join(lines))
fh.write('};\n')
fh.write('_Mat {} = {}\n\t.nr = {},\n\t.nrq = {},\n\t.nc = {},\n\t.stride = {},\n\t.data.f = {}\n{};\n'.format('_' + name, '{', X.shape[1], nrq, X.shape[0], nrq * 4, '__' + name, '}'))
fh.write('const scrappie_matrix {} = &{};\n\n'.format(name, '_' + name))
def cformatV(fh, name, X):
nrq = int(math.ceil(X.shape[0] / 4.0))
pad = nrq * 4 - X.shape[0]
lines = ', '.join(list(map(lambda f: small_hex(f), X)) + [small_hex(0.0)] * pad)
fh.write('float {}[] = {}\n'.format('__' + name, '{'))
fh.write('\t' + lines)
fh.write('};\n')
fh.write('_Mat {} = {}\n\t.nr = {},\n\t.nrq = {},\n\t.nc = {},\n\t.stride = {},\n\t.data.f = {}\n{};\n'.format('_' + name, '{', X.shape[0], nrq, 1, nrq * 4, '__' + name, '}'))
fh.write('const scrappie_matrix {} = &{};\n\n'.format(name, '_' + name))
def reshape_lstmM(mat):
_, isize = mat.shape
return mat.reshape((-1, 4, isize)).transpose([1, 0, 2]).reshape((-1, isize))
def reshape_lstmV(mat):
return mat.reshape((-1, 4)).transpose().reshape(-1)
with open(model_file, 'rb') as fh:
network = pickle.load(fh, encoding='latin1')
assert network.version == 1, "Sloika model must be version 1. Perhaps you need to run Sloika's model_upgrade.py"
sys.stdout.write("""#pragma once
#ifndef NANONET_EVENTS_MODEL_H
#define NANONET_EVENTS_MODEL_H
#include "../util.h"
""")
""" First LSTM layer
"""
bilstm1 = network.sublayers[1]
lstm = bilstm1.sublayers[0]
cformatM(sys.stdout, 'lstmF1_iW', reshape_lstmM(lstm.iW.get_value()))
cformatM(sys.stdout, 'lstmF1_sW', reshape_lstmM(lstm.sW.get_value()))
cformatV(sys.stdout, 'lstmF1_b', reshape_lstmV(lstm.b.get_value().reshape(-1)))
cformatV(sys.stdout, 'lstmF1_p', lstm.p.get_value().reshape(-1))
lstm = bilstm1.sublayers[1].sublayers[0]
cformatM(sys.stdout, 'lstmB1_iW', reshape_lstmM(lstm.iW.get_value()))
cformatM(sys.stdout, 'lstmB1_sW', reshape_lstmM(lstm.sW.get_value()))
cformatV(sys.stdout, 'lstmB1_b', reshape_lstmV(lstm.b.get_value().reshape(-1)))
cformatV(sys.stdout, 'lstmB1_p', lstm.p.get_value().reshape(-1))
""" First feed forward layer
"""
size = network.sublayers[2].insize // 2
cformatM(sys.stdout, 'FF1_Wf', network.sublayers[2].W.get_value()[:, : size])
cformatM(sys.stdout, 'FF1_Wb', network.sublayers[2].W.get_value()[:, size : 2 * size])
cformatV(sys.stdout, 'FF1_b', network.sublayers[2].b.get_value())
""" Second LSTM layer
"""
bilstm2 = network.sublayers[3]
lstm = bilstm2.sublayers[0]
cformatM(sys.stdout, 'lstmF2_iW', reshape_lstmM(lstm.iW.get_value()))
cformatM(sys.stdout, 'lstmF2_sW', reshape_lstmM(lstm.sW.get_value()))
cformatV(sys.stdout, 'lstmF2_b', reshape_lstmV(lstm.b.get_value().reshape(-1)))
cformatV(sys.stdout, 'lstmF2_p', lstm.p.get_value().reshape(-1))
lstm = bilstm2.sublayers[1].sublayers[0]
cformatM(sys.stdout, 'lstmB2_iW', reshape_lstmM(lstm.iW.get_value()))
cformatM(sys.stdout, 'lstmB2_sW', reshape_lstmM(lstm.sW.get_value()))
cformatV(sys.stdout, 'lstmB2_b', reshape_lstmV(lstm.b.get_value().reshape(-1)))
cformatV(sys.stdout, 'lstmB2_p', lstm.p.get_value().reshape(-1))
""" Second feed forward layer
"""
size = network.sublayers[4].insize // 2
cformatM(sys.stdout, 'FF2_Wf', network.sublayers[4].W.get_value()[:, : size])
cformatM(sys.stdout, 'FF2_Wb', network.sublayers[4].W.get_value()[:, size : 2 * size])
cformatV(sys.stdout, 'FF2_b', network.sublayers[4].b.get_value())
""" Softmax layer
"""
nstate = network.sublayers[5].W.get_value().shape[0]
shuffle = np.append(np.arange(nstate - 1) + 1, 0)
cformatM(sys.stdout, 'FF3_W', network.sublayers[5].W.get_value()[shuffle])
cformatV(sys.stdout, 'FF3_b', network.sublayers[5].b.get_value()[shuffle])
sys.stdout.write('#endif /* NANONET_EVENTS_MODEL_H */')
|