├── .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 | 
36 |
37 | If you see the steering wheel, change the camera settings like so:
38 | 
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 | 
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 |
--------------------------------------------------------------------------------