//  [python]
def train(self, opt):
        opt.num_source = opt.seq_length - 1
        # TODO: currently fixed to 5. (5 for FlowNet-C, 4 for SfMLearner)
        opt.num_scales = 5
        self.opt = opt

        with tf.device('/cpu:0'):
            self.build_train_graph()
            self.collect_summaries()
            with tf.name_scope("parameter_count"):
                parameter_count = tf.reduce_sum([tf.reduce_prod(tf.shape(v)) \
                                                for v in tf.trainable_variables()])
            self.saver = tf.train.Saver([var for var in tf.model_variables()] + \
                                        [self.global_step],
                                         max_to_keep=20)
            saver_flow = tf.train.Saver([var for var in tf.all_variables() if 'flownet' in var.name and 'Adam' not in var.name and 'Momentum' not in var.name])
            if opt.ckpt_pose is None:
                # Use same ckpt for both depth and pose
                saver_dp   = tf.train.Saver([var for var in tf.trainable_variables() if 'depth_net' in var.name or 'pose_net' in var.name])
            else:
                # Use diffrent ckpts for depth and pose
                saver_dp   = tf.train.Saver([var for var in tf.trainable_variables() if 'depth_net' in var.name])
                saver_pose = tf.train.Saver([var for var in tf.trainable_variables() if 'pose_net' in var.name])

            sv = tf.train.Supervisor(logdir=opt.checkpoint_dir, 
                                     save_summaries_secs=0, 
                                     saver=None)
            config = tf.ConfigProto(allow_soft_placement=True)
            config.gpu_options.allow_growth = True
            with sv.managed_session(config=config) as sess:
                print('Trainable variables: ')
                for var in tf.trainable_variables():
                    print(var.name)
                print("parameter_count =", sess.run(parameter_count))
                if opt.continue_train:
                    ckpt_flow = opt.ckpt_flow
                    ckpt_dp = opt.ckpt_dp
                    ckpt_pose = opt.ckpt_pose
                    # Load weights from different checkpoints
                    print("Resume flow_net from previous checkpoint: %s" % ckpt_flow)
                    saver_flow.restore(sess, ckpt_flow)
                    if ckpt_pose is None:
                        # Use same ckpt for both depth and pose
                        print("Resume depth_net and pose_net from previous checkpoint: %s" % ckpt_dp)
                        saver_dp.restore(sess, ckpt_dp)
                    else:
                        # Use diffrent ckpts for depth and pose
                        print("Resume depth_net from previous checkpoint: %s" % ckpt_dp)
                        saver_dp.restore(sess, ckpt_dp)
                        print("Resume pose_net from previous checkpoint: %s" % ckpt_pose)
                        saver_pose.restore(sess, ckpt_pose)

                start_time = time.time()
                for step in range(1, opt.max_steps):
                    fetches = {
                        "train": self.train_op,
                        "global_step": self.global_step
                    }

                    if step % opt.summary_freq == 0:
                        fetches["loss"] = self.total_loss
                        fetches["summary"] = sv.summary_op

                    results = sess.run(fetches)
                    gs = results["global_step"]

                    
                    if step % opt.summary_freq == 0:
                        sv.summary_writer.add_summary(results['summary'], gs)
                        train_epoch = math.ceil(gs / self.steps_per_epoch)
                        train_step = gs - (train_epoch - 1) * self.steps_per_epoch
                        print("Epoch: [%2d] [%5d/%5d] time: %4.4f/it loss: %.3f" \
                                % (train_epoch, train_step, self.steps_per_epoch, \
                                    (time.time() - start_time)/opt.summary_freq, 
                                    results['loss']))
                        start_time = time.time()
                    
                    if step % opt.save_latest_freq == 0:
                        self.save(sess, opt.checkpoint_dir, gs)
                    if step % self.steps_per_epoch == 0 or step == opt.max_steps-1:
                        self.save(sess, opt.checkpoint_dir, gs)