(self, deltas, alpha=1.0, beta=0.0)
return self.out_deltas_buffer
Backpropagation of errors, output delta for previous layer, and calculate the update on
            model params.

        Arguments:
            deltas (Tensor): error tensors for each time step of unrolling
            alpha (float, optional): scale to apply to input for activation
                                     gradient bprop.  Defaults to 1.0
            beta (float, optional): scale to apply to output activation
                                    gradient bprop.  Defaults to 0.0

        Attributes:
            dW_input (Tensor): input weight gradients
            dW_recur (Tensor): recurrent weight gradients
            db (Tensor): bias gradients

        Returns:
            Tensor: Backpropagated errors for each time step of model unrolling
Backpropagation of errors, output delta for previous layer, and calculate the update on
            model params.
Backpropagation of errors output delta for previous layer and calculate the update on model params .
def bprop(self, deltas, alpha=1.0, beta=0.0):
        """
        Backpropagation of errors, output delta for previous layer, and calculate the update on
            model params.

        Arguments:
            deltas (Tensor): error tensors for each time step of unrolling
            alpha (float, optional): scale to apply to input for activation
                                     gradient bprop.  Defaults to 1.0
            beta (float, optional): scale to apply to output activation
                                    gradient bprop.  Defaults to 0.0

        Attributes:
            dW_input (Tensor): input weight gradients
            dW_recur (Tensor): recurrent weight gradients
            db (Tensor): bias gradients

        Returns:
            Tensor: Backpropagated errors for each time step of model unrolling
        """

        self.dW[:] = 0

        if self.in_deltas is None:
            self.in_deltas = get_steps(deltas, self.out_shape)
            self.prev_in_deltas = self.in_deltas[-1:] + self.in_deltas[:-1]

        params = (self.r, self.z, self.hcan, self.rh_prev, self.h_prev_bprop,
                  self.r_delta, self.z_delta, self.hcan_delta, self.rz_delta, self.rzhcan_delta,
                  self.h_delta, self.in_deltas, self.prev_in_deltas)

        for (r, z, hcan, rh_prev, h_prev, r_delta, z_delta, hcan_delta, rz_delta,
             rzhcan_delta, h_delta, in_deltas, prev_in_deltas) in reversed(list(zip(*params))):

            # hcan_delta
            hcan_delta[:] = self.activation.bprop(hcan) * in_deltas * z
            z_delta[:] = self.gate_activation.bprop(z) * in_deltas * (hcan - h_prev)

            # r_delta
            self.be.compound_dot(self.Whcan_recur.T, hcan_delta, r_delta)
            r_delta[:] = self.gate_activation.bprop(r) * r_delta * h_prev

            # out hidden delta
            h_delta[:] = in_deltas * (1 - z)
            self.be.compound_dot(self.Wrz_recur.T, rz_delta, h_delta, beta=1.0)
            self.be.compound_dot(self.Whcan_recur.T, hcan_delta, self.wrc_T_dc)
            h_delta[:] = h_delta + r * self.wrc_T_dc

            if h_prev != 0:
                self.be.compound_dot(rz_delta, h_prev.T, self.dWrz_recur, beta=1.0)
                self.be.compound_dot(hcan_delta, rh_prev.T, self.dWhcan_recur, beta=1.0)

            prev_in_deltas[:] = prev_in_deltas + h_delta

        # Weight deltas and accumulate
        self.be.compound_dot(self.rzhcan_delta_buffer, self.x.T, self.dW_input)  # batch
        self.db[:] = self.be.sum(self.rzhcan_delta_buffer, axis=1)

        # out deltas
        if self.out_deltas_buffer:  # save a bit of computation
            self.be.compound_dot(self.W_input.T, self.rzhcan_delta_buffer,
                                 self.out_deltas_buffer.reshape(self.nin, -1),
                                 alpha=alpha, beta=beta)

        self.final_hidden_error[:] = self.h_delta[0]
        return self.out_deltas_buffer
def bprop ( self , deltas , alpha = 1.0 , beta = 0.0 ) : self . dW [ : ] = 0 if self . in_deltas is None : self . in_deltas = get_steps ( deltas , self . out_shape ) self . prev_in_deltas = self . in_deltas [ - 1 : ] + self . in_deltas [ : - 1 ] params = ( self . r , self . z , self . hcan , self . rh_prev , self . h_prev_bprop , self . r_delta , self . z_delta , self . hcan_delta , self . rz_delta , self . rzhcan_delta , self . h_delta , self . in_deltas , self . prev_in_deltas ) for ( r , z , hcan , rh_prev , h_prev , r_delta , z_delta , hcan_delta , rz_delta , rzhcan_delta , h_delta , in_deltas , prev_in_deltas ) in reversed ( list ( zip ( * params ) ) ) : # hcan_delta hcan_delta [ : ] = self . activation . bprop ( hcan ) * in_deltas * z z_delta [ : ] = self . gate_activation . bprop ( z ) * in_deltas * ( hcan - h_prev ) # r_delta self . be . compound_dot ( self . Whcan_recur . T , hcan_delta , r_delta ) r_delta [ : ] = self . gate_activation . bprop ( r ) * r_delta * h_prev # out hidden delta h_delta [ : ] = in_deltas * ( 1 - z ) self . be . compound_dot ( self . Wrz_recur . T , rz_delta , h_delta , beta = 1.0 ) self . be . compound_dot ( self . Whcan_recur . T , hcan_delta , self . wrc_T_dc ) h_delta [ : ] = h_delta + r * self . wrc_T_dc if h_prev != 0 : self . be . compound_dot ( rz_delta , h_prev . T , self . dWrz_recur , beta = 1.0 ) self . be . compound_dot ( hcan_delta , rh_prev . T , self . dWhcan_recur , beta = 1.0 ) prev_in_deltas [ : ] = prev_in_deltas + h_delta # Weight deltas and accumulate self . be . compound_dot ( self . rzhcan_delta_buffer , self . x . T , self . dW_input ) # batch self . db [ : ] = self . be . sum ( self . rzhcan_delta_buffer , axis = 1 ) # out deltas if self . out_deltas_buffer : # save a bit of computation self . be . compound_dot ( self . W_input . T , self . rzhcan_delta_buffer , self . out_deltas_buffer . reshape ( self . nin , - 1 ) , alpha = alpha , beta = beta ) self . final_hidden_error [ : ] = self . h_delta [ 0 ] return self . out_deltas_buffer