def Bidirectional(l2r, r2l):
nO = l2r.nO<EOL>def birnn_fwd(Xs, drop=<NUM_LIT:0.0>):<EOL><INDENT>l2r_Zs, bp_l2r_Zs = l2r.begin_update(Xs, drop=drop)<EOL>r2l_Zs, bp_r2l_Zs = r2l.begin_update(<EOL>[l2r.ops.xp.ascontiguousarray(X[::-<NUM_LIT:1>]) for X in Xs]<EOL>)<EOL>def birnn_bwd(dZs, sgd=None):<EOL><INDENT>d_l2r_Zs = []<EOL>d_r2l_Zs = []<EOL>for dZ in dZs:<EOL><INDENT>l2r_fwd = dZ[:, :nO]<EOL>r2l_fwd = dZ[:, nO:]<EOL>d_l2r_Zs.append(l2r.ops.xp.ascontiguousarray(l2r_fwd))<EOL>d_r2l_Zs.append(l2r.ops.xp.ascontiguousarray(r2l_fwd[::-<NUM_LIT:1>]))<EOL><DEDENT>dXs_l2r = bp_l2r_Zs(d_l2r_Zs, sgd=sgd)<EOL>dXs_r2l = bp_r2l_Zs(d_r2l_Zs, sgd=sgd)<EOL>dXs = [dXf + dXb[::-<NUM_LIT:1>] for dXf, dXb in zip(dXs_l2r, dXs_r2l)]<EOL>return dXs<EOL><DEDENT>Zs = [l2r.ops.xp.hstack((Zf, Zb[::-<NUM_LIT:1>])) for Zf, Zb in zip(l2r_Zs, r2l_Zs)]<EOL>return Zs, birnn_bwd<EOL><DEDENT>return wrap(birnn_fwd, l2r, r2l)<EOL>
Stitch two RNN models into a bidirectional layer.