class lwpr_dyn_model(DynamicsLearnerInterface):
    def __init__(self,
                 history_length,
                 prediction_horizon,
                 difference_learning,
                 averaging,
                 streaming,
                 settings=None):
        super().__init__(history_length,
                         prediction_horizon,
                         difference_learning,
                         averaging=averaging,
                         streaming=streaming)
        self.model_ = LWPR(self._get_input_dim(), self.observation_dimension)

        # Default values.
        init_D = 25
        init_alpha = 175
        self.time_threshold = np.inf
        if settings:
            init_D = settings['init_D']
            init_alpha = settings['init_alpha']
            self.time_threshold = settings.get('time_threshold', np.inf)
        self.model_.init_D = init_D * np.eye(self._get_input_dim())
        self.model_.init_alpha = init_alpha * np.eye(self._get_input_dim())

    def _learn(self, training_inputs, training_targets):
        def gen(inputs, targets):
            for i in range(inputs.shape[0]):
                yield targets[i], inputs[i]

        self._learn_from_stream(gen(training_inputs, training_targets),
                                training_inputs.shape[0])

    def _learn_from_stream(self, training_generator, generator_size):
        deck = deque(maxlen=100)
        for count in range(generator_size):
            training_target, training_input = next(training_generator)
            assert training_input.shape[0] == self._get_input_dim()
            assert training_target.shape[0] == self.observation_dimension
            time_before_update = time.perf_counter()
            self.model_.update(training_input, training_target)
            elapsed_time = time.perf_counter() - time_before_update
            deck.append(elapsed_time)
            if count and count % 1000 == 0:
                median_time = sorted(deck)[deck.maxlen // 2]
                print('Update time for iter {} is {}'.format(
                    count, median_time))
                if median_time > self.time_threshold:
                    break

    def _predict(self, inputs):
        assert self.model_, "a trained model must be available"
        prediction = np.zeros((inputs.shape[0], self.observation_dimension))
        for idx in range(inputs.shape[0]):
            prediction[idx, :] = self.model_.predict(inputs[idx])
        return prediction

    def name(self):
        return "LWPR"
Example #2
0
class LWPRFA(FA):
    
    parametric = False

    def __init__(self, indim, outdim):
        FA.__init__(self, indim, outdim)
        self.filename = None

    def reset(self):
        FA.reset(self)
        
        # initialize the LWPR function
        self.lwpr = LWPR(self.indim, self.outdim)     
        self.lwpr.init_D = 10.*np.eye(self.indim)
        self.lwpr.init_alpha = 0.1*np.ones([self.indim, self.indim])
        self.lwpr.meta = True
    
    def predict(self, inp):
        """ predict the output for the given input. """
        # the next 3 lines fix a bug when lwpr models are pickled and unpickled again
        # without it, a TypeError is thrown "Expected a double precision numpy array."
        # even though the numpy array is double precision.
        inp = self._asFlatArray(inp)
        inp_tmp = np.zeros(inp.shape)
        inp_tmp[:] = inp
        return self.lwpr.predict(inp_tmp)

    def train(self):
        for i, t in self.dataset:
            i = self._asFlatArray(i)
            t = self._asFlatArray(t)
            self.lwpr.update(i, t)


    def _cleanup(self):
        if self.filename and os.path.exists(self.filename):
            os.remove(self.filename)

    def __getstate__(self):
        """ required for pickle. removes the lwpr model from the dictionary
            and saves it to file explicitly.
        """
        # create unique hash key for filename and write lwpr to file
        hashkey = hashlib.sha1(str(self.lwpr) + time.ctime() + str(np.random.random())).hexdigest()[:8]
        if not os.path.exists('.lwprmodels'):
            os.makedirs('.lwprmodels')
            
        # remove any old files if existing
        if self.filename:
            os.remove(self.filename)    
               
        self.filename = '.lwprmodels/lwpr_%s.binary'%hashkey
        self.lwpr.write_binary(self.filename)
        
        # remove lwpr from dictionary and return state
        state = self.__dict__.copy()
        del state['lwpr']
        return state
        
    def __setstate__(self, state):
        """ required for pickle. loads the stored lwpr model explicitly.
        """
        self.__dict__.update(state)
        self.lwpr = LWPR(self.filename)