00001 import chainer 00002 import chainer.functions as F 00003 from chainer import initializers 00004 import chainer.links as L 00005 00006 00007 class BottleNeckA(chainer.Chain): 00008 00009 def __init__(self, in_size, ch, out_size, stride=2): 00010 super(BottleNeckA, self).__init__() 00011 initialW = initializers.HeNormal() 00012 self.stride = stride 00013 00014 with self.init_scope(): 00015 self.preact = L.BatchNormalization(in_size) 00016 self.conv1 = L.Convolution2D( 00017 in_size, ch, 1, stride, 0, initialW=initialW, nobias=True) 00018 self.bn1 = L.BatchNormalization(ch) 00019 self.conv2 = L.Convolution2D( 00020 ch, ch, 3, stride, 1, initialW=initialW, nobias=True) 00021 self.bn2 = L.BatchNormalization(ch) 00022 self.conv3 = L.Convolution2D( 00023 ch, out_size, 1, 1, 0, initialW=initialW, nobias=False) 00024 self.conv4 = L.Convolution2D( 00025 in_size, out_size, 1, stride, 0, 00026 initialW=initialW, nobias=False) 00027 00028 def __call__(self, x): 00029 preact = F.relu(self.preact(x)) 00030 shortcut = self.conv4(preact) 00031 h = self.conv1(preact) 00032 h = F.relu(self.bn1(h)) 00033 h = F.relu(self.bn2(self.conv2(h))) 00034 h = self.conv3(h) 00035 return shortcut + h 00036 00037 00038 class BottleNeckB(chainer.Chain): 00039 00040 def __init__(self, in_size, ch, stride=2): 00041 super(BottleNeckB, self).__init__() 00042 initialW = initializers.HeNormal() 00043 self.stride = stride 00044 00045 with self.init_scope(): 00046 self.preact = L.BatchNormalization(in_size) 00047 self.conv1 = L.Convolution2D( 00048 in_size, ch, 1, 1, 0, initialW=initialW, nobias=True) 00049 self.bn1 = L.BatchNormalization(ch) 00050 self.conv2 = L.Convolution2D( 00051 ch, ch, 3, self.stride, 1, initialW=initialW, nobias=True) 00052 self.bn2 = L.BatchNormalization(ch) 00053 self.conv3 = L.Convolution2D( 00054 ch, in_size, 1, 1, 0, initialW=initialW, nobias=False) 00055 00056 def __call__(self, x): 00057 preact = F.relu(self.preact(x)) 00058 if self.stride == 1: 00059 shortcut = x 00060 else: 00061 shortcut = F.max_pooling_2d( 00062 x, 1, stride=self.stride, cover_all=False) 00063 h = self.conv1(preact) 00064 h = F.relu(self.bn1(h)) 00065 h = F.relu(self.bn2(self.conv2(h))) 00066 h = self.conv3(h) 00067 return shortcut + h 00068 00069 00070 class Block(chainer.ChainList): 00071 00072 def __init__(self, layer, in_size, ch, out_size, stride=2): 00073 super(Block, self).__init__() 00074 self.add_link(BottleNeckA(in_size, ch, out_size, 1)) 00075 for i in range(layer - 2): 00076 self.add_link(BottleNeckB(out_size, ch, stride=1)) 00077 self.add_link(BottleNeckB(out_size, ch, stride=stride)) 00078 00079 def __call__(self, x): 00080 for f in self.children(): 00081 x = f(x) 00082 return x 00083 00084 00085 class ResNet_v2_50(chainer.Chain): 00086 00087 insize = 224 00088 00089 def __init__(self): 00090 super(ResNet_v2_50, self).__init__() 00091 with self.init_scope(): 00092 self.conv1 = L.Convolution2D( 00093 3, 64, 7, 2, 3, initialW=initializers.HeNormal()) 00094 self.res2 = Block(3, 64, 64, 256, stride=2) 00095 self.res3 = Block(4, 256, 128, 512, stride=2) 00096 self.res4 = Block(6, 512, 256, 1024, stride=2) 00097 self.res5 = Block(3, 1024, 512, 2048, stride=1) 00098 self.postnorm = L.BatchNormalization(2048) 00099 00100 def __call__(self, x): 00101 h = self.conv1(x) 00102 h = F.max_pooling_2d(h, 3, stride=2) 00103 h = self.res2(h) 00104 h = self.res3(h) 00105 h = self.res4(h) 00106 h = self.res5(h) 00107 h = self.postnorm(h) 00108 h = F.relu(h) 00109 h = F.average_pooling_2d(h, 7, stride=1) 00110 return h