Пример #1
0
def setup_integrator(method, use_adjoint, step_size, rtol=1e-3, atol=1e-5):
    integrator_options = dict()

    if method not in ['dopri5', 'adams']:
        integrator_options  = {'step_size': step_size}
    
    integrator = generic_integrator.GenericIntegrator(
            integrator_library = 'odeint', 
            integrator_name = method,
            use_adjoint_integration=use_adjoint, 
            integrator_options=integrator_options,
            rtol=rtol, atol=atol)

    return integrator
Пример #2
0
def setup_integrator(method,
                     use_adjoint,
                     step_size,
                     rtol=1e-8,
                     atol=1e-12,
                     nr_of_checkpoints=None,
                     checkpointing_time_interval=None):

    integrator_options = dict()

    if method not in ['dopri5', 'adams']:
        integrator_options = {'step_size': step_size}

    integrator = generic_integrator.GenericIntegrator(
        integrator_library='odeint',
        integrator_name=method,
        use_adjoint_integration=use_adjoint,
        integrator_options=integrator_options,
        rtol=rtol,
        atol=atol,
        nr_of_checkpoints=nr_of_checkpoints,
        checkpointing_time_interval=checkpointing_time_interval)
    return integrator
Пример #3
0
    def __init__(self,
                 nr_of_image_channels,
                 layer_channels=[64, 128, 256, 512],
                 nr_of_blocks_per_layer=[1, 1, 1, 1],
                 downsampling_stride=2,
                 nonlinearity='relu',
                 particle_sizes=[[15, 15], [11, 11], [7, 7], [5, 5]],
                 nr_of_particles=10,
                 nr_of_classes=10,
                 state_initializer=None,
                 costate_initializer=None,
                 integrator=None,
                 shooting_model=None,
                 shooting_model_kwargs=None):

        super(BasicResNet, self).__init__()
        self.nr_of_image_channels = nr_of_image_channels
        self.layer_channels = layer_channels
        self.nr_of_blocks_per_layer = nr_of_blocks_per_layer
        self.nr_of_classes = nr_of_classes

        self.nonlinearity = nonlinearity
        self.nl, _ = ad.get_nonlinearity(nonlinearity=nonlinearity)

        if state_initializer is not None:
            print('INFO: Using externally defined state initializer')
            self._state_initializer = state_initializer
        else:
            print('WARNING: Using default state initializer')
            self._state_initializer = parameter_initialization.ConvolutionEvolutionParameterInitializer(
                only_random_initialization=True,
                random_initialization_magnitude=0.05)

        if costate_initializer is not None:
            print('INFO: Using externally defined costate initializer')
            self._costate_initializer = costate_initializer
        else:
            print('WARNING: Using default costate initializer')
            self._costate_initializer = parameter_initialization.ConvolutionEvolutionParameterInitializer(
                only_random_initialization=True,
                random_initialization_magnitude=0.05)

        # setup the integrator
        if integrator is not None:
            print('INFO: Using externally defined integrator')
            self._integrator = integrator
        else:
            print('WARNING: Using default integrator')
            integrator_options = dict()
            integrator_options['step_size'] = 0.1
            self._integrator = generic_integrator.GenericIntegrator(
                integrator_library='odeint',
                integrator_name='rk4',
                integrator_options=integrator_options)

        self.nr_of_particles = nr_of_particles
        self.particle_sizes = particle_sizes

        if len(layer_channels) != len(self.particle_sizes):
            raise ValueError(
                'Dimension mismatch, between laters and particle sizes. A particle size needs to be defined for each layer.'
            )

        # initial convolution layer
        self.initial_conv = nn.Conv2d(self.nr_of_image_channels,
                                      layer_channels[0],
                                      kernel_size=3,
                                      padding=1,
                                      bias=True)
        self.batch_norm = nn.BatchNorm2d(layer_channels[0])

        downsampling_strides = [downsampling_stride
                                ] * (len(layer_channels) - 1) + [None]

        if shooting_model is not None:
            self.shooting_model = shooting_model
        else:
            self.shooting_model = shooting_models.AutoShootingIntegrandModelSimpleConv2D
            print('WARNING: Using default shooting model {}'.format(
                self.shooting_model))

        if shooting_model_kwargs is not None:
            self._shooting_model_kwargs = shooting_model_kwargs
        else:
            self._shooting_model_kwargs = {}

        self.shooting_layers = self._create_shooting_layers(
            layer_channels=self.layer_channels,
            nr_of_blocks_per_layer=self.nr_of_blocks_per_layer)

        self.striding_blocks = self._create_striding_blocks(
            strides=downsampling_strides)

        self.last_linear = nn.Linear(layer_channels[-1], self.nr_of_classes)

        self._forward_not_yet_executed = True
Пример #4
0
    def __init__(self,
                 name,
                 shooting_integrand=None,
                 shooting_integrand_name=None,
                 integrator_library='odeint',
                 integrator_name='rk4',
                 use_adjoint_integration=False,
                 integrator_options=None,
                 integrator=None,
                 keep_initial_state_parameters_at_zero=False,
                 enlarge_pass_through_states_and_costates=True,
                 use_particle_free_rnn_mode=False,
                 use_particle_free_time_dependent_mode=False,
                 nr_of_particle_free_time_dependent_steps=10,
                 max_integration_time=None,
                 *args,
                 **kwargs):
        """

        :param name: unique name of this block (needed to keep track of the parameters when there is pass through)
        :param shooting_integrand:
        :param shooting_integrand_name:
        :param integrator_library:
        :param integrator_name:
        :param use_adjoint_integration:
        :param integrator_options:
        :param integrator: We can also instantiate an integrator externally and simply pass it here
        :param keep_initial_state_parameters_at_zero: If set to true than all the newly created initial state parameters are kept at zero (and not optimized over); this includes state parameters created via state/costate enlargement.
        :param enlarge_pass_through_states_and_costates: all the pass through states/costates are enlarged so they match the dimensions of the states/costates. This assures that parameters can be concatenated.
        :param use_particle_free_rnn_mode: if set to true than the particles are not used to compute the parameterization, instead an RNN model is assumed and the layer parameters are optimized directly, particles will stay as initialized
        :param use_particle_free_time_dependent_mode: mimicks a more classical resnet, by parameterizing via a finite number of direct transformations
        :param nr_of_particle_free_time_dependent_steps: specifies the number of steps where the parameterization happens (piecewise constant in the middle)
        :param max_integration_time: sets the maximum integration time. So default integrations are from 0 to max_integration_times. Also affects time-interval for particle_free_time_dependent_mode
        :param args:
        :param kwargs:
        """

        super(ShootingBlockBase, self).__init__()

        self._block_name = name
        """Name of the shooting block"""

        self._forward_not_yet_executed = True
        """This is to keep track if it has been run forward. To assure parameters() is not called before one forward pass has been accomplished.
        As for convenience the parameters are constructed dynamically."""

        if shooting_integrand is None and shooting_integrand_name is None:
            raise ValueError(
                'Either shooting_integrand or shooting_integrand_name need to be specified'
            )

        if shooting_integrand is not None and shooting_integrand_name is not None:
            raise ValueError(
                'Either shooting_integrand or shooting_integrand_name need to be specified. You specified both. Pick one option.'
            )

        if shooting_integrand is not None:
            self.shooting_integrand = shooting_integrand
        else:
            self.shooting_integrand = self._get_shooting_integrand_by_name(
                shooting_integrand_name=shooting_integrand_name)

        #self.add_module(name='shooting_integrand', module=self.shooting_integrand) # probably remove

        if max_integration_time is not None:
            self.integration_time = torch.tensor([0, max_integration_time
                                                  ]).float()
        else:
            # set to default integration interval
            self.integration_time = torch.tensor([0, 1]).float()

        self.integration_time_vector = None

        if integrator is not None:
            print('INFO: using externally specified integrator')
            self.integrator = integrator
        else:
            self.integrator_name = integrator_name
            self.integrator_library = integrator_library
            self.integrator_options = integrator_options
            self.use_adjoint_integration = use_adjoint_integration

            if self.integrator_options is None:
                print(
                    'WARNING: integrator options are NOT set. Will use default options'
                )

            self.integrator = generic_integrator.GenericIntegrator(
                integrator_library=self.integrator_library,
                integrator_name=self.integrator_name,
                use_adjoint_integration=self.use_adjoint_integration,
                integrator_options=self.integrator_options)

        self._state_parameter_dict = None
        """Dictionary holding the state variables"""

        self.keep_state_parameters_at_zero = keep_initial_state_parameters_at_zero
        """
        If set to true one only optimizes over the costate and the state parameters are kept at zero (i.e., are no parameters).
        This is for example useful when mimicking ResNet style dimension increase. 
        """

        self.enlarge_pass_through_states_and_costates = enlarge_pass_through_states_and_costates
        """If set to true the pass through states and costates will be enlarged so they are compatible in size with the states and costates and can be concatenated"""

        self.use_particle_free_rnn_mode = use_particle_free_rnn_mode
        """if set to true than the particles are not used to compute the parameterization, instead an RNN model is assumed and the layer parameters are optimized directly, particles will stay as initialized"""
        self._particle_free_rnn_parameter_func = None

        self.use_particle_free_time_dependent_mode = use_particle_free_time_dependent_mode
        self.nr_of_particle_free_time_dependent_steps = nr_of_particle_free_time_dependent_steps

        if self.use_particle_free_time_dependent_mode and self.use_particle_free_rnn_mode:
            raise ValueError(
                'use_particle_free_time_depdenent_mode and use_particle_free_rnn_mode cannot be set simultaneosusly'
            )

        self._costate_parameter_dict = None
        """Dictionary holding the costates (i.e., adjoints/duals)"""

        # TODO: see if we really need these variables, seems like they are no longer needed
        # self._pass_through_state_parameter_dict_of_dicts = None
        # """State parameters that are passed in externally, but are not parameters to be optimized over"""
        # self._pass_through_costate_parameter_dict_of_dicts = None
        # """Costate parameters that are passed in externally, but are not parameters to be optimized over"""

        self._pass_through_state_dict_of_dicts_enlargement_parameters = None
        self._pass_through_costate_dict_of_dicts_enlargement_parameters = None

        state_dict, costate_dict = self.create_initial_state_and_costate_parameters(
            *args, **kwargs)

        # particle-free RNN mode is a direct optimization over the NN parameters (a la Neural ODE)
        # it is included here simply to allow for direct comparisions with the same code
        # if self.use_particle_free_rnn_mode:
        #     # those will have the default initialization
        #     self._particle_free_rnn_parameters = self.shooting_integrand.create_default_parameter_objects_on_consistent_device()
        #     # let's register them for optimization
        #     self._particle_free_rnn_parameters = self.register_particle_free_rnn_parameters(rnn_parameters=self._particle_free_rnn_parameters)
        #     # and then associate them with the integrand, so the integrand knows that these are externally managed
        #     self.shooting_integrand.set_externally_managed_rnn_parameters(self._particle_free_rnn_parameters)
        #     # we just set them to default, these will not really be needed though (as we are not optimizing over these values)
        #     self._state_parameter_dict = state_dict
        #     self._costate_parameter_dict = costate_dict

        if self.use_particle_free_rnn_mode or self.use_particle_free_time_dependent_mode:

            if self.use_particle_free_rnn_mode:
                time_dependent_steps = 1
            else:
                time_dependent_steps = self.nr_of_particle_free_time_dependent_steps

            # create the function that contains the parameters and that we can query for a parameter at a particular time
            self._particle_free_rnn_parameter_func = ParticleFreeParameterFunc(
                time_dependent_steps=time_dependent_steps,
                integration_time=self.integration_time,
                parameter_creation_func=self.shooting_integrand.
                create_default_parameter_objects_on_consistent_device)
            # register its parameters
            pars = self._particle_free_rnn_parameter_func.get_time_parameter_list(
            )
            for i, p in enumerate(pars):
                self.register_particle_free_parameters(
                    parameters=p, name_prefix='pf_timestep{}_'.format(i))

            # and then associate them with the integrand, so the integrand knows that these are externally managed
            self.shooting_integrand.set_externally_managed_rnn_parameter_func(
                self._particle_free_rnn_parameter_func)

            # we just set them to default, these will not really be needed though (as we are not optimizing over these values)
            self._state_parameter_dict = state_dict
            self._costate_parameter_dict = costate_dict
        else:
            self._state_parameter_dict, self._costate_parameter_dict = self.register_state_and_costate_parameters(
                state_dict=state_dict,
                costate_dict=costate_dict,
                keep_state_parameters_at_zero=
                keep_initial_state_parameters_at_zero)

        # now register the parameters that are part of the integrands (this allows for easy definition of parameters in the integrand constructors
        self.register_integrand_parameters(integrand=self.shooting_integrand)
in_features_size = 2

#check_models = ['updown']
#check_models = ['DEBUG']
check_models = ['simple']
#check_models = ['universal']

#check_models = ['updown','DEBUG','simple',"universal"]

number_of_tests_passed = 0
number_of_tests_attempted = 0
tolerance = 5e-3

integrator = generic_integrator.GenericIntegrator(
    integrator_library='odeint',
    integrator_name='rk4',
    use_adjoint_integration=False,
    integrator_options=integrator_options)

for current_model in check_models:

    if current_model == 'simple':
        shooting_model = shooting_models.AutoShootingIntegrandModelSimple(
            in_features=in_features_size,
            nonlinearity=nonlinearity,
            nr_of_particles=nr_of_particles,
            particle_dimension=1,
            particle_size=in_features_size,
            parameter_weight=parameter_weight)
    elif current_model == 'universal':
        shooting_model = shooting_models.AutoShootingIntegrandModelUniversal(
        weight_decay = 0.0001
        print('Using ResNet: weight = {}'.format(weight_decay))
        simple_resnet = sdnn.ResNet(nr_of_layers=args.nr_of_layers)
    elif args.use_double_resnet:
        #weight_decay = 0.025
        weight_decay = 0.01
        print('Using DoubleResNetUpDown: weight = {}'.format(weight_decay))
        simple_resnet = sdnn.DoubleResNetUpDown(
            nr_of_layers=args.nr_of_layers, inflation_factor=inflation_factor)
    elif args.use_neural_ode:
        print('Using neural ode')
        func = sdnn.ODESimpleFunc()
        optimizer = optim.RMSprop(func.parameters(), lr=1e-3)
        integrator = gi.GenericIntegrator(integrator_library='odeint',
                                          integrator_name=args.method,
                                          use_adjoint_integration=False,
                                          rtol=1e-8,
                                          atol=1e-12)

    else:
        use_shooting = True
        print('Using shooting')

    if not use_shooting:
        if args.use_neural_ode:
            params = func.parameters()
        else:
            params = simple_resnet.parameters()
    else:

        sample_batch_in, sample_batch_out = get_sample_batch(