MCPcopy Create free account
hub / github.com/DeepRec-AI/DeepRec / _SvdGrad

Function _SvdGrad

tensorflow/python/ops/linalg_grad.py:347–468  ·  view source on GitHub ↗

Gradient for the singular value decomposition.

(op, grad_s, grad_u, grad_v)

Source from the content-addressed store, hash-verified

345
346@ops.RegisterGradient("Svd")
347def _SvdGrad(op, grad_s, grad_u, grad_v):
348 """Gradient for the singular value decomposition."""
349
350 # The derivation for the compute_uv=False case, and most of
351 # the derivation for the full_matrices=True case, are in
352 # Giles' paper (see reference at top of file). A derivation for
353 # the full_matrices=False case is available at
354 # https://j-towns.github.io/papers/svd-derivative.pdf
355 a = op.inputs[0]
356 a_shape = a.get_shape().with_rank_at_least(2)
357 grad_s_mat = array_ops.matrix_diag(grad_s)
358
359 if not op.get_attr("compute_uv"):
360 s, u, v = linalg_ops.svd(a, compute_uv=True)
361 grad_a = math_ops.matmul(u, math_ops.matmul(grad_s_mat, v, adjoint_b=True))
362 grad_a.set_shape(a_shape)
363 return grad_a
364
365 full_matrices = op.get_attr("full_matrices")
366
367 # TODO(rmlarsen): Make this work with complex types.
368 if a.dtype.is_complex:
369 raise NotImplementedError(
370 "SVD gradient is not implemented for complex types and "
371 "compute_uv=True.")
372 grad_u_shape = grad_u.get_shape().with_rank_at_least(2)
373 grad_v_shape = grad_v.get_shape().with_rank_at_least(2)
374 m = a_shape.dims[-2].merge_with(grad_u_shape[-2])
375 n = a_shape.dims[-1].merge_with(grad_v_shape[-2])
376 batch_shape = a_shape[:-2].merge_with(grad_u_shape[:-2]).merge_with(
377 grad_v_shape[:-2])
378 a_shape = batch_shape.concatenate([m, n])
379
380 m = a_shape.dims[-2].value
381 n = a_shape.dims[-1].value
382 # TODO(rmlarsen): Make this work with placeholders.
383 if m is None or n is None:
384 raise NotImplementedError(
385 "SVD gradient has not been implemented for input with unknown "
386 "inner matrix shape.")
387
388 s = op.outputs[0]
389 u = op.outputs[1]
390 v = op.outputs[2]
391
392 use_adjoint = False
393 if m > n:
394 # Compute the gradient for A^H = V * S^T * U^H, and (implicitly) take the
395 # Hermitian transpose of the gradient at the end.
396 use_adjoint = True
397 m, n = n, m
398 u, v = v, u
399 grad_u, grad_v = grad_v, grad_u
400
401 with ops.control_dependencies([grad_s, grad_u, grad_v]):
402 if full_matrices and abs(m - n) > 1:
403 raise NotImplementedError(
404 "svd gradient is not implemented for abs(m - n) > 1 "

Callers

nothing calls this directly

Calls 13

with_rank_at_leastMethod · 0.80
adjointMethod · 0.80
absFunction · 0.70
get_shapeMethod · 0.45
get_attrMethod · 0.45
matmulMethod · 0.45
set_shapeMethod · 0.45
merge_withMethod · 0.45
concatenateMethod · 0.45
control_dependenciesMethod · 0.45
squareMethod · 0.45
shapeMethod · 0.45

Tested by

no test coverage detected