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.options[:seed]
random = _get_randomizer(tensor, seed)
shape = tensor.options[: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.options.fetch(:maxval, 1)
minval = tensor.options.fetch(:minval, 0)
seed = tensor.options[: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.options[:seed]
random = _get_randomizer(tensor, seed)
r = RandomGaussian.new(tensor.options.fetch(:mean), tensor.options.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.options[:seed]
random = _get_randomizer(tensor, seed)
r = RandomGaussian.new(tensor.options.fetch(:mean), tensor.options.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
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)
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
|