build_from_onnx_conv1d Subroutine

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

Read ONNX attributes for 1D convolutional layer

Arguments

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

Instance of the 1D convolutional layer

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

ONNX node information

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

ONNX initialiser information

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

ONNX value info information

integer, intent(in) :: verbose

Verbosity level


Source Code

  subroutine build_from_onnx_conv1d( &
       this, node, initialisers, value_info, verbose &
  )
    !! Read ONNX attributes for 1D convolutional layer
    use athena__activation, only: activation_setup
    use athena__initialiser_data, only: data_init_type
    implicit none

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

    ! Local variables
    integer :: i, weight_idx, bias_idx
    !! Loop index and temporary integer
    integer :: num_filters
    !! Number of filters
    logical :: use_bias = .true.
    !! Whether to use bias
    integer, dimension(1) :: padding, stride, kernel_size, dilation
    !! Padding, stride, kernel size, and dilation
    integer, dimension(:), allocatable :: dims
    !! Dimensions
    character(256) :: val
    !! Attribute value
    class(base_actv_type), allocatable :: activation
    !! Activation function
    class(base_init_type), allocatable :: kernel_initialiser, bias_initialiser

    ! Set default values
    padding = 0
    stride = 1
    kernel_size = 3
    dilation = 1

    do i = 1, size(node%attributes)
       val = node%attributes(i)%val
       select case(trim(adjustl(node%attributes(i)%name)))
       case("pads")
          read(val,*) padding
       case("strides")
          read(val,*) stride
       case("kernel_shape")
          read(val,*) kernel_size
       case("dilations")
          read(val,*) dilation
       case default
          ! Do nothing
          write(0,*) "WARNING: Unrecognised attribute in ONNX CONV1D layer: ", &
               trim(adjustl(node%attributes(i)%name))
       end select
    end do

    weight_idx = -1
    bias_idx = -1
    allocate(dims(0))
    if(size(initialisers).lt.1)then
       call stop_program("ONNX CONV1D layer requires at least 1 initialiser")
       return
    else
       ! check which initialiser has weights and which has biases
       do i = 1, size(initialisers)
          if(allocated(initialisers(i)%dims))then
             dims = [ dims, product(initialisers(i)%dims) ]
          end if
       end do
    end if

    select case(size(dims))
    case(1)
       if(mod(dims(1), kernel_size(1)).eq.0)then
          weight_idx = 1
       else
          call stop_program("ONNX CONV1D layer initialiser dimensions do not &
               &match kernel size")
          return
       end if
       use_bias = .false.
    case(2)
       ! check which is weight and which is bias
       if(mod(dims(1), kernel_size(1)).eq.0 .and. &
            dims(1)/kernel_size(1).eq.dims(2))then
          weight_idx = 1
          bias_idx = 2
       elseif(mod(dims(2), kernel_size(1)).eq.0 .and. &
            dims(2)/kernel_size(1).eq.dims(1))then
          weight_idx = 2
          bias_idx = 1
       else
          call stop_program("ONNX CONV1D layer initialiser dimensions do not &
               &match kernel size")
          return
       end if
    case default
       call stop_program("ONNX CONV1D layer number of initialisers not supported")
       return
    end select

    num_filters = dims(weight_idx) / kernel_size(1)
    if(num_filters .ne. value_info(1)%dims(2))then
       call stop_program("ONNX CONV1D layer number of filters does not match &
            &value info")
       return
    end if

    kernel_initialiser = data_init_type( data = initialisers(weight_idx)%data )
    if(use_bias)then
       bias_initialiser = data_init_type( data = initialisers(bias_idx)%data )
    end if

    activation = activation_setup("none")
    call this%set_hyperparams( &
         num_filters = num_filters, &
         kernel_size = kernel_size, stride = stride, &
         dilation = dilation, &
         padding = "valid", &
         use_bias = use_bias, &
         activation = activation, &
         verbose = verbose, &
         kernel_initialiser = kernel_initialiser, &
         bias_initialiser = bias_initialiser &
    )

  end subroutine build_from_onnx_conv1d