Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor tests to use the new data structure #66

Merged
merged 12 commits into from
Jul 10, 2023
49 changes: 0 additions & 49 deletions example/icar-qr-network.f90

This file was deleted.

3 changes: 1 addition & 2 deletions example/read.f90
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ program read_json
inference_engine = inference_engine_t(file_t(input_file_name))
print *, "number of inputs: ", inference_engine%num_inputs()
print *, "number of outputs: ", inference_engine%num_outputs()
print *, "number of hidden layers: ", inference_engine%num_hidden_layers()
print *, "number of neurons per layer: ", inference_engine%neurons_per_layer()
print *, "number of nodes per layer: ", inference_engine%nodes_per_layer()
activation_name = inference_engine%activation_function_name()
print *, "activation function: ", activation_name%string()
print *, "using skip connections: ", merge("true ", "false", inference_engine%skip())
Expand Down
8 changes: 4 additions & 4 deletions example/write-read-infer.f90
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ program write_read_infer
use inference_engine_m, only : inference_engine_t
use string_m, only : string_t
use step_m, only : step_t
use matmul_m, only : matmul_t
use file_m, only : file_t
use kind_parameters_m, only : rkind
use outputs_m, only : outputs_t
use inputs_m, only : inputs_t
implicit none

type(string_t) file_name
Expand All @@ -39,6 +39,7 @@ subroutine write_read_query_infer(output_file_name)
type(inference_engine_t) xor_network, inference_engine
type(file_t) json_output_file, json_input_file
type(outputs_t) network_outputs
real(rkind), parameter :: false = 0._rkind, true = 1._rkind

print *, "Constructing an inference_engine_t neural-network object from scratch."
xor_network = inference_engine_t( &
Expand All @@ -63,13 +64,12 @@ subroutine write_read_query_infer(output_file_name)

print *, "Querying the new inference_engine_t object for several properties:"
print *, "number of outputs:", inference_engine%num_outputs()
print *, "number of hidden layers:", inference_engine%num_hidden_layers()
print *, "number of neurons per layer:", inference_engine%neurons_per_layer()
print *, "nodes per layer:", inference_engine%nodes_per_layer()
activation_name = inference_engine%activation_function_name()
print *, "activation function: ", activation_name%string()
print *, "using skip connections: ", merge("true ", "false", inference_engine%skip())
print *, "Performing inference:"
network_outputs = inference_engine%infer([real(rkind):: 0.,1.], matmul_t())
network_outputs = inference_engine%infer(inputs_t([real(rkind):: false,true]))
print *, "inference_engine%infer([0.,1.]) =", network_outputs%outputs()
print *, "Correct answer for the XOR neural network: ", 1.
end subroutine write_read_query_infer
Expand Down
2 changes: 2 additions & 0 deletions src/inference_engine/activation_strategy_m.f90
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
! Copyright (c), The Regents of the University of California
! Terms of use are as specified in LICENSE.txt
module activation_strategy_m

! External dependencies
use kind_parameters_m, only : rkind
use string_m, only : string_t
implicit none
Expand Down
89 changes: 24 additions & 65 deletions src/inference_engine/inference_engine_m_.f90
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@
module inference_engine_m_
!! Define an abstraction that supports inference operationsn on a neural network
use string_m, only : string_t
use inference_strategy_m, only : inference_strategy_t
use activation_strategy_m, only : activation_strategy_t
use file_m, only : file_t
use kind_parameters_m, only : rkind
use inputs_m, only : inputs_t
use outputs_m, only : outputs_t
use differentiable_activation_strategy_m, only :differentiable_activation_strategy_t
use network_increment_m, only : network_increment_t
implicit none

private
Expand All @@ -23,38 +21,43 @@ module inference_engine_m_
!! Encapsulate the minimal information needed to perform inference
private
type(string_t) metadata_(size(key))
real(rkind), allocatable :: weights_(:,:,:), biases__(:,:)
integer, allocatable :: nodes_(:)
class(activation_strategy_t), allocatable :: activation_strategy_ ! Strategy Pattern facilitates elemental activation

! TODO: rm these legacy components
real(rkind), allocatable :: input_weights_(:,:) ! weights applied to go from the inputs to first hidden layer
real(rkind), allocatable :: hidden_weights_(:,:,:) ! weights applied to go from one hidden layer to the next
real(rkind), allocatable :: output_weights_(:,:) ! weights applied to go from the final hidden layer to the outputs
real(rkind), allocatable :: biases_(:,:) ! neuronal offsets for each hidden layer
real(rkind), allocatable :: output_biases_(:) ! neuronal offsets applied to outputs
class(activation_strategy_t), allocatable :: activation_strategy_ ! Strategy Pattern facilitates elemental activation
contains
procedure :: infer
procedure :: to_json
procedure, private :: infer_from_array_of_inputs
procedure, private :: infer_from_inputs_object
generic :: infer => infer_from_array_of_inputs, infer_from_inputs_object
procedure :: num_inputs
procedure :: num_outputs
procedure :: neurons_per_layer
procedure :: num_hidden_layers
procedure :: nodes_per_layer
procedure :: norm
procedure :: assert_conformable_with
procedure :: skip
procedure, private :: subtract
generic :: operator(-) => subtract
procedure :: skip
procedure :: activation_function_name
procedure :: assert_consistent
procedure :: input_weights
procedure :: hidden_weights
procedure :: output_weights
procedure :: increment
end type

interface inference_engine_t

pure module function construct_from_components(metadata, input_weights, hidden_weights, output_weights, biases, output_biases) &
result(inference_engine)
pure module function construct_from_padded_arrays(metadata, weights, biases, nodes) result(inference_engine)
implicit none
type(string_t), intent(in) :: metadata(:)
real(rkind), intent(in) :: weights(:,:,:), biases(:,:)
integer, intent(in) :: nodes(0:)
type(inference_engine_t) inference_engine
end function

pure module function construct_from_legacy_arrays( &
metadata, input_weights, hidden_weights, output_weights, biases, output_biases &
) result(inference_engine)
implicit none
type(string_t), intent(in) :: metadata(:)
real(rkind), intent(in), dimension(:,:) :: input_weights, output_weights, biases
Expand All @@ -72,11 +75,6 @@ impure elemental module function construct_from_json(file_) result(inference_eng

interface

pure module subroutine assert_consistent(self)
implicit none
class(inference_engine_t), intent(in) :: self
end subroutine

impure elemental module function to_json(self) result(json_file)
implicit none
class(inference_engine_t), intent(in) :: self
Expand All @@ -102,19 +100,10 @@ elemental module subroutine assert_conformable_with(self, inference_engine)
type(inference_engine_t), intent(in) :: inference_engine
end subroutine

pure module function infer_from_array_of_inputs(self, input, inference_strategy) result(outputs)
implicit none
class(inference_engine_t), intent(in) :: self
real(rkind), intent(in) :: input(:)
class(inference_strategy_t), intent(in) :: inference_strategy
type(outputs_t) outputs
end function

elemental module function infer_from_inputs_object(self, inputs, inference_strategy) result(outputs)
elemental module function infer(self, inputs) result(outputs)
implicit none
class(inference_engine_t), intent(in) :: self
type(inputs_t), intent(in) :: inputs
class(inference_strategy_t), intent(in) :: inference_strategy
type(outputs_t) outputs
end function

Expand All @@ -130,22 +119,10 @@ elemental module function num_inputs(self) result(input_count)
integer input_count
end function

elemental module function neurons_per_layer(self) result(neuron_count)
implicit none
class(inference_engine_t), intent(in) :: self
integer neuron_count
end function

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

elemental module function skip(self) result(use_skip_connections)
pure module function nodes_per_layer(self) result(node_count)
implicit none
class(inference_engine_t), intent(in) :: self
logical use_skip_connections
integer, allocatable :: node_count(:)
end function

elemental module function activation_function_name(self) result(activation_name)
Expand All @@ -154,30 +131,12 @@ elemental module function activation_function_name(self) result(activation_name)
type(string_t) activation_name
end function

pure module function input_weights(self) result(w)
implicit none
class(inference_engine_t), intent(in) :: self
real(rkind), allocatable :: w(:,:)
end function

pure module function hidden_weights(self) result(w)
implicit none
class(inference_engine_t), intent(in) :: self
real(rkind), allocatable :: w(:,:,:)
end function

pure module function output_weights(self) result(w)
pure module function skip(self) result(use_skip_connections)
implicit none
class(inference_engine_t), intent(in) :: self
real(rkind), allocatable :: w(:,:)
logical use_skip_connections
end function

pure module subroutine increment(self, network_increment)
implicit none
class(inference_engine_t), intent(inout) :: self
type(network_increment_t), intent(in) :: network_increment
end subroutine

end interface

end module inference_engine_m_
Loading