Apply a function on all gradient if the name matches regex. Keep the other gradients unchanged. It can be used for gradient clipping, etc.
| 103 | |
| 104 | |
| 105 | class MapGradient(GradientProcessor): |
| 106 | """ |
| 107 | Apply a function on all gradient if the name matches regex. |
| 108 | Keep the other gradients unchanged. |
| 109 | |
| 110 | It can be used for gradient clipping, etc. |
| 111 | """ |
| 112 | |
| 113 | def __init__(self, func, regex='.*'): |
| 114 | """ |
| 115 | Args: |
| 116 | func: a user-supplied function which takes one or two arguments. |
| 117 | The argument(s) can be either a `grad` tensor, or `grad` and `var`. |
| 118 | The function should return the new gradient to be used. |
| 119 | If it return None, the gradient is discarded (hence no update to the variable will happen). |
| 120 | regex (str): used to match variables. Defaults to match all variables. |
| 121 | """ |
| 122 | args = inspect.getfullargspec(func).args |
| 123 | arg_num = len(args) - inspect.ismethod(func) |
| 124 | assert arg_num in [1, 2], \ |
| 125 | "The function must take 1 or 2 arguments! ({})".format(args) |
| 126 | if arg_num == 1: |
| 127 | self.func = lambda grad, var: func(grad) |
| 128 | else: |
| 129 | self.func = func |
| 130 | |
| 131 | if not regex.endswith('$'): |
| 132 | regex = regex + '$' |
| 133 | self.regex = regex |
| 134 | super(MapGradient, self).__init__() |
| 135 | |
| 136 | def _process(self, grads): |
| 137 | ret = [] |
| 138 | matched = False |
| 139 | for grad, var in grads: |
| 140 | if re.match(self.regex, var.op.name): |
| 141 | matched = True |
| 142 | grad = self.func(grad, var) |
| 143 | if grad is not None: |
| 144 | ret.append((grad, var)) |
| 145 | else: |
| 146 | ret.append((grad, var)) |
| 147 | if not matched: |
| 148 | logger.warn("[MapGradient] No match was found for regex {}.".format(self.regex)) |
| 149 | return ret |
| 150 | |
| 151 | |
| 152 | # TODO has dependency problems: sess.run may not depend on grad |
no outgoing calls
no test coverage detected
searching dependent graphs…