├── images
└── architecture.png
├── .idea
├── vcs.xml
├── modules.xml
├── SqueezeNet-tf.iml
└── misc.xml
├── README.md
├── LICENSE
└── SqueezeNet.py
/images/architecture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dawars/SqueezeNet-tf/HEAD/images/architecture.png
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/SqueezeNet-tf.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SqueezeNet-tf
2 | A Tensorflow SqueezeNet implementation of the research https://arxiv.org/abs/1602.07360
3 |
4 | ## What is SqueezeNet?
5 | SqueezeNet is a convolutional neural network with 80.3% top-5 accuracy on the ImageNet dataset.
6 | This architecture aims to signifanctly reduce the size of the model.
7 |
8 | ## Goals
9 | - [x] Building the network
10 | - [ ] Training the network on imagenet
11 | * Currently published pre-trained weights cannot be used in TensorFlow, the goal of this project is to produce easy-to-use save files.
12 | - [ ] Neural Style Transfer (http://arxiv.org/abs/1508.06576) on mobile devices
13 | * Running on mobile devices in reasonable time without sacraficing quality too much like other feed-forward approaches.
14 |
15 | 
16 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Dávid Komorowicz
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/SqueezeNet.py:
--------------------------------------------------------------------------------
1 | import tensorflow as tf
2 | import numpy as np
3 | import cv2
4 |
5 |
6 | class SqueezeNet(object):
7 | def __init__(self, session, alpha, optimizer=tf.train.GradientDescentOptimizer, squeeze_ratio=1):
8 | if session:
9 | self.session = session
10 | else:
11 | self.session = tf.Session()
12 |
13 | self.dropout = tf.placeholder(tf.float32)
14 | self.target = tf.placeholder(tf.float32, [None, 1000])
15 | self.imgs = tf.placeholder(tf.float32, [None, 224, 224, 3])
16 |
17 | self.alpha = alpha
18 | self.sq_ratio = squeeze_ratio
19 | self.optimizer = optimizer
20 |
21 | self.weights = {}
22 | self.net = {}
23 |
24 | self.build_model()
25 | self.init_opt()
26 | self.init_model()
27 |
28 | def build_model(self):
29 | net = {}
30 |
31 | # Caffe order is BGR, this model is RGB.
32 | # The mean values are from caffe protofile from DeepScale/SqueezeNet github repo.
33 | self.mean = tf.constant([123.0, 117.0, 104.0],
34 | dtype=tf.float32, shape=[1, 1, 1, 3], name='img_mean')
35 | images = self.imgs-self.mean
36 |
37 | net['input'] = images
38 |
39 | # conv1_1
40 | net['conv1'] = self.conv_layer('conv1', net['input'],
41 | W=self.weight_variable([3, 3, 3, 64], name='conv1_w'), stride=[1, 2, 2, 1])
42 |
43 | net['relu1'] = self.relu_layer('relu1', net['conv1'], b=self.bias_variable([64], 'relu1_b'))
44 | net['pool1'] = self.pool_layer('pool1', net['relu1'])
45 |
46 | net['fire2'] = self.fire_module('fire2', net['pool1'], self.sq_ratio * 16, 64, 64)
47 | net['fire3'] = self.fire_module('fire3', net['fire2'], self.sq_ratio * 16, 64, 64, True)
48 | net['pool3'] = self.pool_layer('pool3', net['fire3'])
49 |
50 | net['fire4'] = self.fire_module('fire4', net['pool3'], self.sq_ratio * 32, 128, 128)
51 | net['fire5'] = self.fire_module('fire5', net['fire4'], self.sq_ratio * 32, 128, 128, True)
52 | net['pool5'] = self.pool_layer('pool5', net['fire5'])
53 |
54 | net['fire6'] = self.fire_module('fire6', net['pool5'], self.sq_ratio * 48, 192, 192)
55 | net['fire7'] = self.fire_module('fire7', net['fire6'], self.sq_ratio * 48, 192, 192, True)
56 | net['fire8'] = self.fire_module('fire8', net['fire7'], self.sq_ratio * 64, 256, 256)
57 | net['fire9'] = self.fire_module('fire9', net['fire8'], self.sq_ratio * 64, 256, 256, True)
58 |
59 | # 50% dropout
60 | net['dropout9'] = tf.nn.dropout(net['fire9'], self.dropout)
61 | net['conv10'] = self.conv_layer('conv10', net['dropout9'],
62 | W=self.weight_variable([1, 1, 512, 1000], name='conv10', init='normal'))
63 | net['relu10'] = self.relu_layer('relu10', net['conv10'], b=self.bias_variable([1000], 'relu10_b'))
64 | net['pool10'] = self.pool_layer('pool10', net['relu10'], pooling_type='avg')
65 |
66 | avg_pool_shape = tf.shape(net['pool10'])
67 | net['pool_reshaped'] = tf.reshape(net['pool10'], [avg_pool_shape[0],-1])
68 | self.fc2 = net['pool_reshaped']
69 | self.logits = net['pool_reshaped']
70 |
71 | self.probs = tf.nn.softmax(self.logits)
72 | self.net = net
73 |
74 | def init_opt(self):
75 | self.cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=self.logits, labels=self.target))
76 | self.optimize = self.optimizer(self.alpha).minimize(self.cost)
77 |
78 | def init_model(self):
79 | init_op = tf.global_variables_initializer()
80 | self.session.run(init_op)
81 |
82 | def bias_variable(self, shape, name, value=0.1):
83 | initial = tf.constant(value, shape=shape)
84 | self.weights[name] = tf.Variable(initial)
85 | return self.weights[name]
86 |
87 | def weight_variable(self, shape, name=None, init='xavier'):
88 | if init == 'variance':
89 | initial = tf.get_variable('W' + name, shape, initializer=tf.contrib.layers.variance_scaling_initializer())
90 | elif init == 'xavier':
91 | initial = tf.get_variable('W' + name, shape, initializer=tf.contrib.layers.xavier_initializer())
92 | else:
93 | initial = tf.Variable(tf.random_normal(shape, stddev=0.01), name='W'+name)
94 |
95 | self.weights[name] = initial
96 | return self.weights[name]
97 |
98 | def relu_layer(self, layer_name, layer_input, b=None):
99 | if b:
100 | layer_input += b
101 | relu = tf.nn.relu(layer_input)
102 | return relu
103 |
104 | def pool_layer(self, layer_name, layer_input, pooling_type='max'):
105 | if pooling_type == 'avg':
106 | pool = tf.nn.avg_pool(layer_input, ksize=[1, 13, 13, 1],
107 | strides=[1, 1, 1, 1], padding='VALID')
108 | elif pooling_type == 'max':
109 | pool = tf.nn.max_pool(layer_input, ksize=[1, 3, 3, 1],
110 | strides=[1, 2, 2, 1], padding='VALID')
111 | return pool
112 |
113 | def conv_layer(self, layer_name, layer_input, W, stride=[1, 1, 1, 1]):
114 | return tf.nn.conv2d(layer_input, W, strides=stride, padding='SAME')
115 |
116 | def fire_module(self, layer_name, layer_input, s1x1, e1x1, e3x3, residual=False):
117 | """ Fire module consists of squeeze and expand convolutional layers. """
118 | fire = {}
119 |
120 | shape = layer_input.get_shape()
121 |
122 | # squeeze
123 | s1_weight = self.weight_variable([1, 1, int(shape[3]), s1x1], layer_name + '_s1')
124 |
125 | # expand
126 | e1_weight = self.weight_variable([1, 1, s1x1, e1x1], layer_name + '_e1')
127 | e3_weight = self.weight_variable([3, 3, s1x1, e3x3], layer_name + '_e3')
128 |
129 | fire['s1'] = self.conv_layer(layer_name + '_s1', layer_input, W=s1_weight)
130 | fire['relu1'] = self.relu_layer(layer_name + '_relu1', fire['s1'],
131 | b=self.bias_variable([s1x1], layer_name + '_fire_bias_s1'))
132 |
133 | fire['e1'] = self.conv_layer(layer_name + '_e1', fire['relu1'], W=e1_weight)
134 | fire['e3'] = self.conv_layer(layer_name + '_e3', fire['relu1'], W=e3_weight)
135 | fire['concat'] = tf.concat([tf.add(fire['e1'], self.bias_variable([e1x1],
136 | name=layer_name + '_fire_bias_e1' )),
137 | tf.add(fire['e3'], self.bias_variable([e3x3],
138 | name=layer_name + '_fire_bias_e3' ))], 3)
139 |
140 | if residual:
141 | fire['relu2'] = self.relu_layer(layer_name + 'relu2_res', tf.add(fire['concat'],layer_input))
142 | else:
143 | fire['relu2'] = self.relu_layer(layer_name + '_relu2', fire['concat'])
144 |
145 | return fire['relu2']
146 |
147 | def save_model(self, path):
148 | """
149 | Save the neural network model.
150 | :param path: path where will be stored
151 | :return: path if success
152 | """
153 | saver = tf.train.Saver(self.weights)
154 | save_path = saver.save(self.session, path)
155 | return save_path
156 |
157 | def load_model(self, path):
158 | """
159 | Load neural network model from path.
160 | :param path: path where is network located.
161 | :return: None
162 | """
163 | saver = tf.train.Saver(self.weights)
164 | saver.restore(self.session, path)
165 |
166 | if __name__ == '__main__':
167 | sess = tf.Session()
168 | alpha= tf.placeholder(tf.float32)
169 | net = SqueezeNet(sess, alpha)
170 |
171 | img1 = cv2.imread('./images/architecture.png')#, mode='RGB')
172 | img1 = cv2.cvtColor(img1,cv2.COLOR_BGR2RGB)
173 | img1 = cv2.resize(img1, (224, 224))
174 | prob = sess.run(net.probs, feed_dict={net.net['input']: [img1], net.dropout:1.0})
175 | print(prob)
176 | net.save_model('./test.ckpt')
177 | net.load_model('./test.ckpt')
178 |
--------------------------------------------------------------------------------