├── .gitignore ├── GameSettingsEvent.py ├── README.md ├── benchmark.py ├── driver_base.py ├── drivers ├── __init__.py ├── deepdrive │ ├── __init__.py │ ├── deep_drive_model.prototxt │ └── deep_driver.py └── deepdrive_tf │ ├── __init__.py │ ├── deep_driver_tf.py │ ├── gtanet.py │ ├── layers.py │ └── train │ ├── .gitignore │ ├── __init__.py │ ├── data_utils.py │ ├── layers.py │ └── train_gtanet.py └── main.py /.gitignore: -------------------------------------------------------------------------------- 1 | /drivers/pt/* 2 | .DS_Store 3 | .idea/ 4 | *.pyc 5 | *_log 6 | drivers/deepdrive/caffe_deep_drive_train_iter_35352.caffemodel 7 | -------------------------------------------------------------------------------- /GameSettingsEvent.py: -------------------------------------------------------------------------------- 1 | class GTASetting(object): 2 | def __init__(self, key, value): 3 | self.key = key 4 | self.value = value 5 | 6 | def __repr__(self): 7 | return str(type(self)) + '<{}={}>'.format(self.key, self.value) 8 | 9 | def __str__(self): 10 | return repr(self) 11 | 12 | def __hash__(self): 13 | return self.value.__hash__() 14 | 15 | def __eq__(self, other): 16 | return type(other) == type(self) and \ 17 | other.amount == self.value 18 | 19 | def compile(self): 20 | return 'GameSettings', self.key, self.value 21 | 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DeepDrive in [Universe](https://universe.openai.com/) 2 | 3 | _Pretrained self-driving car models that run in GTAV / Universe_ 4 | 5 | ## Prerequisites 6 | 7 | Follow the env setup instructions [here](https://github.com/openai/universe-windows-envs/blob/master/vnc-gtav/README.md) 8 | 9 | ## Setup 10 | ``` 11 | git clone https://github.com/deepdrive/deepdrive-universe 12 | ``` 13 | 14 | Note: You will need GPU acceleration to do inference at the 8Hz that the model runs. Slower (or faster) inference may work, but is not the standard way the model is run. 15 | 16 | ### Baseline model - Caffe version 17 | Install the latest version of Caffe and download the model via 18 | ``` 19 | cd drivers/deepdrive 20 | wget -O caffe_deep_drive_train_iter_35352.caffemodel https://goo.gl/sVAedm 21 | ``` 22 | 23 | ### (Work in progress) Baseline model - Tensorflow version 24 | _Thanks to [Rafal jozefowicz](https://github.com/rafaljozefowicz) for helping train this model_ 25 | ``` 26 | cd drivers/deepdrive_tf 27 | wget -O model.ckpt-20048 https://goo.gl/zanx88 28 | wget -O model.ckpt-20048.meta https://goo.gl/LNqHoj 29 | ``` 30 | 31 | 32 | Baseline models were trained with the standard hood camera in GTAV. 33 | 34 | To enable the hood camera, hit v until you see something like this 35 | ![deepdrive load](https://www.dropbox.com/s/q28tce40ukurm9p/Screenshot%202016-10-30%2014.33.50.png?dl=1) 36 | 37 | If you see the steering wheel, change the camera settings like so: 38 | ![deepdrive load](https://www.dropbox.com/s/h3xu98jz45bafld/Screenshot%202016-10-30%2014.28.42.png?dl=1) 39 | 40 | In addition, set the resolution to 800x600 to minimize network I/O and enable borderless mode to avoid sending the window chrome through the network 41 | 42 | ![borderless](https://www.dropbox.com/s/dci8o6z3129bwpl/borderless.jpg?dl=1) 43 | 44 | ## Run the model 45 | ``` 46 | python main.py -d [DeepDriver|DeepDriverTF] -r vnc://:5900+15900 47 | ``` 48 | 49 | ## Sample data returned by the env 50 | 51 | ``` 52 | { 53 | "body" : 54 | { 55 | "done" : false, 56 | "info" : 57 | { 58 | "center_of_lane_reward" : 0, 59 | "distance_from_destination" : 1306.6157153344816, 60 | "forward_vector_x" : -0.9870644211769104, 61 | "forward_vector_y" : 0.15973846614360809, 62 | "forward_vector_z" : 0.013689413666725159, 63 | "game_time.day_of_month" : 6, 64 | "game_time.hour" : 16, 65 | "game_time.minute" : 8, 66 | "game_time.month" : 9, 67 | "game_time.ms_per_game_min" : 2000, 68 | "game_time.second" : 47, 69 | "game_time.year" : 2009, 70 | "heading" : 80.808067321777344, 71 | "is_game_driving" : false, 72 | "last_collision_time" : 1481999559, 73 | "last_material_collided_with" : "4201905313", 74 | "on_road" : true, 75 | "script_hook_loadtime" : 1481939095, 76 | "speed" : 0, 77 | "spin" : 0, 78 | "x_coord" : -2372.70068359375, 79 | "y_coord" : 1032.6005859375, 80 | "z_coord" : 195.53288269042969 81 | }, 82 | "reward" : 0 83 | }, 84 | "headers" : 85 | { 86 | "episode_id" : "1", 87 | "sent_at" : 1481999938.4742091 88 | }, 89 | "method" : "v0.env.reward" 90 | } 91 | ``` 92 | 93 | ## Directly connected machines 94 | To connect your Windows and Ubuntu machines directly via ethernet, follow [these instructions](http://askubuntu.com/a/26770/158805) for adding the interface to Ubuntu. 95 | 96 | Use the _Netmask_ provided by `ipconfig` in Windows for your ethernet interface. 97 | 98 | ## Contributors 99 | 100 | Several people, without which, this project would not have been possible 101 | ``` 102 | Aitor Ruano 103 | Alec Radford 104 | Alex Ray 105 | Andrej Karpathy 106 | Andrew Gray 107 | Brad Templeton 108 | Catherine Olsson 109 | Christina Araiza 110 | Dan Van Boxel 111 | Dario Amodei 112 | Felipe Code 113 | Greg Brockman 114 | Gustavo Youngberg 115 | Ilya Sutskever 116 | Jack Clark 117 | James Denney 118 | Jeremy Schlatter 119 | Jon Gautier 120 | Jonas Schneider 121 | Krystian Gebis 122 | Lance Martin 123 | Ludwig Pettersson 124 | Matthew Kleinsmith 125 | Matthew O'Kelly 126 | Mike Roberts 127 | Paul Baumgart 128 | Pieter Abbeel 129 | Rafał Józefowicz 130 | Tom Brown 131 | Vicki Cheung 132 | ``` 133 | -------------------------------------------------------------------------------- /benchmark.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from __future__ import print_function 3 | import argparse 4 | import collections 5 | import json 6 | import logging 7 | import gym 8 | import sys 9 | import universe 10 | from universe import pyprofile, wrappers 11 | 12 | from GameSettingsEvent import GTASetting 13 | from drivers.deepdrive.deep_driver import DeepDriver 14 | 15 | 16 | # if not os.getenv("PYPROFILE_FREQUENCY"): 17 | # pyprofile.profile.print_frequency = 5 18 | from drivers.deepdrive_tf.deep_driver_tf import DeepDriverTF 19 | 20 | logger = logging.getLogger() 21 | extra_logger = logging.getLogger('universe') 22 | 23 | stdout_log_handler = logging.StreamHandler(sys.stdout) 24 | stdout_log_handler.setLevel(logging.ERROR) 25 | 26 | 27 | formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') 28 | stdout_log_handler.setFormatter(formatter) 29 | extra_logger.addHandler(stdout_log_handler) 30 | 31 | 32 | def main(): 33 | # You can optionally set up the logger. Also fine to set the level 34 | # to logging.DEBUG or logging.WARN if you want to change the 35 | # amount of output. 36 | logger.setLevel(logging.INFO) 37 | universe.configure_logging() 38 | 39 | parser = argparse.ArgumentParser(description=None) 40 | parser.add_argument('-e', '--env_id', default='gtav.SaneDriving-v0', help='Which environment to run on.') 41 | parser.add_argument('-m', '--monitor', action='store_false', help='Whether to activate the monitor.') 42 | parser.add_argument('-r', '--remote', help='The number of environments to create (e.g. -r 20), or the address of pre-existing VNC servers and rewarders to use (e.g. -r vnc://localhost:5900+15900,localhost:5901+15901), or a query to the allocator (e.g. -r http://allocator.sci.openai-tech.com?n=2)') 43 | parser.add_argument('-v', '--verbose', action='count', dest='verbosity', default=0, help='Set verbosity.') 44 | parser.add_argument('-R', '--no-render', action='store_true', help='Do not render the environment locally.') 45 | parser.add_argument('-f', '--fps', default=8., type=float, help='Desired frames per second') 46 | parser.add_argument('-N', '--max-steps', type=int, default=10**7, help='Maximum number of steps to take') 47 | parser.add_argument('-d', '--driver', default='DeepDriver', help='Choose your driver') 48 | parser.add_argument('-c', '--custom_camera', action='store_true', help='Customize the GTA camera') 49 | 50 | args = parser.parse_args() 51 | 52 | logging.getLogger('gym').setLevel(logging.NOTSET) 53 | logging.getLogger('universe').setLevel(logging.NOTSET) 54 | if args.verbosity == 0: 55 | logger.setLevel(logging.INFO) 56 | elif args.verbosity >= 1: 57 | logger.setLevel(logging.DEBUG) 58 | 59 | if args.env_id is not None: 60 | # N.B. This does not set the actual environment mode yet, which 61 | # is currently driven by environment itself. 62 | env = gym.make(args.env_id) 63 | else: 64 | env = wrappers.WrappedVNCEnv() 65 | if not isinstance(env, wrappers.GymCoreAction): 66 | # Theopenai GymCoreSyncEnv's try to mimic their core counterparts, 67 | # and thus came pre-wrapped wth an action space 68 | # translator. Everything else probably wants a SafeActionSpace 69 | # wrapper to shield them from random-agent clicking around 70 | # everywhere. 71 | env = wrappers.SafeActionSpace(env) 72 | else: 73 | # Only gym-core are seedable 74 | env.seed([0]) 75 | env = wrappers.Logger(env) 76 | 77 | env.configure( 78 | fps=args.fps, 79 | # print_frequency=None, 80 | # ignore_clock_skew=True, 81 | remotes=args.remote, 82 | vnc_driver='go', vnc_kwargs={ 83 | 'encoding': 'tight', 'compress_level': 0, 'fine_quality_level': 50, 'subsample_level': 0, 'quality_level': 5, 84 | }, 85 | ) 86 | 87 | if args.driver == 'DeepDriver': 88 | driver = DeepDriver() 89 | elif args.driver == 'DeepDriverTF': 90 | driver = DeepDriverTF() 91 | else: 92 | raise Exception('That driver is not available') 93 | 94 | # driver = DeepDriver() 95 | driver.setup() 96 | 97 | if args.monitor: 98 | env.monitor.start('/tmp/vnc_random_agent', force=True, video_callable=lambda i: True) 99 | 100 | render = not args.no_render 101 | observation_n = env.reset() 102 | reward_n = [0] * env.n 103 | done_n = [False] * env.n 104 | info = None 105 | 106 | for i in range(args.max_steps): 107 | # print(observation_n) 108 | # user_input.handle_events() 109 | 110 | if render: 111 | # Note the first time you call render, it'll be relatively 112 | # slow and you'll have some aggregated rewards. We could 113 | # open the render() window before `reset()`, but that's 114 | # confusing since it pops up a black window for the 115 | # duration of the reset. 116 | env.render() 117 | 118 | action_n = driver.step(observation_n, reward_n, done_n, info) 119 | 120 | logger.debug('reward %s', reward_n) 121 | # logger.info('info %s', info) 122 | try: 123 | logger.debug('distance %s', info['n'][0]['distance_from_destination']) 124 | except Exception as e: 125 | logger.warn('distance not available %s', str(e)) 126 | 127 | if args.custom_camera: 128 | # Sending this every step is probably overkill 129 | for action in action_n: 130 | action.append(GTASetting('use_custom_camera', True)) 131 | 132 | # Take an action 133 | with pyprofile.push('env.step'): 134 | _step = env.step(action_n) 135 | observation_n, reward_n, done_n, info = _step 136 | # if reward_n[0] != 0: 137 | # print('reward', reward_n[0]) 138 | od = collections.OrderedDict(sorted(info['n'][0].items())) 139 | try: 140 | print() 141 | print('info') 142 | print(' distance_from_destination', od['distance_from_destination']) 143 | print(' speed', od['speed']) 144 | print(' on_road', od['on_road']) 145 | print(' heading', od['heading']) 146 | print(' lateral_velocity', od['velocity_x']) 147 | print(' vertical_velocity', od['velocity_z']) 148 | print(' pitch_velocity', od['spin_x']) 149 | print(' roll_velocity', od['spin_y']) 150 | print(' yaw_velocity', od['spin_z']) 151 | print(' secs_since_drove_against_traffic', od['time_since_drove_against_traffic']) 152 | print(' last_collision_time', od['last_collision_time']) 153 | print(' last_material_collided_with', od['last_material_collided_with']) 154 | print(' stats.vnc.updates.bytes', od['stats.vnc.updates.bytes']) 155 | print(' stats.vnc.updates.n', od['stats.vnc.updates.n']) 156 | print(' stats.vnc.updates.pixels', od['stats.vnc.updates.pixels']) 157 | print(' stats.vnc.updates.rectangles', od['stats.vnc.updates.rectangles']) 158 | print() 159 | print() 160 | print() 161 | print() 162 | print() 163 | print() 164 | print() 165 | print() 166 | print() 167 | print() 168 | print() 169 | print() 170 | print() 171 | except KeyError: 172 | pass 173 | 174 | # We're done! clean up 175 | env.close() 176 | 177 | if __name__ == '__main__': 178 | sys.exit(main()) 179 | 180 | -------------------------------------------------------------------------------- /driver_base.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import time 3 | from universe.spaces.joystick_event import JoystickAxisXEvent, JoystickAxisZEvent 4 | import logging 5 | logger = logging.getLogger() 6 | 7 | 8 | class DriverBase(object): 9 | def __init__(self): 10 | self.net = None 11 | self.image_transformer = None 12 | self.env = None 13 | self.action_space = None 14 | self.target = None 15 | self.observation_n = None 16 | self.reward_n = None 17 | self.done_n = None 18 | self.throttle = 0. 19 | self.steer = 0. 20 | 21 | def load_net(self): 22 | raise NotImplementedError('Show us how to load your net') 23 | 24 | def set_input(self, image): 25 | raise NotImplementedError('Show us how to set your net\'s inputs') 26 | 27 | def get_next_action(self, net_out, info): 28 | raise NotImplementedError('Show us how to get the next action given the net\'s outputs') 29 | 30 | def get_net_out(self): 31 | raise NotImplementedError('Show us how to get output from your net') 32 | 33 | def setup(self): 34 | self.load_net() 35 | 36 | def step(self, observation_n, reward_n, done_n, info): 37 | if observation_n[0] is None: 38 | return self.get_noop() 39 | image = observation_n[0]['vision'] 40 | if image is None: 41 | logger.warning('No image received. ' 42 | 'You may need to restart the environment - Also make sure to leave the RDP session open.') 43 | return self.get_noop() 44 | else: 45 | begin = time.time() 46 | self.set_input(image) 47 | end = time.time() 48 | logger.debug('time to set net input %s', end - begin) 49 | 50 | begin = time.time() 51 | net_out = self.get_net_out() 52 | end = time.time() 53 | logger.debug('time to get net out %s', end - begin) 54 | 55 | begin = time.time() 56 | next_action_n = self.get_next_action(net_out, info) 57 | end = time.time() 58 | logger.debug('time to get next action %s', end - begin) 59 | 60 | errored = [i for i, info_i in enumerate(info['n']) if 'error' in info_i] 61 | if errored: 62 | logger.error('had errored indexes: %s: %s', errored, info) 63 | 64 | if any(r != 0.0 and r is not None for r in reward_n): 65 | print('reward', reward_n[0]) 66 | 67 | return next_action_n 68 | 69 | 70 | def get_noop(self): 71 | x_axis_event = JoystickAxisXEvent(0) 72 | z_axis_event = JoystickAxisZEvent(0) 73 | noop = [[x_axis_event, z_axis_event]] 74 | return noop 75 | -------------------------------------------------------------------------------- /drivers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OSSDC/deepdrive-universe/62ef2f2c96fb827fe997e27a03931593907ebdc5/drivers/__init__.py -------------------------------------------------------------------------------- /drivers/deepdrive/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OSSDC/deepdrive-universe/62ef2f2c96fb827fe997e27a03931593907ebdc5/drivers/deepdrive/__init__.py -------------------------------------------------------------------------------- /drivers/deepdrive/deep_drive_model.prototxt: -------------------------------------------------------------------------------- 1 | name: "GTANet" 2 | 3 | # Can be used with pretrained Caffenet (AlexNet architecture). 4 | # Layers with names containing 'gtanet' are not transferred from Caffenet. 5 | 6 | 7 | layer { 8 | name: "gta_frames_input_layer" 9 | type: "Input" 10 | top: "images" 11 | top: "targets" 12 | include { phase:TEST } 13 | input_param { 14 | shape: { 15 | dim: 1 16 | dim: 3 17 | dim: 227 18 | dim: 227 19 | } 20 | } 21 | } 22 | 23 | layer { 24 | name: "conv1" 25 | type: "Convolution" 26 | bottom: "images" 27 | top: "conv1" 28 | param { 29 | lr_mult: 1 30 | decay_mult: 1 31 | } 32 | param { 33 | lr_mult: 2 34 | decay_mult: 0 35 | } 36 | convolution_param { 37 | num_output: 96 38 | kernel_size: 11 39 | stride: 4 40 | weight_filler { 41 | type: "gaussian" 42 | std: 0.01 43 | } 44 | bias_filler { 45 | type: "constant" 46 | value: 0 47 | } 48 | } 49 | } 50 | 51 | layer { 52 | name: "relu1" 53 | type: "ReLU" 54 | bottom: "conv1" 55 | top: "conv1" 56 | } 57 | 58 | layer { 59 | name: "pool1" 60 | type: "Pooling" 61 | bottom: "conv1" 62 | top: "pool1" 63 | pooling_param { 64 | pool: MAX 65 | kernel_size: 3 66 | stride: 2 67 | } 68 | } 69 | 70 | layer { 71 | name: "norm1" 72 | type: "LRN" 73 | bottom: "pool1" 74 | top: "norm1" 75 | lrn_param { 76 | local_size: 5 77 | alpha: 0.0001 78 | beta: 0.75 79 | } 80 | } 81 | 82 | layer { 83 | name: "conv2" 84 | type: "Convolution" 85 | bottom: "norm1" 86 | top: "conv2" 87 | param { 88 | lr_mult: 1 89 | decay_mult: 1 90 | } 91 | param { 92 | lr_mult: 2 93 | decay_mult: 0 94 | } 95 | convolution_param { 96 | num_output: 256 97 | pad: 2 98 | kernel_size: 5 99 | group: 2 100 | weight_filler { 101 | type: "gaussian" 102 | std: 0.01 103 | } 104 | bias_filler { 105 | type: "constant" 106 | value: 1 107 | } 108 | } 109 | } 110 | 111 | layer { 112 | name: "relu2" 113 | type: "ReLU" 114 | bottom: "conv2" 115 | top: "conv2" 116 | } 117 | 118 | layer { 119 | name: "pool2" 120 | type: "Pooling" 121 | bottom: "conv2" 122 | top: "pool2" 123 | pooling_param { 124 | pool: MAX 125 | kernel_size: 3 126 | stride: 2 127 | } 128 | } 129 | 130 | layer { 131 | name: "norm2" 132 | type: "LRN" 133 | bottom: "pool2" 134 | top: "norm2" 135 | lrn_param { 136 | local_size: 5 137 | alpha: 0.0001 138 | beta: 0.75 139 | } 140 | } 141 | 142 | layer { 143 | name: "conv3" 144 | type: "Convolution" 145 | bottom: "norm2" 146 | top: "conv3" 147 | param { 148 | lr_mult: 1 149 | decay_mult: 1 150 | } 151 | param { 152 | lr_mult: 2 153 | decay_mult: 0 154 | } 155 | convolution_param { 156 | num_output: 384 157 | pad: 1 158 | kernel_size: 3 159 | weight_filler { 160 | type: "gaussian" 161 | std: 0.01 162 | } 163 | bias_filler { 164 | type: "constant" 165 | value: 0 166 | } 167 | } 168 | } 169 | 170 | layer { 171 | name: "relu3" 172 | type: "ReLU" 173 | bottom: "conv3" 174 | top: "conv3" 175 | } 176 | 177 | layer { 178 | name: "conv4" 179 | type: "Convolution" 180 | bottom: "conv3" 181 | top: "conv4" 182 | param { 183 | lr_mult: 1 184 | decay_mult: 1 185 | } 186 | param { 187 | lr_mult: 2 188 | decay_mult: 0 189 | } 190 | convolution_param { 191 | num_output: 384 192 | pad: 1 193 | kernel_size: 3 194 | group: 2 195 | weight_filler { 196 | type: "gaussian" 197 | std: 0.01 198 | } 199 | bias_filler { 200 | type: "constant" 201 | value: 1 202 | } 203 | } 204 | } 205 | 206 | layer { 207 | name: "relu4" 208 | type: "ReLU" 209 | bottom: "conv4" 210 | top: "conv4" 211 | } 212 | 213 | layer { 214 | name: "conv5" 215 | type: "Convolution" 216 | bottom: "conv4" 217 | top: "conv5" 218 | param { 219 | lr_mult: 1 220 | decay_mult: 1 221 | } 222 | param { 223 | lr_mult: 2 224 | decay_mult: 0 225 | } 226 | convolution_param { 227 | num_output: 256 228 | pad: 1 229 | kernel_size: 3 230 | group: 2 231 | weight_filler { 232 | type: "gaussian" 233 | std: 0.01 234 | } 235 | bias_filler { 236 | type: "constant" 237 | value: 1 238 | } 239 | } 240 | } 241 | 242 | layer { 243 | name: "relu5" 244 | type: "ReLU" 245 | bottom: "conv5" 246 | top: "conv5" 247 | } 248 | 249 | layer { 250 | name: "pool5" 251 | type: "Pooling" 252 | bottom: "conv5" 253 | top: "pool5" 254 | pooling_param { 255 | pool: MAX 256 | kernel_size: 3 257 | stride: 2 258 | } 259 | } 260 | 261 | layer { 262 | name: "fc6_gtanet" 263 | type: "InnerProduct" 264 | bottom: "pool5" 265 | top: "fc6" 266 | param { 267 | lr_mult: 1 # learning rate multiplier for the filters 268 | decay_mult: 1 # weight decay multiplier for the filters 269 | } 270 | param { 271 | lr_mult: 2 # learning rate multiplier for the biases 272 | decay_mult: 0 # weight decay multiplier for the biases 273 | } 274 | inner_product_param { 275 | num_output: 4096 276 | weight_filler { 277 | type: "gaussian" 278 | std: 0.005 279 | } 280 | bias_filler { 281 | type: "constant" 282 | value: 1 283 | } 284 | } 285 | } 286 | 287 | layer { 288 | name: "relu6_gtanet" 289 | type: "ReLU" 290 | bottom: "fc6" 291 | top: "fc6" 292 | } 293 | 294 | layer { 295 | name: "drop6_gtanet" 296 | type: "Dropout" 297 | bottom: "fc6" 298 | top: "fc6" 299 | dropout_param { 300 | dropout_ratio: 0.5 301 | } 302 | } 303 | 304 | 305 | layer { 306 | name: "fc7_gtanet" 307 | type: "InnerProduct" 308 | bottom: "fc6" 309 | top: "fc7" 310 | param { 311 | lr_mult: 1 # learning rate multiplier for the filters 312 | decay_mult: 1 # weight decay multiplier for the filters 313 | } 314 | param { 315 | lr_mult: 2 # learning rate multiplier for the biases 316 | decay_mult: 0 # weight decay multiplier for the biases 317 | } 318 | inner_product_param { 319 | num_output: 4096 320 | weight_filler { 321 | type: "gaussian" 322 | std: 0.005 323 | } 324 | bias_filler { 325 | type: "constant" 326 | value: 1 327 | } 328 | } 329 | } 330 | 331 | layer { 332 | name: "relu7_gtanet" 333 | type: "ReLU" 334 | bottom: "fc7" 335 | top: "fc7" 336 | } 337 | 338 | layer { 339 | name: "drop7_gtanet" 340 | type: "Dropout" 341 | bottom: "fc7" 342 | top: "fc7" 343 | dropout_param { 344 | dropout_ratio: 0.05 345 | } 346 | } 347 | 348 | # The output layer is a fully-connected linear layer with a single output for each valid action. 349 | layer { 350 | name: "gtanet_fctop" 351 | type: "InnerProduct" 352 | bottom: "fc7" 353 | top: "gtanet_fctop" 354 | param { 355 | lr_mult: 1 # learning rate multiplier for the filters 356 | decay_mult: 1 # weight decay multiplier for the filters 357 | } 358 | param { 359 | lr_mult: 2 # learning rate multiplier for the biases 360 | decay_mult: 0 # weight decay multiplier for the biases 361 | } 362 | inner_product_param { 363 | num_output: 6 # Number of output neurons 364 | weight_filler { 365 | type: "gaussian" 366 | std: 0.01 367 | } 368 | bias_filler { 369 | type: "constant" 370 | value: 0 371 | } 372 | } 373 | } -------------------------------------------------------------------------------- /drivers/deepdrive/deep_driver.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | import time 4 | 5 | from driver_base import DriverBase 6 | from universe.spaces.joystick_event import JoystickAxisXEvent, JoystickAxisZEvent 7 | import logging 8 | logger = logging.getLogger() 9 | 10 | DIR_PATH = os.path.dirname(os.path.realpath(__file__)) 11 | 12 | 13 | class DeepDriver(DriverBase): 14 | def __init__(self): 15 | super(DeepDriver, self).__init__() 16 | self.input_layer_name = 'images' 17 | 18 | def load_net(self): 19 | import caffe # Don't require caffe unless this driver is used 20 | caffe.set_mode_gpu() 21 | model_def = os.path.join(DIR_PATH, 'deep_drive_model.prototxt') 22 | model_weights = os.path.join(DIR_PATH, 'caffe_deep_drive_train_iter_35352.caffemodel') 23 | self.net = caffe.Net(model_def, # defines the structure of the model 24 | model_weights, # contains the trained weights 25 | caffe.TEST) # use test mode (e.g., don't perform dropout) 26 | transformer = caffe.io.Transformer({'data': self.net.blobs[self.input_layer_name].data.shape}) 27 | transformer.set_transpose('data', (2, 0, 1)) # convert to Channel Width Height 28 | transformer.set_channel_swap('data', (2, 1, 0)) # swap channels from RGB to BGR 29 | self.image_transformer = transformer 30 | 31 | def get_next_action(self, net_out, info): 32 | spin, direction, speed, speed_change, steer, throttle = net_out['gtanet_fctop'][0] 33 | steer = -float(steer) 34 | steer_dead_zone = 0.2 35 | 36 | # Add dead zones 37 | if steer > 0: 38 | steer += steer_dead_zone 39 | elif steer < 0: 40 | steer -= steer_dead_zone 41 | 42 | logger.debug('steer %f', steer) 43 | print('control') 44 | print(' steer %f' % steer) 45 | x_axis_event = JoystickAxisXEvent(steer) 46 | if 'n' in info and 'speed' in info['n'][0]: 47 | current_speed = info['n'][0]['speed'] 48 | desired_speed = speed / 0.05 # Denormalize per deep_drive.h in deepdrive-caffe 49 | if desired_speed < current_speed: 50 | logger.debug('braking') 51 | throttle = self.throttle - (current_speed - desired_speed) * 0.085 # Magic number 52 | throttle = max(throttle, 0.0) 53 | print(' throttle %s' % throttle) 54 | print(' braking: true') 55 | else: 56 | throttle += 13. / 50. # Joystick dead zone 57 | print(' throttle %s' % throttle) 58 | print(' braking false') 59 | 60 | z_axis_event = JoystickAxisZEvent(float(throttle)) 61 | logging.debug('throttle %s', throttle) 62 | else: 63 | z_axis_event = JoystickAxisZEvent(0) 64 | logging.debug('No info received from environment for this frame - sending noop') 65 | next_action_n = [[x_axis_event, z_axis_event]] 66 | 67 | self.throttle = throttle 68 | self.steer = steer 69 | 70 | return next_action_n 71 | 72 | def set_input(self, image): 73 | # print(image) 74 | transformed_image = self.image_transformer.preprocess('data', image) 75 | self.net.blobs[self.input_layer_name].data[...] = transformed_image 76 | 77 | def get_net_out(self): 78 | begin = time.time() 79 | net_out = self.net.forward() 80 | end = time.time() 81 | logger.debug('inference time %s', end - begin) 82 | return net_out 83 | -------------------------------------------------------------------------------- /drivers/deepdrive_tf/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OSSDC/deepdrive-universe/62ef2f2c96fb827fe997e27a03931593907ebdc5/drivers/deepdrive_tf/__init__.py -------------------------------------------------------------------------------- /drivers/deepdrive_tf/deep_driver_tf.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import time 3 | 4 | from driver_base import DriverBase 5 | from universe.spaces.joystick_event import JoystickAxisXEvent, JoystickAxisZEvent 6 | import logging 7 | import numpy as np 8 | from scipy.misc import imresize 9 | 10 | logger = logging.getLogger() 11 | 12 | import tensorflow as tf 13 | import os 14 | from drivers.deepdrive_tf.gtanet import GTANetModel 15 | 16 | DIR_PATH = os.path.dirname(os.path.realpath(__file__)) 17 | 18 | 19 | class DeepDriverTF(DriverBase): 20 | def __init__(self): 21 | super(DeepDriverTF, self).__init__() 22 | self.sess = None 23 | self.net = None 24 | self.image_var = None 25 | self.net_out_var = None 26 | self.image_shape = (227, 227, 3) 27 | self.image = None 28 | self.num_targets = 6 29 | self.mean_pixel = np.array([104., 117., 123.], np.float32) 30 | self.min_outputs = np.array([10., 10., 10., 10., 10., 10.]) 31 | self.max_outputs = np.array([-10., -10., -10., -10., -10., -10.]) 32 | 33 | def load_net(self): 34 | self.image_var = tf.placeholder(tf.float32, (None,) + self.image_shape) 35 | with tf.variable_scope("model") as vs: 36 | self.net = GTANetModel(self.image_var, 6, is_training=False) 37 | saver = tf.train.Saver() 38 | self.sess = tf.Session() 39 | saver.restore(self.sess, os.path.join(DIR_PATH, 'model.ckpt-20048')) 40 | 41 | def get_next_action(self, net_out, info): 42 | spin, direction, speed, speed_change, steer, throttle = net_out[0] 43 | steer = -float(steer) 44 | 45 | # Add dead zones 46 | if steer > 0: 47 | steer += 0.2 48 | elif steer < 0: 49 | steer -= 0.4 50 | 51 | logger.debug('steer %f', steer) 52 | print('control tf') 53 | print(' steer %f' % steer) 54 | x_axis_event = JoystickAxisXEvent(steer) 55 | if 'n' in info and 'speed' in info['n'][0]: 56 | current_speed = info['n'][0]['speed'] 57 | desired_speed = speed / 0.05 # Denormalize per deep_drive.h in deepdrive-caffe 58 | if desired_speed < current_speed: 59 | logger.debug('braking') 60 | throttle = self.throttle - (current_speed - desired_speed) * 0.085 # Magic number 61 | throttle = max(throttle, 0.0) 62 | print(' throttle %s' % throttle) 63 | print(' braking: true') 64 | else: 65 | throttle += 0.4 # Joystick dead zone 66 | print(' throttle %s' % throttle) 67 | print(' braking false') 68 | 69 | z_axis_event = JoystickAxisZEvent(float(throttle)) 70 | logging.debug('throttle %s', throttle) 71 | else: 72 | z_axis_event = JoystickAxisZEvent(0) 73 | logging.debug('No info received from environment for this frame - sending noop') 74 | next_action_n = [[x_axis_event, z_axis_event]] 75 | 76 | self.throttle = throttle 77 | self.steer = steer 78 | 79 | return next_action_n 80 | 81 | def set_input(self, img): 82 | img = imresize(img, self.image_shape) 83 | img = img.astype(np.float32) 84 | img -= self.mean_pixel 85 | self.image = img 86 | 87 | def get_net_out(self): 88 | begin = time.time() 89 | net_out = self.sess.run(self.net.p, feed_dict={self.image_var: self.image.reshape(1, 227, 227, 3)}) 90 | # print(net_out) 91 | end = time.time() 92 | logger.debug('inference time %s', end - begin) 93 | return net_out 94 | -------------------------------------------------------------------------------- /drivers/deepdrive_tf/gtanet.py: -------------------------------------------------------------------------------- 1 | import tensorflow as tf 2 | from drivers.deepdrive_tf.layers import conv2d, max_pool_2x2, linear, lrn 3 | 4 | 5 | class GTANetModel(object): 6 | def __init__(self, x, num_targets=6, is_training=True): 7 | self.x = x 8 | conv1 = tf.nn.relu(conv2d(x, "conv1", 96, 11, 4, 1)) 9 | lrn1 = lrn(conv1) 10 | maxpool1 = max_pool_2x2(lrn1) 11 | conv2 = tf.nn.relu(conv2d(maxpool1, "conv2", 256, 5, 1, 2)) 12 | lrn2 = lrn(conv2) 13 | maxpool2 = max_pool_2x2(lrn2) 14 | conv3 = tf.nn.relu(conv2d(maxpool2, "conv3", 384, 3, 1, 1)) 15 | conv4 = tf.nn.relu(conv2d(conv3, "conv4", 384, 3, 1, 2)) 16 | conv5 = tf.nn.relu(conv2d(conv4, "conv5", 256, 3, 1, 2)) 17 | maxpool5 = max_pool_2x2(conv5) 18 | fc6 = tf.nn.relu(linear(maxpool5, "fc6", 4096)) 19 | if is_training: 20 | fc6 = tf.nn.dropout(fc6, 0.5) 21 | fc7 = tf.nn.relu(linear(fc6, "fc7", 4096)) 22 | if is_training: 23 | fc7 = tf.nn.dropout(fc7, 0.95) 24 | fc8 = linear(fc7, "fc8", num_targets) 25 | 26 | self.p = fc8 27 | self.global_step = tf.get_variable("global_step", [], tf.int32, initializer=tf.zeros_initializer, 28 | trainable=False) 29 | -------------------------------------------------------------------------------- /drivers/deepdrive_tf/layers.py: -------------------------------------------------------------------------------- 1 | from __future__ import division 2 | import numpy as np 3 | import tensorflow as tf 4 | 5 | def conv(input, kernel, biases, k_h, k_w, c_o, s_h, s_w, padding="VALID", group=1): 6 | '''From https://github.com/ethereon/caffe-tensorflow 7 | ''' 8 | c_i = input.get_shape()[-1] 9 | assert c_i % group == 0 10 | assert c_o % group == 0 11 | def convolve(i, k): 12 | return tf.nn.conv2d(i, k, [1, s_h, s_w, 1], padding=padding) 13 | 14 | if group == 1: 15 | conv = convolve(input, kernel) 16 | else: 17 | input_groups = tf.split(3, group, input) 18 | kernel_groups = tf.split(3, group, kernel) 19 | output_groups = [convolve(i, k) for i, k in zip(input_groups, kernel_groups)] 20 | conv = tf.concat(3, output_groups) 21 | return tf.reshape(tf.nn.bias_add(conv, biases), [-1] + conv.get_shape().as_list()[1:]) 22 | 23 | def conv2d(x, name, num_features, kernel_size, stride, group): 24 | input_features = x.get_shape()[3] 25 | w = tf.get_variable(name + "_W", [kernel_size, kernel_size, int(input_features) // group, num_features]) 26 | b = tf.get_variable(name + "_b", [num_features]) 27 | return conv(x, w, b, kernel_size, kernel_size, num_features, stride, stride, padding="SAME", group=group) 28 | 29 | def linear(x, name, size): 30 | input_size = np.prod(list(map(int, x.get_shape()[1:]))) 31 | x = tf.reshape(x, [-1, input_size]) 32 | w = tf.get_variable(name + "_W", [input_size, size]) 33 | b = tf.get_variable(name + "_b", [size]) 34 | return tf.matmul(x, w) + b 35 | 36 | def max_pool_2x2(x): 37 | return tf.nn.max_pool(x, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1], padding='VALID') 38 | 39 | def lrn(x): 40 | return tf.nn.local_response_normalization(x, depth_radius=2, alpha=2e-05, beta=0.75, bias=1.0) 41 | -------------------------------------------------------------------------------- /drivers/deepdrive_tf/train/.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | .hypothesis/ 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | local_settings.py 55 | 56 | # Flask stuff: 57 | instance/ 58 | .webassets-cache 59 | 60 | # Scrapy stuff: 61 | .scrapy 62 | 63 | # Sphinx documentation 64 | docs/_build/ 65 | 66 | # PyBuilder 67 | target/ 68 | 69 | # IPython Notebook 70 | .ipynb_checkpoints 71 | 72 | # pyenv 73 | .python-version 74 | 75 | # celery beat schedule file 76 | celerybeat-schedule 77 | 78 | # dotenv 79 | .env 80 | 81 | # virtualenv 82 | venv/ 83 | ENV/ 84 | 85 | # Spyder project settings 86 | .spyderproject 87 | 88 | # Rope project settings 89 | .ropeproject 90 | -------------------------------------------------------------------------------- /drivers/deepdrive_tf/train/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OSSDC/deepdrive-universe/62ef2f2c96fb827fe997e27a03931593907ebdc5/drivers/deepdrive_tf/train/__init__.py -------------------------------------------------------------------------------- /drivers/deepdrive_tf/train/data_utils.py: -------------------------------------------------------------------------------- 1 | import json 2 | import glob 3 | import numpy as np 4 | import os 5 | import h5py 6 | import random 7 | import threading 8 | import queue 9 | 10 | class BackgroundGenerator(threading.Thread): 11 | def __init__(self, generator): 12 | threading.Thread.__init__(self) 13 | self.queue = queue.Queue(1) 14 | self.generator = generator 15 | self.daemon = True 16 | self.start() 17 | 18 | def run(self): 19 | for item in self.generator: 20 | self.queue.put(item) 21 | self.queue.put(None) 22 | 23 | def __iter__(self): 24 | return self 25 | 26 | def __next__(self): 27 | next_item = self.queue.get() 28 | if next_item is None: 29 | raise StopIteration 30 | return next_item 31 | 32 | def get_good_files(hdf5_path, train=True): 33 | if train: 34 | # https://gist.github.com/crizCraig/65677883e07c74bdc08f987e806cd95f 35 | with open(hdf5_path + "/good_files.json", "rb") as f: 36 | ids = json.loads(f.read().decode('utf8')) 37 | ids.remove(1) 38 | else: 39 | ids = [1] 40 | 41 | ret = [] 42 | for i in ids: 43 | name = os.path.join(hdf5_path, "train_%04d.h5" % i) 44 | ret += [name] 45 | return set(ret) 46 | 47 | def load_file(h5_filename): 48 | mean_pixel = np.array([104., 117., 123.], np.float32) 49 | out_images = [] 50 | out_targets = [] 51 | 52 | with h5py.File(h5_filename, 'r') as hf: 53 | images = list(hf.get('images')) 54 | targets = list(hf.get('targets')) 55 | perm = np.arange(len(images)) 56 | for i in range(len(images)): 57 | idx = perm[i] 58 | img = images[idx].transpose((1, 2, 0)) # CHW => HWC 59 | img = img[:, :, ::-1] # BGR => RGB 60 | img = img.astype(np.float32) 61 | img -= mean_pixel 62 | out_images.append(img) 63 | out_targets.append(targets[idx]) 64 | return out_images, out_targets 65 | 66 | def file_loader(file_stream): 67 | for h5_filename in file_stream: 68 | print('input file: {}'.format(h5_filename)) 69 | yield load_file(h5_filename) 70 | 71 | def batch_gen(file_stream, batch_size): 72 | gen = BackgroundGenerator(file_loader(file_stream)) 73 | for images, targets in gen: 74 | num_iters = len(images) // batch_size 75 | for i in range(num_iters): 76 | yield images[i * batch_size:(i+1) * batch_size], targets[i * batch_size:(i+1) * batch_size] 77 | 78 | class Dataset(object): 79 | def __init__(self, files): 80 | self._files = files 81 | 82 | def iterate_once(self, batch_size): 83 | def file_stream(): 84 | for file_name in self._files: 85 | yield file_name 86 | yield from batch_gen(file_stream(), batch_size) 87 | 88 | def iterate_forever(self, batch_size): 89 | def file_stream(): 90 | while True: 91 | random.shuffle(self._files) 92 | for file_name in self._files: 93 | yield file_name 94 | yield from batch_gen(file_stream(), batch_size) 95 | 96 | 97 | def get_dataset(hdf5_path, train=True): 98 | good_files = get_good_files(hdf5_path, train=train) 99 | file_names = glob.glob(hdf5_path + "/*.h5") 100 | file_names = [fname for fname in file_names if fname in good_files] 101 | return Dataset(file_names) 102 | 103 | def run(): 104 | hdf5_path = os.environ('DEEPDRIVE_HDF5_PATH') 105 | 106 | # print(get_good_files(hdf5_path)) 107 | dataset = get_dataset(hdf5_path) 108 | print(dataset) 109 | 110 | if __name__ == "__main__": 111 | run() 112 | -------------------------------------------------------------------------------- /drivers/deepdrive_tf/train/layers.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import tensorflow as tf 3 | 4 | def conv(input, kernel, biases, k_h, k_w, c_o, s_h, s_w, padding="VALID", group=1): 5 | '''From https://github.com/ethereon/caffe-tensorflow 6 | ''' 7 | c_i = input.get_shape()[-1] 8 | assert c_i % group == 0 9 | assert c_o % group == 0 10 | def convolve(i, k): 11 | return tf.nn.conv2d(i, k, [1, s_h, s_w, 1], padding=padding) 12 | 13 | # TODO: random weight initialization 14 | # W = tf.get_variable("W", shape=[784, 256], 15 | # initializer=tf.contrib.layers.xavier_initializer()) 16 | 17 | if group == 1: 18 | conv = convolve(input, kernel) 19 | else: 20 | input_groups = tf.split(3, group, input) 21 | kernel_groups = tf.split(3, group, kernel) 22 | output_groups = [convolve(i, k) for i, k in zip(input_groups, kernel_groups)] 23 | conv = tf.concat(3, output_groups) 24 | return tf.reshape(tf.nn.bias_add(conv, biases), [-1] + conv.get_shape().as_list()[1:]) 25 | 26 | def conv2d(x, name, num_features, kernel_size, stride, group): 27 | input_features = x.get_shape()[3] 28 | w = tf.get_variable(name + "_W", [kernel_size, kernel_size, input_features // group, num_features]) 29 | b = tf.get_variable(name + "_b", [num_features]) 30 | return conv(x, w, b, kernel_size, kernel_size, num_features, stride, stride, padding="SAME", group=group) 31 | 32 | def linear(x, name, size): 33 | input_size = np.prod(list(map(int, x.get_shape()[1:]))) 34 | x = tf.reshape(x, [-1, input_size]) 35 | w = tf.get_variable(name + "_W", [input_size, size], initializer=tf.random_normal_initializer(0.0, 0.005)) 36 | b = tf.get_variable(name + "_b", [size], initializer=tf.zeros_initializer) 37 | return tf.matmul(x, w) + b 38 | 39 | def max_pool_2x2(x): 40 | return tf.nn.max_pool(x, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1], padding='VALID') 41 | 42 | def lrn(x): 43 | return tf.nn.local_response_normalization(x, depth_radius=2, alpha=2e-05, beta=0.75, bias=1.0) 44 | -------------------------------------------------------------------------------- /drivers/deepdrive_tf/train/train_gtanet.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import tensorflow as tf 3 | import os 4 | 5 | from drivers.deepdrive_tf.train.data_utils import get_dataset 6 | from drivers.deepdrive_tf.gtanet import GTANetModel 7 | 8 | # settings 9 | flags = tf.flags 10 | flags.DEFINE_string("logdir", "/tmp/gtanet", "Logging directory.") 11 | flags.DEFINE_string("data_path", os.environ('DEEPDRIVE_HDF5_PATH'), "Data path.") 12 | flags.DEFINE_string("hpconfig", "", "Overrides default hyper-parameters.") 13 | flags.DEFINE_string("mode", "train", "Whether to run 'train' or 'eval' model.") 14 | # flags.DEFINE_integer("num_gpus", 8, "Number of GPUs used.") 15 | FLAGS = flags.FLAGS 16 | 17 | def visualize_model(model, y): 18 | names = ["spin", "direction", "speed", "speed_change", "steering", "throttle"] 19 | for i in range(6): 20 | p = tf.reduce_mean(model.p[:, i]) 21 | tf.scalar_summary("losses/{}/p".format(names[i]), tf.reduce_mean(p)) 22 | err = 0.5 * tf.reduce_mean(tf.square(model.p[:, i] - y[:, i])) 23 | tf.scalar_summary("losses/{}/error".format(names[i]), err) 24 | tf.image_summary("model/x", model.x, max_images=10) 25 | 26 | def visualize_gradients(grads_and_vars): 27 | grads = [g for g, v in grads_and_vars] 28 | var_list = [v for g, v in grads_and_vars] 29 | for g, v in grads_and_vars: 30 | if g is None: 31 | continue 32 | tf.histogram_summary(v.name, v) 33 | tf.histogram_summary(v.name + "/grad", g) 34 | tf.scalar_summary("norms/" + v.name, tf.global_norm([v])) 35 | tf.scalar_summary("norms/" + v.name + "/grad", tf.global_norm([g])) 36 | grad_norm = tf.global_norm(grads) 37 | tf.scalar_summary("model/grad_global_norm", grad_norm) 38 | tf.scalar_summary("model/var_global_norm", tf.global_norm(var_list)) 39 | 40 | def run(): 41 | batch_size = 64 42 | num_targets = 6 43 | image_shape = (227, 227, 3) 44 | x = tf.placeholder(tf.float32, (None,) + image_shape) 45 | y = tf.placeholder(tf.float32, (None, num_targets)) 46 | 47 | with tf.variable_scope("model") as vs: 48 | model = GTANetModel(x, num_targets) 49 | vs.reuse_variables() 50 | eval_model = GTANetModel(x, num_targets, is_training=False) 51 | 52 | # TODO: add polyak averaging. 53 | l2_norm = tf.global_norm(tf.trainable_variables()) 54 | loss = 0.5 * tf.reduce_sum(tf.square(model.p - y)) / tf.to_float(tf.shape(x)[0]) 55 | tf.scalar_summary("model/loss", loss) 56 | tf.scalar_summary("model/l2_norm", l2_norm) 57 | total_loss = loss + 0.0005 * l2_norm 58 | tf.scalar_summary("model/total_loss", total_loss) 59 | opt = tf.train.AdamOptimizer(2e-4) 60 | grads_and_vars = opt.compute_gradients(total_loss) 61 | visualize_model(model, y) 62 | visualize_gradients(grads_and_vars) 63 | summary_op = tf.merge_all_summaries() 64 | train_op = opt.apply_gradients(grads_and_vars, model.global_step) 65 | 66 | init_op = tf.initialize_all_variables() 67 | pretrained_var_map = {} 68 | for v in tf.trainable_variables(): 69 | found = False 70 | for bad_layer in ["fc6", "fc7", "fc8"]: 71 | if bad_layer in v.name: 72 | found = True 73 | if found: 74 | continue 75 | 76 | pretrained_var_map[v.op.name[6:]] = v 77 | print(v.op.name, v.get_shape()) 78 | alexnet_saver = tf.train.Saver(pretrained_var_map) 79 | 80 | def init_fn(ses): 81 | print("Initializing parameters.") 82 | ses.run(init_op) 83 | alexnet_saver.restore(ses, "bvlc_alexnet.ckpt") 84 | 85 | saver = tf.train.Saver() 86 | sv = tf.train.Supervisor(is_chief=True, 87 | logdir=FLAGS.logdir + "/train", 88 | summary_op=None, # Automatic summaries don"t work with placeholders. 89 | saver=saver, 90 | global_step=model.global_step, 91 | save_summaries_secs=30, 92 | save_model_secs=60, 93 | init_op=None, 94 | init_fn=init_fn) 95 | 96 | eval_sw = tf.train.SummaryWriter(FLAGS.logdir + "/eval") 97 | train_dataset = get_dataset(FLAGS.data_path) 98 | eval_dataset = get_dataset(FLAGS.data_path, train=False) 99 | config = tf.ConfigProto(allow_soft_placement=True) 100 | with sv.managed_session(config=config) as sess, sess.as_default(): 101 | train_data_provider = train_dataset.iterate_forever(batch_size) 102 | while True: 103 | for i in range(1000): 104 | images, targets = next(train_data_provider) 105 | if i % 100 == 0 and i > 0: 106 | _, summ = sess.run([train_op, summary_op], {x: images, y: targets}) 107 | sv.summary_computed(sess, summ) 108 | sv.summary_writer.flush() 109 | else: 110 | sess.run(train_op, {x: images, y: targets}) 111 | 112 | step = model.global_step.eval() 113 | # Do evaluation 114 | losses = [] 115 | for images, targets in eval_dataset.iterate_once(batch_size): 116 | preds = sess.run(eval_model.p, {x: images}) 117 | losses += [np.square(targets - preds)] 118 | losses = np.concatenate(losses) 119 | print("Eval: shape: {}".format(losses.shape)) 120 | summary = tf.Summary() 121 | summary.value.add(tag="eval/loss", simple_value=float(0.5 * losses.sum() / losses.shape[0])) 122 | names = ["spin", "direction", "speed", "speed_change", "steering", "throttle"] 123 | for i in range(len(names)): 124 | summary.value.add(tag="eval/{}".format(names[i]), simple_value=float(0.5 * losses[:, i].mean())) 125 | print(summary) 126 | eval_sw.add_summary(summary, step) 127 | eval_sw.flush() 128 | 129 | if __name__ == "__main__": 130 | run() 131 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import argparse 3 | import logging 4 | import gym 5 | import sys 6 | import universe 7 | from universe import pyprofile, wrappers 8 | 9 | from GameSettingsEvent import GTASetting 10 | from drivers.deepdrive.deep_driver import DeepDriver 11 | from drivers.deepdrive_tf.deep_driver_tf import DeepDriverTF 12 | 13 | logger = logging.getLogger() 14 | extra_logger = logging.getLogger('universe') 15 | 16 | stdout_log_handler = logging.StreamHandler(sys.stdout) 17 | stdout_log_handler.setLevel(logging.DEBUG) 18 | 19 | formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') 20 | stdout_log_handler.setFormatter(formatter) 21 | extra_logger.addHandler(stdout_log_handler) 22 | 23 | 24 | def main(): 25 | # You can optionally set up the logger. Also fine to set the level 26 | # to logging.DEBUG or logging.WARN if you want to change the 27 | # amount of output. 28 | logger.setLevel(logging.INFO) 29 | universe.configure_logging() 30 | 31 | parser = argparse.ArgumentParser(description=None) 32 | parser.add_argument('-e', '--env_id', default='gtav.SaneDriving-v0', help='Which environment to run on.') 33 | parser.add_argument('-m', '--monitor', action='store_false', help='Whether to activate the monitor.') 34 | parser.add_argument('-r', '--remote', help='The number of environments to create (e.g. -r 20), or the address of pre-existing VNC servers and rewarders to use (e.g. -r vnc://localhost:5900+15900,localhost:5901+15901), or a query to the allocator (e.g. -r http://allocator.sci.openai-tech.com?n=2)') 35 | parser.add_argument('-v', '--verbose', action='count', dest='verbosity', default=0, help='Set verbosity.') 36 | parser.add_argument('-R', '--no-render', action='store_true', help='Do not render the environment locally.') 37 | parser.add_argument('-f', '--fps', default=8., type=float, help='Desired frames per second') 38 | parser.add_argument('-N', '--max-steps', type=int, default=10**7, help='Maximum number of steps to take') 39 | parser.add_argument('-d', '--driver', default='DeepDriver', help='Choose your driver') 40 | parser.add_argument('-c', '--custom_camera', action='store_true', help='Customize the GTA camera') 41 | 42 | args = parser.parse_args() 43 | 44 | logging.getLogger('gym').setLevel(logging.NOTSET) 45 | logging.getLogger('universe').setLevel(logging.NOTSET) 46 | if args.verbosity == 0: 47 | logger.setLevel(logging.INFO) 48 | elif args.verbosity >= 1: 49 | logger.setLevel(logging.DEBUG) 50 | 51 | if args.env_id is not None: 52 | # N.B. This does not set the actual environment mode yet, which 53 | # is currently driven by environment itself. 54 | env = gym.make(args.env_id) 55 | else: 56 | env = wrappers.WrappedVNCEnv() 57 | if not isinstance(env, wrappers.GymCoreAction): 58 | # The GymCoreSyncEnv's try to mimic their core counterparts, 59 | # and thus came pre-wrapped wth an action space 60 | # translator. Everything else probably wants a SafeActionSpace 61 | # wrapper to shield them from random-agent clicking around 62 | # everywhere. 63 | env = wrappers.SafeActionSpace(env) 64 | else: 65 | # Only gym-core are seedable 66 | env.seed([0]) 67 | env = wrappers.Logger(env) 68 | 69 | env.configure( 70 | fps=args.fps, 71 | # print_frequency=None, 72 | # ignore_clock_skew=True, 73 | remotes=args.remote, 74 | vnc_driver='go', vnc_kwargs={ 75 | 'encoding': 'tight', 'compress_level': 0, 'fine_quality_level': 50, 'subsample_level': 0, 'quality_level': 5, 76 | }, 77 | ) 78 | 79 | if args.driver == 'DeepDriver': 80 | driver = DeepDriver() 81 | elif args.driver == 'DeepDriverTF': 82 | driver = DeepDriverTF() 83 | else: 84 | raise Exception('That driver is not available') 85 | 86 | driver.setup() 87 | 88 | if args.monitor: 89 | # env.monitor.start('/tmp/vnc_random_agent', force=True, video_callable=lambda i: True) 90 | wrappers.Monitor(env, '/tmp/vnc_random_agent', video_callable=False, force=True) 91 | 92 | render = not args.no_render 93 | observation_n = env.reset() 94 | reward_n = [0] * env.n 95 | done_n = [False] * env.n 96 | info = None 97 | 98 | for i in range(args.max_steps): 99 | if render: 100 | # Note the first time you call render, it'll be relatively 101 | # slow and you'll have some aggregated rewards. We could 102 | # open the render() window before `reset()`, but that's 103 | # confusing since it pops up a black window for the 104 | # duration of the reset. 105 | env.render() 106 | 107 | action_n = driver.step(observation_n, reward_n, done_n, info) 108 | 109 | try: 110 | if info is not None: 111 | distance = info['n'][0]['distance_from_destination'] 112 | logger.info('distance %s', distance) 113 | except KeyError as e: 114 | logger.debug('distance not available %s', str(e)) 115 | 116 | if args.custom_camera: 117 | # Sending this every step is probably overkill 118 | for action in action_n: 119 | action.append(GTASetting('use_custom_camera', True)) 120 | 121 | # Take an action 122 | with pyprofile.push('env.step'): 123 | _step = env.step(action_n) 124 | observation_n, reward_n, done_n, info = _step 125 | 126 | if any(done_n) and info and not any(info_n.get('env_status.artificial.done', False) for info_n in info['n']): 127 | print('done_n', done_n, 'i', i) 128 | logger.info('end of episode') 129 | env.reset() 130 | 131 | # We're done! clean up 132 | env.close() 133 | 134 | if __name__ == '__main__': 135 | sys.exit(main()) 136 | 137 | --------------------------------------------------------------------------------