Permalink
Browse files

move model into sep file. clean up

  • Loading branch information...
1 parent 24b393a commit b4e472890e42550ea5997855e49c5b2ab9738c02 @ry committed Jan 21, 2016
Showing with 130 additions and 141 deletions.
  1. +32 −140 caffe_to_tensorflow.py
  2. +0 −1 utils.py
  3. +98 −0 vgg16.py
View
@@ -7,6 +7,8 @@
import caffe
import numpy as np
import tensorflow as tf
+import vgg16
+
FLAGS = tf.app.flags.FLAGS
@@ -27,19 +29,19 @@ def preprocess(img):
out = np.copy(img) * 255
out = out[:, :, [2,1,0]] # swap channel from RGB to BGR
# sub mean
- out[:,:,0] -= VGG_MEAN[0]
- out[:,:,1] -= VGG_MEAN[1]
- out[:,:,2] -= VGG_MEAN[2]
+ out[:,:,0] -= vgg16.VGG_MEAN[0]
+ out[:,:,1] -= vgg16.VGG_MEAN[1]
+ out[:,:,2] -= vgg16.VGG_MEAN[2]
out = out.transpose((2,0,1)) # h, w, c -> c, h, w
return out
def deprocess(img):
out = np.copy(img)
out = out.transpose((1,2,0)) # c, h, w -> h, w, c
- out[:,:,0] += VGG_MEAN[0]
- out[:,:,1] += VGG_MEAN[1]
- out[:,:,2] += VGG_MEAN[2]
+ out[:,:,0] += vgg16.VGG_MEAN[0]
+ out[:,:,1] += vgg16.VGG_MEAN[1]
+ out[:,:,2] += vgg16.VGG_MEAN[2]
out = out[:, :, [2,1,0]]
out /= 255
return out
@@ -83,121 +85,26 @@ def caffe2tf_1d_blob(name):
blob = net_caffe.blobs[name].data[0]
return blob
-def conv_layer(m, bottom, name):
- with tf.variable_scope(name) as scope:
- w = caffe2tf_filter(name)
- #print name + " w shape", w.shape
- conv_weight = tf.constant(w, dtype=tf.float32, name="filter")
-
- conv = tf.nn.conv2d(bottom, conv_weight, [1, 1, 1, 1], padding='SAME')
-
- conv_biases = tf.constant(caffe_bias(name), dtype=tf.float32, name="biases")
- bias = tf.nn.bias_add(conv, conv_biases)
-
- if name == "conv1_1":
- m["conv1_1_weights"] = conv_weight
- m["conv1_1a"] = bias
-
- relu = tf.nn.relu(bias)
- return relu
-
-def fc_layer(bottom, name):
- shape = bottom.get_shape().as_list()
- dim = 1
- for d in shape[1:]:
- dim *= d
- x = tf.reshape(bottom, [-1, dim])
-
- print name, "caffe weight shape", caffe_weights(name).shape
-
- cw = caffe_weights(name)
- if name == "fc6":
- assert cw.shape == (4096, 25088)
- cw = cw.reshape((4096, 512, 7, 7))
- cw = cw.transpose((2, 3, 1, 0))
- cw = cw.reshape(25088, 4096)
- else:
- cw = cw.transpose((1, 0))
-
- weights = tf.constant(cw, dtype=tf.float32)
- biases = tf.constant(caffe_bias(name), dtype=tf.float32)
-
- # Fully connected layer. Note that the '+' operation automatically
- # broadcasts the biases.
- fc = tf.nn.bias_add(tf.matmul(x, weights), biases)
-
- return fc
-
-# Input should be an rgb image [batch, height, width, 3]
-# values scaled [0, 1]
-def inference(rgb):
- m = {}
-
- rgb_scaled = rgb * 255.0
-
- # Convert RGB to BGR
- red, green, blue = tf.split(3, 3, rgb_scaled)
- assert red.get_shape().as_list()[1:] == [224, 224, 1]
- assert green.get_shape().as_list()[1:] == [224, 224, 1]
- assert blue.get_shape().as_list()[1:] == [224, 224, 1]
- bgr = tf.concat(3, [
- blue - VGG_MEAN[0],
- green - VGG_MEAN[1],
- red - VGG_MEAN[2],
- ])
- assert bgr.get_shape().as_list()[1:] == [224, 224, 3]
-
- relu1_1 = conv_layer(m, bgr, "conv1_1")
- relu1_2 = conv_layer(m, relu1_1, "conv1_2")
- pool1 = tf.nn.max_pool(relu1_2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1],
- padding='SAME', name='pool1')
-
- m["relu1_1"] = relu1_1
+class ModelFromCaffe(vgg16.Model):
+ def get_conv_filter(self, name):
+ w = caffe2tf_filter(name)
+ return tf.constant(w, dtype=tf.float32, name="filter")
- relu2_1 = conv_layer(m, pool1, "conv2_1")
- relu2_2 = conv_layer(m, relu2_1, "conv2_2")
- pool2 = tf.nn.max_pool(relu2_2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1],
- padding='SAME', name='pool2')
+ def get_bias(self, name):
+ b = caffe_bias(name)
+ return tf.constant(b, dtype=tf.float32, name="bias")
- relu3_1 = conv_layer(m, pool2, "conv3_1")
- relu3_2 = conv_layer(m, relu3_1, "conv3_2")
- relu3_3 = conv_layer(m, relu3_2, "conv3_3")
- pool3 = tf.nn.max_pool(relu3_3, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1],
- padding='SAME', name='pool3')
+ def get_fc_weight(self, name):
+ cw = caffe_weights(name)
+ if name == "fc6":
+ assert cw.shape == (4096, 25088)
+ cw = cw.reshape((4096, 512, 7, 7))
+ cw = cw.transpose((2, 3, 1, 0))
+ cw = cw.reshape(25088, 4096)
+ else:
+ cw = cw.transpose((1, 0))
- relu4_1 = conv_layer(m, pool3, "conv4_1")
- relu4_2 = conv_layer(m, relu4_1, "conv4_2")
- relu4_3 = conv_layer(m, relu4_2, "conv4_3")
- pool4 = tf.nn.max_pool(relu4_3, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1],
- padding='SAME', name='pool4')
-
- relu5_1 = conv_layer(m, pool4, "conv5_1")
- relu5_2 = conv_layer(m, relu5_1, "conv5_2")
- relu5_3 = conv_layer(m, relu5_2, "conv5_3")
- pool5 = tf.nn.max_pool(relu5_3, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1],
- padding='SAME', name='pool5')
-
- m['pool5'] = pool5
-
- print "pool5 shape", pool5.get_shape().as_list()
-
- fc6 = fc_layer(pool5, "fc6")
- assert fc6.get_shape().as_list() == [None, 4096]
- m['fc6a'] = fc6
-
- relu6 = tf.nn.relu(fc6)
- drop6 = tf.nn.dropout(relu6, 0.5)
-
- fc7 = fc_layer(drop6, "fc7")
- relu7 = tf.nn.relu(fc7)
- drop7 = tf.nn.dropout(relu7, 0.5)
-
- fc8 = fc_layer(drop7, "fc8")
- prob = tf.nn.softmax(fc8, name="prob")
-
- m["prob"] = prob
-
- return m
+ return tf.constant(cw, dtype=tf.float32)
def show_caffe_net_input():
x = net_caffe.blobs['data'].data[0]
@@ -230,16 +137,12 @@ def main():
top1 = print_prob(prob)
assert top1 == "n02123045 tabby, tabby cat"
- caffe_activations = {
- 'conv1_1_weights': caffe_weights("conv1_1"),
- 'prob': net_caffe.blobs['prob'].data[0],
- }
-
if run_tf:
print "tensorflow session"
images = tf.placeholder("float", [None, 224, 224, 3], name="images")
- m = inference(images)
+ m = ModelFromCaffe()
+ m.build(images)
with tf.Session() as sess:
sess.run(tf.initialize_all_variables())
@@ -249,15 +152,12 @@ def main():
assert batch.shape == (1, 224, 224, 3)
assert (0 <= batch).all() and (batch <= 1.0).all()
- out = sess.run([m['prob'], m['relu1_1'], m['conv1_1_weights'], \
- m['conv1_1a'], m['pool5'], m['fc6a']], feed_dict={ images: batch })
+ out = sess.run([m.prob, m.relu1_1, m.pool5, m.fc6], feed_dict={ images: batch })
tf_activations = {
'prob': out[0][0],
'relu1_1': out[1][0],
- 'conv1_1_weights': out[2],
- 'conv1_1a': out[3][0],
- 'pool5': out[4][0],
- 'fc6a': out[5][0],
+ 'pool5': out[2][0],
+ 'fc6': out[3][0],
}
top1 = print_prob(tf_activations['prob'])
@@ -266,23 +166,15 @@ def main():
# Now we compare tf_activations to net_caffe's if we ran a forward pass
# in both networks.
if ran_both:
- #print "shape tf conv1_1a", tf_activations["conv1_1a"].shape
- #tf_show_layer(tf_activations["conv1_1a"][:, :, 0])
- #tf_show_layer(caffe2tf_conv_blob("conv1_1a")[:, :, 0])
-
- assert same_tensor(caffe2tf_conv_blob("conv1_1a"), tf_activations["conv1_1a"])
-
- assert same_tensor(caffe2tf_filter("conv1_1"), tf_activations['conv1_1_weights'])
-
assert same_tensor(caffe2tf_conv_blob("conv1_1"), tf_activations['relu1_1'])
assert same_tensor(caffe2tf_conv_blob("pool5"), tf_activations['pool5'])
- print "diff fc6a", np.linalg.norm(caffe2tf_1d_blob("fc6a") - tf_activations['fc6a'])
+ print "diff fc6", np.linalg.norm(caffe2tf_1d_blob("fc6a") - tf_activations['fc6'])
assert caffe_weights("fc6").shape == (4096, 25088)
assert caffe_bias("fc6").shape == (4096,)
- assert same_tensor(caffe2tf_1d_blob("fc6a"), tf_activations['fc6a'])
+ assert same_tensor(caffe2tf_1d_blob("fc6a"), tf_activations['fc6'])
assert same_tensor(caffe2tf_1d_blob("prob"), tf_activations['prob'])
View
@@ -4,7 +4,6 @@
import numpy as np
synset = [l.strip() for l in open('synset.txt').readlines()]
-VGG_MEAN = [103.939, 116.779, 123.68]
# returns image of shape [224, 224, 3]
# [height, width, depth]
View
@@ -0,0 +1,98 @@
+import tensorflow as tf
+
+VGG_MEAN = [103.939, 116.779, 123.68]
+
+class Model():
+ def get_conv_filter(self, name):
+ raise NotImplementedError
+
+ def get_bias(self, name):
+ raise NotImplementedError
+
+ def get_fc_weight(self, name):
+ raise NotImplementedError
+
+ def _max_pool(self, bottom, name):
+ return tf.nn.max_pool(bottom, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1],
+ padding='SAME', name=name)
+
+ def _conv_layer(self, bottom, name):
+ with tf.variable_scope(name) as scope:
+ filt = self.get_conv_filter(name)
+ conv = tf.nn.conv2d(bottom, filt, [1, 1, 1, 1], padding='SAME')
+
+ conv_biases = self.get_bias(name)
+ bias = tf.nn.bias_add(conv, conv_biases)
+
+ relu = tf.nn.relu(bias)
+ return relu
+
+ def _fc_layer(self, bottom, name):
+ shape = bottom.get_shape().as_list()
+ dim = 1
+ for d in shape[1:]:
+ dim *= d
+ x = tf.reshape(bottom, [-1, dim])
+
+ weights = self.get_fc_weight(name)
+ biases = self.get_bias(name)
+
+ # Fully connected layer. Note that the '+' operation automatically
+ # broadcasts the biases.
+ fc = tf.nn.bias_add(tf.matmul(x, weights), biases)
+
+ return fc
+
+ # Input should be an rgb image [batch, height, width, 3]
+ # values scaled [0, 1]
+ def build(self, rgb):
+ rgb_scaled = rgb * 255.0
+
+ # Convert RGB to BGR
+ red, green, blue = tf.split(3, 3, rgb_scaled)
+ assert red.get_shape().as_list()[1:] == [224, 224, 1]
+ assert green.get_shape().as_list()[1:] == [224, 224, 1]
+ assert blue.get_shape().as_list()[1:] == [224, 224, 1]
+ bgr = tf.concat(3, [
+ blue - VGG_MEAN[0],
+ green - VGG_MEAN[1],
+ red - VGG_MEAN[2],
+ ])
+ assert bgr.get_shape().as_list()[1:] == [224, 224, 3]
+
+ self.relu1_1 = self._conv_layer(bgr, "conv1_1")
+ self.relu1_2 = self._conv_layer(self.relu1_1, "conv1_2")
+ self.pool1 = self._max_pool(self.relu1_2, 'pool1')
+
+ self.relu2_1 = self._conv_layer(self.pool1, "conv2_1")
+ self.relu2_2 = self._conv_layer(self.relu2_1, "conv2_2")
+ self.pool2 = self._max_pool(self.relu2_2, 'pool2')
+
+ self.relu3_1 = self._conv_layer(self.pool2, "conv3_1")
+ self.relu3_2 = self._conv_layer(self.relu3_1, "conv3_2")
+ self.relu3_3 = self._conv_layer(self.relu3_2, "conv3_3")
+ self.pool3 = self._max_pool(self.relu3_3, 'pool3')
+
+ self.relu4_1 = self._conv_layer(self.pool3, "conv4_1")
+ self.relu4_2 = self._conv_layer(self.relu4_1, "conv4_2")
+ self.relu4_3 = self._conv_layer(self.relu4_2, "conv4_3")
+ self.pool4 = self._max_pool(self.relu4_3, 'pool4')
+
+ self.relu5_1 = self._conv_layer(self.pool4, "conv5_1")
+ self.relu5_2 = self._conv_layer(self.relu5_1, "conv5_2")
+ self.relu5_3 = self._conv_layer(self.relu5_2, "conv5_3")
+ self.pool5 = self._max_pool(self.relu5_3, 'pool5')
+
+ self.fc6 = self._fc_layer(self.pool5, "fc6")
+ assert self.fc6.get_shape().as_list() == [None, 4096]
+
+ self.relu6 = tf.nn.relu(self.fc6)
+ self.drop6 = tf.nn.dropout(self.relu6, 0.5)
+
+ self.fc7 = self._fc_layer(self.drop6, "fc7")
+ self.relu7 = tf.nn.relu(self.fc7)
+ self.drop7 = tf.nn.dropout(self.relu7, 0.5)
+
+ self.fc8 = self._fc_layer(self.drop7, "fc8")
+ self.prob = tf.nn.softmax(self.fc8, name="prob")
+

0 comments on commit b4e4728

Please sign in to comment.