forward_recurrent Subroutine

private subroutine forward_recurrent(this, input)

Forward propagation

Type Bound

recurrent_layer_type

Arguments

Type IntentOptional Attributes Name
class(recurrent_layer_type), intent(inout) :: this

Instance of the recurrent layer

class(array_type), intent(in), dimension(:,:) :: input

Input values


Source Code

  subroutine forward_recurrent(this, input)
    !! Forward propagation
    implicit none

    ! Arguments
    class(recurrent_layer_type), intent(inout) :: this
    !! Instance of the recurrent layer
    class(array_type), dimension(:,:), intent(in) :: input
    !! Input values

    type(array_type), pointer :: ptr1, ptr2, ptr

    if(.not.associated(this%hidden_state))then
       call this%reset_state()
       allocate(this%hidden_state)
       call this%hidden_state%allocate( &
            [this%hidden_size, size(input(1,1)%val,2)], &
            source = 0._real32 &
       )
       this%hidden_state%is_temporary = .false.
    end if


    ! Generate outputs from weights, biases, and inputs
    !---------------------------------------------------------------------------
    if(this%use_bias)then
       ptr1 => matmul(this%params(1), input(1,1) ) + this%params(3)
       ptr2 => matmul(this%params(2), this%hidden_state ) + this%params(4)
    else
       ptr1 => matmul(this%params(1), input(1,1) )
       ptr2 => matmul(this%params(2), this%hidden_state )
    end if
    ptr => ptr1 + ptr2

    ! Apply activation function to activation
    !---------------------------------------------------------------------------
    call this%output(1,1)%zero_grad()
    if(trim(this%activation%name) .ne. "none")then
       ptr => this%activation%apply(ptr)
    end if
    this%hidden_state => ptr
    call this%output(1,1)%assign_shallow(ptr)
    this%output(1,1)%is_temporary = .false.
    this%time_step = this%time_step + 1

  end subroutine forward_recurrent