This repository was archived by the owner on Jul 1, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 137
/
Copy pathrnn.py
72 lines (60 loc) · 2.55 KB
/
rnn.py
1
2
3
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
# Computes expected results for `testRNN()` in `Tests/TensorFlowTests/LayerTests.swift`.
# Requires 'tensorflow>=2.0.0a0' (e.g. "pip install tensorflow==2.2.0").
import numpy
import tensorflow as tf
# Set random seed for repetable results
tf.random.set_seed(0)
def indented(s):
return '\n'.join([' ' + l for l in s.split('\n')])
def swift_tensor(name, tensor):
if hasattr(tensor, 'numpy'):
tensor = tensor.numpy()
def format_float(x):
formatted = numpy.format_float_positional(x, unique=True)
if formatted[-1] == '.':
return formatted + '0'
return formatted
formatter = {
'float_kind': format_float
}
return 'let {} = Tensor<Float>(\n{}\n)'.format(
name,
indented(numpy.array2string(tensor, separator=',', formatter=formatter)))
# Initialize the keras model with the SimpleRNN.
rnn = tf.keras.layers.SimpleRNN(
units=4, activation="tanh",
return_sequences=True, return_state=True)
x_input = tf.keras.Input(shape=[4, 4])
initial_state = tf.keras.Input(shape=[4])
initial_state_input = [initial_state]
output = rnn(x_input, initial_state=initial_state_input)
model = tf.keras.Model(inputs=[x_input, initial_state_input], outputs=[output])
# Print the SimpleRNN weights.
[kernel, recurrent_kernel, bias] = rnn.get_weights()
print(swift_tensor('kernel', kernel))
print(swift_tensor('recurrentKernel', recurrent_kernel))
print(swift_tensor('bias', bias))
# Initialize input data and print it.
x = tf.keras.initializers.GlorotUniform()(shape=[1, 4, 4])
initial_state = [
tf.keras.initializers.GlorotUniform()(shape=[1, 4]),
]
print(swift_tensor('x', x))
print(swift_tensor('initialState', initial_state[0]))
# Run forwards and backwards pass and print the results.
with tf.GradientTape() as tape:
tape.watch(x)
tape.watch(initial_state)
[[states, final_state]] = model([x, initial_state])
sum_output = tf.reduce_sum(states[0][-1])
[grad_model, grad_x, grad_initial_state] = tape.gradient(sum_output, [model.variables, x, initial_state])
[grad_kernel, grad_recurrent_kernel, grad_bias] = grad_model
[grad_initial_state] = grad_initial_state
print(swift_tensor('expectedSum', sum_output))
print(swift_tensor('expectedStates', states))
print(swift_tensor('expectedFinalState', final_state))
print(swift_tensor('expectedGradKernel', grad_kernel))
print(swift_tensor('expectedGradRecurrentKernel', grad_recurrent_kernel))
print(swift_tensor('expectedGradBias', grad_bias))
print(swift_tensor('expectedGradX', grad_x))
print(swift_tensor('expectedGradInitialState', grad_initial_state))