SqueezeNet v1.1

original repo: https://github.com/DeepScale/SqueezeNet

for keras: https://github.com/rcmalli/keras-squeezenet (pretrained imagenet weights downloaded from here)

$ wget -O squeezenet_v1.1.hdf5 https://github.com/rcmalli/keras-squeezenet/releases/download/v1.0/squeezenet_weights_tf_dim_ordering_tf_kernels.h5

Pre-trained imagenet weights renamed from squeezenet_weights_tf_dim_ordering_tf_kernels.h5 to squeezenet_v1.1.hdf5. Weight names are converted to Keras v2 format, since Keras.js uses these names to load layer weights.


In [1]:
WEIGHTS_FILEPATH = 'squeezenet_v1.1.hdf5'
MODEL_ARCH_FILEPATH = 'squeezenet_v1.1.json'

In [2]:
import h5py

hdf5_file = h5py.File(WEIGHTS_FILEPATH, mode='r+')
f = hdf5_file
layer_names = [n.decode('utf8') for n in f.attrs['layer_names']]
offset = 0
for layer_name in layer_names:
    g = f[layer_name]
    weight_names = [n.decode('utf8') for n in g.attrs['weight_names']]
    if weight_names:
        old_weight_names = weight_names
        new_weight_names = []
        for weight_name in weight_names:
            if '_W:' in weight_name:
                new_weight_name = weight_name.replace('_W', '/kernel')
                g[new_weight_name] = g[weight_name]
                del g[weight_name]
            elif '_b:' in weight_name:
                new_weight_name = weight_name.replace('_b', '/bias')
                g[new_weight_name] = g[weight_name]
                del g[weight_name]
            else:
                new_weight_name = weight_name
            new_weight_names.append(new_weight_name)
        g.attrs['weight_names'] = [n.encode('utf8') for n in new_weight_names]
        print(old_weight_names, '-->', new_weight_names)
        
hdf5_file.close()


['conv1_W:0', 'conv1_b:0'] --> ['conv1/kernel:0', 'conv1/bias:0']
['fire2/squeeze1x1_W:0', 'fire2/squeeze1x1_b:0'] --> ['fire2/squeeze1x1/kernel:0', 'fire2/squeeze1x1/bias:0']
['fire2/expand1x1_W:0', 'fire2/expand1x1_b:0'] --> ['fire2/expand1x1/kernel:0', 'fire2/expand1x1/bias:0']
['fire2/expand3x3_W:0', 'fire2/expand3x3_b:0'] --> ['fire2/expand3x3/kernel:0', 'fire2/expand3x3/bias:0']
['fire3/squeeze1x1_W:0', 'fire3/squeeze1x1_b:0'] --> ['fire3/squeeze1x1/kernel:0', 'fire3/squeeze1x1/bias:0']
['fire3/expand1x1_W:0', 'fire3/expand1x1_b:0'] --> ['fire3/expand1x1/kernel:0', 'fire3/expand1x1/bias:0']
['fire3/expand3x3_W:0', 'fire3/expand3x3_b:0'] --> ['fire3/expand3x3/kernel:0', 'fire3/expand3x3/bias:0']
['fire4/squeeze1x1_W:0', 'fire4/squeeze1x1_b:0'] --> ['fire4/squeeze1x1/kernel:0', 'fire4/squeeze1x1/bias:0']
['fire4/expand1x1_W:0', 'fire4/expand1x1_b:0'] --> ['fire4/expand1x1/kernel:0', 'fire4/expand1x1/bias:0']
['fire4/expand3x3_W:0', 'fire4/expand3x3_b:0'] --> ['fire4/expand3x3/kernel:0', 'fire4/expand3x3/bias:0']
['fire5/squeeze1x1_W:0', 'fire5/squeeze1x1_b:0'] --> ['fire5/squeeze1x1/kernel:0', 'fire5/squeeze1x1/bias:0']
['fire5/expand1x1_W:0', 'fire5/expand1x1_b:0'] --> ['fire5/expand1x1/kernel:0', 'fire5/expand1x1/bias:0']
['fire5/expand3x3_W:0', 'fire5/expand3x3_b:0'] --> ['fire5/expand3x3/kernel:0', 'fire5/expand3x3/bias:0']
['fire6/squeeze1x1_W:0', 'fire6/squeeze1x1_b:0'] --> ['fire6/squeeze1x1/kernel:0', 'fire6/squeeze1x1/bias:0']
['fire6/expand1x1_W:0', 'fire6/expand1x1_b:0'] --> ['fire6/expand1x1/kernel:0', 'fire6/expand1x1/bias:0']
['fire6/expand3x3_W:0', 'fire6/expand3x3_b:0'] --> ['fire6/expand3x3/kernel:0', 'fire6/expand3x3/bias:0']
['fire7/squeeze1x1_W:0', 'fire7/squeeze1x1_b:0'] --> ['fire7/squeeze1x1/kernel:0', 'fire7/squeeze1x1/bias:0']
['fire7/expand1x1_W:0', 'fire7/expand1x1_b:0'] --> ['fire7/expand1x1/kernel:0', 'fire7/expand1x1/bias:0']
['fire7/expand3x3_W:0', 'fire7/expand3x3_b:0'] --> ['fire7/expand3x3/kernel:0', 'fire7/expand3x3/bias:0']
['fire8/squeeze1x1_W:0', 'fire8/squeeze1x1_b:0'] --> ['fire8/squeeze1x1/kernel:0', 'fire8/squeeze1x1/bias:0']
['fire8/expand1x1_W:0', 'fire8/expand1x1_b:0'] --> ['fire8/expand1x1/kernel:0', 'fire8/expand1x1/bias:0']
['fire8/expand3x3_W:0', 'fire8/expand3x3_b:0'] --> ['fire8/expand3x3/kernel:0', 'fire8/expand3x3/bias:0']
['fire9/squeeze1x1_W:0', 'fire9/squeeze1x1_b:0'] --> ['fire9/squeeze1x1/kernel:0', 'fire9/squeeze1x1/bias:0']
['fire9/expand1x1_W:0', 'fire9/expand1x1_b:0'] --> ['fire9/expand1x1/kernel:0', 'fire9/expand1x1/bias:0']
['fire9/expand3x3_W:0', 'fire9/expand3x3_b:0'] --> ['fire9/expand3x3/kernel:0', 'fire9/expand3x3/bias:0']
['conv10_W:0', 'conv10_b:0'] --> ['conv10/kernel:0', 'conv10/bias:0']

In [3]:
from keras.layers import Input, Conv2D, MaxPooling2D, Activation, concatenate, Dropout, GlobalAveragePooling2D
from keras.models import Model

sq1x1 = "squeeze1x1"
exp1x1 = "expand1x1"
exp3x3 = "expand3x3"
relu = "relu_"

def fire_module(x, fire_id, squeeze=16, expand=64):
    s_id = 'fire' + str(fire_id) + '/'

    channel_axis = 3
    
    x = Conv2D(squeeze, (1, 1), padding='valid', name=s_id + sq1x1)(x)
    x = Activation('relu', name=s_id + relu + sq1x1)(x)

    left = Conv2D(expand, (1, 1), padding='valid', name=s_id + exp1x1)(x)
    left = Activation('relu', name=s_id + relu + exp1x1)(left)

    right = Conv2D(expand, (3, 3), padding='same', name=s_id + exp3x3)(x)
    right = Activation('relu', name=s_id + relu + exp3x3)(right)

    x = concatenate([left, right], axis=channel_axis, name=s_id + 'concat')
    return x


input_shape = (227, 227, 3)
classes = 1000

img_input = Input(shape=input_shape)

x = Conv2D(64, (3, 3), strides=(2, 2), padding='valid', name='conv1')(img_input)
x = Activation('relu', name='relu_conv1')(x)
x = MaxPooling2D(pool_size=(3, 3), strides=(2, 2), name='pool1')(x)

x = fire_module(x, fire_id=2, squeeze=16, expand=64)
x = fire_module(x, fire_id=3, squeeze=16, expand=64)
x = MaxPooling2D(pool_size=(3, 3), strides=(2, 2), name='pool3')(x)

x = fire_module(x, fire_id=4, squeeze=32, expand=128)
x = fire_module(x, fire_id=5, squeeze=32, expand=128)
x = MaxPooling2D(pool_size=(3, 3), strides=(2, 2), name='pool5')(x)

x = fire_module(x, fire_id=6, squeeze=48, expand=192)
x = fire_module(x, fire_id=7, squeeze=48, expand=192)
x = fire_module(x, fire_id=8, squeeze=64, expand=256)
x = fire_module(x, fire_id=9, squeeze=64, expand=256)
x = Dropout(0.5, name='drop9')(x)

x = Conv2D(classes, (1, 1), padding='valid', name='conv10')(x)
x = Activation('relu', name='relu_conv10')(x)
x = GlobalAveragePooling2D()(x)
out = Activation('softmax', name='loss')(x)

model = Model(inputs=img_input, outputs=out, name='squeezenet')


Using TensorFlow backend.

In [4]:
model.load_weights(WEIGHTS_FILEPATH)

In [5]:
with open(MODEL_ARCH_FILEPATH, 'w') as f:
    f.write(model.to_json())

In [ ]: