class IdentityBlock: def __init__(self, mi, fm_sizes, activation=tf.nn.relu): # conv1, conv2, conv3 # note: # feature maps shortcut = # feauture maps conv 3 assert (len(fm_sizes) == 3) # note: kernel size in 2nd conv is always 3 # so we won't bother including it as an arg self.session = None self.f = tf.nn.relu # init main branch # Conv -> BN -> F() ---> Conv -> BN -> F() ---> Conv -> BN self.conv1 = ConvLayer(1, mi, fm_sizes[0], 1) self.bn1 = BatchNormLayer(fm_sizes[0]) self.conv2 = ConvLayer(3, fm_sizes[0], fm_sizes[1], 1, 'SAME') self.bn2 = BatchNormLayer(fm_sizes[1]) self.conv3 = ConvLayer(1, fm_sizes[1], fm_sizes[2], 1) self.bn3 = BatchNormLayer(fm_sizes[2]) # in case needed later self.layers = [ self.conv1, self.bn1, self.conv2, self.bn2, self.conv3, self.bn3, ] # this will not be used when input passed in from # a previous layer self.input_ = tf.placeholder(tf.float32, shape=(1, 224, 224, mi)) self.output = self.forward(self.input_) def forward(self, X): # main branch FX = self.conv1.forward(X) FX = self.bn1.forward(FX) FX = self.f(FX) FX = self.conv2.forward(FX) FX = self.bn2.forward(FX) FX = self.f(FX) FX = self.conv3.forward(FX) FX = self.bn3.forward(FX) return self.f(FX + X) def predict(self, X): assert (self.session is not None) return self.session.run(self.output, feed_dict={self.input_: X}) def set_session(self, session): # need to make this a session # so assignment happens on sublayers too self.session = session self.conv1.session = session self.bn1.session = session self.conv2.session = session self.bn2.session = session self.conv3.session = session self.bn3.session = session def copyFromKerasLayers(self, layers): assert (len(layers) == 10) # <keras.layers.convolutional.Conv2D at 0x7fa44255ff28>, # <keras.layers.normalization.BatchNormalization at 0x7fa44250e7b8>, # <keras.layers.core.Activation at 0x7fa44252d9e8>, # <keras.layers.convolutional.Conv2D at 0x7fa44253af60>, # <keras.layers.normalization.BatchNormalization at 0x7fa4424e4f60>, # <keras.layers.core.Activation at 0x7fa442494828>, # <keras.layers.convolutional.Conv2D at 0x7fa4424a2da0>, # <keras.layers.normalization.BatchNormalization at 0x7fa44244eda0>, # <keras.layers.merge.Add at 0x7fa44245d5c0>, # <keras.layers.core.Activation at 0x7fa44240aba8> self.conv1.copyFromKerasLayers(layers[0]) self.bn1.copyFromKerasLayers(layers[1]) self.conv2.copyFromKerasLayers(layers[3]) self.bn2.copyFromKerasLayers(layers[4]) self.conv3.copyFromKerasLayers(layers[6]) self.bn3.copyFromKerasLayers(layers[7]) def get_params(self): params = [] for layer in self.layers: params += layer.get_params() return params
class IdentityBlock(keras.layers.Layer): def __init__(self, mi, fm_sizes, activation=tf.compat.v1.nn.relu): super(IdentityBlock, self).__init__() # conv1, conv2, conv3 # note: # feature maps shortcut = # feauture maps conv 3 assert (len(fm_sizes) == 3) # note: kernel size in 2nd conv is always 3 # so we won't bother including it as an arg self.session = None self.f = tf.compat.v1.nn.relu # init main branch # Conv -> BN -> F() ---> Conv -> BN -> F() ---> Conv -> BN self.conv1 = ConvLayer(1, mi, fm_sizes[0], 1) self.bn1 = BatchNormLayer(fm_sizes[0]) self.conv2 = ConvLayer(3, fm_sizes[0], fm_sizes[1], 1) self.bn2 = BatchNormLayer(fm_sizes[1]) self.conv3 = ConvLayer(1, fm_sizes[1], fm_sizes[2], 1) self.bn3 = BatchNormLayer(fm_sizes[2]) # in case needed later self.layers = [ self.conv1, self.bn1, self.conv2, self.bn2, self.conv3, self.bn3, ] def call(self, X): FX = self.conv1(X) FX = self.bn1(FX) FX = self.f(FX) FX = self.conv2(FX) FX = self.bn2(FX) FX = self.f(FX) FX = self.conv3(FX) FX = self.bn3(FX) # sum + activation Y = self.f(tf.math.add(FX, X)) return Y def copyFromKerasLayers(self, layers): #assert(len(layers) == 10) # <keras.layers.convolutional.Conv2D at 0x7fa44255ff28>, # <keras.layers.normalization.BatchNormalization at 0x7fa44250e7b8>, # <keras.layers.core.Activation at 0x7fa44252d9e8>, # <keras.layers.convolutional.Conv2D at 0x7fa44253af60>, # <keras.layers.normalization.BatchNormalization at 0x7fa4424e4f60>, # <keras.layers.core.Activation at 0x7fa442494828>, # <keras.layers.convolutional.Conv2D at 0x7fa4424a2da0>, # <keras.layers.normalization.BatchNormalization at 0x7fa44244eda0>, # <keras.layers.merge.Add at 0x7fa44245d5c0>, # <keras.layers.core.Activation at 0x7fa44240aba8> self.conv1.copyFromKerasLayers(layers[0]) self.bn1.copyFromKerasLayers(layers[1]) self.conv2.copyFromKerasLayers(layers[3]) self.bn2.copyFromKerasLayers(layers[4]) self.conv3.copyFromKerasLayers(layers[6]) self.bn3.copyFromKerasLayers(layers[7]) def get_params(self): params = [] for layer in self.layers: params += layer.get_params() return params
class IdentityBlock: def __init__(self, mi, fm_sizes, activation=tf.nn.relu): assert (len(fm_sizes) == 3) self.session = None self.f = tf.nn.relu self.conv1 = ConvLayer(1, mi, fm_sizes[0], 1) self.bn1 = BatchNormLayer(fm_sizes[0]) self.conv2 = ConvLayer(3, fm_sizes[0], fm_sizes[1], 1, 'SAME') self.bn2 = BatchNormLayer(fm_sizes[1]) self.conv3 = ConvLayer(1, fm_sizes[1], fm_sizes[2], 1) self.bn3 = BatchNormLayer(fm_sizes[2]) self.layers = [ self.conv1, self.bn1, self.conv2, self.bn2, self.conv3, self.bn3, ] self.input_ = tf.placeholder(tf.float32, shape=(1, 224, 224, mi)) self.output = self.forward(self.input_) def forward(self, X): # main branch FX = self.conv1.forward(X) FX = self.bn1.forward(FX) FX = self.f(FX) FX = self.conv2.forward(FX) FX = self.bn2.forward(FX) FX = self.f(FX) FX = self.conv3.forward(FX) FX = self.bn3.forward(FX) return self.f(FX + X) def predict(self, X): assert (self.session is not None) return self.session.run(self.output, feed_dict={self.input_: X}) def set_session(self, session): self.session = session self.conv1.session = session self.bn1.session = session self.conv2.session = session self.bn2.session = session self.conv3.session = session self.bn3.session = session def copyFromKerasLayers(self, layers): assert (len(layers) == 10) self.conv1.copyFromKerasLayers(layers[0]) self.bn1.copyFromKerasLayers(layers[1]) self.conv2.copyFromKerasLayers(layers[3]) self.bn2.copyFromKerasLayers(layers[4]) self.conv3.copyFromKerasLayers(layers[6]) self.bn3.copyFromKerasLayers(layers[7]) def get_params(self): params = [] for layer in self.layers: params += layer.get_params() return params
class IdentityBlock: def __init__(self, c_in, fm_sizes, activation=tf.nn.relu): # and IdentityBlock consists of 3 ConvLayers: # conv1, conv2, conv3 assert(len(fm_sizes) == 3) self.session = None self.activation = activation # note: stride is always 1 # init main branch: # Conv -> BN -> activation ---> Conv -> BN -> activation ---> Conv -> BN self.conv1 = ConvLayer((1, 1), c_in, fm_sizes[0], stride=1) self.bn1 = BatchNormLayer(fm_sizes[0]) self.conv2 = ConvLayer((3, 3), fm_sizes[0], fm_sizes[1], stride=1, padding='SAME') self.bn2 = BatchNormLayer(fm_sizes[1]) self.conv3 = ConvLayer((1, 1), fm_sizes[1], fm_sizes[2], stride=1) self.bn3 = BatchNormLayer(fm_sizes[2]) # for later use: self.layers = [ self.conv1, self.bn1, self.conv2, self.bn2, self.conv3, self.bn3, ] # next lines won't be used when using whole ResNet: self.input_ = tf.placeholder(tf.float32, shape=(1, 224, 224, c_in)) self.output = self.forward(self.input_) def forward(self, X): # main branch: fX = self.conv1.forward(X) fX = self.bn1.forward(fX) fX = self.activation(fX) fX = self.conv2.forward(fX) fX = self.bn2.forward(fX) fX = self.activation(fX) fX = self.conv3.forward(fX) fX = self.bn3.forward(fX) # shortcut is just input data X return self.activation(fX + X) def predict(self, X): # we need to run the prediction in a session: assert(self.session is not None) return self.session.run( self.output, feed_dict={self.input_: X} ) def set_session(self, session): # we need to set a session on every layer/sub-layer: self.session = session self.conv1.session = session self.bn1.session = session self.conv2.session = session self.bn2.session = session self.conv3.session = session self.bn3.session = session def copyFromKerasLayers(self, layers): assert(len(layers) == 10) # <keras.layers.convolutional.Conv2D at 0x7fa44255ff28>, # <keras.layers.normalization.BatchNormalization at 0x7fa44250e7b8>, # <keras.layers.core.Activation at 0x7fa44252d9e8>, # <keras.layers.convolutional.Conv2D at 0x7fa44253af60>, # <keras.layers.normalization.BatchNormalization at 0x7fa4424e4f60>, # <keras.layers.core.Activation at 0x7fa442494828>, # <keras.layers.convolutional.Conv2D at 0x7fa4424a2da0>, # <keras.layers.normalization.BatchNormalization at 0x7fa44244eda0>, # <keras.layers.merge.Add at 0x7fa44245d5c0>, # <keras.layers.core.Activation at 0x7fa44240aba8> self.conv1.copyFromKerasLayers(layers[0]) self.bn1.copyFromKerasLayers(layers[1]) self.conv2.copyFromKerasLayers(layers[3]) self.bn2.copyFromKerasLayers(layers[4]) self.conv3.copyFromKerasLayers(layers[6]) self.bn3.copyFromKerasLayers(layers[7]) def get_params(self): params = [] for layer in self.layers: params += layer.get_params() return params
class IdentityBlock: def __init__(self, mi, fm_sizes, activation=tf.nn.relu): # conv1, conv2, conv3 # note: # feature maps shortcut = # feauture maps conv 3 assert(len(fm_sizes) == 3) # note: kernel size in 2nd conv is always 3 # so we won't bother including it as an arg self.session = None self.f = tf.nn.relu # init main branch # Conv -> BN -> F() ---> Conv -> BN -> F() ---> Conv -> BN self.conv1 = ConvLayer(1, mi, fm_sizes[0], 1) self.bn1 = BatchNormLayer(fm_sizes[0]) self.conv2 = ConvLayer(3, fm_sizes[0], fm_sizes[1], 1, 'SAME') self.bn2 = BatchNormLayer(fm_sizes[1]) self.conv3 = ConvLayer(1, fm_sizes[1], fm_sizes[2], 1) self.bn3 = BatchNormLayer(fm_sizes[2]) # in case needed later self.layers = [ self.conv1, self.bn1, self.conv2, self.bn2, self.conv3, self.bn3, ] # this will not be used when input passed in from # a previous layer self.input_ = tf.placeholder(tf.float32, shape=(1, 224, 224, mi)) self.output = self.forward(self.input_) def forward(self, X): # main branch FX = self.conv1.forward(X) FX = self.bn1.forward(FX) FX = self.f(FX) FX = self.conv2.forward(FX) FX = self.bn2.forward(FX) FX = self.f(FX) FX = self.conv3.forward(FX) FX = self.bn3.forward(FX) return self.f(FX + X) def predict(self, X): assert(self.session is not None) return self.session.run( self.output, feed_dict={self.input_: X} ) def set_session(self, session): # need to make this a session # so assignment happens on sublayers too self.session = session self.conv1.session = session self.bn1.session = session self.conv2.session = session self.bn2.session = session self.conv3.session = session self.bn3.session = session def copyFromKerasLayers(self, layers): assert(len(layers) == 10) # <keras.layers.convolutional.Conv2D at 0x7fa44255ff28>, # <keras.layers.normalization.BatchNormalization at 0x7fa44250e7b8>, # <keras.layers.core.Activation at 0x7fa44252d9e8>, # <keras.layers.convolutional.Conv2D at 0x7fa44253af60>, # <keras.layers.normalization.BatchNormalization at 0x7fa4424e4f60>, # <keras.layers.core.Activation at 0x7fa442494828>, # <keras.layers.convolutional.Conv2D at 0x7fa4424a2da0>, # <keras.layers.normalization.BatchNormalization at 0x7fa44244eda0>, # <keras.layers.merge.Add at 0x7fa44245d5c0>, # <keras.layers.core.Activation at 0x7fa44240aba8> self.conv1.copyFromKerasLayers(layers[0]) self.bn1.copyFromKerasLayers(layers[1]) self.conv2.copyFromKerasLayers(layers[3]) self.bn2.copyFromKerasLayers(layers[4]) self.conv3.copyFromKerasLayers(layers[6]) self.bn3.copyFromKerasLayers(layers[7]) def get_params(self): params = [] for layer in self.layers: params += layer.get_params() return params