def __init__(self, sensor_ids, action_ids, n_hidden, bias=True): super(FFNetwork, self).__init__(sensor_ids=sensor_ids, action_ids=action_ids) self.net = buildNetwork(SensorModel.array_length(sensor_ids), n_hidden, 1, hiddenclass=TanhLayer, #outclass=TanhLayer, bias=bias) self.scaler_input = None self.trainer = None
def train(self, training_files, learningrate=0.01, scaling=True, noise=False, verbose=True): print "building dataset..." ds = SupervisedDataSet(SensorModel.array_length(self.sensor_ids), 1) # read training file line, create sensormodel object, do backprop a = None s = None for logfile in training_files: print "loading file", logfile with open(logfile) as f: for line in f: if line.startswith("Received:"): s = SensorModel(string=line.split(' ', 1)[1]) elif line.startswith("Sending:"): a = Actions.from_string(string=line.split(' ', 1)[1]) if s is not None and a is not None: ds.addSample(inp=s.get_array(self.sensor_ids), target=a[self.action_ids[0]]) if noise: # add the same training sample again but with noise in the sensors s.add_noise() ds.addSample(inp=s.get_array(self.sensor_ids), target=a[self.action_ids[0]]) s = None a = None print "dataset size:", len(ds) if scaling: print "scaling dataset" self.scaler_input = StandardScaler(with_mean=True, with_std=False).fit(ds.data['input']) ds.data['input'] = self.scaler_input.transform(ds.data['input']) ds.data['target'] = ds.data['target'] #self.trainer = BackpropTrainer(self.net, learningrate=learningrate, verbose=verbose) self.trainer = RPropMinusTrainer(self.net, verbose=verbose, batchlearning=True) print "training network..." self.trainer.trainUntilConvergence(dataset=ds, validationProportion=0.25, maxEpochs=10, continueEpochs=2)
def race(self, driver): """ Let a driver race in a preconfigured quickrace :param driver: a driver object that generates actions based on sensors :return: driver fitness value after race """ if not self.connect(): raise IOError("could not connect to TORCS") start_time = timeit.default_timer() try: print "Start racing..." s = None lap_times = [] cur_lap_time = -10.0 timeout_reached = False recovery_lock = 0 max_speed = 0.0 avg_speed = RunningAverage() driver.prepare() while True: data = self.sock.recv(2048) if data.strip().startswith("("): s = SensorModel(string=data) action = driver.get_action(sensors=s) # save maximum speed for fitness function max_speed = max(max_speed, s['speedX']) avg_speed.add_value(float(s['speedX'])) # AUTORECOVERY: if off track, go backwards until back on track and then some more if self.auto_recover and (s.is_off_track() or recovery_lock > 0): action.gear = -1 action.accel = 0.4 action.clutch = 0.0 action.steering = s['angle'] / -2.0 if s.is_off_track(): recovery_lock = RECOVERY_LOCK else: recovery_lock -= 1 self.sock.sendto(str(action), self.server_address) if s['curLapTime'][0] < cur_lap_time: lap_times.append(cur_lap_time) print "lap %i: %0.2f seconds" % (len(lap_times), cur_lap_time) cur_lap_time = s['curLapTime'][0] else: if data.startswith("***shutdown***"): if s['curLapTime'][0] > 1: lap_times.append(s['curLapTime'][0]) print "--- END OF RACE --- finished at position %i, avg/max speed: %0.2f/%0.2f km/h" % ( int(s['racePos']), avg_speed.avg, max_speed) break if self.timeout is not None and s['curLapTime'] > self.timeout: print "--- RACE TIMEOUT REACHED ---" timeout_reached = True break if s is not None: print "lap times:", lap_times # print "distance raced:", s['distRaced'] return driver.compute_fitness(last_sensor=s, lap_times=lap_times, max_speed=max_speed, average_speed=avg_speed.avg, timeout_reached=timeout_reached) else: return 0.0 except KeyboardInterrupt: print "Exit client" except Exception as e: print "Client Error:", e finally: #print "race call took %0.1f seconds." % (timeit.default_timer() - start_time) self.close()