參考keras.applications.ReNet50
#! -*- coding: utf-8 -*-
from tensorflow.contrib import layers
import tensorflow as tf
class ResNet50:
def __init__(self, inputs, num_classes, training, momentum=0.99):
self.inputs = inputs
self.num_classes = num_classes
self.training = training
self.momentum = momentum
def build(self):
x = tf.layers.conv2d(self.inputs, 64, 7, 2, "SAME", kernel_initializer=layers.xavier_initializer_conv2d(), name="conv1")
x = tf.layers.batch_normalization(x, momentum=self.momentum, training=self.training, name="bn_conv1")
x = tf.nn.relu(x, "relu")
x = tf.layers.max_pooling2d(x, 3, 2, "SAME", name="pool1")
print(x.shape)
x = self.conv_block(x, [64, 64, 256], 3, 2, 2, "a")
x = self.identity_block(x, [64, 64, 256], 3, 2, "b")
x = self.identity_block(x, [64, 64, 256], 3, 2, "c")
print(x.shape)
x = self.conv_block(x, [128, 128, 512], 3, 2, 3, "a")
x = self.identity_block(x, [128, 128, 512], 3, 3, "b")
x = self.identity_block(x, [128, 128, 512], 3, 3, "c")
x = self.identity_block(x, [128, 128, 512], 3, 3, "d")
print(x.shape)
x = self.conv_block(x, [256, 256, 1024], 3, 2, 4, "a")
x = self.identity_block(x, [256, 256, 1024], 3, 4, "b")
x = self.identity_block(x, [256, 256, 1024], 3, 4, "c")
x = self.identity_block(x, [256, 256, 1024], 3, 4, "d")
x = self.identity_block(x, [256, 256, 1024], 3, 4, "e")
x = self.identity_block(x, [256, 256, 1024], 3, 4, "f")
print(x.shape)
x = self.conv_block(x, [512, 512, 2048], 3, 2, 5, "a")
x = self.identity_block(x, [512, 512, 2048], 3, 5, "b")
x = self.identity_block(x, [512, 512, 2048], 3, 5, "c")
print(x.shape)
pool_size = x.get_shape().as_list()[1]
x = tf.layers.average_pooling2d(x, pool_size, 1, name="avg_pool")
print(x.shape)
x = tf.layers.flatten(x, "flatten")
print(x.shape)
x = tf.layers.dense(x, self.num_classes, name="outputs")
print(x.shape)
return x
def conv_block(self, inputs, filters, k, s, stage, block):
filter1, filter2, filter3 = filters
base_name = str(stage) + block + "_branch"
conv_name_base = "res" + base_name
bn_name_base = "bn" + base_name
relu_name_base = "relu" + base_name
x = tf.layers.conv2d(inputs, filter1, 1, s, "VALID", kernel_initializer=layers.xavier_initializer_conv2d(), name=conv_name_base + "2a")
x = tf.layers.batch_normalization(x, momentum=self.momentum, training=self.training, name=bn_name_base + "2a")
x = tf.nn.relu(x, relu_name_base + "2a")
x = tf.layers.conv2d(x, filter2, k, 1, "SAME", kernel_initializer=layers.xavier_initializer_conv2d(), name=conv_name_base + "2b")
x = tf.layers.batch_normalization(x, momentum=self.momentum, training=self.training, name=bn_name_base + "2b")
x = tf.nn.relu(x, relu_name_base + "2b")
x = tf.layers.conv2d(x, filter3, 1, 1, "VALID", kernel_initializer=layers.xavier_initializer_conv2d(), name=conv_name_base + "2c")
x = tf.layers.batch_normalization(x, momentum=self.momentum, training=self.training, name=bn_name_base + "2c")
shorcut = tf.layers.conv2d(inputs, filter3, 1, s, "VALID", kernel_initializer=layers.xavier_initializer_conv2d(), name=conv_name_base + "1")
shorcut = tf.layers.batch_normalization(shorcut, momentum=self.momentum, training=self.training, name=bn_name_base + "1")
x = tf.add(x, shorcut, name="fusion" + base_name)
x = tf.nn.relu(x, relu_name_base + "fusion")
return x
def identity_block(self, inputs, filters, k, stage, block):
filter1, filter2, filter3 = filters
base_name = str(stage) + block + "_branch"
conv_name_base = "res" + base_name
bn_name_base = "bn" + base_name
relu_name_base = "relu" + base_name
x = tf.layers.conv2d(inputs, filter1, 1, 1, "VALID", kernel_initializer=layers.xavier_initializer_conv2d(),
name=conv_name_base + "2a")
x = tf.layers.batch_normalization(x, momentum=self.momentum, training=self.training, name=bn_name_base + "2a")
x = tf.nn.relu(x, relu_name_base + "2a")
x = tf.layers.conv2d(x, filter2, k, 1, "SAME", kernel_initializer=layers.xavier_initializer_conv2d(),
name=conv_name_base + "2b")
x = tf.layers.batch_normalization(x, momentum=self.momentum, training=self.training, name=bn_name_base + "2b")
x = tf.nn.relu(x, relu_name_base + "2b")
x = tf.layers.conv2d(x, filter3, 1, 1, "VALID", kernel_initializer=layers.xavier_initializer_conv2d(),
name=conv_name_base + "2c")
x = tf.layers.batch_normalization(x, momentum=self.momentum, training=self.training, name=bn_name_base + "2c")
x = tf.add(x, inputs, name="fusion" + base_name)
x = tf.nn.relu(x, relu_name_base + "fusion")
return x