Build an experiment specification

Description

Either from arguments, or from a YAML file by passing its path as the only argument. Both produce the same object, and everything downstream treats them identically.

Usage

platypus_spec(
  data,
  models = NULL,
  task = NULL,
  seed = NULL,
  deterministic = NULL,
  output_dir = NULL,
  check_paths = TRUE
)

Arguments

data A segmentation_data(), detection_data() or instance_data() specification, or the path to a YAML file. Which one it is decides task.
models A list of model specifications, see models and available_models(). More than one is the ordinary case rather than the exception: they are trained in turn against the same data and the same split, which is what makes their numbers comparable, and a comparison is written by listing several entries of the same architecture with different settings.
task

Which task this specification describes, one of “semantic_segmentation”, “object_detection” or “instance_segmentation”. Normally left unset: the data and model constructors already decide it, and segmentation_data() with u_net() can only mean one thing. Given, it is checked against them rather than trusted, so it can only agree or refuse.

The third task sharpened what this argument is for rather than making it load-bearing. An instance data block declares nothing a segmentation one lacks, so instance_data() is what says the word - but a model can still say it on its own, because separation is required on an instance model and has no counterpart on a semantic one.
seed

Makes a run repeatable as far as the arithmetic is deterministic, which goes further on some hardware than others - so it is worth knowing where it stops.

Repeatable: the split (split_dataset() gives the same partition on any machine), a detector’s fitted anchors, the order the data arrives in and its augmentation - including inside the loader’s worker processes - and, on the processor, every number to twelve decimal places.

Not repeatable: a run on a CUDA device. Measured on a GTX 1070, two runs of one configuration at one seed agreed to twelve decimals on the processor and differed in the fourth after a single epoch on the card, because cuDNN chooses algorithms neither package constrains. Nor across versions of the engine: anything that changes the order data is drawn in changes what one seed draws, and 0.8.0a3 did exactly that.

So it is the argument for comparing two of your own runs, and not for publishing a number somebody else can land on. platypus_device() reports which device yours will use.
deterministic

Ask the engine for deterministic algorithms as well, which is the only thing that makes a run on a card repeatable - seed on its own does not, as above.

The cost is real and arrives later than any other refusal here. Some convolutions become much slower, and an operation with no deterministic implementation raises when it is reached, so a run can stop ten minutes in rather than when the specification is built. Everything else this package refuses, it refuses before reading a single image; this cannot, because whether an operation has a deterministic algorithm is a fact about the installed engine and the device rather than about the specification.

Needs seed, and is refused without one: constraining the algorithms while the draw still varies leaves the run exactly as unrepeatable and only slower.
output_dir

Where to write a record of the run: the specification, the history, and anything the run worked out that the specification does not already say - a detector’s fitted anchors, which it cannot be reloaded without. NULL, the default, writes nothing.

Unset means nothing is written, not "written to a default place". A field with a default cannot be told apart from one somebody set to that default, so sending the default from here would have put files in every user’s working directory the moment the engine learned to write them - which it just did.
check_paths Verify that the data paths exist. Turn it off to build a specification on a machine that does not hold the data.

Details

The engine validates it, so a mistake is caught here rather than part-way through a training run - and reported against the model that has it, by the name you gave it.

Value

A platypus_spec.

Examples

library("rplatypus")

spec <- platypus_spec(
  data = segmentation_data("train/", "valid/", colormap = binary_colormap),
  models = list(
    u_net("unet", input_shape = c(256, 256)),
    linknet("linknet", input_shape = c(256, 256), loss = loss_focal_tversky(alpha = 0.7))
  )
)

# The same thing, from a file
spec <- platypus_spec("experiment.yaml")