def save_keras_predictions(pred, pred_indices, dataset, num_images = 20, use_flattened_datasets = True): from settings import touch_dir from settings import ASSETS_DIR if use_flattened_datasets: touch_dir(ASSETS_DIR) print_positive("Saving result images (outer frame input, inner frame prediction, true inner frame, and combination of outer frame + prediction and outer frame + true inner frame) within the directory: {}".format(ASSETS_DIR)) for row in range(num_images): idt = pred_indices[row] Image.fromarray(dataset.images_outer2d[idt]).save(join(ASSETS_DIR, 'images_outer2d_' + str(row) + '.jpg')) Image.fromarray(pred[row]).save(join(ASSETS_DIR, 'images_pred_' + str(row) + '.jpg')) Image.fromarray(dataset.images_inner2d[idt]).save(join(ASSETS_DIR, 'images_inner2d_' + str(row) + '.jpg')) Image.fromarray(dataset.images[idt]).save(join(ASSETS_DIR, 'fullimages_' + str(row) + '.jpg')) fullimg_pred = np.copy(dataset.images[idt]) center = (int(np.floor(fullimg_pred.shape[0] / 2.)), int(np.floor(fullimg_pred.shape[1] / 2.))) fullimg_pred[center[0]-16:center[0]+16, center[1]-16:center[1]+16, :] = pred[row, :, :, :] Image.fromarray(fullimg_pred).save(join(ASSETS_DIR, 'fullimages_pred_' + str(row) + '.jpg')) else: raise NotImplementedError("Haven't implemented save_predictions_info for 2D images (only flattened images).")
def train(self, Dataset, num_epochs=200, batchsize=128, initial_eta=2e-4): # Load the dataset log("Loading data...") X_train, X_test, y_train, y_test, ind_train, ind_test = Dataset.return_train_data() # Prepare Theano variables for inputs and targets noise_var = T.matrix('noise') input_var = T.tensor4('inputs') # target_var = T.ivector('targets') # Create neural network model log("Building model and compiling functions...") generator = build_generator(noise_var) discriminator = build_discriminator(input_var) # Create expression for passing real data through the discriminator real_out = lasagne.layers.get_output(discriminator) # Create expression for passing fake data through the discriminator fake_out = lasagne.layers.get_output(discriminator, lasagne.layers.get_output(generator)) # Create loss expressions generator_loss = lasagne.objectives.binary_crossentropy(fake_out, 1).mean() discriminator_loss = (lasagne.objectives.binary_crossentropy(real_out, 1) + lasagne.objectives.binary_crossentropy(fake_out, 0)).mean() # Create update expressions for training generator_params = lasagne.layers.get_all_params(generator, trainable=True) discriminator_params = lasagne.layers.get_all_params(discriminator, trainable=True) eta = theano.shared(lasagne.utils.floatX(initial_eta)) updates = lasagne.updates.adam( generator_loss, generator_params, learning_rate=eta, beta1=0.5) updates.update(lasagne.updates.adam( discriminator_loss, discriminator_params, learning_rate=eta, beta1=0.5)) # Compile a function performing a training step on a mini-batch (by giving # the updates dictionary) and returning the corresponding training loss: train_fn = theano.function([noise_var, input_var], [(real_out > .5).mean(), (fake_out < .5).mean()], updates=updates) # Compile another function generating some data gen_fn = theano.function([noise_var], lasagne.layers.get_output(generator, deterministic=True)) # Create experiment's results directories settings.touch_dir(settings.MODELS_DIR) settings.touch_dir(settings.EPOCHS_DIR) # Finally, launch the training loop. log("Starting training...") # We iterate over epochs: for epoch in range(num_epochs): # In each epoch, we do a full pass over the training data: train_err = 0 train_batches = 0 start_time = time.time() for batch in iterate_minibatches(X_train, y_train, batchsize, shuffle=True): inputs, targets = batch noise = lasagne.utils.floatX(np.random.rand(len(inputs), 100)) train_err += np.array(train_fn(noise, inputs)) train_batches += 1 # Then we print the results for this epoch: log("Epoch {} of {} took {:.3f}s".format( epoch + 1, num_epochs, time.time() - start_time)) log(" training loss:\t\t{}".format(train_err / train_batches)) # And finally, we plot some generated data samples = np.array(gen_fn(lasagne.utils.floatX(np.random.rand(10*10, 100)))) sample = np.array(gen_fn(lasagne.utils.floatX(np.random.rand(1, 100)))) samples = dataset.denormalize_data(samples) sample = dataset.denormalize_data(sample) samples_path = os.path.join(settings.EPOCHS_DIR, 'samples_epoch{0:<5}.png'.format(epoch + 1)) Image.fromarray(samples.reshape(10, 10, 3, 64, 64) .transpose(0, 3, 1, 4, 2) .reshape(10*64, 10*64, 3)).save(samples_path) sample_path = os.path.join(settings.EPOCHS_DIR, 'one_sample_epoch{0:<5}.png'.format(epoch + 1)) Image.fromarray(sample.reshape(3, 64, 64).transpose(1, 2, 0).reshape(64, 64, 3)).save(sample_path) # After half the epochs, we start decaying the learn rate towards zero if epoch >= num_epochs // 2: progress = float(epoch) / num_epochs eta.set_value(lasagne.utils.floatX(initial_eta*2*(1 - progress))) # Optionally, you could now dump the network weights to a file like this: np.savez(os.path.join(settings.MODELS_DIR, 'dcgan_gen.npz'), *lasagne.layers.get_all_param_values(generator)) np.savez(os.path.join(settings.MODELS_DIR, 'dcgan_disc.npz'), *lasagne.layers.get_all_param_values(discriminator)) # And load them again later on like this: # with np.load('model.npz') as f: # param_values = [f['arr_%d' % i] for i in range(len(f.files))] # lasagne.layers.set_all_param_values(network, param_values) self.generator = generator self.discriminator = discriminator self.train_fn = train_fn self.gen_fn = gen_fn return True
def train(self, Dataset, num_epochs=1000, epochsize=100, batchsize=64, initial_eta=5e-5, clip=0.01): # Load the dataset log("Loading data...") X_train, X_test, y_train, y_test, ind_train, ind_test = Dataset.return_train_data( ) # Prepare Theano variables for inputs and targets noise_var = T.matrix('noise') input_var = T.tensor4('inputs') # Create neural network model log("Building model and compiling functions...") generator = build_generator(noise_var) critic = build_critic(input_var) # Create expression for passing real data through the critic real_out = lasagne.layers.get_output(critic) # Create expression for passing fake data through the critic fake_out = lasagne.layers.get_output( critic, lasagne.layers.get_output(generator)) # Create score expressions to be maximized (i.e., negative losses) generator_score = fake_out.mean() critic_score = real_out.mean() - fake_out.mean() # Create update expressions for training generator_params = lasagne.layers.get_all_params(generator, trainable=True) critic_params = lasagne.layers.get_all_params(critic, trainable=True) eta = theano.shared(lasagne.utils.floatX(initial_eta)) generator_updates = lasagne.updates.rmsprop(-generator_score, generator_params, learning_rate=eta) critic_updates = lasagne.updates.rmsprop(-critic_score, critic_params, learning_rate=eta) # Clip critic parameters in a limited range around zero (except biases) for param in lasagne.layers.get_all_params(critic, trainable=True, regularizable=True): critic_updates[param] = T.clip(critic_updates[param], -clip, clip) # Instantiate a symbolic noise generator to use for training from theano.sandbox.rng_mrg import MRG_RandomStreams as RandomStreams srng = RandomStreams(seed=np.random.randint(2147462579, size=6)) noise = srng.uniform((batchsize, 100)) # Compile functions performing a training step on a mini-batch (according # to the updates dictionary) and returning the corresponding score: generator_train_fn = theano.function([], generator_score, givens={noise_var: noise}, updates=generator_updates) critic_train_fn = theano.function([input_var], critic_score, givens={noise_var: noise}, updates=critic_updates) # Compile another function generating some data gen_fn = theano.function([noise_var], lasagne.layers.get_output(generator, deterministic=True)) # Create experiment's results directories settings.touch_dir(settings.MODELS_DIR) settings.touch_dir(settings.EPOCHS_DIR) # Finally, launch the training loop. log("Starting training...") # We create an infinite supply of batches (as an iterable generator): batches = iterate_minibatches(X_train, y_train, batchsize, shuffle=True, forever=True) # We iterate over epochs: generator_runs = 0 for epoch in range(num_epochs): start_time = time.time() # In each epoch, we do `epochsize` generator updates. Usually, the # critic is updated 5 times before every generator update. For the # first 25 generator updates and every 500 generator updates, the # critic is updated 100 times instead, following the authors' code. critic_scores = [] generator_scores = [] for _ in range(epochsize): # if (generator_runs < 25) or (generator_runs % 500 == 0): # critic_runs = 100 # else: critic_runs = 5 for _ in range(critic_runs): batch = next(batches) inputs, targets = batch critic_scores.append(critic_train_fn(inputs)) generator_scores.append(generator_train_fn()) generator_runs += 1 # Then we print the results for this epoch: log("Epoch {} of {} took {:.3f}s".format(epoch + 1, num_epochs, time.time() - start_time)) log(" generator score:\t\t{}".format(np.mean(generator_scores))) log(" Wasserstein distance:\t\t{}".format(np.mean(critic_scores))) # And finally, we plot some generated data samples = np.array( gen_fn(lasagne.utils.floatX(np.random.rand(10 * 10, 100)))) sample = np.array( gen_fn(lasagne.utils.floatX(np.random.rand(1, 100)))) samples = dataset.denormalize_data(samples) sample = dataset.denormalize_data(sample) samples_path = os.path.join(settings.EPOCHS_DIR, 'samples_epoch%i.png' % (epoch + 1)) Image.fromarray( samples.reshape(10, 10, 3, 64, 64).transpose(0, 3, 1, 4, 2).reshape(10 * 64, 10 * 64, 3)).save(samples_path) sample_path = os.path.join(settings.EPOCHS_DIR, 'one_sample_epoch%i.png' % (epoch + 1)) Image.fromarray( sample.reshape(3, 64, 64).transpose(1, 2, 0).reshape(64, 64, 3)).save(sample_path) # After half the epochs, we start decaying the learn rate towards zero if epoch >= num_epochs // 2: progress = float(epoch) / num_epochs eta.set_value( lasagne.utils.floatX(initial_eta * 2 * (1 - progress))) # Optionally, you could now dump the network weights to a file like this: np.savez(os.path.join(settings.MODELS_DIR, 'wgan_gen.npz'), *lasagne.layers.get_all_param_values(generator)) np.savez(os.path.join(settings.MODELS_DIR, 'wgan_crit.npz'), *lasagne.layers.get_all_param_values(critic)) # # And load them again later on like this: # with np.load('model.npz') as f: # param_values = [f['arr_%d' % i] for i in range(len(f.files))] # lasagne.layers.set_all_param_values(network, param_values) self.generator = generator self.critic = critic self.generator_train_fn = generator_train_fn self.critic_train_fn = critic_train_fn self.gen_fn = gen_fn return True
def run_experiment(): log("Welcome! This is my final project for the course:") log(' IFT6266-H2017 (a.k.a. "Deep Learning"') log(" Prof. Aaron Courville") log("") log("This program is copyrighted 2017 Philippe Paradis. All Rights Reserved." ) log("") log("Enjoy!") log("") model = None if settings.MODEL == "conv_mlp_vgg16": settings.MODEL = "conv_mlp" settings.USE_VGG16_LOSS = True # Define model's specific settings if settings.MODEL == "test": from keras_models import Test_Model model = Test_Model() elif settings.MODEL == "mlp": from keras_models import MLP_Model model = MLP_Model() elif settings.MODEL == "conv_mlp": from keras_models import Conv_MLP model = Conv_MLP() elif settings.MODEL == "conv_deconv": from keras_models import Conv_Deconv model = Conv_Deconv() elif settings.MODEL == "lasagne_conv_deconv": from lasagne_models import Lasagne_Conv_Deconv model = Lasagne_Conv_Deconv(use_dropout=False) elif settings.MODEL == "lasagne_conv_deconv_dropout": from lasagne_models import Lasagne_Conv_Deconv model = Lasagne_Conv_Deconv(use_dropout=True) settings.MODEL = "lasagne_conv_deconv" elif settings.MODEL == "dcgan": model = models.DCGAN_Model() elif settings.MODEL == "wgan": from wgan import WGAN_Model model = WGAN_Model() elif settings.MODEL == "lsgan": from lsgan import LSGAN_Model model = LSGAN_Model() elif settings.MODEL == "vgg16": if not os.path.isfile("vgg16.pkl"): log("Could not find VGG-16 pre-trained weights file 'vgg16.pkl'. Downloading..." ) download_vgg16_weights() from vgg16 import VGG16_Model model = VGG16_Model() else: raise NotImplementedError() ### Check if --force flag was passed if settings.FORCE_RUN: stopfile = os.path.join(settings.BASE_DIR, "STOP") if os.path.isfile(stopfile): os.remove(stopfile) ### Check for STOP file in BASE_DIR. Who knows, this experiment could ### be a baddy which we certainly don't want to waste precious GPU time on! Oh no! if model.check_stop_file(): print_error( "Oh dear, it looks like a STOP file is present in this experiment's base directory, located here:\n{}\nIf you think the STOP file was added by error and you would like to pursue this experiment further, simply feel absolute free to delete this file (which is empty, anyway)." .format(os.path.join(settings.BASE_DIR, "STOP"))) sys.exit(-2) ### Load checkpoint (if any). This will also load the hyper parameters file. ### This will also load the model's architecture, weights, optimizer states, ### that is, everything necessary to resume training. print_info( "Checking for a valid checkpoint. If so, load hyper parameters and all data from the last known state..." ) checkpoint, hyperparams, resume_from_checkpoint = model.resume_last_checkpoint( ) if resume_from_checkpoint: print_positive( "Found checkpoint, hyper parameters and model data all passing the integrity tests!" "Ready to resume training!") log("") print_info("State of last checkpoint:") for key in checkpoint: log(" * {0: <20} = {1}".format(str(key), str(checkpoint[key]))) log("") else: print_info( "No valid checkpoint found for this experiment. Building and training model from scratch." ) ### Build model's architecture model.build() ### Save hyperparameters to a file model.save_hyperparams() if settings.NUM_EPOCHS == 0 and not settings.PERFORM_PREDICT_ONLY: log("Okay, we specified 0 epochs, so we only created the experiment directory:\m{}\mand the hyper parameters file within that directory 'hyperparameters.json'." .format(settings.BASE_DIR)) sys.exit(0) ### ### Make sure the dataset has been downloaded and extracted correctly on disk ### if check_mscoco_dir(settings.MSCOCO_DIR) == False: log("(!) The project dataset based on MSCOCO was not found in its expected location '{}' or the symlink is broken." .format(settings.MSCOCO_DIR)) log("Attempting to download the dataset...") rc = download_dataset() if rc != 0: log("(!) Failed to download the project dataset, exiting...") sys.exit(rc) if settings.TINY_DATASET == True: if check_mscoco_dir(os.path.join(settings.THIS_DIR, "mscoco_small/")) == False: create_tiny_dataset() settings.MSCOCO_DIR = os.path.join(settings.THIS_DIR, "mscoco_small/") verbosity_level = "Low" if settings.VERBOSE == 1: verbosity_level = "High" elif settings.VERBOSE == 2: verbosity_level = "Medium" # Print info about our settings log("============================================================") print_info("Experiment name = %s" % settings.EXP_NAME) log("============================================================") log("") print_info("Experiment settings and options:") log(" * Model type = " + str(settings.MODEL)) log(" * Training epochs = " + str(settings.NUM_EPOCHS)) log(" * Batch size = " + str(settings.BATCH_SIZE)) log(" * Learning rate = " + str(settings.LEARNING_RATE)) log(" * Epochs per checkpoint = " + str(settings.EPOCHS_PER_CHECKPOINT)) log(" * Epochs per samples = " + str(settings.EPOCHS_PER_SAMPLES)) log(" * Feature Matching Loss = " + str(settings.FEATURE_MATCHING)) log(" * Keep model's data for every checkpoint = " + str(settings.KEEP_ALL_CHECKPOINTS)) log(" * Verbosity = " + str(settings.VERBOSE) + " ({})".format(verbosity_level)) log(" * Data augmentation = " + str(settings.DATASET_AUGMENTATION)) log(" * Load greyscale images = " + str(settings.LOAD_BLACK_AND_WHITE_IMAGES)) log("") if settings.MODEL in ["dcgan", "wgan", "lsgan"]: print_info("GAN-specific settings:") log(" * Type of GAN used = " + str(settings.MODEL)) log(" * Generator/critic updates per epoch = " + str(settings.UPDATES_PER_EPOCH)) log(" * GAN learning rate = " + str(settings.GAN_LEARNING_RATE)) if settings.MODEL == "lsgan": log(" * LSGAN architecture # = " + str(settings.LSGAN_ARCHITECTURE)) log("") ### Print hyperparameters, as loaded from existing file or as initialized for new experiment print_info("Hyper parameters:") for key in model.hyper: log(" * {0: <20} = {1}".format(str(key), str(model.hyper[key]))) log("") ####################################### # Info about the dataset ####################################### # The data is already split into training and validation datasets # The training dataset has: # - 82782 items # - 984 MB of data # The validation dataset has: # - 40504 items # - 481 MB of data # # There is also a pickled dictionary that maps image filenames (minutes the # .jpg extension) to a list of 5 strings (the 5 human-generated captions). # This dictionary is an OrderedDict with 123286 entries. import dataset ### Create and initialize an empty InpaintingDataset object Dataset = dataset.ColorsFirstDataset(settings.IMAGE_WIDTH, settings.IMAGE_HEIGHT) ### Load dataset Dataset.load_dataset() log("") print_info("Summary of data within dataset:") log(" * images.shape = " + str(Dataset.images.shape)) log(" * captions_ids.shape = " + str(Dataset.captions_ids.shape)) log(" * captions_dict.shape = " + str(Dataset.captions_dict.shape)) log("") ### Train the model (computation intensive) if settings.MODEL == "mlp" or settings.MODEL == "test" or settings.MODEL == "conv_mlp": Dataset.preprocess() Dataset.normalize() Dataset.preload() model.train(Dataset) Dataset.denormalize() ### Produce predictions Y_test_pred = model.predict(Dataset.get_data(X=True, Test=True), batch_size=model.hyper['batch_size']) ### Reshape predictions to a 2d image and denormalize data Y_test_pred = dataset.denormalize_data(Y_test_pred) num_rows = Y_test_pred.shape[0] Y_test_pred_2d = unflatten_to_4tensor(Y_test_pred, num_rows, 32, 32, is_colors_channel_first=True) Y_test_pred_2d = transpose_colors_channel(Y_test_pred_2d, from_first_to_last=True) ### Create dataset with colors channel last NewDataset = dataset.ColorsLastDataset(settings.IMAGE_WIDTH, settings.IMAGE_HEIGHT) NewDataset.load_dataset() NewDataset.preprocess(model="conv_deconv") NewDataset.preload(model="conv_deconv") ### Save predictions to disk save_keras_predictions(Y_test_pred_2d, Dataset.id_val, NewDataset, num_images=50) create_html_results_page("results.html", "assets/", num_images=50) elif settings.MODEL == "conv_deconv": Dataset.preprocess() Dataset.normalize() Dataset.preload() model.train(Dataset) Dataset.denormalize() ### Produce predictions Y_test_pred_2d = model.predict(Dataset.get_data(X=True, Test=True), batch_size=model.hyper['batch_size']) ### Reshape predictions Y_test_pred_2d = dataset.denormalize_data(Y_test_pred_2d) Y_test_pred_2d = transpose_colors_channel(Y_test_pred_2d, from_first_to_last=True) ### Create dataset with colors channel last NewDataset = dataset.ColorsLastDataset(settings.IMAGE_WIDTH, settings.IMAGE_HEIGHT) NewDataset.load_dataset() NewDataset.preprocess(model="conv_deconv") NewDataset.preload(model="conv_deconv") ### Save predictions to disk save_keras_predictions(Y_test_pred_2d, Dataset.id_val, NewDataset, num_images=50) create_html_results_page("results.html", "assets/", num_images=50) elif settings.MODEL == "lasagne_conv_deconv" or settings.MODEL == "vgg16": Dataset.preprocess() Dataset.normalize() Dataset.preload() model.train(Dataset) elif settings.MODEL == "dcgan": from lasagne.utils import floatX Dataset.preprocess() Dataset.normalize() Dataset.preload() generator, discriminator, train_fn, gen_fn = model.train( Dataset, num_epochs=settings.NUM_EPOCHS, epochsize=10, batchsize=64, initial_eta=8e-5) Dataset.denormalize() settings.touch_dir(settings.SAMPLES_DIR) for i in range(100): samples = gen_fn(floatX(np.random.rand(10 * 10, 100))) path = os.path.join(settings.EPOCHS_DIR, 'samples_%i.png' % i) samples = dataset.denormalize_data(samples) Image.fromarray( samples.reshape(10, 10, 3, 64, 64).transpose(0, 3, 1, 4, 2).reshape(10 * 64, 10 * 64, 3)).save(path) sample = gen_fn(floatX(np.random.rand(1, 100))) sample = dataset.denormalize_data(sample) path = os.path.join(settings.SAMPLES_DIR, 'one_sample_%i.png' % i) Image.fromarray( sample.reshape(3, 64, 64).transpose(1, 2, 0).reshape(64, 64, 3)).save(path) elif settings.MODEL == "wgan": import wgan from lasagne.utils import floatX Dataset.preprocess() Dataset.normalize() Dataset.preload() generator, critic, generator_train_fn, critic_train_fn, gen_fn = wgan.train( Dataset, num_epochs=settings.NUM_EPOCHS) Dataset.denormalize() settings.touch_dir(settings.SAMPLES_DIR) for i in range(100): samples = gen_fn(floatX(np.random.rand(10 * 10, 100))) path = os.path.join(settings.EPOCHS_DIR, 'samples_%i.png' % i) samples = dataset.denormalize_data(samples) Image.fromarray( samples.reshape(10, 10, 3, 64, 64).transpose(0, 3, 1, 4, 2).reshape(10 * 64, 10 * 64, 3)).save(path) sample = gen_fn(floatX(np.random.rand(1, 100))) sample = dataset.denormalize_data(sample) path = os.path.join(settings.SAMPLES_DIR, 'one_sample_%i.png' % i) Image.fromarray( sample.reshape(3, 64, 64).transpose(1, 2, 0).reshape(64, 64, 3)).save(path) elif settings.MODEL == "lsgan": from lasagne.utils import floatX Dataset.preprocess() Dataset.normalize() Dataset.preload() generator, critic, gen_fn = model.train( Dataset, num_epochs=settings.NUM_EPOCHS, epochsize=settings.UPDATES_PER_EPOCH, batchsize=settings.BATCH_SIZE, initial_eta=settings.GAN_LEARNING_RATE, architecture=settings.LSGAN_ARCHITECTURE) Dataset.denormalize() for i in range(100): samples = gen_fn(floatX(np.random.rand(10 * 10, 100))) path = os.path.join(settings.SAMPLES_DIR, "samples_{:0>3}.png".format(i)) samples = dataset.denormalize_data(samples) Image.fromarray( samples.reshape(10, 10, 3, 64, 64).transpose(0, 3, 1, 4, 2).reshape(10 * 64, 10 * 64, 3)).save(path) sample = gen_fn(floatX(np.random.rand(1, 100))) sample = dataset.denormalize_data(sample) path = os.path.join(settings.SAMPLES_DIR, "one_sample_{:0>3}.png".format(i)) Image.fromarray( sample.reshape(3, 64, 64).transpose(1, 2, 0).reshape(64, 64, 3)).save(path) ### Success...? Well, at least we didn't crash :P log("Exiting normally. That's typically a good sign :-)") sys.exit(0)
def initialize_directories(): import settings settings.BASE_DIR = os.path.join(settings.MODEL, settings.EXP_NAME) settings.MODELS_DIR = os.path.join(settings.BASE_DIR, "models/") settings.EPOCHS_DIR = os.path.join(settings.BASE_DIR, "epochs/") settings.PERF_DIR = os.path.join(settings.BASE_DIR, "performance/") settings.SAMPLES_DIR = os.path.join(settings.BASE_DIR, "samples/") settings.PRED_DIR = os.path.join(settings.BASE_DIR, "predictions/") settings.ASSETS_DIR = os.path.join(settings.PRED_DIR, "assets/") settings.HTML_DIR = settings.PRED_DIR settings.CHECKPOINTS_DIR = os.path.join(settings.BASE_DIR, "checkpoints/") settings.LOGS_DIR = os.path.join(settings.BASE_DIR, "logs/") # Create the directories settings.touch_dir(settings.BASE_DIR) settings.touch_dir(settings.MODELS_DIR) settings.touch_dir(settings.EPOCHS_DIR) settings.touch_dir(settings.PERF_DIR) settings.touch_dir(settings.SAMPLES_DIR) settings.touch_dir(settings.PRED_DIR) settings.touch_dir(settings.ASSETS_DIR) settings.touch_dir(settings.HTML_DIR) settings.touch_dir(settings.CHECKPOINTS_DIR) settings.touch_dir(settings.LOGS_DIR) # Set some file paths settings.OUTLOGFILE = os.path.join(settings.LOGS_DIR, "output.log") settings.ERRLOGFILE = os.path.join(settings.LOGS_DIR, "errors.log") # Clean up the log files if they already are present (rather than append to them, if os.path.isfile(settings.OUTLOGFILE): os.remove(settings.OUTLOGFILE) if os.path.isfile(settings.ERRLOGFILE): os.remove(settings.ERRLOGFILE)