get_partial_softmax_val_sum Subroutine

pure subroutine get_partial_softmax_val_sum(this, upstream_grad, output)

Get partial derivative of softmax activation (in-place version, summed over samples)

Arguments

Type IntentOptional Attributes Name
class(array_type), intent(in) :: this
real(kind=real32), intent(in), dimension(:,:) :: upstream_grad
real(kind=real32), intent(out), dimension(:) :: output

Source Code

  pure subroutine get_partial_softmax_val_sum(this, upstream_grad, output)
    !! Get partial derivative of softmax activation (in-place version, summed over samples)
    implicit none
    class(array_type), intent(in) :: this
    real(real32), dimension(:,:), intent(in) :: upstream_grad
    real(real32), dimension(:), intent(out) :: output

    integer :: s, i, nfeat, nsamp
    real(real32) :: dot

    output = 0.0_real32
    if(this%indices(1) .eq. 1)then
       nsamp = size(this%val,1)
       nfeat = size(this%val,2)
       do s = 1, nsamp
          ! compute g·y
          dot = 0.0_real32
          do i = 1, nfeat
             dot = dot + upstream_grad(s,i) * this%val(s,i)
          end do
          ! accumulate reduced gradient
          do concurrent( i = 1 : nfeat )
             output(i) = output(i) + this%val(s,i) * (upstream_grad(s,i) - dot)
          end do
       end do
    else
       nsamp = size(this%val,2)
       nfeat = size(this%val,1)
       do s = 1, nsamp
          dot = 0.0_real32
          do i = 1, nfeat
             dot = dot + upstream_grad(i,s) * this%val(i,s)
          end do
          do concurrent( i = 1 : nfeat )
             output(i) = output(i) + this%val(i,s) * (upstream_grad(i,s) - dot)
          end do
       end do
    end if
  end subroutine get_partial_softmax_val_sum