Module: TensorStream::RandomOps
- Included in:
- Evaluator::RubyEvaluator
- Defined in:
- lib/tensor_stream/evaluator/ruby/random_ops.rb
Overview
Collection of machine learning related ops
Class Method Summary collapse
Class Method Details
.included(klass) ⇒ Object
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/tensor_stream/evaluator/ruby/random_ops.rb', line 4 def self.included(klass) klass.class_eval do register_op :glorot_uniform, no_eval: true do |_context, tensor, _inputs| seed = tensor.[:seed] random = _get_randomizer(tensor, seed) shape = tensor.[:shape] || tensor.shape.shape fan_in, fan_out = if shape.size.zero? [1, 1] elsif shape.size == 1 [1, shape[0]] else [shape[0], shape.last] end limit = Math.sqrt(6.0 / (fan_in + fan_out)) minval = -limit maxval = limit generator = -> { random.rand * (maxval - minval) + minval } generate_vector(shape, generator: generator) end register_op :random_uniform, no_eval: true do |_context, tensor, inputs| maxval = tensor..fetch(:maxval, 1) minval = tensor..fetch(:minval, 0) seed = tensor.[:seed] random = _get_randomizer(tensor, seed) generator = -> { random.rand * (maxval - minval) + minval } shape = inputs[0] || tensor.shape.shape generate_vector(shape, generator: generator) end register_op :random_standard_normal, no_eval: true do |_context, tensor, inputs| seed = tensor.[:seed] random = _get_randomizer(tensor, seed) r = RandomGaussian.new(tensor..fetch(:mean), tensor..fetch(:stddev), -> { random.rand }) random = _get_randomizer(tensor, seed) generator = -> { r.rand } shape = inputs[0] || tensor.shape.shape generate_vector(shape, generator: generator) end register_op :truncated_normal, no_eval: true do |_context, tensor, inputs| seed = tensor.[:seed] random = _get_randomizer(tensor, seed) r = RandomGaussian.new(tensor..fetch(:mean), tensor..fetch(:stddev), -> { random.rand }) generator = -> { r.rand } shape = inputs[0] || tensor.shape.shape random_values = Array.new(shape.reduce(:*) || 1) { generator.call } mean = random_values.reduce(:+) / random_values.size # standard deviation stddev = Math.sqrt(random_values.map { |v| (v - mean)**2 }.reduce(:+) / (random_values.size - 1)) minval = random_values.min maxval = random_values.max max_iterations = 100 if (minval.infinite? && minval < 0.0) || (maxval < mean) # Reverse all calculations. normMin and normMax will be flipped. a = minval minval = maxval maxval = a stddev = -stddev end norm_min = (minval - mean) / stddev norm_max = (maxval - mean) / stddev val = random_values.map { |v| iterations = 0 pick = v while (pick > norm_max) || (pick < norm_min) pick = generator.call iterations += 1 if iterations > max_iterations pick = v break end end pick } TensorShape.reshape(val, shape) end end end |