build_from_onnx_full Subroutine

private subroutine build_from_onnx_full(this, node, initialisers, value_info, verbose)

Read ONNX attributes for fully connected layer

Type Bound

full_layer_type

Arguments

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

Instance of the fully connected layer

type(onnx_node_type), intent(in) :: node

Instance of ONNX node information

type(onnx_initialiser_type), intent(in), dimension(:) :: initialisers

Instance of ONNX initialiser information

type(onnx_tensor_type), intent(in), dimension(:) :: value_info

Instance of ONNX value info information

integer, intent(in) :: verbose

Verbosity level


Source Code

  subroutine build_from_onnx_full(this, node, initialisers, value_info, verbose )
    !! Read ONNX attributes for fully connected layer
    use athena__activation, only: activation_setup
    use athena__initialiser_data, only: data_init_type
    implicit none

    ! Arguments
    class(full_layer_type), intent(inout) :: this
    !! Instance of the fully connected layer
    type(onnx_node_type), intent(in) :: node
    !! Instance of ONNX node information
    type(onnx_initialiser_type), dimension(:), intent(in) :: initialisers
    !! Instance of ONNX initialiser information
    type(onnx_tensor_type), dimension(:), intent(in) :: value_info
    !! Instance of ONNX value info information
    integer, intent(in) :: verbose
    !! Verbosity level

    ! Local variables
    integer :: i
    !! Loop index
    logical :: use_bias = .true.
    !! Whether to use bias
    integer, dimension(:), allocatable :: dim_products, init_indices
    !! Initialiser flattened sizes and their source indices
    integer :: num_init_products
    !! Number of initialisers with dimension metadata
    integer :: weight_idx, bias_idx
    !! Indices for weight and bias initialisers
    integer :: num_outputs
    !! Number of outputs
    class(base_actv_type), allocatable :: activation
    !! Activation function
    class(base_init_type), allocatable :: kernel_initialiser, bias_initialiser


    weight_idx = -1
    bias_idx = -1
    allocate(dim_products(size(initialisers)))
    allocate(init_indices(size(initialisers)))
    num_init_products = 0
    if(size(initialisers).lt.1)then
       call stop_program("ONNX FULL layer requires at least 1 initialiser")
       return
    else
       ! check which initialiser has weights and which has biases,
       ! look for dimensions
       do i = 1, size(initialisers)
          if(allocated(initialisers(i)%dims))then
             num_init_products = num_init_products + 1
             dim_products(num_init_products) = product(initialisers(i)%dims)
             init_indices(num_init_products) = i
          end if
       end do
    end if
    ! if both weight and bias have dimension 1, check which is larger and that
    ! the division of it by the kernel size is equal to the length of the other
    select case(num_init_products)
    case(1)
       weight_idx = init_indices(1)
       use_bias = .false.
    case(2)
       ! check which is weight and which is bias
       if(mod(dim_products(1), dim_products(2)).eq.0)then
          weight_idx = init_indices(1)
          bias_idx = init_indices(2)
       elseif(mod(dim_products(2), dim_products(1)).eq.0)then
          weight_idx = init_indices(2)
          bias_idx = init_indices(1)
       else
          call stop_program("ONNX FULL layer initialiser dimensions not compatible")
          return
       end if
    case default
       call stop_program("ONNX FULL layer number of initialisers not supported")
       return
    end select
    num_outputs = value_info(1)%dims(2)

    allocate(data_init_type :: kernel_initialiser)
    select type(kernel_init_data => kernel_initialiser)
    type is(data_init_type)
       kernel_init_data%name = 'data'
       allocate(kernel_init_data%data(size(initialisers(weight_idx)%data)))
       kernel_init_data%data = initialisers(weight_idx)%data
    end select
    if(use_bias)then
       allocate(data_init_type :: bias_initialiser)
       select type(bias_init_data => bias_initialiser)
       type is(data_init_type)
          bias_init_data%name = 'data'
          allocate(bias_init_data%data(size(initialisers(bias_idx)%data)))
          bias_init_data%data = initialisers(bias_idx)%data
       end select
    end if

    activation = activation_setup("none")
    call this%set_hyperparams( &
         num_outputs = num_outputs, &
         use_bias = use_bias, &
         activation = activation, &
         verbose = verbose, &
         kernel_initialiser = kernel_initialiser, &
         bias_initialiser = bias_initialiser &
    )

  end subroutine build_from_onnx_full