Advertisement
Guest User

Untitled

a guest
Nov 20th, 2017
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.60 KB | None | 0 0
  1. # Copyright 2016 The TensorFlow Authors. All Rights Reserved.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. # ==============================================================================
  15. """Contains the definition of the Inception Resnet V2 architecture.
  16.  
  17. As described in http://arxiv.org/abs/1602.07261.
  18.  
  19. Inception-v4, Inception-ResNet and the Impact of Residual Connections
  20. on Learning
  21. Christian Szegedy, Sergey Ioffe, Vincent Vanhoucke, Alex Alemi
  22. """
  23. from __future__ import absolute_import
  24. from __future__ import division
  25. from __future__ import print_function
  26.  
  27. import tensorflow as tf
  28.  
  29. slim = tf.contrib.slim
  30.  
  31.  
  32. def block35(net, scale=1.0, activation_fn=tf.nn.relu, scope=None, reuse=None):
  33. """Builds the 35x35 resnet block."""
  34. with tf.variable_scope(scope, 'Block35', [net], reuse=reuse):
  35. with tf.variable_scope('Branch_0'):
  36. tower_conv = slim.conv2d(net, 32, 1, scope='Conv2d_1x1')
  37. with tf.variable_scope('Branch_1'):
  38. tower_conv1_0 = slim.conv2d(net, 32, 1, scope='Conv2d_0a_1x1')
  39. tower_conv1_1 = slim.conv2d(tower_conv1_0, 32, 3, scope='Conv2d_0b_3x3')
  40. with tf.variable_scope('Branch_2'):
  41. tower_conv2_0 = slim.conv2d(net, 32, 1, scope='Conv2d_0a_1x1')
  42. tower_conv2_1 = slim.conv2d(tower_conv2_0, 48, 3, scope='Conv2d_0b_3x3')
  43. tower_conv2_2 = slim.conv2d(tower_conv2_1, 64, 3, scope='Conv2d_0c_3x3')
  44. mixed = tf.concat(axis=3, values=[tower_conv, tower_conv1_1, tower_conv2_2])
  45. up = slim.conv2d(mixed, net.get_shape()[3], 1, normalizer_fn=None,
  46. activation_fn=None, scope='Conv2d_1x1')
  47. net += scale * up
  48. if activation_fn:
  49. net = activation_fn(net)
  50. return net
  51.  
  52.  
  53. def block17(net, scale=1.0, activation_fn=tf.nn.relu, scope=None, reuse=None):
  54. """Builds the 17x17 resnet block."""
  55. with tf.variable_scope(scope, 'Block17', [net], reuse=reuse):
  56. with tf.variable_scope('Branch_0'):
  57. tower_conv = slim.conv2d(net, 192, 1, scope='Conv2d_1x1')
  58. with tf.variable_scope('Branch_1'):
  59. tower_conv1_0 = slim.conv2d(net, 128, 1, scope='Conv2d_0a_1x1')
  60. tower_conv1_1 = slim.conv2d(tower_conv1_0, 160, [1, 7],
  61. scope='Conv2d_0b_1x7')
  62. tower_conv1_2 = slim.conv2d(tower_conv1_1, 192, [7, 1],
  63. scope='Conv2d_0c_7x1')
  64. mixed = tf.concat(axis=3, values=[tower_conv, tower_conv1_2])
  65. up = slim.conv2d(mixed, net.get_shape()[3], 1, normalizer_fn=None,
  66. activation_fn=None, scope='Conv2d_1x1')
  67. net += scale * up
  68. if activation_fn:
  69. net = activation_fn(net)
  70. return net
  71.  
  72.  
  73. def block8(net, scale=1.0, activation_fn=tf.nn.relu, scope=None, reuse=None):
  74. """Builds the 8x8 resnet block."""
  75. with tf.variable_scope(scope, 'Block8', [net], reuse=reuse):
  76. with tf.variable_scope('Branch_0'):
  77. tower_conv = slim.conv2d(net, 192, 1, scope='Conv2d_1x1')
  78. with tf.variable_scope('Branch_1'):
  79. tower_conv1_0 = slim.conv2d(net, 192, 1, scope='Conv2d_0a_1x1')
  80. tower_conv1_1 = slim.conv2d(tower_conv1_0, 224, [1, 3],
  81. scope='Conv2d_0b_1x3')
  82. tower_conv1_2 = slim.conv2d(tower_conv1_1, 256, [3, 1],
  83. scope='Conv2d_0c_3x1')
  84. mixed = tf.concat(axis=3, values=[tower_conv, tower_conv1_2])
  85. up = slim.conv2d(mixed, net.get_shape()[3], 1, normalizer_fn=None,
  86. activation_fn=None, scope='Conv2d_1x1')
  87. net += scale * up
  88. if activation_fn:
  89. net = activation_fn(net)
  90. return net
  91.  
  92.  
  93. def inception_resnet_v2_base(inputs,
  94. final_endpoint='Conv2d_7b_1x1',
  95. output_stride=16,
  96. align_feature_maps=False,
  97. scope=None):
  98. """Inception model from http://arxiv.org/abs/1602.07261.
  99.  
  100. Constructs an Inception Resnet v2 network from inputs to the given final
  101. endpoint. This method can construct the network up to the final inception
  102. block Conv2d_7b_1x1.
  103.  
  104. Args:
  105. inputs: a tensor of size [batch_size, height, width, channels].
  106. final_endpoint: specifies the endpoint to construct the network up to. It
  107. can be one of ['Conv2d_1a_3x3', 'Conv2d_2a_3x3', 'Conv2d_2b_3x3',
  108. 'MaxPool_3a_3x3', 'Conv2d_3b_1x1', 'Conv2d_4a_3x3', 'MaxPool_5a_3x3',
  109. 'Mixed_5b', 'Mixed_6a', 'PreAuxLogits', 'Mixed_7a', 'Conv2d_7b_1x1']
  110. output_stride: A scalar that specifies the requested ratio of input to
  111. output spatial resolution. Only supports 8 and 16.
  112. align_feature_maps: When true, changes all the VALID paddings in the network
  113. to SAME padding so that the feature maps are aligned.
  114. scope: Optional variable_scope.
  115.  
  116. Returns:
  117. tensor_out: output tensor corresponding to the final_endpoint.
  118. end_points: a set of activations for external use, for example summaries or
  119. losses.
  120.  
  121. Raises:
  122. ValueError: if final_endpoint is not set to one of the predefined values,
  123. or if the output_stride is not 8 or 16, or if the output_stride is 8 and
  124. we request an end point after 'PreAuxLogits'.
  125. """
  126. if output_stride != 8 and output_stride != 16:
  127. raise ValueError('output_stride must be 8 or 16.')
  128.  
  129. padding = 'SAME' if align_feature_maps else 'VALID'
  130.  
  131. end_points = {}
  132.  
  133. def add_and_check_final(name, net):
  134. end_points[name] = net
  135. return name == final_endpoint
  136.  
  137. with tf.variable_scope(scope, 'InceptionResnetV2', [inputs]):
  138. with slim.arg_scope([slim.conv2d, slim.max_pool2d, slim.avg_pool2d],
  139. stride=1, padding='SAME'):
  140. # 149 x 149 x 32
  141. net = slim.conv2d(inputs, 32, 3, stride=2, padding=padding,
  142. scope='Conv2d_1a_3x3')
  143. if add_and_check_final('Conv2d_1a_3x3', net): return net, end_points
  144.  
  145. # 147 x 147 x 32
  146. net = slim.conv2d(net, 32, 3, padding=padding,
  147. scope='Conv2d_2a_3x3')
  148. if add_and_check_final('Conv2d_2a_3x3', net): return net, end_points
  149. # 147 x 147 x 64
  150. net = slim.conv2d(net, 64, 3, scope='Conv2d_2b_3x3')
  151. if add_and_check_final('Conv2d_2b_3x3', net): return net, end_points
  152. # 73 x 73 x 64
  153. net = slim.max_pool2d(net, 3, stride=2, padding=padding,
  154. scope='MaxPool_3a_3x3')
  155. if add_and_check_final('MaxPool_3a_3x3', net): return net, end_points
  156. # 73 x 73 x 80
  157. net = slim.conv2d(net, 80, 1, padding=padding,
  158. scope='Conv2d_3b_1x1')
  159. if add_and_check_final('Conv2d_3b_1x1', net): return net, end_points
  160. # 71 x 71 x 192
  161. net = slim.conv2d(net, 192, 3, padding=padding,
  162. scope='Conv2d_4a_3x3')
  163. if add_and_check_final('Conv2d_4a_3x3', net): return net, end_points
  164. # 35 x 35 x 192
  165. net = slim.max_pool2d(net, 3, stride=2, padding=padding,
  166. scope='MaxPool_5a_3x3')
  167. if add_and_check_final('MaxPool_5a_3x3', net): return net, end_points
  168.  
  169. # 35 x 35 x 320
  170. with tf.variable_scope('Mixed_5b'):
  171. with tf.variable_scope('Branch_0'):
  172. tower_conv = slim.conv2d(net, 96, 1, scope='Conv2d_1x1')
  173. with tf.variable_scope('Branch_1'):
  174. tower_conv1_0 = slim.conv2d(net, 48, 1, scope='Conv2d_0a_1x1')
  175. tower_conv1_1 = slim.conv2d(tower_conv1_0, 64, 5,
  176. scope='Conv2d_0b_5x5')
  177. with tf.variable_scope('Branch_2'):
  178. tower_conv2_0 = slim.conv2d(net, 64, 1, scope='Conv2d_0a_1x1')
  179. tower_conv2_1 = slim.conv2d(tower_conv2_0, 96, 3,
  180. scope='Conv2d_0b_3x3')
  181. tower_conv2_2 = slim.conv2d(tower_conv2_1, 96, 3,
  182. scope='Conv2d_0c_3x3')
  183. with tf.variable_scope('Branch_3'):
  184. tower_pool = slim.avg_pool2d(net, 3, stride=1, padding='SAME',
  185. scope='AvgPool_0a_3x3')
  186. tower_pool_1 = slim.conv2d(tower_pool, 64, 1,
  187. scope='Conv2d_0b_1x1')
  188. net = tf.concat(
  189. [tower_conv, tower_conv1_1, tower_conv2_2, tower_pool_1], 3)
  190.  
  191. if add_and_check_final('Mixed_5b', net): return net, end_points
  192. # TODO(alemi): Register intermediate endpoints
  193. net = slim.repeat(net, 10, block35, scale=0.17)
  194.  
  195. # 17 x 17 x 1088 if output_stride == 8,
  196. # 33 x 33 x 1088 if output_stride == 16
  197. use_atrous = output_stride == 8
  198.  
  199. with tf.variable_scope('Mixed_6a'):
  200. with tf.variable_scope('Branch_0'):
  201. tower_conv = slim.conv2d(net, 384, 3, stride=1 if use_atrous else 2,
  202. padding=padding,
  203. scope='Conv2d_1a_3x3')
  204. with tf.variable_scope('Branch_1'):
  205. tower_conv1_0 = slim.conv2d(net, 256, 1, scope='Conv2d_0a_1x1')
  206. tower_conv1_1 = slim.conv2d(tower_conv1_0, 256, 3,
  207. scope='Conv2d_0b_3x3')
  208. tower_conv1_2 = slim.conv2d(tower_conv1_1, 384, 3,
  209. stride=1 if use_atrous else 2,
  210. padding=padding,
  211. scope='Conv2d_1a_3x3')
  212. with tf.variable_scope('Branch_2'):
  213. tower_pool = slim.max_pool2d(net, 3, stride=1 if use_atrous else 2,
  214. padding=padding,
  215. scope='MaxPool_1a_3x3')
  216. net = tf.concat([tower_conv, tower_conv1_2, tower_pool], 3)
  217.  
  218. if add_and_check_final('Mixed_6a', net): return net, end_points
  219.  
  220. # TODO(alemi): register intermediate endpoints
  221. with slim.arg_scope([slim.conv2d], rate=2 if use_atrous else 1):
  222. net = slim.repeat(net, 20, block17, scale=0.10)
  223. if add_and_check_final('PreAuxLogits', net): return net, end_points
  224.  
  225. if output_stride == 8:
  226. # TODO(gpapan): Properly support output_stride for the rest of the net.
  227. raise ValueError('output_stride==8 is only supported up to the '
  228. 'PreAuxlogits end_point for now.')
  229.  
  230. # 8 x 8 x 2080
  231. with tf.variable_scope('Mixed_7a'):
  232. with tf.variable_scope('Branch_0'):
  233. tower_conv = slim.conv2d(net, 256, 1, scope='Conv2d_0a_1x1')
  234. tower_conv_1 = slim.conv2d(tower_conv, 384, 3, stride=2,
  235. padding=padding,
  236. scope='Conv2d_1a_3x3')
  237. with tf.variable_scope('Branch_1'):
  238. tower_conv1 = slim.conv2d(net, 256, 1, scope='Conv2d_0a_1x1')
  239. tower_conv1_1 = slim.conv2d(tower_conv1, 288, 3, stride=2,
  240. padding=padding,
  241. scope='Conv2d_1a_3x3')
  242. with tf.variable_scope('Branch_2'):
  243. tower_conv2 = slim.conv2d(net, 256, 1, scope='Conv2d_0a_1x1')
  244. tower_conv2_1 = slim.conv2d(tower_conv2, 288, 3,
  245. scope='Conv2d_0b_3x3')
  246. tower_conv2_2 = slim.conv2d(tower_conv2_1, 320, 3, stride=2,
  247. padding=padding,
  248. scope='Conv2d_1a_3x3')
  249. with tf.variable_scope('Branch_3'):
  250. tower_pool = slim.max_pool2d(net, 3, stride=2,
  251. padding=padding,
  252. scope='MaxPool_1a_3x3')
  253. net = tf.concat(
  254. [tower_conv_1, tower_conv1_1, tower_conv2_2, tower_pool], 3)
  255.  
  256. if add_and_check_final('Mixed_7a', net): return net, end_points
  257.  
  258. # TODO(alemi): register intermediate endpoints
  259. net = slim.repeat(net, 9, block8, scale=0.20)
  260. net = block8(net, activation_fn=None)
  261.  
  262. # 8 x 8 x 1536
  263. net = slim.conv2d(net, 1536, 1, scope='Conv2d_7b_1x1')
  264. if add_and_check_final('Conv2d_7b_1x1', net): return net, end_points
  265.  
  266. raise ValueError('final_endpoint (%s) not recognized', final_endpoint)
  267.  
  268.  
  269. def inception_resnet_v2(inputs, num_classes=1001, is_training=True,
  270. dropout_keep_prob=0.8,
  271. reuse=None,
  272. scope='InceptionResnetV2',
  273. create_aux_logits=True):
  274. """Creates the Inception Resnet V2 model.
  275.  
  276. Args:
  277. inputs: a 4-D tensor of size [batch_size, height, width, 3].
  278. num_classes: number of predicted classes.
  279. is_training: whether is training or not.
  280. dropout_keep_prob: float, the fraction to keep before final layer.
  281. reuse: whether or not the network and its variables should be reused. To be
  282. able to reuse 'scope' must be given.
  283. scope: Optional variable_scope.
  284. create_aux_logits: Whether to include the auxilliary logits.
  285.  
  286. Returns:
  287. logits: the logits outputs of the model.
  288. end_points: the set of end_points from the inception model.
  289. """
  290. end_points = {}
  291.  
  292. with tf.variable_scope(scope, 'InceptionResnetV2', [inputs, num_classes],
  293. reuse=reuse) as scope:
  294. with slim.arg_scope([slim.batch_norm, slim.dropout],
  295. is_training=is_training):
  296. net, end_points = inception_resnet_v2_base(inputs, scope=scope)
  297.  
  298. if create_aux_logits:
  299. with tf.variable_scope('AuxLogits'):
  300. aux = end_points['PreAuxLogits']
  301. aux = slim.avg_pool2d(aux, 5, stride=3, padding='VALID',
  302. scope='Conv2d_1a_3x3')
  303. aux = slim.conv2d(aux, 128, 1, scope='Conv2d_1b_1x1')
  304. aux = slim.conv2d(aux, 768, aux.get_shape()[1:3],
  305. padding='VALID', scope='Conv2d_2a_5x5')
  306. aux = slim.flatten(aux)
  307. aux = slim.fully_connected(aux, num_classes, activation_fn=None,
  308. scope='Logits')
  309. end_points['AuxLogits'] = aux
  310.  
  311. with tf.variable_scope('Logits'):
  312. net = slim.avg_pool2d(net, net.get_shape()[1:3], padding='VALID',
  313. scope='AvgPool_1a_8x8')
  314. net = slim.flatten(net)
  315.  
  316. net = slim.dropout(net, dropout_keep_prob, is_training=is_training,
  317. scope='Dropout')
  318.  
  319. end_points['PreLogitsFlatten'] = net
  320. logits = slim.fully_connected(net, num_classes, activation_fn=None,
  321. scope='Logits')
  322. end_points['Logits'] = logits
  323. end_points['Predictions'] = tf.nn.softmax(logits, name='Predictions')
  324.  
  325. return logits, end_points
  326.  
  327.  
  328. inception_resnet_v2.default_image_size = 299
  329.  
  330.  
  331. def inception_resnet_v2_arg_scope(weight_decay=0.00004,
  332. batch_norm_decay=0.9997,
  333. batch_norm_epsilon=0.001):
  334. """Returns the scope with the default parameters for inception_resnet_v2.
  335.  
  336. Args:
  337. weight_decay: the weight decay for weights variables.
  338. batch_norm_decay: decay for the moving average of batch_norm momentums.
  339. batch_norm_epsilon: small float added to variance to avoid dividing by zero.
  340.  
  341. Returns:
  342. a arg_scope with the parameters needed for inception_resnet_v2.
  343. """
  344. # Set weight_decay for weights in conv2d and fully_connected layers.
  345. with slim.arg_scope([slim.conv2d, slim.fully_connected],
  346. weights_regularizer=slim.l2_regularizer(weight_decay),
  347. biases_regularizer=slim.l2_regularizer(weight_decay)):
  348. batch_norm_params = {
  349. 'decay': batch_norm_decay,
  350. 'epsilon': batch_norm_epsilon,
  351. }
  352. # Set activation_fn and parameters for batch_norm.
  353. with slim.arg_scope([slim.conv2d], activation_fn=tf.nn.relu,
  354. normalizer_fn=slim.batch_norm,
  355. normalizer_params=batch_norm_params) as scope:
  356. return scope
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement