Skip to content

Commit 9f1d383

Browse files
authored
add resnet50
1 parent 6011c67 commit 9f1d383

File tree

1 file changed

+143
-0
lines changed

1 file changed

+143
-0
lines changed

Diff for: CNNs/ResNet50.py

+143
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
"""
2+
ResNet50
3+
2017/12/06
4+
"""
5+
6+
import tensorflow as tf
7+
from tensorflow.python.training import moving_averages
8+
9+
fc_initializer = tf.contrib.layers.xavier_initializer
10+
conv2d_initializer = tf.contrib.layers.xavier_initializer_conv2d
11+
12+
# create weight variable
13+
def create_var(name, shape, initializer, trainable=True):
14+
return tf.get_variable(name, shape=shape, dtype=tf.float32,
15+
initializer=initializer, trainable=trainable)
16+
17+
# conv2d layer
18+
def conv2d(x, num_outputs, kernel_size, stride=1, scope="conv2d"):
19+
num_inputs = x.get_shape()[-1]
20+
with tf.variable_scope(scope):
21+
kernel = create_var("kernel", [kernel_size, kernel_size,
22+
num_inputs, num_outputs],
23+
conv2d_initializer())
24+
return tf.nn.conv2d(x, kernel, strides=[1, stride, stride, 1],
25+
padding="SAME")
26+
27+
# fully connected layer
28+
def fc(x, num_outputs, scope="fc"):
29+
num_inputs = x.get_shape()[-1]
30+
with tf.variable_scope(scope):
31+
weight = create_var("weight", [num_inputs, num_outputs],
32+
fc_initializer())
33+
bias = create_var("bias", [num_outputs,],
34+
tf.zeros_initializer())
35+
return tf.nn.xw_plus_b(x, weight, bias)
36+
37+
38+
# batch norm layer
39+
def batch_norm(x, decay=0.999, epsilon=1e-03, is_training=True,
40+
scope="scope"):
41+
x_shape = x.get_shape()
42+
num_inputs = x_shape[-1]
43+
reduce_dims = list(range(len(x_shape) - 1))
44+
with tf.variable_scope(scope):
45+
beta = create_var("beta", [num_inputs,],
46+
initializer=tf.zeros_initializer())
47+
gamma = create_var("gamma", [num_inputs,],
48+
initializer=tf.ones_initializer())
49+
# for inference
50+
moving_mean = create_var("moving_mean", [num_inputs,],
51+
initializer=tf.zeros_initializer(),
52+
trainable=False)
53+
moving_variance = create_var("moving_variance", [num_inputs],
54+
initializer=tf.ones_initializer(),
55+
trainable=False)
56+
if is_training:
57+
mean, variance = tf.nn.moments(x, axes=reduce_dims)
58+
update_move_mean = moving_averages.assign_moving_average(moving_mean,
59+
mean, decay=decay)
60+
update_move_variance = moving_averages.assign_moving_average(moving_variance,
61+
variance, decay=decay)
62+
tf.add_to_collection(tf.GraphKeys.UPDATE_OPS, update_move_mean)
63+
tf.add_to_collection(tf.GraphKeys.UPDATE_OPS, update_move_variance)
64+
else:
65+
mean, variance = moving_mean, moving_variance
66+
return tf.nn.batch_normalization(x, mean, variance, beta, gamma, epsilon)
67+
68+
69+
# avg pool layer
70+
def avg_pool(x, pool_size, scope):
71+
with tf.variable_scope(scope):
72+
return tf.nn.avg_pool(x, [1, pool_size, pool_size, 1],
73+
strides=[1, pool_size, pool_size, 1], padding="VALID")
74+
75+
# max pool layer
76+
def max_pool(x, pool_size, stride, scope):
77+
with tf.variable_scope(scope):
78+
return tf.nn.max_pool(x, [1, pool_size, pool_size, 1],
79+
[1, stride, stride, 1], padding="SAME")
80+
81+
class ResNet50(object):
82+
def __init__(self, inputs, num_classes=1000, is_training=True,
83+
scope="resnet50"):
84+
self.inputs =inputs
85+
self.is_training = is_training
86+
self.num_classes = num_classes
87+
88+
with tf.variable_scope(scope):
89+
# construct the model
90+
net = conv2d(inputs, 64, 7, 2, scope="conv1") # -> [batch, 112, 112, 64]
91+
net = tf.nn.relu(batch_norm(net, is_training=self.is_training, scope="bn1"))
92+
net = max_pool(net, 3, 2, scope="maxpool1") # -> [batch, 56, 56, 64]
93+
net = self._block(net, 256, 3, init_stride=1, is_training=self.is_training,
94+
scope="block2") # -> [batch, 56, 56, 256]
95+
net = self._block(net, 512, 4, is_training=self.is_training, scope="block3")
96+
# -> [batch, 28, 28, 512]
97+
net = self._block(net, 1024, 6, is_training=self.is_training, scope="block4")
98+
# -> [batch, 14, 14, 1024]
99+
net = self._block(net, 2048, 3, is_training=self.is_training, scope="block5")
100+
# -> [batch, 7, 7, 2048]
101+
net = avg_pool(net, 7, scope="avgpool5") # -> [batch, 1, 1, 2048]
102+
net = tf.squeeze(net, [1, 2], name="SpatialSqueeze") # -> [batch, 2048]
103+
self.logits = fc(net, self.num_classes, "fc6") # -> [batch, num_classes]
104+
self.predictions = tf.nn.softmax(self.logits)
105+
106+
107+
def _block(self, x, n_out, n, init_stride=2, is_training=True, scope="block"):
108+
with tf.variable_scope(scope):
109+
h_out = n_out // 4
110+
out = self._bottleneck(x, h_out, n_out, stride=init_stride,
111+
is_training=is_training, scope="bottlencek1")
112+
for i in range(1, n):
113+
out = self._bottleneck(out, h_out, n_out, is_training=is_training,
114+
scope=("bottlencek%s" % (i + 1)))
115+
return out
116+
117+
def _bottleneck(self, x, h_out, n_out, stride=None, is_training=True, scope="bottleneck"):
118+
""" A residual bottleneck unit"""
119+
n_in = x.get_shape()[-1]
120+
if stride is None:
121+
stride = 1 if n_in == n_out else 2
122+
123+
with tf.variable_scope(scope):
124+
h = conv2d(x, h_out, 1, stride=stride, scope="conv_1")
125+
h = batch_norm(h, is_training=is_training, scope="bn_1")
126+
h = tf.nn.relu(h)
127+
h = conv2d(h, h_out, 3, stride=1, scope="conv_2")
128+
h = batch_norm(h, is_training=is_training, scope="bn_2")
129+
h = tf.nn.relu(h)
130+
h = conv2d(h, n_out, 1, stride=1, scope="conv_3")
131+
h = batch_norm(h, is_training=is_training, scope="bn_3")
132+
133+
if n_in != n_out:
134+
shortcut = conv2d(x, n_out, 1, stride=stride, scope="conv_4")
135+
shortcut = batch_norm(shortcut, is_training=is_training, scope="bn_4")
136+
else:
137+
shortcut = x
138+
return tf.nn.relu(shortcut + h)
139+
140+
if __name__ == "__main__":
141+
x = tf.random_normal([32, 224, 224, 3])
142+
resnet50 = ResNet50(x)
143+
print(resnet50.logits)

0 commit comments

Comments
 (0)