neural_network_m.f90 Source File


This file depends on

sourcefile~~neural_network_m.f90~~EfferentGraph sourcefile~neural_network_m.f90 neural_network_m.f90 sourcefile~activation_m.f90 activation_m.f90 sourcefile~neural_network_m.f90->sourcefile~activation_m.f90 sourcefile~double_precision_file_m.f90 double_precision_file_m.f90 sourcefile~neural_network_m.f90->sourcefile~double_precision_file_m.f90 sourcefile~kind_parameters_m.f90 kind_parameters_m.f90 sourcefile~neural_network_m.f90->sourcefile~kind_parameters_m.f90 sourcefile~metadata_m.f90 metadata_m.f90 sourcefile~neural_network_m.f90->sourcefile~metadata_m.f90 sourcefile~mini_batch_m.f90 mini_batch_m.f90 sourcefile~neural_network_m.f90->sourcefile~mini_batch_m.f90 sourcefile~tensor_m.f90 tensor_m.f90 sourcefile~neural_network_m.f90->sourcefile~tensor_m.f90 sourcefile~tensor_map_m.f90 tensor_map_m.f90 sourcefile~neural_network_m.f90->sourcefile~tensor_map_m.f90 sourcefile~double_precision_string_m.f90 double_precision_string_m.f90 sourcefile~double_precision_file_m.f90->sourcefile~double_precision_string_m.f90 sourcefile~metadata_m.f90->sourcefile~double_precision_string_m.f90 sourcefile~mini_batch_m.f90->sourcefile~kind_parameters_m.f90 sourcefile~input_output_pair_m.f90 input_output_pair_m.f90 sourcefile~mini_batch_m.f90->sourcefile~input_output_pair_m.f90 sourcefile~tensor_m.f90->sourcefile~kind_parameters_m.f90 sourcefile~tensor_map_m.f90->sourcefile~kind_parameters_m.f90 sourcefile~tensor_map_m.f90->sourcefile~tensor_m.f90 sourcefile~tensor_map_m.f90->sourcefile~double_precision_string_m.f90 sourcefile~input_output_pair_m.f90->sourcefile~kind_parameters_m.f90 sourcefile~input_output_pair_m.f90->sourcefile~tensor_m.f90

Files dependent on this one

sourcefile~~neural_network_m.f90~~AfferentGraph sourcefile~neural_network_m.f90 neural_network_m.f90 sourcefile~fiats_m.f90 fiats_m.f90 sourcefile~fiats_m.f90->sourcefile~neural_network_m.f90 sourcefile~trainable_network_m.f90 trainable_network_m.f90 sourcefile~fiats_m.f90->sourcefile~trainable_network_m.f90 sourcefile~layer_m.f90 layer_m.f90 sourcefile~layer_m.f90->sourcefile~neural_network_m.f90 sourcefile~neural_network_s.f90 neural_network_s.F90 sourcefile~neural_network_s.f90->sourcefile~neural_network_m.f90 sourcefile~neural_network_s.f90->sourcefile~layer_m.f90 sourcefile~trainable_network_m.f90->sourcefile~neural_network_m.f90 sourcefile~unmapped_network_s.f90 unmapped_network_s.F90 sourcefile~unmapped_network_s.f90->sourcefile~neural_network_m.f90 sourcefile~workspace_s.f90 workspace_s.F90 sourcefile~workspace_s.f90->sourcefile~neural_network_m.f90 sourcefile~concurrent-inferences.f90 concurrent-inferences.f90 sourcefile~concurrent-inferences.f90->sourcefile~fiats_m.f90 sourcefile~layer_s.f90 layer_s.F90 sourcefile~layer_s.f90->sourcefile~layer_m.f90 sourcefile~learn-addition.f90 learn-addition.F90 sourcefile~learn-addition.f90->sourcefile~fiats_m.f90 sourcefile~learn-exponentiation.f90 learn-exponentiation.F90 sourcefile~learn-exponentiation.f90->sourcefile~fiats_m.f90 sourcefile~learn-multiplication.f90 learn-multiplication.F90 sourcefile~learn-multiplication.f90->sourcefile~fiats_m.f90 sourcefile~learn-power-series.f90 learn-power-series.F90 sourcefile~learn-power-series.f90->sourcefile~fiats_m.f90 sourcefile~learn-saturated-mixing-ratio.f90 learn-saturated-mixing-ratio.F90 sourcefile~learn-saturated-mixing-ratio.f90->sourcefile~fiats_m.f90 sourcefile~saturated_mixing_ratio_m.f90 saturated_mixing_ratio_m.f90 sourcefile~learn-saturated-mixing-ratio.f90->sourcefile~saturated_mixing_ratio_m.f90 sourcefile~print-training-configuration.f90 print-training-configuration.F90 sourcefile~print-training-configuration.f90->sourcefile~fiats_m.f90 sourcefile~read-query-infer.f90 read-query-infer.f90 sourcefile~read-query-infer.f90->sourcefile~fiats_m.f90 sourcefile~saturated_mixing_ratio_m.f90->sourcefile~fiats_m.f90 sourcefile~train-and-write.f90 train-and-write.F90 sourcefile~train-and-write.f90->sourcefile~fiats_m.f90 sourcefile~trainable_network_s.f90 trainable_network_s.f90 sourcefile~trainable_network_s.f90->sourcefile~trainable_network_m.f90 sourcefile~write-read-infer.f90 write-read-infer.F90 sourcefile~write-read-infer.f90->sourcefile~fiats_m.f90

Source Code

! Copyright (c), The Regents of the University of California
! Terms of use are as specified in LICENSE.txt
module neural_network_m
  !! Define an abstraction that supports inference operations on a neural network
  use activation_m, only : activation_t
  use double_precision_file_m, only : double_precision_file_t
  use kind_parameters_m, only : default_real, double_precision
  use julienne_m, only : file_t, string_t
  use metadata_m, only : metadata_t
  use mini_batch_m, only : mini_batch_t
  use tensor_m, only : tensor_t
  use tensor_map_m, only : tensor_map_t
  implicit none

  private
  public :: neural_network_t
  public :: unmapped_network_t
  public :: workspace_t
  public :: assert_consistency

  type neural_network_t(k)
    !! Encapsulate the information needed to perform inference
    integer, kind :: k = default_real 
    type(tensor_map_t(k)), private :: input_map_, output_map_
    type(metadata_t), private :: metadata_
    real(k), allocatable, private :: weights_(:,:,:), biases_(:,:)
    integer, allocatable, private :: nodes_(:)
    type(activation_t), private :: activation_
  contains
    generic :: operator(==)             => default_real_approximately_equal,     double_precision_approximately_equal
    generic :: infer                    => default_real_infer,                   double_precision_infer
    generic :: to_json                  => default_real_to_json,                 double_precision_to_json
    generic :: map_to_input_range       => default_real_map_to_input_range,      double_precision_map_to_input_range
    generic :: map_from_output_range    => default_real_map_from_output_range,   double_precision_map_from_output_range
    generic :: num_hidden_layers        => default_real_num_hidden_layers,       double_precision_num_hidden_layers
    generic :: num_inputs               => default_real_num_inputs,              double_precision_num_inputs
    generic :: num_outputs              => default_real_num_outputs,             double_precision_num_outputs
    generic :: nodes_per_layer          => default_real_nodes_per_layer,         double_precision_nodes_per_layer
    generic :: skip                     => default_real_skip,                    double_precision_skip
    generic :: activation_function_name => default_real_activation_name,         double_precision_activation_name
    generic :: learn                    => default_real_learn
    procedure, private, non_overridable :: default_real_approximately_equal,     double_precision_approximately_equal
    procedure, private, non_overridable :: default_real_infer,                   double_precision_infer
    procedure, private, non_overridable :: default_real_learn
    procedure, private, non_overridable :: default_real_to_json,                 double_precision_to_json
    procedure, private, non_overridable :: default_real_map_to_input_range,      double_precision_map_to_input_range
    procedure, private, non_overridable :: default_real_map_from_output_range,   double_precision_map_from_output_range
    procedure, private, non_overridable :: default_real_num_hidden_layers,       double_precision_num_hidden_layers
    procedure, private, non_overridable :: default_real_num_inputs,              double_precision_num_inputs
    procedure, private, non_overridable :: default_real_num_outputs,             double_precision_num_outputs
    procedure, private, non_overridable :: default_real_nodes_per_layer,         double_precision_nodes_per_layer
    procedure, private, non_overridable :: default_real_skip,                    double_precision_skip
    procedure, private, non_overridable :: default_real_activation_name,         double_precision_activation_name
  end type

  type workspace_t(k)
    integer, kind :: k = default_real
    real(k), allocatable, dimension(:,:) :: a
    real(k), allocatable, dimension(:,:,:) :: dcdw, vdw, sdw, vdwc, sdwc
    real(k), allocatable, dimension(:,:) :: z, delta, dcdb, vdb, sdb, vdbc, sdbc
  contains
    generic :: fully_allocated          => default_real_allocated
    generic :: allocate_if_necessary    => default_real_allocate
    procedure, non_overridable, private :: default_real_allocated
    procedure, non_overridable, private :: default_real_allocate
  end type

  interface workspace_t

    pure module function default_real_workspace(neural_network) result(workspace)
      implicit none
      type(neural_network_t), intent(in) :: neural_network
      type(workspace_t) workspace
    end function

  end interface

  interface

    module subroutine default_real_allocate(self, neural_network)
      implicit none
      class(workspace_t), intent(inout) :: self
      type(neural_network_t), intent(in) :: neural_network
    end subroutine

    pure module function default_real_allocated(self) result(all_allocated)
      implicit none
      class(workspace_t), intent(in) :: self
      logical all_allocated
    end function

  end interface

  interface neural_network_t

    module function default_real_construct_from_components(metadata, weights, biases, nodes, input_map, output_map) &
      result(neural_network)
      implicit none
      type(string_t), intent(in) :: metadata(:)
      real, intent(in) :: weights(:,:,:), biases(:,:)
      integer, intent(in) :: nodes(0:)
      type(tensor_map_t), intent(in), optional :: input_map, output_map
      type(neural_network_t) neural_network
    end function

    module function double_precision_construct_from_components(metadata, weights, biases, nodes, input_map, output_map) &
      result(neural_network)
      implicit none
      type(metadata_t), intent(in) :: metadata
      double precision, intent(in) :: weights(:,:,:), biases(:,:)
      integer, intent(in) :: nodes(0:)
      type(tensor_map_t(double_precision)), intent(in), optional :: input_map, output_map
      type(neural_network_t(double_precision)) neural_network
    end function

    impure elemental module function default_real_from_json(file_) result(neural_network)
      implicit none
      type(file_t), intent(in) :: file_
      type(neural_network_t) neural_network
    end function

    impure elemental module function double_precision_from_json(file) result(neural_network)
      implicit none
      type(double_precision_file_t), intent(in) :: file
      type(neural_network_t(double_precision)) neural_network
    end function

  end interface

  interface ! neural_network_t type-bound procedures

    elemental module function default_real_approximately_equal(lhs, rhs) result(lhs_eq_rhs)
      !! The result is true if lhs and rhs are the same to within a tolerance
      implicit none
      class(neural_network_t), intent(in) :: lhs, rhs
      logical lhs_eq_rhs
    end function

    elemental module function double_precision_approximately_equal(lhs, rhs) result(lhs_eq_rhs)
      !! The result is true if lhs and rhs are the same to within a tolerance
      implicit none
      class(neural_network_t(double_precision)), intent(in) :: lhs, rhs
      logical lhs_eq_rhs
    end function

    elemental module function default_real_map_to_input_range(self, tensor) result(normalized_tensor)
      !! The result contains the input tensor values normalized to fall on the range used during training
      implicit none
      class(neural_network_t), intent(in) :: self
      type(tensor_t), intent(in) :: tensor
      type(tensor_t) normalized_tensor
    end function

    elemental module function double_precision_map_to_input_range(self, tensor) result(normalized_tensor)
      !! The result contains the input tensor values normalized to fall on the range used during training
      implicit none
      class(neural_network_t(double_precision)), intent(in) :: self
      type(tensor_t(double_precision)), intent(in) :: tensor
      type(tensor_t(double_precision)) normalized_tensor
    end function

    elemental module function default_real_map_from_output_range(self, normalized_tensor) result(tensor)
      !! The result contains the output tensor values unmapped via the inverse of the mapping used in training
      implicit none
      class(neural_network_t), intent(in) :: self
      type(tensor_t), intent(in) :: normalized_tensor
      type(tensor_t) tensor
    end function

    elemental module function double_precision_map_from_output_range(self, normalized_tensor) result(tensor)
      !! The result contains the output tensor values unmapped via the inverse of the mapping used in training
      implicit none
      class(neural_network_t(double_precision)), intent(in) :: self
      type(tensor_t(double_precision)), intent(in) :: normalized_tensor
      type(tensor_t(double_precision)) tensor
    end function

    impure elemental module function default_real_to_json(self) result(json_file)
      implicit none
      class(neural_network_t), intent(in) :: self
      type(file_t) json_file
    end function

    impure elemental module function double_precision_to_json(self) result(json_file)
      implicit none
      class(neural_network_t(double_precision)), intent(in) :: self
      type(file_t) json_file
    end function

    elemental module function default_real_infer(self, inputs) result(outputs)
      implicit none
      class(neural_network_t), intent(in) :: self
      type(tensor_t), intent(in) :: inputs
      type(tensor_t) outputs
    end function

    elemental module function double_precision_infer(self, inputs) result(outputs)
      implicit none
      class(neural_network_t(double_precision)), intent(in) :: self
      type(tensor_t(double_precision)), intent(in) :: inputs
      type(tensor_t(double_precision)) outputs
    end function

    elemental module function default_real_num_outputs(self) result(output_count)
      implicit none
      class(neural_network_t), intent(in) :: self
      integer output_count
    end function

    elemental module function double_precision_num_outputs(self) result(output_count)
      implicit none
      class(neural_network_t(double_precision)), intent(in) :: self
      integer output_count
    end function

    elemental module function default_real_num_hidden_layers(self) result(hidden_layer_count)
      implicit none
      class(neural_network_t), intent(in) :: self
      integer hidden_layer_count
    end function

    elemental module function double_precision_num_hidden_layers(self) result(hidden_layer_count)
      implicit none
      class(neural_network_t(double_precision)), intent(in) :: self
      integer hidden_layer_count
    end function

    elemental module function default_real_num_inputs(self) result(input_count)
      implicit none
      class(neural_network_t), intent(in) :: self
      integer input_count
    end function

    elemental module function double_precision_num_inputs(self) result(input_count)
      implicit none
      class(neural_network_t(double_precision)), intent(in) :: self
      integer input_count
    end function

    pure module function default_real_nodes_per_layer(self) result(node_count)
      implicit none
      class(neural_network_t), intent(in) :: self
      integer, allocatable :: node_count(:)
    end function

    pure module function double_precision_nodes_per_layer(self) result(node_count)
      implicit none
      class(neural_network_t(double_precision)), intent(in) :: self
      integer, allocatable :: node_count(:)
    end function

    elemental module function default_real_activation_name(self) result(activation_name)
      implicit none
      class(neural_network_t), intent(in) :: self
      type(string_t) activation_name
    end function

    elemental module function double_precision_activation_name(self) result(activation_name)
      implicit none
      class(neural_network_t(double_precision)), intent(in) :: self
      type(string_t) activation_name
    end function

    pure module function default_real_skip(self) result(use_skip_connections)
      implicit none
      class(neural_network_t), intent(in) :: self
      logical use_skip_connections
    end function

    pure module function double_precision_skip(self) result(use_skip_connections)
      implicit none
      class(neural_network_t(double_precision)), intent(in) :: self
      logical use_skip_connections
    end function

    pure module subroutine default_real_learn(self, mini_batches_arr, cost, adam, learning_rate, workspace)
      implicit none
      class(neural_network_t), intent(inout) :: self
      type(mini_batch_t), intent(in) :: mini_batches_arr(:)
      real, intent(out), allocatable, optional :: cost(:)
      logical, intent(in) :: adam
      real, intent(in) :: learning_rate
      type(workspace_t), intent(inout) :: workspace
    end subroutine

  end interface

  interface assert_consistency

    pure module subroutine default_real_consistency(self)
      implicit none
      class(neural_network_t), intent(in) :: self
    end subroutine

    pure module subroutine double_precision_consistency(self)
      implicit none
      class(neural_network_t(double_precision)), intent(in) :: self
    end subroutine

  end interface

  type unmapped_network_t(k)
    integer, kind :: k = default_real
    private
    type(neural_network_t(k)) neural_network_
  contains
    generic :: infer                    => default_real_infer_unmapped, double_precision_infer_unmapped
    procedure, private, non_overridable :: default_real_infer_unmapped, double_precision_infer_unmapped
  end type

  interface unmapped_network_t

    impure elemental module function double_precision_unmapped_from_json(file) result(unmapped_network)
      implicit none
      type(double_precision_file_t), intent(in) :: file
      type(unmapped_network_t(double_precision)) unmapped_network
    end function

  end interface

  interface

    elemental module function default_real_infer_unmapped(self, inputs) result(outputs)
      implicit none
      class(unmapped_network_t), intent(in) :: self
      type(tensor_t), intent(in) :: inputs
      type(tensor_t) outputs
    end function

    elemental module function double_precision_infer_unmapped(self, inputs) result(outputs)
      implicit none
      class(unmapped_network_t(double_precision)), intent(in) :: self
      type(tensor_t(double_precision)), intent(in) :: inputs
      type(tensor_t(double_precision)) outputs
    end function

  end interface

end module neural_network_m