You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

Dropout.py 3.5 kB

5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. from __future__ import absolute_import
  2. from .Node import Op
  3. import ctypes
  4. import numpy as np
  5. from .._base import DNNL_LIB
  6. from ..cpu_links import dropout as cpu_dropout
  7. from ..cpu_links import dropout_gradient as cpu_dropout_gradient
  8. from ..gpu_links import dropout_gradient
  9. from ..gpu_links import dropout
  10. class DropoutOp(Op):
  11. def __init__(self, node_in, keep_prob, ctx=None):
  12. super().__init__(DropoutOp, [node_in], ctx)
  13. self.seed = ctypes.c_ulonglong(0)
  14. self.mask = None
  15. self.keep_prob = keep_prob
  16. def compute(self, input_vals, output_val, stream_handle=None, inference=False):
  17. if inference == False:
  18. if self.on_cpu:
  19. if DNNL_LIB['cpu_Dropout']:
  20. cpu_dropout(input_vals[0], self.keep_prob, output_val)
  21. else:
  22. np.random.seed(self.seed.value)
  23. if self.mask is None:
  24. self.mask = np.random.uniform(
  25. 0, 1.0, input_vals[0].shape) >= (1-self.keep_prob)
  26. output_val[:] = dropout_np(
  27. input_vals[0].asnumpy(), self.keep_prob, output_val, self.mask)
  28. else:
  29. dropout(input_vals[0], 1 - self.keep_prob,
  30. output_val, self.seed, stream_handle)
  31. def gradient(self, output_grad):
  32. return [dropout_gradient_op(output_grad, self.keep_prob, self, ctx=self.raw_ctx)]
  33. def infer_shape(self, input_shapes):
  34. return input_shapes[0]
  35. class Dropout_GradientOp(Op):
  36. def __init__(self, node_in, keep_prob, forward_node, ctx=None):
  37. super().__init__(Dropout_GradientOp, [node_in], ctx)
  38. self.forward_node = forward_node
  39. self.keep_prob = keep_prob
  40. def compute(self, input_vals, output_val, stream_handle=None):
  41. if self.on_cpu:
  42. if DNNL_LIB['cpu_Dropout_Gradient']:
  43. cpu_dropout_gradient(input_vals[0], self.keep_prob, output_val)
  44. else:
  45. output_val[:] = dropout_np_gradient(
  46. input_vals[0].asnumpy(), self.keep_prob, self.forward_node.mask)
  47. else:
  48. dropout_gradient(input_vals[0], 1 - self.keep_prob,
  49. output_val, self.forward_node.seed, stream_handle)
  50. def gradient(self, output_grad):
  51. raise NotImplementedError
  52. def infer_shape(self, input_shapes):
  53. return input_shapes[0]
  54. def dropout_op(node_in, keep_prob, ctx=None):
  55. """Drops elements of input variable randomly.
  56. Parameters:
  57. ----
  58. node_in : Node
  59. Input variable.
  60. keep_prob : float
  61. Probability of the results to be kept.
  62. Returns:
  63. ----
  64. A new Node instance created by Op.
  65. """
  66. return DropoutOp(node_in, keep_prob, ctx=ctx)
  67. def dropout_gradient_op(node_in, keep_prob, forward_node, ctx=None):
  68. """Gradient node of dropout operation.
  69. Parameters:
  70. ----
  71. node_in : Node
  72. Input variable.
  73. keep_prob : float
  74. Probability of the results to be kept.
  75. Returns:
  76. ----
  77. A new Node instance created by Op.
  78. """
  79. return Dropout_GradientOp(node_in, keep_prob, forward_node, ctx=ctx)
  80. def dropout_np(inputs, keep_prob, out_arr, mask):
  81. return mask*inputs*(1/keep_prob)
  82. def dropout_np_gradient(in_gradient_y, keep_prob, mask):
  83. out_grads = in_gradient_y
  84. out_grads *= mask * (1 / keep_prob)
  85. return out_grads