-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathcustom_vgg19.py
127 lines (94 loc) · 4.53 KB
/
custom_vgg19.py
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
122
123
124
125
126
127
import tensorflow as tf
import numpy as np
from functools import reduce
VGG_MEAN = [103.939, 116.779, 123.68]
class Vgg19:
"""
A trainable version VGG19.
"""
def __init__(self, vgg19_npy_path=None, trainable=True):
if vgg19_npy_path is not None:
self.data_dict = np.load(vgg19_npy_path, encoding='latin1').item()
else:
self.data_dict = None
self.var_dict = {}
self.trainable = trainable
def build(self, rgb, train_mode=None):
"""
load variable from npy to build the VGG
:param rgb: rgb image [batch, height, width, 3] values scaled [0, 1]
:param train_mode: a bool tensor, usually a placeholder: if True, dropout will be turned on
"""
rgb_scaled = rgb * 255.0
# Convert RGB to BGR
red, green, blue = tf.split(axis=3, num_or_size_splits=3, value=rgb_scaled)
bgr = tf.concat(axis=3, values=[
blue - VGG_MEAN[0],
green - VGG_MEAN[1],
red - VGG_MEAN[2],
])
self.conv1_1 = self.conv_layer(bgr, 3, 64, "conv1_1")
self.conv1_2 = self.conv_layer(self.conv1_1, 64, 64, "conv1_2")
self.pool1 = self.max_pool(self.conv1_2, 'pool1')
self.conv2_1 = self.conv_layer(self.pool1, 64, 128, "conv2_1")
self.conv2_2 = self.conv_layer(self.conv2_1, 128, 128, "conv2_2")
self.pool2 = self.max_pool(self.conv2_2, 'pool2')
self.conv3_1 = self.conv_layer(self.pool2, 128, 256, "conv3_1")
self.conv3_2 = self.conv_layer(self.conv3_1, 256, 256, "conv3_2")
self.conv3_3 = self.conv_layer(self.conv3_2, 256, 256, "conv3_3")
self.conv3_4 = self.conv_layer(self.conv3_3, 256, 256, "conv3_4")
self.pool3 = self.max_pool(self.conv3_4, 'pool3')
self.conv4_1 = self.conv_layer(self.pool3, 256, 512, "conv4_1")
self.conv4_2 = self.conv_layer(self.conv4_1, 512, 512, "conv4_2")
self.conv4_3 = self.conv_layer(self.conv4_2, 512, 512, "conv4_3")
self.conv4_4 = self.conv_layer(self.conv4_3, 512, 512, "conv4_4")
self.pool4 = self.max_pool(self.conv4_4, 'pool4')
self.conv5_1 = self.conv_layer(self.pool4, 512, 512, "conv5_1")
self.conv5_2 = self.conv_layer(self.conv5_1, 512, 512, "conv5_2")
self.conv5_3 = self.conv_layer(self.conv5_2, 512, 512, "conv5_3")
self.conv5_4 = self.conv_layer(self.conv5_3, 512, 512, "conv5_4")
self.data_dict = None
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, in_channels, out_channels, name):
with tf.variable_scope(name):
filt, conv_biases = self.get_conv_var(3, in_channels, out_channels, name)
conv = tf.nn.conv2d(bottom, filt, [1, 1, 1, 1], padding='SAME')
bias = tf.nn.bias_add(conv, conv_biases)
relu = tf.nn.relu(bias)
return relu
def get_conv_var(self, filter_size, in_channels, out_channels, name):
initial_value = tf.truncated_normal([filter_size, filter_size, in_channels, out_channels], 0.0, 0.001)
filters = self.get_var(initial_value, name, 0, name + "_filters")
initial_value = tf.truncated_normal([out_channels], .0, .001)
biases = self.get_var(initial_value, name, 1, name + "_biases")
return filters, biases
def get_var(self, initial_value, name, idx, var_name):
if self.data_dict is not None and name in self.data_dict:
value = self.data_dict[name][idx]
else:
value = initial_value
if self.trainable:
var = tf.Variable(value, name=var_name)
else:
var = tf.constant(value, dtype=tf.float32, name=var_name)
self.var_dict[(name, idx)] = var
# print var_name, var.get_shape().as_list()
assert var.get_shape() == initial_value.get_shape()
return var
def save_npy(self, sess, npy_path="./vgg19-save.npy"):
assert isinstance(sess, tf.Session)
data_dict = {}
for (name, idx), var in list(self.var_dict.items()):
var_out = sess.run(var)
if name not in data_dict:
data_dict[name] = {}
data_dict[name][idx] = var_out
np.save(npy_path, data_dict)
print(("file saved", npy_path))
return npy_path
def get_var_count(self):
count = 0
for v in list(self.var_dict.values()):
count += reduce(lambda x, y: x * y, v.get_shape().as_list())
return count