Args: grad_list ([[(grad, var), ...], ...]): #GPU lists to be reduced. Each is the gradients computed on each GPU. get_opt_fn (-> tf.train.Optimizer): callable which returns an optimizer Returns: tf.Operation: the training op
(self, grad_list, get_opt_fn)
| 389 | return DataParallelBuilder.build_on_towers(self.towers, tower_fn, devices) |
| 390 | |
| 391 | def build(self, grad_list, get_opt_fn): |
| 392 | """ |
| 393 | Args: |
| 394 | grad_list ([[(grad, var), ...], ...]): #GPU lists to be reduced. Each is the gradients computed on each GPU. |
| 395 | get_opt_fn (-> tf.train.Optimizer): callable which returns an optimizer |
| 396 | |
| 397 | Returns: |
| 398 | tf.Operation: the training op |
| 399 | """ |
| 400 | assert len(grad_list) == len(self.towers) |
| 401 | DataParallelBuilder._check_grad_list(grad_list) |
| 402 | |
| 403 | if self._scale_gradient and len(self.towers) > 1: |
| 404 | # pretend to average the grads, in order to make async and |
| 405 | # sync have consistent effective learning rate |
| 406 | gradproc = ScaleGradient(('.*', 1.0 / len(self.towers)), verbose=False) |
| 407 | grad_list = [gradproc.process(gv) for gv in grad_list] |
| 408 | # Ngpu x Nvar x 2 |
| 409 | |
| 410 | train_ops = [] |
| 411 | opt = get_opt_fn() |
| 412 | with tf.name_scope('async_apply_gradients'): |
| 413 | for i, grad_and_vars in enumerate(zip(*grad_list)): |
| 414 | # Ngpu x 2 |
| 415 | v = grad_and_vars[0][1] |
| 416 | with tf.device(v.device): |
| 417 | # will call apply_gradients (therefore gradproc) multiple times |
| 418 | train_ops.append(opt.apply_gradients( |
| 419 | grad_and_vars, name='apply_grad_{}'.format(i))) |
| 420 | return tf.group(*train_ops, name='train_op') |
nothing calls this directly
no test coverage detected