Read ONNX attributes for fully connected layer
| Type | Intent | Optional | 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 |
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