Architecture of FlowNetSimple in Figure 2 of FlowNet 1.0. Args: x: 2CHW if standalone==True, else NCHW where C=12 is a concatenation of 5 tensors of [3, 3, 3, 2, 1] channels. standalone: If True, this model is used to predict flow from two in
(self, x, standalone=True)
| 322 | |
| 323 | class FlowNet2S(FlowNetBase): |
| 324 | def graph_structure(self, x, standalone=True): |
| 325 | """ |
| 326 | Architecture of FlowNetSimple in Figure 2 of FlowNet 1.0. |
| 327 | |
| 328 | Args: |
| 329 | x: 2CHW if standalone==True, else NCHW where C=12 is a concatenation |
| 330 | of 5 tensors of [3, 3, 3, 2, 1] channels. |
| 331 | standalone: If True, this model is used to predict flow from two inputs. |
| 332 | If False, this model is used as part of the FlowNet2. |
| 333 | """ |
| 334 | if standalone: |
| 335 | x = tf.concat(tf.split(x, 2, axis=0), axis=1) |
| 336 | |
| 337 | with argscope([tf.layers.conv2d], activation=lambda x: tf.nn.leaky_relu(x, 0.1), |
| 338 | padding='valid', strides=2, kernel_size=3, |
| 339 | data_format='channels_first'), \ |
| 340 | argscope([tf.layers.conv2d_transpose], padding='same', activation=tf.identity, |
| 341 | data_format='channels_first', strides=2, kernel_size=4): |
| 342 | x = tf.layers.conv2d(pad(x, 3), 64, kernel_size=7, name='conv1') |
| 343 | conv2 = tf.layers.conv2d(pad(x, 2), 128, kernel_size=5, name='conv2') |
| 344 | x = tf.layers.conv2d(pad(conv2, 2), 256, kernel_size=5, name='conv3') |
| 345 | conv3 = tf.layers.conv2d(pad(x, 1), 256, name='conv3_1', strides=1) |
| 346 | x = tf.layers.conv2d(pad(conv3, 1), 512, name='conv4') |
| 347 | conv4 = tf.layers.conv2d(pad(x, 1), 512, name='conv4_1', strides=1) |
| 348 | x = tf.layers.conv2d(pad(conv4, 1), 512, name='conv5') |
| 349 | conv5 = tf.layers.conv2d(pad(x, 1), 512, name='conv5_1', strides=1) |
| 350 | x = tf.layers.conv2d(pad(conv5, 1), 1024, name='conv6') |
| 351 | conv6 = tf.layers.conv2d(pad(x, 1), 1024, name='conv6_1', strides=1) |
| 352 | |
| 353 | flow6 = tf.layers.conv2d(pad(conv6, 1), 2, name='predict_flow6', strides=1, activation=tf.identity) |
| 354 | flow6_up = tf.layers.conv2d_transpose(flow6, 2, name='upsampled_flow6_to_5', use_bias=False) |
| 355 | x = tf.layers.conv2d_transpose(conv6, 512, name='deconv5', activation=lambda x: tf.nn.leaky_relu(x, 0.1)) |
| 356 | |
| 357 | concat5 = tf.concat([conv5, x, flow6_up], axis=1, name='concat5') |
| 358 | flow5 = tf.layers.conv2d(pad(concat5, 1), 2, name='predict_flow5', strides=1, activation=tf.identity) |
| 359 | flow5_up = tf.layers.conv2d_transpose(flow5, 2, name='upsampled_flow5_to_4', use_bias=False) |
| 360 | x = tf.layers.conv2d_transpose(concat5, 256, name='deconv4', activation=lambda x: tf.nn.leaky_relu(x, 0.1)) |
| 361 | |
| 362 | concat4 = tf.concat([conv4, x, flow5_up], axis=1, name='concat4') |
| 363 | flow4 = tf.layers.conv2d(pad(concat4, 1), 2, name='predict_flow4', strides=1, activation=tf.identity) |
| 364 | flow4_up = tf.layers.conv2d_transpose(flow4, 2, name='upsampled_flow4_to_3', use_bias=False) |
| 365 | x = tf.layers.conv2d_transpose(concat4, 128, name='deconv3', activation=lambda x: tf.nn.leaky_relu(x, 0.1)) |
| 366 | |
| 367 | concat3 = tf.concat([conv3, x, flow4_up], axis=1, name='concat3') |
| 368 | flow3 = tf.layers.conv2d(pad(concat3, 1), 2, name='predict_flow3', strides=1, activation=tf.identity) |
| 369 | flow3_up = tf.layers.conv2d_transpose(flow3, 2, name='upsampled_flow3_to_2', use_bias=False) |
| 370 | x = tf.layers.conv2d_transpose(concat3, 64, name='deconv2', activation=lambda x: tf.nn.leaky_relu(x, 0.1)) |
| 371 | |
| 372 | concat2 = tf.concat([conv2, x, flow3_up], axis=1, name='concat2') |
| 373 | flow2 = tf.layers.conv2d(pad(concat2, 1), 2, name='predict_flow2', strides=1, activation=tf.identity) |
| 374 | |
| 375 | return tf.identity(flow2, name='flow2') |
| 376 | |
| 377 | |
| 378 | class FlowNet2C(FlowNetBase): |