├── images ├── cozmo.jpg └── youtube.jpg ├── util ├── pygpu-test.py └── theano_test.py ├── .gitignore ├── autodrive_constants.py ├── LICENSE ├── create_model.py ├── evaluate.ipynb ├── README.md ├── drive.py ├── train.py ├── record.py └── autopilot_basic_model.json /images/cozmo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahouston/Cozmo-Autonomous-Driving/HEAD/images/cozmo.jpg -------------------------------------------------------------------------------- /images/youtube.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahouston/Cozmo-Autonomous-Driving/HEAD/images/youtube.jpg -------------------------------------------------------------------------------- /util/pygpu-test.py: -------------------------------------------------------------------------------- 1 | import pygpu 2 | import os 3 | 4 | os.environ['DEVICE'] = 'cuda0' 5 | pygpu.test() 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.npz 2 | *.pyc 3 | .vscode/ 4 | data/ 5 | scratch/ 6 | weights/ 7 | backup/ 8 | .ipynb_checkpoints/ -------------------------------------------------------------------------------- /autodrive_constants.py: -------------------------------------------------------------------------------- 1 | from cozmo import robot 2 | from cozmo.util import degrees 3 | 4 | HEAD_ANGLE = robot.MIN_HEAD_ANGLE + degrees(5) 5 | RECORD_DRIVE_SPEED = 50.0 6 | AUTO_DRIVE_SPEED = 50.0 7 | 8 | IMG_SIZE = (66, 200, 3) # h, w, channels 9 | -------------------------------------------------------------------------------- /util/theano_test.py: -------------------------------------------------------------------------------- 1 | from theano import function, config, shared, tensor 2 | import numpy 3 | import time 4 | 5 | vlen = 10 * 30 * 768 # 10 x #cores x # threads per core 6 | iters = 1000 7 | 8 | rng = numpy.random.RandomState(22) 9 | x = shared(numpy.asarray(rng.rand(vlen), config.floatX)) 10 | f = function([], tensor.exp(x)) 11 | print(f.maker.fgraph.toposort()) 12 | t0 = time.time() 13 | for i in range(iters): 14 | r = f() 15 | t1 = time.time() 16 | print("Looping %d times took %f seconds" % (iters, t1 - t0)) 17 | print("Result is %s" % (r,)) 18 | if numpy.any([isinstance(x.op, tensor.Elemwise) and 19 | ('Gpu' not in type(x.op).__name__) 20 | for x in f.maker.fgraph.toposort()]): 21 | print('Used the cpu') 22 | else: 23 | print('Used the gpu') -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Steven Houston 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /create_model.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | os.environ['KERAS_BACKEND'] = 'theano' 4 | os.environ['THEANO_FLAGS']='mode=FAST_RUN,device=cuda0,floatX=float32,optimizer=None' 5 | 6 | import keras.models as models 7 | from keras.models import Sequential 8 | from keras.layers.core import Dense, Dropout, Activation, Flatten, Reshape 9 | from keras.layers import BatchNormalization 10 | from keras.layers import Conv2D 11 | 12 | import json 13 | 14 | imgSize = (66, 200, 3) # h, w, channels 15 | 16 | # model start here 17 | model = Sequential() 18 | 19 | model.add(BatchNormalization(epsilon=0.001, axis=1, input_shape=imgSize)) 20 | 21 | model.add(Conv2D(24, (5,5), padding='valid', activation='relu', strides=(2,2))) 22 | model.add(Conv2D(36, (5,5), padding='valid', activation='relu', strides=(2,2))) 23 | model.add(Conv2D(48, (5,5), padding='valid', activation='relu', strides=(2,2))) 24 | model.add(Conv2D(64, (3,3), padding='valid', activation='relu', strides=(1,1))) 25 | model.add(Conv2D(64, (3,3), padding='valid', activation='relu', strides=(1,1))) 26 | model.add(Flatten()) 27 | model.add(Dense(100, activation='relu')) 28 | model.add(Dense(50, activation='relu')) 29 | model.add(Dense(10, activation='relu')) 30 | model.add(Dense(1, activation='tanh')) 31 | 32 | model.summary() 33 | # Save model to JSON 34 | with open('autopilot_basic_model.json', 'w') as outfile: 35 | outfile.write(json.dumps(json.loads(model.to_json()), indent=2)) 36 | -------------------------------------------------------------------------------- /evaluate.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import os\n", 10 | "import autodrive_constants\n", 11 | "\n", 12 | "os.environ['KERAS_BACKEND'] = 'theano'\n", 13 | "os.environ['THEANO_FLAGS']='mode=FAST_RUN,device=cuda0,floatX=float32,optimizer=None'\n", 14 | "\n", 15 | "import keras.models as models\n", 16 | "from keras.models import Sequential, Model\n", 17 | "\n", 18 | "import numpy as np\n", 19 | "import json\n", 20 | "import glob\n", 21 | "\n", 22 | "import matplotlib.pyplot as plt\n", 23 | "plt.ion()\n", 24 | "\n", 25 | "\n", 26 | "imgfiles = sorted(glob.glob('data_val/*-images.npz'))\n", 27 | "steerfiles = sorted(glob.glob('data_val/*-steer.npz'))\n", 28 | "# TODO: Handle more than one of each file (concat)\n", 29 | "imgs = np.load(imgfiles[0])['img_arr']\n", 30 | "targets = np.load(steerfiles[0])['steer_arr']\n", 31 | "\n", 32 | "print(f'Have {imgs.shape[0]} images')\n", 33 | "\n", 34 | "# load the model:\n", 35 | "model = Sequential()\n", 36 | "with open('autopilot_basic_model.json') as model_file:\n", 37 | " model = models.model_from_json(model_file.read())\n", 38 | "\n", 39 | "# load weights\n", 40 | "model.load_weights(\"weights/model_basic_weight.hdf5\")\n", 41 | "preds = model.predict(imgs)" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": null, 47 | "metadata": {}, 48 | "outputs": [], 49 | "source": [ 50 | "# Plot the expected steer vs predicted steer\n", 51 | "preds = preds.reshape(len(preds))\n", 52 | "plt.figure(0, figsize=(12, 10))\n", 53 | "plt.plot(np.array([targets[0:1000], preds.reshape(len(preds))[0:1000]]).T, '.')\n" 54 | ] 55 | } 56 | ], 57 | "metadata": { 58 | "kernelspec": { 59 | "display_name": "Python 3", 60 | "language": "python", 61 | "name": "python3" 62 | }, 63 | "language_info": { 64 | "codemirror_mode": { 65 | "name": "ipython", 66 | "version": 3 67 | }, 68 | "file_extension": ".py", 69 | "mimetype": "text/x-python", 70 | "name": "python", 71 | "nbconvert_exporter": "python", 72 | "pygments_lexer": "ipython3", 73 | "version": "3.6.8" 74 | } 75 | }, 76 | "nbformat": 4, 77 | "nbformat_minor": 2 78 | } 79 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Machine Learning for Autonomous Control of a Cozmo Robot. 2 | 3 | Anki's Cozmo robot has a built in camera and an extensive python SDK, everything we need for autonomous driving. 4 | 5 | Youtube video of self driving Cozmo: 6 | 7 | [![Cozmo autonomous driving](images/youtube.jpg)](https://www.youtube.com/watch?v=1NHsIE3mchw "Cozmo autonomous driving") 8 | 9 | This uses a convolutional neural network (CNN) architecture developed by nVidia for their self driving car called PilotNet. More details are available in this [end-to-end deep learning for self-driving cars](https://devblogs.nvidia.com/deep-learning-self-driving-cars/) blog. It is implemented using Keras with Theano back-end and is based on [this implementation](https://github.com/0bserver07/Nvidia-Autopilot-Keras). It was trained on an nVidia 1050Ti. 10 | 11 | 12 | ## Cozmo SDK 13 | The [Cozmo SDK](http://cozmosdk.anki.com/docs/) allows us to control the robot using python from a PC. 14 | 15 | PC -- USB Cable -- Mobile Device running Cozmo App -- WiFi connection -- Robot 16 | 17 | With this configuration we can get live images from the robot's camera to the PC and send steering commands back to the robot. 18 | 19 | ## Collecting Training Data 20 | 21 | To train the network we require many images from the camera and the corresponding correct steering commands. The script [record.py](record.py) uses a joystick connected to the PC to control Cozmo. While you are driving the camera images and your steering inputs are recorded (saved in the data_train/ directory). Joystick button 1 is used to toggle recording on and off (Cozmo's LEDs turns red while recording). When the youtube video was recorded the model had been trained with 17,818 images. 22 | 23 | ## Training 24 | 25 | [train.py](train.py) loads all of the recorded images and steering instructions in data_train/ and the network is trained on it for 25 epochs. 26 | 27 | ## Autonomous Driving 28 | 29 | Once training is complete [drive.py](drive.py) loads the trained weights, passes images from the live camera feed through PilotNet to predict in realtime which direction to steer and sends the steering command to the robot. 30 | 31 | 32 | # Installation 33 | 34 | Install Miniconda (Python 3) 35 | https://conda.io/miniconda.html 36 | 37 | Install Cuda (using 9.0) 38 | https://developer.nvidia.com/cuda-toolkit-archive 39 | and CuDNN 40 | https://docs.nvidia.com/deeplearning/sdk/cudnn-install/ 41 | 42 | Then: 43 | 44 | ``` 45 | conda install numpy scipy mkl-service libpython nose sklearn theano pygpu 46 | conda install -c conda-forge opencv keras 47 | pip install pygame 48 | ``` 49 | 50 | Finally follow the [Cozmo SDK setup instructions](http://cozmosdk.anki.com/docs/initial.html) and ensure the SDK examples are working. 51 | 52 | this will include `pip install cozmo[camera]` 53 | 54 | 55 | -------------------------------------------------------------------------------- /drive.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | os.environ['KERAS_BACKEND'] = 'theano' 4 | os.environ['THEANO_FLAGS']='mode=FAST_RUN,device=cuda0,floatX=float32,optimizer=None' 5 | 6 | import keras.models as models 7 | from keras.models import Sequential 8 | 9 | import numpy as np 10 | import pygame 11 | import cozmo 12 | import autodrive_constants 13 | from PIL import Image 14 | 15 | def run(sdk_conn): 16 | imgSize = autodrive_constants.IMG_SIZE 17 | 18 | # load the model: 19 | model = Sequential() 20 | with open('autopilot_basic_model.json') as model_file: 21 | model = models.model_from_json(model_file.read()) 22 | 23 | # load weights 24 | model.load_weights("weights/model_basic_weight.hdf5") 25 | 26 | # Prime Keras by making a first prediction 27 | steer = model.predict(np.zeros((1,imgSize[0],imgSize[1],imgSize[2]), dtype=np.float16)) 28 | 29 | robot = sdk_conn.wait_for_robot() 30 | robot.camera.image_stream_enabled = True 31 | robot.camera.color_image_enabled = True 32 | # Lift arms and look down to get good view of road ahead 33 | robot.set_lift_height(1.0, in_parallel=True) 34 | robot.set_head_angle(autodrive_constants.HEAD_ANGLE, in_parallel=True) 35 | robot.set_head_light(True) 36 | 37 | screen = pygame.display.set_mode((320,240)) 38 | 39 | # -------- Main Program Loop ----------- 40 | run = True 41 | while run: 42 | steer = 0.0 43 | # Get events 44 | for event in pygame.event.get(): 45 | if event.type == pygame.JOYBUTTONDOWN or event.type == pygame.QUIT: 46 | robot.stop_all_motors() 47 | run = False 48 | 49 | latest_image = robot.world.latest_image 50 | if latest_image is not None: 51 | raw = latest_image.raw_image 52 | # Convert to pygame image and display in window 53 | py_image = pygame.image.fromstring(raw.tobytes(), raw.size, raw.mode) 54 | screen.blit(py_image, (0,0)) 55 | pygame.display.flip() # update the display 56 | # Scale image 57 | scaled_img = raw.resize((imgSize[1], imgSize[0]), Image.BICUBIC) 58 | steer = model.predict(np.array(scaled_img, dtype=np.float16, ndmin=4)/255.) 59 | 60 | l_wheel_speed = autodrive_constants.AUTO_DRIVE_SPEED + (steer * 75.0) 61 | r_wheel_speed = autodrive_constants.AUTO_DRIVE_SPEED - (steer * 75.0) 62 | robot.drive_wheel_motors(l_wheel_speed, r_wheel_speed, l_wheel_acc=500, r_wheel_acc=500) 63 | 64 | pygame.time.wait(100) # sleep 65 | 66 | robot.stop_all_motors() 67 | robot.set_head_light(False) 68 | pygame.quit() 69 | 70 | if __name__ == "__main__": 71 | pygame.init() 72 | cozmo.setup_basic_logging() 73 | try: 74 | cozmo.connect(run) 75 | except KeyboardInterrupt as e: 76 | pass 77 | except cozmo.ConnectionError as e: 78 | sys.exit("A connection error occurred: %s" % e) 79 | -------------------------------------------------------------------------------- /train.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | os.environ['KERAS_BACKEND'] = 'theano' 4 | os.environ['THEANO_FLAGS']='mode=FAST_RUN,device=cuda0,floatX=float32,optimizer=None' 5 | 6 | import keras.models as models 7 | from keras.models import Sequential, Model 8 | from keras.optimizers import SGD, Adam, RMSprop 9 | from keras.callbacks import ModelCheckpoint 10 | 11 | import autodrive_constants 12 | import numpy as np 13 | import glob 14 | 15 | import matplotlib.pyplot as plt 16 | 17 | imgSize = autodrive_constants.IMG_SIZE 18 | imgs = np.zeros((0, imgSize[0], imgSize[1], imgSize[2]), dtype=np.float16) 19 | targets = np.zeros(0, dtype=np.float32) 20 | imgs_val = np.zeros((0, imgSize[0], imgSize[1], imgSize[2]), dtype=np.float16) 21 | targets_val = np.zeros(0, dtype=np.float32) 22 | 23 | # Load training data 24 | imgfiles = sorted(glob.glob('data_train/*-images.npz')) 25 | steerfiles = sorted(glob.glob('data_train/*-steer.npz')) 26 | for imgfile, steerfile in zip(imgfiles, steerfiles): 27 | imgs = np.append(imgs, np.load(imgfile)['img_arr'], axis=0) 28 | targets = np.append(targets, np.load(steerfile)['steer_arr'], axis=0) 29 | 30 | # Augment the training data by flipping each image left to right 31 | # and reversing the steering inputs 32 | imgs_aug = np.zeros(imgs.shape, dtype=np.float16) 33 | targets_aug = np.zeros(targets.shape, dtype=np.float32) 34 | for i in range(0, imgs.shape[0]): 35 | imgs_aug[i,:] = np.fliplr(imgs[i,:]) 36 | targets_aug[i] = -targets[i] 37 | 38 | imgs = np.append(imgs, imgs_aug, axis=0) 39 | targets = np.append(targets, targets_aug, axis=0) 40 | 41 | imgs_aug = None 42 | target_aug = None 43 | 44 | print(f'Have {imgs.shape[0]} training images') 45 | 46 | # Load validation data 47 | imgfiles = sorted(glob.glob('data_val/*-images.npz')) 48 | steerfiles = sorted(glob.glob('data_val/*-steer.npz')) 49 | for imgfile, steerfile in zip(imgfiles, steerfiles): 50 | imgs_val = np.append(imgs_val, np.load(imgfile)['img_arr'], axis=0) 51 | targets_val = np.append(targets_val, np.load(steerfile)['steer_arr'], axis=0) 52 | 53 | print(f'Have {imgs_val.shape[0]} validation images') 54 | 55 | #idx = 2000 56 | #imgplot = plt.imshow(imgs[idx,:].astype(np.float32)) 57 | #print(f'steer: {targets[idx]}') 58 | #plt.show() 59 | 60 | # Shuffle images and steering targets 61 | idx = np.arange(0,imgs.shape[0]) 62 | idx = np.random.permutation(idx) 63 | imgs = imgs[idx,:,:,:] 64 | targets = targets[idx] 65 | 66 | # load the model: 67 | model = Sequential() 68 | with open('autopilot_basic_model.json') as model_file: 69 | model = models.model_from_json(model_file.read()) 70 | 71 | adam = Adam(lr=0.0001) 72 | model.compile(loss='mse', 73 | optimizer=adam, 74 | metrics=['mse']) 75 | 76 | epochs = 25 77 | batch_size = 64 78 | 79 | model.fit(imgs, targets, 80 | batch_size=batch_size, epochs=epochs, verbose=1, 81 | validation_data=(imgs_val, targets_val), shuffle=True) 82 | 83 | model.save_weights('weights/model_basic_weight.hdf5') 84 | 85 | -------------------------------------------------------------------------------- /record.py: -------------------------------------------------------------------------------- 1 | import pygame 2 | import cozmo 3 | import numpy as np 4 | import os, sys, time 5 | import autodrive_constants 6 | from PIL import Image 7 | 8 | # Choose whether you are recording training or validation data 9 | data_dir = 'data_train' 10 | #data_dir = 'data_val' 11 | 12 | class Joystick: 13 | def __init__(self): 14 | pygame.joystick.init() 15 | joystick = pygame.joystick.Joystick(0) 16 | joystick.init() 17 | self.x = 0.0 18 | self.y = 0.0 19 | self.z = 0.0 20 | self.throttle = 0.0 21 | 22 | def event(self, event): 23 | # You may need to change the axis mapping. 24 | # Currently axis 0 turns cozmo left/right (x) 25 | # axis 2 (inverted) controls fwd/reverse speed (throttle) 26 | if event.type == pygame.JOYAXISMOTION: 27 | if event.axis == 0: 28 | self.x = event.value 29 | elif event.axis == 1: 30 | self.y = event.value 31 | elif event.axis == 2: 32 | self.throttle = -event.value 33 | elif event.axis == 3: 34 | self.z = event.value 35 | 36 | 37 | def run(sdk_conn): 38 | robot = sdk_conn.wait_for_robot() 39 | robot.camera.image_stream_enabled = True 40 | robot.camera.color_image_enabled = True 41 | # Lift arms and look down to get good view of road ahead 42 | robot.set_lift_height(1.0, in_parallel=True) 43 | robot.set_head_angle(autodrive_constants.HEAD_ANGLE, in_parallel=True) 44 | robot.set_head_light(True) 45 | 46 | joystick = Joystick() 47 | 48 | screen = pygame.display.set_mode((320,240)) 49 | 50 | images = list() 51 | steer = list() 52 | imgSize = autodrive_constants.IMG_SIZE 53 | 54 | # -------- Main Program Loop ----------- 55 | run = True 56 | recording = False 57 | print("Not recording, press joystick button to start. Cozmo's lights will turn red while recording.") 58 | print("Close video window to save data and exit.") 59 | while run: 60 | joystickMoved = False 61 | # Get events 62 | for event in pygame.event.get(): 63 | if event.type == pygame.JOYAXISMOTION: 64 | joystick.event(event) 65 | joystickMoved = True 66 | elif event.type == pygame.JOYBUTTONUP: 67 | if event.button == 0: 68 | recording = not recording 69 | if recording: 70 | robot.set_all_backpack_lights(cozmo.lights.red_light) 71 | else: 72 | robot.set_backpack_lights_off() 73 | elif event.type == pygame.QUIT: 74 | run = False 75 | 76 | if joystickMoved: 77 | if abs(joystick.throttle) < 0.1: 78 | robot.stop_all_motors() 79 | else: 80 | if joystick.throttle > 0.0: 81 | direction = 1 82 | else: 83 | direction = -1 84 | l_wheel_speed = (direction * autodrive_constants.RECORD_DRIVE_SPEED) + (joystick.x * 75.0) 85 | r_wheel_speed = (direction * autodrive_constants.RECORD_DRIVE_SPEED) - (joystick.x * 75.0) 86 | robot.drive_wheel_motors(l_wheel_speed, r_wheel_speed, l_wheel_acc=500, r_wheel_acc=500) 87 | 88 | latest_image = robot.world.latest_image 89 | if latest_image is not None: 90 | raw = latest_image.raw_image 91 | # Convert to pygame image and display in window 92 | py_image = pygame.image.fromstring(raw.tobytes(), raw.size, raw.mode) 93 | screen.blit(py_image, (0,0)) 94 | pygame.display.flip() # update the display 95 | # Scale image 96 | scaled_img = raw.resize((imgSize[1], imgSize[0]), Image.BICUBIC) 97 | if recording: 98 | images.append(scaled_img) 99 | steer.append(joystick.x) 100 | 101 | pygame.time.wait(100) # sleep 102 | 103 | robot.stop_all_motors() 104 | robot.set_head_light(False) 105 | pygame.quit() 106 | 107 | # Save images and steering inputs 108 | if len(images) > 0: 109 | print('Saving images') 110 | img_arr = np.zeros((len(images), imgSize[0], imgSize[1], imgSize[2]), dtype=np.float16) 111 | steer_arr = np.zeros(len(steer), dtype=np.float32) 112 | for i in range(0, len(images)): 113 | img_arr[i] = np.array(images[i], dtype=np.float16) / 255. 114 | steer_arr[i] = steer[i] 115 | 116 | timestr = time.strftime("%Y%m%d-%H%M%S") 117 | 118 | if not os.path.exists(data_dir): 119 | os.mkdir(data_dir) 120 | np.savez(f'{data_dir}/{timestr}-images.npz', img_arr=img_arr) 121 | np.savez(f'{data_dir}/{timestr}-steer.npz', steer_arr=steer_arr) 122 | 123 | print('Done') 124 | 125 | if __name__ == "__main__": 126 | pygame.init() 127 | cozmo.setup_basic_logging() 128 | try: 129 | cozmo.connect(run) 130 | except KeyboardInterrupt as e: 131 | pass 132 | except cozmo.ConnectionError as e: 133 | sys.exit("A connection error occurred: %s" % e) 134 | -------------------------------------------------------------------------------- /autopilot_basic_model.json: -------------------------------------------------------------------------------- 1 | { 2 | "class_name": "Sequential", 3 | "config": { 4 | "name": "sequential_1", 5 | "layers": [ 6 | { 7 | "class_name": "BatchNormalization", 8 | "config": { 9 | "name": "batch_normalization_1", 10 | "trainable": true, 11 | "batch_input_shape": [ 12 | null, 13 | 66, 14 | 200, 15 | 3 16 | ], 17 | "dtype": "float32", 18 | "axis": 1, 19 | "momentum": 0.99, 20 | "epsilon": 0.001, 21 | "center": true, 22 | "scale": true, 23 | "beta_initializer": { 24 | "class_name": "Zeros", 25 | "config": {} 26 | }, 27 | "gamma_initializer": { 28 | "class_name": "Ones", 29 | "config": {} 30 | }, 31 | "moving_mean_initializer": { 32 | "class_name": "Zeros", 33 | "config": {} 34 | }, 35 | "moving_variance_initializer": { 36 | "class_name": "Ones", 37 | "config": {} 38 | }, 39 | "beta_regularizer": null, 40 | "gamma_regularizer": null, 41 | "beta_constraint": null, 42 | "gamma_constraint": null 43 | } 44 | }, 45 | { 46 | "class_name": "Conv2D", 47 | "config": { 48 | "name": "conv2d_1", 49 | "trainable": true, 50 | "filters": 24, 51 | "kernel_size": [ 52 | 5, 53 | 5 54 | ], 55 | "strides": [ 56 | 2, 57 | 2 58 | ], 59 | "padding": "valid", 60 | "data_format": "channels_last", 61 | "dilation_rate": [ 62 | 1, 63 | 1 64 | ], 65 | "activation": "relu", 66 | "use_bias": true, 67 | "kernel_initializer": { 68 | "class_name": "VarianceScaling", 69 | "config": { 70 | "scale": 1.0, 71 | "mode": "fan_avg", 72 | "distribution": "uniform", 73 | "seed": null 74 | } 75 | }, 76 | "bias_initializer": { 77 | "class_name": "Zeros", 78 | "config": {} 79 | }, 80 | "kernel_regularizer": null, 81 | "bias_regularizer": null, 82 | "activity_regularizer": null, 83 | "kernel_constraint": null, 84 | "bias_constraint": null 85 | } 86 | }, 87 | { 88 | "class_name": "Conv2D", 89 | "config": { 90 | "name": "conv2d_2", 91 | "trainable": true, 92 | "filters": 36, 93 | "kernel_size": [ 94 | 5, 95 | 5 96 | ], 97 | "strides": [ 98 | 2, 99 | 2 100 | ], 101 | "padding": "valid", 102 | "data_format": "channels_last", 103 | "dilation_rate": [ 104 | 1, 105 | 1 106 | ], 107 | "activation": "relu", 108 | "use_bias": true, 109 | "kernel_initializer": { 110 | "class_name": "VarianceScaling", 111 | "config": { 112 | "scale": 1.0, 113 | "mode": "fan_avg", 114 | "distribution": "uniform", 115 | "seed": null 116 | } 117 | }, 118 | "bias_initializer": { 119 | "class_name": "Zeros", 120 | "config": {} 121 | }, 122 | "kernel_regularizer": null, 123 | "bias_regularizer": null, 124 | "activity_regularizer": null, 125 | "kernel_constraint": null, 126 | "bias_constraint": null 127 | } 128 | }, 129 | { 130 | "class_name": "Conv2D", 131 | "config": { 132 | "name": "conv2d_3", 133 | "trainable": true, 134 | "filters": 48, 135 | "kernel_size": [ 136 | 5, 137 | 5 138 | ], 139 | "strides": [ 140 | 2, 141 | 2 142 | ], 143 | "padding": "valid", 144 | "data_format": "channels_last", 145 | "dilation_rate": [ 146 | 1, 147 | 1 148 | ], 149 | "activation": "relu", 150 | "use_bias": true, 151 | "kernel_initializer": { 152 | "class_name": "VarianceScaling", 153 | "config": { 154 | "scale": 1.0, 155 | "mode": "fan_avg", 156 | "distribution": "uniform", 157 | "seed": null 158 | } 159 | }, 160 | "bias_initializer": { 161 | "class_name": "Zeros", 162 | "config": {} 163 | }, 164 | "kernel_regularizer": null, 165 | "bias_regularizer": null, 166 | "activity_regularizer": null, 167 | "kernel_constraint": null, 168 | "bias_constraint": null 169 | } 170 | }, 171 | { 172 | "class_name": "Conv2D", 173 | "config": { 174 | "name": "conv2d_4", 175 | "trainable": true, 176 | "filters": 64, 177 | "kernel_size": [ 178 | 3, 179 | 3 180 | ], 181 | "strides": [ 182 | 1, 183 | 1 184 | ], 185 | "padding": "valid", 186 | "data_format": "channels_last", 187 | "dilation_rate": [ 188 | 1, 189 | 1 190 | ], 191 | "activation": "relu", 192 | "use_bias": true, 193 | "kernel_initializer": { 194 | "class_name": "VarianceScaling", 195 | "config": { 196 | "scale": 1.0, 197 | "mode": "fan_avg", 198 | "distribution": "uniform", 199 | "seed": null 200 | } 201 | }, 202 | "bias_initializer": { 203 | "class_name": "Zeros", 204 | "config": {} 205 | }, 206 | "kernel_regularizer": null, 207 | "bias_regularizer": null, 208 | "activity_regularizer": null, 209 | "kernel_constraint": null, 210 | "bias_constraint": null 211 | } 212 | }, 213 | { 214 | "class_name": "Conv2D", 215 | "config": { 216 | "name": "conv2d_5", 217 | "trainable": true, 218 | "filters": 64, 219 | "kernel_size": [ 220 | 3, 221 | 3 222 | ], 223 | "strides": [ 224 | 1, 225 | 1 226 | ], 227 | "padding": "valid", 228 | "data_format": "channels_last", 229 | "dilation_rate": [ 230 | 1, 231 | 1 232 | ], 233 | "activation": "relu", 234 | "use_bias": true, 235 | "kernel_initializer": { 236 | "class_name": "VarianceScaling", 237 | "config": { 238 | "scale": 1.0, 239 | "mode": "fan_avg", 240 | "distribution": "uniform", 241 | "seed": null 242 | } 243 | }, 244 | "bias_initializer": { 245 | "class_name": "Zeros", 246 | "config": {} 247 | }, 248 | "kernel_regularizer": null, 249 | "bias_regularizer": null, 250 | "activity_regularizer": null, 251 | "kernel_constraint": null, 252 | "bias_constraint": null 253 | } 254 | }, 255 | { 256 | "class_name": "Flatten", 257 | "config": { 258 | "name": "flatten_1", 259 | "trainable": true, 260 | "data_format": "channels_last" 261 | } 262 | }, 263 | { 264 | "class_name": "Dense", 265 | "config": { 266 | "name": "dense_1", 267 | "trainable": true, 268 | "units": 100, 269 | "activation": "relu", 270 | "use_bias": true, 271 | "kernel_initializer": { 272 | "class_name": "VarianceScaling", 273 | "config": { 274 | "scale": 1.0, 275 | "mode": "fan_avg", 276 | "distribution": "uniform", 277 | "seed": null 278 | } 279 | }, 280 | "bias_initializer": { 281 | "class_name": "Zeros", 282 | "config": {} 283 | }, 284 | "kernel_regularizer": null, 285 | "bias_regularizer": null, 286 | "activity_regularizer": null, 287 | "kernel_constraint": null, 288 | "bias_constraint": null 289 | } 290 | }, 291 | { 292 | "class_name": "Dense", 293 | "config": { 294 | "name": "dense_2", 295 | "trainable": true, 296 | "units": 50, 297 | "activation": "relu", 298 | "use_bias": true, 299 | "kernel_initializer": { 300 | "class_name": "VarianceScaling", 301 | "config": { 302 | "scale": 1.0, 303 | "mode": "fan_avg", 304 | "distribution": "uniform", 305 | "seed": null 306 | } 307 | }, 308 | "bias_initializer": { 309 | "class_name": "Zeros", 310 | "config": {} 311 | }, 312 | "kernel_regularizer": null, 313 | "bias_regularizer": null, 314 | "activity_regularizer": null, 315 | "kernel_constraint": null, 316 | "bias_constraint": null 317 | } 318 | }, 319 | { 320 | "class_name": "Dense", 321 | "config": { 322 | "name": "dense_3", 323 | "trainable": true, 324 | "units": 10, 325 | "activation": "relu", 326 | "use_bias": true, 327 | "kernel_initializer": { 328 | "class_name": "VarianceScaling", 329 | "config": { 330 | "scale": 1.0, 331 | "mode": "fan_avg", 332 | "distribution": "uniform", 333 | "seed": null 334 | } 335 | }, 336 | "bias_initializer": { 337 | "class_name": "Zeros", 338 | "config": {} 339 | }, 340 | "kernel_regularizer": null, 341 | "bias_regularizer": null, 342 | "activity_regularizer": null, 343 | "kernel_constraint": null, 344 | "bias_constraint": null 345 | } 346 | }, 347 | { 348 | "class_name": "Dense", 349 | "config": { 350 | "name": "dense_4", 351 | "trainable": true, 352 | "units": 1, 353 | "activation": "tanh", 354 | "use_bias": true, 355 | "kernel_initializer": { 356 | "class_name": "VarianceScaling", 357 | "config": { 358 | "scale": 1.0, 359 | "mode": "fan_avg", 360 | "distribution": "uniform", 361 | "seed": null 362 | } 363 | }, 364 | "bias_initializer": { 365 | "class_name": "Zeros", 366 | "config": {} 367 | }, 368 | "kernel_regularizer": null, 369 | "bias_regularizer": null, 370 | "activity_regularizer": null, 371 | "kernel_constraint": null, 372 | "bias_constraint": null 373 | } 374 | } 375 | ] 376 | }, 377 | "keras_version": "2.2.4", 378 | "backend": "theano" 379 | } --------------------------------------------------------------------------------