def main(run_parameters, layer_parameters, _seed=None): # Generating a different reproducible random number from the seed # The second one is used for the image data generation. r1 = rrs(_seed) r2 = rrs(r1.randint(1e9)) epochs = run_parameters["epochs"] steps_per_epoch = run_parameters["steps_per_epoch"] validation_steps = run_parameters["validation_steps"] autoencoder = model(layer_parameters, random_seed=_seed) # Retrieve the output shapes for the input generator # Also converts the tensorflow Dimension into integers output_shapes = [[int(j) for j in tensor.shape] for tensor in autoencoder.outputs] # Retrieve the data for the input. data = ig.retrieve_data( output_shapes, img_type=run_parameters["img_type"], img_type_parameters=run_parameters["img_type_parameters"], shuffle=run_parameters["shuffle"], steps_per_epoch=steps_per_epoch, validation_steps=validation_steps, random_seed=r2) # Create & set the paths and directories for saving weights & Tensorboard. train_dir = os.path.join(ex.observers[0].dir, "trained") tensorboard_dir = os.path.join(ex.observers[0].dir, 'board') weights_path = os.path.join(train_dir, "weights.{epoch:02d}-{val_loss:.2f}.hdf5") # Creating the "trained" directory if it doesn't exist. if not os.path.exists(train_dir): os.makedirs(train_dir) # Checkpointer for saving the weights during training. checkpointer = keras.callbacks.ModelCheckpoint(weights_path, monitor='val_loss', verbose=0, save_best_only=False, save_weights_only=True, mode='auto', period=10) autoencoder.fit_generator( data['training_generator'], epochs=epochs, steps_per_epoch=steps_per_epoch, validation_data=data['val_generator'], validation_steps=validation_steps, verbose=2, max_queue_size=20, callbacks=[checkpointer, TensorBoard(log_dir=tensorboard_dir)], workers=1)
def encoder(input, encoder_parameters, random_seed): r = rrs(random_seed) encoder_dropout_rate = encoder_parameters["encoder_dropout_rate"] kernel_size = encoder_parameters["conv_kernel_size"] x = input # Encoding the features of the input using convolutional layers. # The convolutional layer consist of: # Convolution --> BatchNorm --> Dropout --> Maxpooling for layer_size in encoder_parameters["conv_layer_sizes"]: x = conv_layer(x, layer_size, kernel_size, dropout_rate=encoder_dropout_rate, padding="same", seed=r.randint(1e9)) final_conv_size = encoder_parameters["final_conv_size"] final_conv_kernel = encoder_parameters["final_conv_kernel"] # Latent space # Make sure that we end up with a 1x1 latent space. latent_space = conv_layer(x, final_conv_size, final_conv_kernel, use_max_pooling=False, padding="valid", dropout_rate=encoder_dropout_rate, seed=r.randint(1e9)) return latent_space
def get_encodings(latent_space, decoder_enc_size, random_seed): ''' Returns a 'dense' layer (using convolutional layers) before the softmax. ''' r = rrs(random_seed) # Stamp-selector encoding enc_stamps = Convolution2D( decoder_enc_size, (1, 1), activation=LeakyReLU(), kernel_initializer=glorot_uniform(seed=r.randint(1e9)))(latent_space) enc_stamps = BatchNormalization()(enc_stamps) # Y-coordinate encoding enc_y = Convolution2D( decoder_enc_size, (1, 1), activation=LeakyReLU(), kernel_initializer=glorot_uniform(seed=r.randint(1e9)))(latent_space) enc_y = BatchNormalization()(enc_y) # X-coordinate encoding enc_x = Convolution2D( decoder_enc_size, (1, 1), activation=LeakyReLU(), kernel_initializer=glorot_uniform(seed=r.randint(1e9)))(latent_space) enc_x = BatchNormalization()(enc_x) return enc_stamps, enc_y, enc_x
def stamp_layer(softmax_tensor, stamp_size, random_seed): ''' The stamp layer This layer pads the input according to the size of the stamps and performs a convolutional layer. The kernel of this convolutional layer contains the stamps. ''' r = rrs(random_seed) # Pad the softmax in preparation for the convolution. padding_size_left = stamp_size // 2 padding_size_right = stamp_size // 2 - 1 + stamp_size % 2 padding_singlet = (padding_size_left, padding_size_right) padded_softmax = ZeroPadding2D(padding=(padding_singlet, padding_singlet))(softmax_tensor) # Place the predicted stamp on the predicted coordinate using # a convolutional operator. # This kernel contains the stamps. output = Convolution2D( 1, (stamp_size, stamp_size), activation='linear', padding='same', use_bias=False, name='stamp_layer', kernel_constraint=k_con.NonNegMaxOne(), kernel_initializer=glorot_uniform(seed=r.randint(1e9)))(padded_softmax) # Clipping the value to the maximum value of the dataset. output = Min(value=1.0)(output) return output
def gumbel_softmax_layer(input, softmax_size, gumbel_parameters, nr_of_samples=1, transpose=False, random_seed=False, name="gumbel_sampler"): ''' Perform the gumbel softmax operator. ''' r = rrs(random_seed) x = Convolution2D(softmax_size * nr_of_samples, (1, 1), activation=LeakyReLU(), kernel_initializer=glorot_uniform(seed=r.randint(1e9)), padding='same', name="pre-" + name)(input) x = BatchNormalization(momentum=0.8)(x) x = Flatten()(x) soft = GumbelSampler( softmax_size=softmax_size, nr_of_samples=nr_of_samples, tau_init=gumbel_parameters["tau_init"], anneal_rate=gumbel_parameters["anneal_rate"], min_temperature=gumbel_parameters["min_temperature"], samples_per_epoch=gumbel_parameters["steps_per_epoch"], transpose=transpose, name=name)(x) return soft
def get_shapes(shapes_to_use=False, shape_size=28, train_size=50000, test_size=10000, random_seed=False): """ Returns random shapes as defined in shapes_to_use. Defaults to MNIST-like parameters in terms of shape and size. """ r = rrs(random_seed) if not shapes_to_use: raise ValueError( "Need to define shapes_to_use: " + str(shapes_to_use)) canvas_size = shape_size x_train = np.array([]) y_train = np.array([]) x_test = np.array([]) y_test = np.array([]) print() print() print() print(f"Random seed: {random_seed}") print() print() print() for i in range(train_size): if i % 1000 == 0: print(f"Shape nr:{i}") x_new, y_new, _ = rssg.generate_random_image( target_image=np.zeros((canvas_size, canvas_size)), shape_size=shape_size, flush_out=False, shapes_to_use=shapes_to_use, output_type="upper-left", random_seed=r.randint(1e9) ) x_train = np.append(x_train, x_new) y_train = np.append(y_train, y_new) for _ in range(test_size): x_new, y_new, _ = rssg.generate_random_image( target_image=np.empty((canvas_size, canvas_size)), shape_size=shape_size, flush_out=True, shapes_to_use=shapes_to_use, output_type="upper-left", random_seed=r.randint(1e9) ) x_test.append(x_new) y_test.append(y_new) return (x_train, y_train), (x_test, y_test)
def decoder(latent_space, decoder_parameters, random_seed): r = rrs(random_seed) enc_stamps, enc_y, enc_x = get_encodings( latent_space, decoder_parameters["decoder_enc_size"], r) coord_size = decoder_parameters["coord_tensor_size"] nr_of_stamps = decoder_parameters["nr_of_stamps"] stamps_per_canvas = decoder_parameters["stamps_per_canvas"] gumbel_parameters = decoder_parameters["gumbel_parameters"] y_coords = gumbel_softmax_layer( input=enc_y, softmax_size=coord_size, gumbel_parameters=gumbel_parameters, nr_of_samples=stamps_per_canvas, name="softmax_y", random_seed=r.randint(1e9) ) x_coords = gumbel_softmax_layer( input=enc_x, softmax_size=coord_size, gumbel_parameters=gumbel_parameters, nr_of_samples=stamps_per_canvas, name="softmax_x", random_seed=r.randint(1e9) ) stamp_coords = gumbel_softmax_layer( input=enc_stamps, softmax_size=nr_of_stamps, gumbel_parameters=gumbel_parameters, nr_of_samples=stamps_per_canvas, name="softmax_stamp", random_seed=r.randint(1e9) ) # Calculate the tensor / cartesian product of the X and Y coordinates. # (Multiplies all combinations of X and Y coords.) xy_coords = tensor_product_vector(y_coords, x_coords, coord_size) # Calculate the tensor of the coordinates and the stamp selector. xy_stamp_coords = tensor_product_matrix_vector( xy_coords, stamp_coords, nr_of_stamps, coord_size) # Sum all different predicted stamp coordinates into a single image. xy_stamp_coords_sum = sum_layer(xy_stamp_coords, axis=-4) # The stamp layer with different stamps. decoded = stamp_layer(xy_stamp_coords_sum, decoder_parameters["stamp_size"], random_seed=r.randint(1e9)) return decoded, stamp_coords, xy_coords
def get_img_data(img_rows, img_cols, img_type, img_type_parameters, test_only=False, random_seed=False): r = rrs(random_seed) x_train = False x_test = False if img_type == "t_shape": (x_train, _), (x_test, _), (_, _) = get_localized_images( canvas_size=img_rows, img_type=img_type, shapes_to_use=img_type_parameters["shapes_to_use"], shape_size=img_type_parameters["shape_size"], nr_img_per_canvas=img_type_parameters["nr_img_per_canvas"], overlap=img_type_parameters["overlap"], test_only=test_only, random_seed=r.randint(1e9)) elif img_type == 't_mnist': (x_train, _), (x_test, _), (_, _) = get_localized_images( canvas_size=img_rows, img_type=img_type, nr_img_per_canvas=img_type_parameters["nr_img_per_canvas"], overlap=img_type_parameters['overlap'], test_only=test_only, random_seed=r.randint(1e9)) elif img_type == "ct_mnist": (x_train, _), (x_test, _), (_, _) = get_cluttered_mnist( img_type_parameters["data_filepath"], test_only=test_only, random_seed=r.randint(1e9)) elif img_type == 'pedestrian': (x_train, _), (x_test, _), (_, _) = get_ped_data( file_name=img_type_parameters["file_name"], shuffle=img_type_parameters["shuffle"], random_seed=r.randint(1e9)) else: raise ValueError("Image type " + str(img_type) + " is not currently supported.") x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1) x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1) x_train = x_train.astype('float32') x_test = x_test.astype('float32') return x_train, x_test
def generate_random_image(target_image, shape_size, flush_out=True, shape_idx=None, shapes_to_use=None, const_value=1., output_type="image", random_seed=None): """ Generates a random shape and returns the shape on target_image. The shapes_to_use indicate which shapes to use. While output_type is used to retrieve the coordindates as well if necessary. The value of the shape will be const_value """ r = rrs(random_seed) # Retrieve the shapes to choose from. if shapes_to_use is None: shapes_to_use = list(available_shapes.values()) else: shapes_to_use = [available_shapes[x] for x in shapes_to_use] if flush_out: target_image[:] = 0. if shape_idx is None: random_shape_idx = r.randint(0, len(shapes_to_use)) else: random_shape_idx = shape_idx shape_generator = shapes_to_use[random_shape_idx] center = (r.randint( 0 + shape_size // 2, target_image.shape[0] - shape_size // 2 - shape_size % 2 + 1), r.randint( 0 + shape_size // 2, target_image.shape[1] - shape_size // 2 - shape_size % 2 + 1)) rr, cc = shape_generator(center, target_image.shape, shape_size=(shape_size // 2)) target_image[rr, cc] = const_value if output_type == "center": return target_image, random_shape_idx, center elif output_type == "upper-left": return target_image, random_shape_idx, (center[0] - shape_size // 2, center[1] - shape_size // 2) elif output_type == "image": return target_image
def get_localized_images(canvas_size=84, nr_img_per_canvas=2, img_type='shape_loc', overlap=False, corner=False, random_seed=False, verbose=True, test_only=False, **kwargs): r = rrs(random_seed) if verbose: print("Loading image data...") if 'shape' in img_type: shapes_to_use = kwargs.pop('shapes_to_use', False) (x_train, y_train), (x_test, y_test) = get_shapes( random_seed=r.randint(1e9), shapes_to_use=shapes_to_use) elif 'mnist' in img_type: (x_train, y_train), (x_test, y_test) = get_mnist() else: raise Exception("Localized image type '", img_type, "' is not currently supported.") if verbose: print("Loaded!") print("Localizing train data...") if test_only: x_train_loc = y_train_loc = train_coords = False else: x_train_loc, y_train_loc, train_coords = localize_all_images( images=x_train, image_labels=y_train, canvas_size=canvas_size, nr_img_per_canvas=nr_img_per_canvas, overlap=overlap, corner=corner, random_seed=r.randint(1e9)) if verbose: print("Training data localized!") print("Localizing test data...") x_test_loc, y_test_loc, test_coords = localize_all_images( images=x_test, image_labels=y_test, canvas_size=canvas_size, nr_img_per_canvas=nr_img_per_canvas, overlap=overlap, corner=corner, random_seed=r.randint(1e9)) if verbose: print("Test data localized!") return (x_train_loc, y_train_loc), (x_test_loc, y_test_loc), (train_coords, test_coords)
def get_shapes(shapes_to_use=False, shape_size=28, train_size=60000, test_size=10000, random_seed=False): """ Returns random shapes as defined in shapes_to_use. Defaults to MNIST-like parameters in terms of shape and size. """ r = rrs(random_seed) if not shapes_to_use: raise ValueError( "Need to define shapes_to_use: " + str(shapes_to_use)) canvas_size = shape_size nr_of_shapes = len(shapes_to_use) x_train = np.empty((train_size, shape_size, shape_size)) y_train = np.empty((train_size)) x_test = np.empty([test_size, shape_size, shape_size]) y_test = np.empty([test_size]) shape_images = [] # Pre-generate the different images for shape in shapes_to_use: x_image, _, _ = rssg.generate_random_image( target_image=np.zeros((canvas_size, canvas_size)), shape_size=shape_size, flush_out=False, shapes_to_use=[shape], output_type="upper-left", random_seed=r.randint(1e9) ) shape_images.append(x_image) shape_images = np.array(shape_images) train_img_idx = r.randint(nr_of_shapes, size=train_size) test_img_idx = r.randint(nr_of_shapes, size=test_size) x_train = shape_images[train_img_idx] y_train = train_img_idx x_test = shape_images[test_img_idx] y_test = test_img_idx return (x_train, y_train), (x_test, y_test)
def localize_all_images(images, image_labels, canvas_size=84, nr_img_per_canvas=2, overlap=False, random_seed=False): """ Place the images on an empty canvas in order to create the dataset. Parameter 'overlap' indicates whether these images should overlap or not. """ r = rrs(random_seed) images_new = [] images_labels_new = [] images_coords = [] # Permutate the images for placing them on a canvas. rand_img_idx_list = np.swapaxes([ r.permutation(list(range(images.shape[0]))) for i in range(nr_img_per_canvas) ], 0, 1) # We put nr_img_per_canvas images randomly on the canvas. for rand_img_idx in rand_img_idx_list: # Retrieve the images we need to place according to the current rand_img_idx images_to_place = [images[i] for i in rand_img_idx] # Retrieve their respective labels labels = [image_labels[i] for i in rand_img_idx] # Retrieve a localized version on a single canvas. canvas_image, coords = multi_random_localization( canvas_size=canvas_size, images=images_to_place, overlap=overlap, random_seed=r.randint(1e9)) # Append them on a correct list. images_new.append(canvas_image) images_labels_new.append(labels) images_coords.append(coords) images_new = np.array(images_new) images_labels_new = np.array(images_labels_new) images_coords = np.array(images_coords) return np.array(images_new), np.array(images_labels_new), np.array( images_coords)
def get_batch_and_tensors(data_list, output_shapes, cycle=False, shuffle=False, random_seed=None): """ Returns a generator that generates batches of the data_list. The output_shapes list is used to generate an extra output of zeros, in order to match the additional outputs of the model. """ r = rrs(random_seed) batch_size = output_shapes[0][0] data_chunks = chunks(data_list, batch_size) if cycle: data_iterator = itertools.cycle(data_chunks) else: data_iterator = data_chunks def shuffler(x): return r.random.shuffle(x) for chunked_data in data_iterator: dt = np.stack(chunked_data) # Shuffle if required if shuffle: dt = shuffler(dt) # Gather the outputs by putting the input as the first output. # and zeros for all other outputs (correctly sized). final_outputs = [dt] for i in range(len(output_shapes) - 1): final_outputs.append( np.zeros(output_shapes[i+1]) ) yield (dt, final_outputs)
def model(layer_parameters, random_seed, compile=True): r = rrs(random_seed) input_parameters = layer_parameters["input_parameters"] input = Input( batch_shape=(input_parameters['batch_size'], input_parameters['img_rows'], input_parameters['img_cols'], input_parameters['img_channels']), dtype='float32', name='main_input' ) latent_space = encoder(input, layer_parameters["encoder_parameters"], random_seed=r.randint(1e9)) decoded, stamp_coords, xy_coords = decoder( latent_space, layer_parameters["decoder_parameters"], random_seed=r.randint(1e9)) # Create the autoencoder with inputs and three different outputs. # The final two are used to analyze the softmax. autoencoder = Model(input, [decoded, stamp_coords, xy_coords]) # generator = decoder # Use sum of squared errors as a loss function. def my_loss(x, x_hat): recon = K.sum(mse(x, x_hat), axis=(-1, -2)) return recon if compile: autoencoder.compile(optimizer='nadam', loss=my_loss, loss_weights=[1., 0., 0.]) return autoencoder
def conv_layer(input, layer_size, kernel_size, use_max_pooling=True, padding="valid", dropout_rate=0.1, seed=None): ''' The convolutional layer consisting of: Conv layer --> Batch norm --> Dropout (--> Maxpooling) ''' r = rrs(seed) x = Convolution2D(layer_size, kernel_size, kernel_initializer=glorot_uniform(seed=r.randint(1e9)), padding=padding)(input) x = LeakyReLU()(x) x = BatchNormalization()(x) x = Dropout(dropout_rate, seed=r.randint(1e9))(x) if use_max_pooling: x = MaxPooling2D((2, 2), padding=padding)(x) return x
def get_batch_and_tensors(data_list, output_shapes, cycle=False, shuffle=False, random_seed=None): r = rrs(random_seed) batch_size = output_shapes[0][0] data_chunks = chunks(data_list, batch_size) if cycle: data_iterator = itertools.cycle(data_chunks) else: data_iterator = data_chunks def shuffler(x): return r.random.shuffle(x) for chunked_data in data_iterator: dt = np.stack(chunked_data) # Shuffle if required if shuffle: dt = shuffler(dt) # Gather the outputs by putting the input as the first output. # and zeros for all other outputs (correctly sized). final_outputs = [dt] for i in range(len(output_shapes) - 1): final_outputs.append( np.zeros(output_shapes[i+1]) ) yield (dt, final_outputs)
def get_ped_data(shuffle=True, random_seed=False, shape_size=40, file_name="pedestrian_data"): def get_upper_left_coord(coord, shape_size): return (int(math.ceil(coord[0])) - shape_size // 2, int(math.ceil(coord[1])) - shape_size // 2) r = rrs(random_seed) ped_new_path = os.path.join("..", file_name) all_images = [] print("Loading pedestrian data...") get_coords = False json_path = os.path.join(ped_new_path, "ped_info.json") if os.path.exists(json_path): print("Retrieving coordinate data...") get_coords = True all_coords = [] with open(json_path, 'r') as input_file: coord_dict = json.load(input_file) for minute in sorted(os.listdir(ped_new_path)): # We only want directories. if not minute.isdigit(): continue print(("Minute number: " + str(minute))) minute_dir = os.path.join(ped_new_path, minute) if get_coords: minute_dict = coord_dict[minute] for image_name in sorted(os.listdir(minute_dir)): # We only want images. if image_name[0] == '.': continue if get_coords: upper_left = minute_dict[image_name] image_path = os.path.join(minute_dir, image_name) try: ped_image = imageio.imread(image_path) ped_image = ped_image.astype('float32') ped_image /= 255 if get_coords: all_coords.append(get_upper_left_coord( (upper_left[0], upper_left[1]), shape_size)) all_images.append(ped_image) except Exception as e: print("An error has occurred loading an image. Skipping...") print(("Exception: " + str(e))) all_ped_images = np.array(all_images) random_seed = r.randint(1e9) x_train, x_test = train_test_split( all_ped_images, test_size=0.2, shuffle=False, random_state=random_seed) if get_coords: all_coords = np.array(all_coords) x_train_coords, x_test_coords = train_test_split( all_coords, test_size=0.2, shuffle=False, random_state=random_seed) if shuffle: combined_train = list(zip(x_train, x_train_coords)) combined_test = list(zip(x_test, x_test_coords)) r.shuffle(combined_train) r.shuffle(combined_test) x_train[:], x_train_coords[:] = list(zip(*combined_train)) x_test[:], x_test_coords[:] = list(zip(*combined_test)) elif shuffle: r.shuffle(x_train) r.shuffle(x_test) print("Pedestrian data loaded!") if get_coords: return (x_train, None), (x_test, None), (x_train_coords, x_test_coords) else: return (x_train, None), (x_test, None), (None, None)
def retrieve_data( output_shapes, img_type, img_type_parameters=False, steps_per_epoch=128, validation_steps=128, shuffle=False, test_only=False, random_seed=None, **kwargs): r = rrs(random_seed) # Retrieve information about the input / output image. batch_size = output_shapes[0][0] img_rows, img_cols = output_shapes[0][1], output_shapes[0][2] # Return the training and test data depending on the image type. # No labels will be returned as the network is an autoencoder. x_train, x_test = get_img_data(img_rows, img_cols, img_type, img_type_parameters, test_only=test_only, random_seed=r) # Shuffle again to make sure that the dataset is shuffled. if shuffle: r.shuffle(x_train) r.shuffle(x_test) # Training image generator. def gen_img(): for x in x_train: yield x # Test image generator. def gen_img_test(): for x in x_test: yield x gen = itertools.cycle(gen_img()) gen_test = itertools.cycle(gen_img_test()) def get_new_image(): im = next(gen) return im def get_new_test_image(): im = next(gen_test) return im training_size = steps_per_epoch * batch_size training_data = [get_new_image() for _ in range(training_size)] val_size = validation_steps * batch_size val_data = [get_new_image() for _ in range(val_size)] test_size = steps_per_epoch * batch_size test_data = [get_new_test_image() for _ in range(test_size)] training_generator = itertools.cycle( get_batch_and_tensors(training_data, output_shapes=output_shapes, shuffle=shuffle, random_seed=r.randint(1e9)) ) val_generator = itertools.cycle( get_batch_and_tensors(val_data, output_shapes=output_shapes, shuffle=shuffle, random_seed=r.randint(1e9)) ) test_generator = itertools.cycle( get_batch_and_tensors(test_data, output_shapes=output_shapes, shuffle=shuffle, random_seed=r.randint(1e9)) ) return { "training_generator": training_generator, "val_generator": val_generator, "test_generator": test_generator }
def get_ped_data(shuffle=True, shape_size=40, data_path="data/pedestrian_data", random_seed=False): """ Returns the pedestrian dataset. """ r = rrs(random_seed) all_images = [] def get_upper_left_coord(coord, shape_size): return (int(math.ceil(coord[0])) - shape_size // 2, int(math.ceil(coord[1])) - shape_size // 2) print("Loading pedestrian data...") json_path = os.path.join(data_path, "ped_info.json") if not os.path.exists(json_path): raise ValueError("Could not retrieve data from path: " + str(json_path)) # Load the coordinate data. all_coords = [] with open(json_path, 'r') as input_file: coord_dict = json.load(input_file) for minute in sorted(os.listdir(data_path)): # We only want directories. if not minute.isdigit(): continue # Load the filename minute_dir = os.path.join(data_path, minute) coord_minute_dict = coord_dict[minute] for image_name in sorted(os.listdir(minute_dir)): # We only want images. if image_name[0] == '.': continue upper_left = coord_minute_dict[image_name] image_path = os.path.join(minute_dir, image_name) try: # Read the image and normalize. ped_image = imageio.imread(image_path) ped_image = ped_image.astype('float32') ped_image /= 255 all_images.append(ped_image) # Gather coordinate data. all_coords.append(get_upper_left_coord( (upper_left[0], upper_left[1]), shape_size)) except Exception as e: print("An error has occurred loading an image. Skipping...") print(("Exception: " + str(e))) all_ped_images = np.array(all_images) # Split the training and test data in the same manner. fixed_seed = r.randint(1e9) x_train, x_test = train_test_split( all_ped_images, test_size=0.2, shuffle=False, random_state=fixed_seed) all_coords = np.array(all_coords) x_train_coords, x_test_coords = train_test_split( all_coords, test_size=0.2, shuffle=False, random_state=fixed_seed) if shuffle: combined_train = list(zip(x_train, x_train_coords)) combined_test = list(zip(x_test, x_test_coords)) r.shuffle(combined_train) r.shuffle(combined_test) x_train[:], x_train_coords[:] = list(zip(*combined_train)) x_test[:], x_test_coords[:] = list(zip(*combined_test)) print("Pedestrian data loaded!") return (x_train, None), (x_test, None), (None, None)