1+ import inspect
2+ import os
3+
4+ import numpy as np
5+ import tensorflow as tf
6+ import time
7+
8+ VGG_MEAN = [103.939 , 116.779 , 123.68 ]
9+
10+
11+ class Vgg16 :
12+ def __init__ (self , vgg16_npy_path = None ):
13+ if vgg16_npy_path is None :
14+ path = inspect .getfile (Vgg16 )
15+ path = os .path .abspath (os .path .join (path , os .pardir ))
16+ path = os .path .join (path , "vgg16.npy" )
17+ vgg16_npy_path = path
18+ print (path )
19+
20+ self .data_dict = np .load (vgg16_npy_path , encoding = 'latin1' ).item ()
21+ print ("npy file loaded" )
22+
23+ def build (self , rgb ):
24+ """
25+ load variable from npy to build the VGG
26+ :param rgb: rgb image [batch, height, width, 3] values scaled [0, 1]
27+ """
28+
29+ start_time = time .time ()
30+ print ("build model started" )
31+ rgb_scaled = rgb * 255.0
32+
33+ # Convert RGB to BGR
34+ red , green , blue = tf .split (axis = 3 , num_or_size_splits = 3 , value = rgb_scaled )
35+ assert red .get_shape ().as_list ()[1 :] == [224 , 224 , 1 ]
36+ assert green .get_shape ().as_list ()[1 :] == [224 , 224 , 1 ]
37+ assert blue .get_shape ().as_list ()[1 :] == [224 , 224 , 1 ]
38+ bgr = tf .concat (axis = 3 , values = [
39+ blue - VGG_MEAN [0 ],
40+ green - VGG_MEAN [1 ],
41+ red - VGG_MEAN [2 ],
42+ ])
43+ assert bgr .get_shape ().as_list ()[1 :] == [224 , 224 , 3 ]
44+
45+ self .conv1_1 = self .conv_layer (bgr , "conv1_1" )
46+ self .conv1_2 = self .conv_layer (self .conv1_1 , "conv1_2" )
47+ self .pool1 = self .max_pool (self .conv1_2 , 'pool1' )
48+
49+ self .conv2_1 = self .conv_layer (self .pool1 , "conv2_1" )
50+ self .conv2_2 = self .conv_layer (self .conv2_1 , "conv2_2" )
51+ self .pool2 = self .max_pool (self .conv2_2 , 'pool2' )
52+
53+ self .conv3_1 = self .conv_layer (self .pool2 , "conv3_1" )
54+ self .conv3_2 = self .conv_layer (self .conv3_1 , "conv3_2" )
55+ self .conv3_3 = self .conv_layer (self .conv3_2 , "conv3_3" )
56+ self .pool3 = self .max_pool (self .conv3_3 , 'pool3' )
57+
58+ self .conv4_1 = self .conv_layer (self .pool3 , "conv4_1" )
59+ self .conv4_2 = self .conv_layer (self .conv4_1 , "conv4_2" )
60+ self .conv4_3 = self .conv_layer (self .conv4_2 , "conv4_3" )
61+ self .pool4 = self .max_pool (self .conv4_3 , 'pool4' )
62+
63+ self .conv5_1 = self .conv_layer (self .pool4 , "conv5_1" )
64+ self .conv5_2 = self .conv_layer (self .conv5_1 , "conv5_2" )
65+ self .conv5_3 = self .conv_layer (self .conv5_2 , "conv5_3" )
66+ self .pool5 = self .max_pool (self .conv5_3 , 'pool5' )
67+
68+ self .fc6 = self .fc_layer (self .pool5 , "fc6" )
69+ assert self .fc6 .get_shape ().as_list ()[1 :] == [4096 ]
70+ self .relu6 = tf .nn .relu (self .fc6 )
71+
72+ self .fc7 = self .fc_layer (self .relu6 , "fc7" )
73+ self .relu7 = tf .nn .relu (self .fc7 )
74+
75+ self .fc8 = self .fc_layer (self .relu7 , "fc8" )
76+
77+ self .prob = tf .nn .softmax (self .fc8 , name = "prob" )
78+
79+ self .data_dict = None
80+ print (("build model finished: %ds" % (time .time () - start_time )))
81+
82+ def avg_pool (self , bottom , name ):
83+ return tf .nn .avg_pool (bottom , ksize = [1 , 2 , 2 , 1 ], strides = [1 , 2 , 2 , 1 ], padding = 'SAME' , name = name )
84+
85+ def max_pool (self , bottom , name ):
86+ return tf .nn .max_pool (bottom , ksize = [1 , 2 , 2 , 1 ], strides = [1 , 2 , 2 , 1 ], padding = 'SAME' , name = name )
87+
88+ def conv_layer (self , bottom , name ):
89+ with tf .variable_scope (name ):
90+ filt = self .get_conv_filter (name )
91+
92+ conv = tf .nn .conv2d (bottom , filt , [1 , 1 , 1 , 1 ], padding = 'SAME' )
93+
94+ conv_biases = self .get_bias (name )
95+ bias = tf .nn .bias_add (conv , conv_biases )
96+
97+ relu = tf .nn .relu (bias )
98+ return relu
99+
100+ def fc_layer (self , bottom , name ):
101+ with tf .variable_scope (name ):
102+ shape = bottom .get_shape ().as_list ()
103+ dim = 1
104+ for d in shape [1 :]:
105+ dim *= d
106+ x = tf .reshape (bottom , [- 1 , dim ])
107+
108+ weights = self .get_fc_weight (name )
109+ biases = self .get_bias (name )
110+
111+ # Fully connected layer. Note that the '+' operation automatically
112+ # broadcasts the biases.
113+ fc = tf .nn .bias_add (tf .matmul (x , weights ), biases )
114+
115+ return fc
116+
117+ def get_conv_filter (self , name ):
118+ return tf .constant (self .data_dict [name ][0 ], name = "filter" )
119+
120+ def get_bias (self , name ):
121+ return tf .constant (self .data_dict [name ][1 ], name = "biases" )
122+
123+ def get_fc_weight (self , name ):
124+ return tf .constant (self .data_dict [name ][0 ], name = "weights" )
0 commit comments