GRU#
Domain:
ai.onnxSince version: 22
Computes an one-layer GRU. This operator is usually supported via some custom implementation such as CuDNN.
Notations:
X- input tensorz- update gater- reset gateh- hidden gatet- time step (t-1 means previous time step)W[zrh]- W parameter weight matrix for update, reset, and hidden gatesR[zrh]- R recurrence weight matrix for update, reset, and hidden gatesWb[zrh]- W bias vectors for update, reset, and hidden gatesRb[zrh]- R bias vectors for update, reset, and hidden gatesWB[zrh]- W parameter weight matrix for backward update, reset, and hidden gatesRB[zrh]- R recurrence weight matrix for backward update, reset, and hidden gatesWBb[zrh]- W bias vectors for backward update, reset, and hidden gatesRBb[zrh]- R bias vectors for backward update, reset, and hidden gatesH- Hidden statenum_directions- 2 if direction == bidirectional else 1
Activation functions:
Relu(x) - max(0, x)
Tanh(x) - (1 - e^{-2x})/(1 + e^{-2x})
Sigmoid(x) - 1/(1 + e^{-x})
NOTE:
Below are optional
Affine(x) - alpha * x + beta
LeakyRelu(x) - x if x >= 0 else alpha * x
ThresholdedRelu(x) - x if x >= alpha else 0
ScaledTanh(x) - alpha * Tanh(beta * x)
HardSigmoid(x) - min(max(alpha * x + beta, 0), 1)
Elu(x) - x if x >= 0 else alpha * (e^x - 1)
Softsign(x) - x/(1 +
|x|)Softplus(x) - log(1 + e^x)
Equations (Default: f=Sigmoid, g=Tanh):
zt = f(Xt*(Wz^T) + Ht-1*(Rz^T) + Wbz + Rbz)
rt = f(Xt*(Wr^T) + Ht-1*(Rr^T) + Wbr + Rbr)
ht = g(Xt*(Wh^T) + (rt (.) Ht-1)*(Rh^T) + Rbh + Wbh) # default, when linear_before_reset = 0
ht = g(Xt*(Wh^T) + (rt (.) (Ht-1*(Rh^T) + Rbh)) + Wbh) # when linear_before_reset != 0
Ht = (1 - zt) (.) ht + zt (.) Ht-1
Inputs
X (T): The input sequences packed (and potentially padded) into one 3-D tensor with the shape of
[seq_length, batch_size, input_size].W (T): The weight tensor for the gates. Concatenation of
W[zrh]andWB[zrh](if bidirectional) along dimension 0. This tensor has shape[num_directions, 3*hidden_size, input_size].R (T): The recurrence weight tensor. Concatenation of
R[zrh]andRB[zrh](if bidirectional) along dimension 0. This tensor has shape[num_directions, 3*hidden_size, hidden_size].B (T): The bias tensor for the gates. Concatenation of
[Wb[zrh], Rb[zrh]]and[WBb[zrh], RBb[zrh]](if bidirectional) along dimension 0. This tensor has shape[num_directions, 6*hidden_size]. Optional: If not specified - assumed to be 0sequence_lens (T1): Optional tensor specifying lengths of the sequences in a batch. If not specified - assumed all sequences in the batch to have length
seq_length. It has shape[batch_size].initial_h (T): Optional initial value of the hidden. If not specified - assumed to be 0. It has shape
[num_directions, batch_size, hidden_size].
Outputs
Y (T): A tensor that concats all the intermediate output values of the hidden. It has shape
[seq_length, num_directions, batch_size, hidden_size].Y_h (T): The last output value of the hidden. It has shape
[num_directions, batch_size, hidden_size].
Type Constraints
T: Constrain input and output types to float tensors. Allowed types: tensor(bfloat16), tensor(double), tensor(float), tensor(float16).
T1: Constrain seq_lens to integer tensor. Allowed types: tensor(int32).
Examples#
test_cc_gru_batchwise
Node:
GRU(X, W, R) -> (Y, Y_h)
Attributes:
hidden_size = 6
layout = 1
Inputs:
X: shape=(3, 1, 2), dtype=float32
[[[1., 2.]],
[[3., 4.]],
[[5., 6.]]]
W: shape=(1, 18, 2), dtype=float32
[[[0.2, 0.2],
[0.2, 0.2],
[0.2, 0.2],
[0.2, 0.2],
[0.2, 0.2],
[0.2, 0.2],
[0.2, 0.2],
[0.2, 0.2],
[0.2, 0.2],
[0.2, 0.2],
[0.2, 0.2],
[0.2, 0.2],
[0.2, 0.2],
[0.2, 0.2],
[0.2, 0.2],
[0.2, 0.2],
[0.2, 0.2],
[0.2, 0.2]]]
R: shape=(1, 18, 6), dtype=float32
[[[0.2, 0.2, 0.2, 0.2, 0.2, 0.2],
[0.2, 0.2, 0.2, 0.2, 0.2, 0.2],
[0.2, 0.2, 0.2, 0.2, 0.2, 0.2],
...,
[0.2, 0.2, 0.2, 0.2, 0.2, 0.2],
[0.2, 0.2, 0.2, 0.2, 0.2, 0.2],
[0.2, 0.2, 0.2, 0.2, 0.2, 0.2]]]
Outputs:
Y: shape=(3, 1, 1, 6), dtype=float32
[[[[0.19030015, 0.19030015, 0.19030015, 0.19030015, 0.19030015, 0.19030015]]],
[[[0.17513679, 0.17513679, 0.17513679, 0.17513679, 0.17513679, 0.17513679]]],
[[[0.09733082, 0.09733082, 0.09733082, 0.09733082, 0.09733082, 0.09733082]]]]
Y_h: shape=(3, 1, 6), dtype=float32
[[[0.19030015, 0.19030015, 0.19030015, 0.19030015, 0.19030015, 0.19030015]],
[[0.17513679, 0.17513679, 0.17513679, 0.17513679, 0.17513679, 0.17513679]],
[[0.09733082, 0.09733082, 0.09733082, 0.09733082, 0.09733082, 0.09733082]]]
test_cc_gru_defaults
Node:
GRU(X, W, R) -> ("", Y_h)
Attributes:
hidden_size = 5
Inputs:
X: shape=(1, 3, 2), dtype=float32
[[[1., 2.],
[3., 4.],
[5., 6.]]]
W: shape=(1, 15, 2), dtype=float32
[[[0.1, 0.1],
[0.1, 0.1],
[0.1, 0.1],
[0.1, 0.1],
[0.1, 0.1],
[0.1, 0.1],
[0.1, 0.1],
[0.1, 0.1],
[0.1, 0.1],
[0.1, 0.1],
[0.1, 0.1],
[0.1, 0.1],
[0.1, 0.1],
[0.1, 0.1],
[0.1, 0.1]]]
R: shape=(1, 15, 5), dtype=float32
[[[0.1, 0.1, 0.1, 0.1, 0.1],
[0.1, 0.1, 0.1, 0.1, 0.1],
[0.1, 0.1, 0.1, 0.1, 0.1],
...,
[0.1, 0.1, 0.1, 0.1, 0.1],
[0.1, 0.1, 0.1, 0.1, 0.1],
[0.1, 0.1, 0.1, 0.1, 0.1]]]
Outputs:
Y_h: shape=(1, 3, 5), dtype=float32
[[[0.12397026, 0.12397026, 0.12397026, 0.12397026, 0.12397026],
[0.20053661, 0.20053661, 0.20053661, 0.20053661, 0.20053661],
[0.19991653, 0.19991653, 0.19991653, 0.19991653, 0.19991653]]]
test_cc_gru_seq_length
Node:
GRU(X, W, R, B) -> ("", Y_h)
Attributes:
hidden_size = 5
Inputs:
X: shape=(2, 3, 3), dtype=float32
[[[ 1., 2., 3.],
[ 4., 5., 6.],
[ 7., 8., 9.]],
[[10., 11., 12.],
[13., 14., 15.],
[16., 17., 18.]]]
W: shape=(1, 15, 3), dtype=float32
[[[-0.1 , -0.05 , 0. ],
[ 0.05 , 0.1 , 0.15 ],
[ 0.20000002, -0.1 , -0.05 ],
[ 0. , 0.05 , 0.1 ],
[ 0.15 , 0.20000002, -0.1 ],
[-0.05 , 0. , 0.05 ],
[ 0.1 , 0.15 , 0.20000002],
[-0.1 , -0.05 , 0. ],
[ 0.05 , 0.1 , 0.15 ],
[ 0.20000002, -0.1 , -0.05 ],
[ 0. , 0.05 , 0.1 ],
[ 0.15 , 0.20000002, -0.1 ],
[-0.05 , 0. , 0.05 ],
[ 0.1 , 0.15 , 0.20000002],
[-0.1 , -0.05 , 0. ]]]
R: shape=(1, 15, 5), dtype=float32
[[[-0.15 , -0.11000001, -0.07000001, -0.03000001, 0.00999999],
[ 0.04999998, 0.08999999, 0.13 , 0.16999999, -0.15 ],
[-0.11000001, -0.07000001, -0.03000001, 0.00999999, 0.04999998],
...,
[ 0.08999999, 0.13 , 0.16999999, -0.15 , -0.11000001],
[-0.07000001, -0.03000001, 0.00999999, 0.04999998, 0.08999999],
[ 0.13 , 0.16999999, -0.15 , -0.11000001, -0.07000001]]]
B: shape=(1, 30), dtype=float32
[[-0.05 , -0.03 , -0.01 , 0.01 , 0.03 , 0.04999999,
0.06999999, 0.09 , 0.11 , 0.13 , 0.14999999, 0.17 ,
0.19 , 0.21 , 0.23 , 0.24999999, 0.26999998, 0.29 ,
0.30999997, 0.32999998, 0.34999996, 0.36999997, 0.39 , 0.40999997,
0.42999998, 0.45 , 0.46999997, 0.48999995, 0.51 , 0.53 ]]
Outputs:
Y_h: shape=(1, 3, 5), dtype=float32
[[[ 8.7044084e-01, 2.1826701e-01, 4.3450546e-01, 3.8154891e-01,
1.3391793e-01],
[ 9.3663889e-01, 1.3535304e-01, 4.1170382e-01, 2.8888240e-01,
-8.0563687e-04],
[ 9.7050184e-01, 6.3298374e-02, 3.8574046e-01, 2.0248368e-01,
-4.7147907e-02]]]
test_cc_gru_with_initial_bias
Node:
GRU(X, W, R, B) -> ("", Y_h)
Attributes:
hidden_size = 3
Inputs:
X: shape=(1, 3, 3), dtype=float32
[[[1., 2., 3.],
[4., 5., 6.],
[7., 8., 9.]]]
W: shape=(1, 9, 3), dtype=float32
[[[0.1, 0.1, 0.1],
[0.1, 0.1, 0.1],
[0.1, 0.1, 0.1],
[0.1, 0.1, 0.1],
[0.1, 0.1, 0.1],
[0.1, 0.1, 0.1],
[0.1, 0.1, 0.1],
[0.1, 0.1, 0.1],
[0.1, 0.1, 0.1]]]
R: shape=(1, 9, 3), dtype=float32
[[[0.1, 0.1, 0.1],
[0.1, 0.1, 0.1],
[0.1, 0.1, 0.1],
[0.1, 0.1, 0.1],
[0.1, 0.1, 0.1],
[0.1, 0.1, 0.1],
[0.1, 0.1, 0.1],
[0.1, 0.1, 0.1],
[0.1, 0.1, 0.1]]]
B: shape=(1, 18), dtype=float32
[[0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0. , 0. , 0. , 0. , 0. , 0. ,
0. , 0. , 0. ]]
Outputs:
Y_h: shape=(1, 3, 3), dtype=float32
[[[0.20053661, 0.20053661, 0.20053661],
[0.15482338, 0.15482338, 0.15482338],
[0.07484276, 0.07484276, 0.07484276]]]
Differences with previous version (14)#
SchemaDiff: GRU (domain 'ai.onnx')
old version: 14
new version: 22
breaking: no
Type constraints:
changed ‘T’: added types: [‘tensor(bfloat16)’]