Exemplo n.º 1
0
def download(args):
    """Downloads one or more image files to local computer.
    
    If a range of run ids is provided then files are saved to a folder
    named according to the range.
    
    Args:
        args: A single run id or a range of run ids in the form [start]-[end]
    
    Raises:
        RuntimeError: If arguments are missing or illegal
    """
    if len(args) is not 1:
        raise RuntimeError(
            "The download command requires a single parameter specifying a run number or a range"
        )
    run_numbers = []
    arg = args[0]
    range_requested = "-" in arg
    if range_requested:
        start, end = arg.split("-")
        if not utils.isinteger(start) or not utils.isinteger(end):
            raise ValueError("Run number must be an integer")
        for run_num in range(int(start), int(end) + 1):
            if run_num not in run_numbers:
                run_numbers.append(run_num)
    else:
        if not utils.isinteger(arg):
            raise ValueError("Run number must be an integer")
        run_number = int(arg)
        if run_number not in run_numbers:
            run_numbers.append(run_number)
    create_folder = len(run_numbers) > 1
    if create_folder:
        output_dir = localfs.filepath(paths["resultsDirLocal"],
                                      "result-{}".format(arg))
        if localfs.exists(output_dir):
            localfs.rm(output_dir)
        localfs.mkdir(output_dir)
    else:
        output_dir = paths["resultsDirLocal"]
    log("Fetching remote files...")
    if not localfs.exists(paths["resultsDirLocal"]):
        localfs.mkdir(paths["resultsDirLocal"])
    for run_number in run_numbers:
        spell.download(
            "runs/{}/image_output/result/result.png".format(run_number))
        target_path = localfs.filepath(output_dir,
                                       "result-{}.png".format(run_number))
        localfs.mv("result.png", target_path)
        log("Saved result file [{}]".format(target_path))
Exemplo n.º 2
0
def _transfer(img_group_name, neural_args):
    imgs_base_dir = "{}/{}".format(paths["imagesBaseRemote"], img_group_name)
    style_imgs_dir = "{}/{}".format(imgs_base_dir, "styles")
    style_imgs = spell.ls(style_imgs_dir)
    content_img_dir = "{}/{}".format(imgs_base_dir, "content")
    content_img = spell.ls(content_img_dir)[0]
    neural_style_cmd = _neural_style_cmd(neural_args, style_imgs, content_img)
    run = spell.client.runs.new(
        command=neural_style_cmd,
        machine_type="K80",
        github_url="https://github.com/ebranda/neural-style-tf",
        attached_resources=_mounts(img_group_name))
    spell.wait_until_running(run)
    run_id = spell.get_id(run)
    spell.label_run(run, "Style Transfer single")
    logFilePath = localfs.filepath(paths["resultsDirLocal"],
                                   "log-run-{}.txt".format(run_id))
    with open(logFilePath, "w") as f:
        f.write("{} = {}\n".format("Run ID", run_id))
        f.write("{} = {}\n".format("Command",
                                   "python {}".format(" ".join(sys.argv))))
        f.write("{} = {}\n".format("Parameters", neural_args))
        f.write("{} = {}\n".format("Image group", img_group_name))
        f.write("{} = {}\n".format("Style images", " ".join(style_imgs)))
        f.write("{} = {}\n".format("Content image", content_img))
    log(spell.get_run_started_message(run))
    return run_id
Exemplo n.º 3
0
def create_pair(output_dir_path, img_a_path, img_b_path, img_a_name,
                img_b_name):
    img_a = Image.open(img_a_path)
    img_b = Image.open(img_b_path)
    widths, heights = zip(*(i.size for i in [img_a, img_b]))
    img_pair = Image.new('RGB', (sum(widths), max(heights)))
    img_pair.paste(img_a, (0, 0))
    img_pair.paste(img_b, (img_a.size[0], 0))
    img_pair.save(fs.filepath(output_dir_path, img_a_name))
Exemplo n.º 4
0
def export(args, machine_type="CPU"):
    """Runs a pix2pix model export job on Spell. Automatically downloads
    the finished model to the local "models" directory.
    
    Args:
        args: The command arguments. Should contain only
            the run id from the training run. If no run id
            is provided then the last run id is retrieved
            from the local cache.
        machine_type: The machine type to use. Defaults to "CPU".
    
    Raises:
        ValueError: If run id argument is not an integer.
        RuntimeError: If no run id argument is provided or found in cache.
    """
    run_id = _fetch_run_id(args, 0, "pix2pixTrainingRunId")
    spell.validate_machine_type(machine_type)
    # Build and run the commands. Bundle the two required
    # commands into one Spell run to simplify management.
    pix2pix_export_cmd = "python pix2pix.py \
                        --mode export \
                        --output_dir output/ \
                        --checkpoint input_model/ \
                        --which_direction BtoA"

    pix2pix_convert_cmd = "python server/tools/export-checkpoint.py \
                        --checkpoint output \
                        --output_file output/model.pict"

    log("Converting model. Please wait...")
    run = spell.client.runs.new(
        command=pix2pix_export_cmd + ";" + pix2pix_convert_cmd,
        machine_type=machine_type,
        github_url="https://github.com/affinelayer/pix2pix-tensorflow.git",
        attached_resources={"runs/{}/output".format(run_id): "input_model"})
    spell.label_run(run, "Pix2Pix export")
    spell.wait_until_complete(run)
    # Download the model file now that the run is complete.
    log("Export complete. Downloading model pict file...")
    run.cp("output/model.pict", localfs.filepath("models", "pix2pix"))
    msg = "Download complete. The model.pict file in the models directory "
    msg += "{} is ready for use in tensorflowjs."
    log(msg.format(localfs.filepath("models", "pix2pix")))
Exemplo n.º 5
0
def hyperparam_search(args):
    log("Building hyperparameter grid. Please wait...")
    img_group_name = getstr(args, 0)
    imgs_base_dir = localfs.filepath(paths["imagesBaseLocal"], img_group_name)
    style_imgs_dir = localfs.filepath(imgs_base_dir, "styles")
    style_imgs = localfs.ls(style_imgs_dir)
    content_img_dir = localfs.filepath(imgs_base_dir, "content")
    content_img = localfs.ls(content_img_dir)[0]
    neural_args = params.neural_style_hypergrid
    neural_style_cmd = _neural_style_cmd(neural_args, style_imgs, content_img)
    neural_style_cmd += " --style_weight :STYLE_WEIGHT:"
    neural_style_cmd += " --temporal_weight :TEMPORAL_WEIGHT:"
    search = spell.client.hyper.new_grid_search(
        {
            #"STYLE_WEIGHT": spell.get_value_spec(["1e4","1e1","1e7"]),
            #"TEMPORAL_WEIGHT": spell.get_value_spec(["2e2","2e6","2e-2"])
            "STYLE_WEIGHT": spell.get_value_spec(neural_args.style_weights),
            "TEMPORAL_WEIGHT": spell.get_value_spec(
                neural_args.temporal_weights)
        },
        command=neural_style_cmd,
        machine_type="K80",
        github_url="https://github.com/cysmith/neural-style-tf",
        attached_resources=_mounts(img_group_name))
    for run in search.runs:
        spell.label_run(run, "Style Transfer hyperparams")
    logFilePath = localfs.filepath(paths["resultsDirLocal"],
                                   "log-hyperparams-{}.txt".format(search.id))
    with open(logFilePath, "w") as f:
        f.write("{} = {}\n".format("Search ID", search.id))
        f.write("{} = {}\n".format(
            "Command",
            "python " + sys.argv[0] + " sthyperparams " + (" ".join(args))))
        f.write("{} = {}\n".format("Image group", img_group_name))
        f.write("{} = {}\n".format("Parameters", neural_args))
        f.write("{} = {}\n".format("Style images", " ".join(style_imgs)))
        f.write("{} = {}\n".format("Content image", content_img))
    msg = "Hyperparameter search {} has started. Visit https://web.spell.run/{}/hyper-searches/{} for progress."
    msg += "\nWhen all runs have completed, execute 'python run.py stdownload {}-{}'"
    msg += "\nto download the result files."
    log(
        msg.format(search.id, spell.get_username(), search.id,
                   search.runs[0].id, search.runs[-1].id))
Exemplo n.º 6
0
def download_latest(args):
    """Downloads the most recent output image from a training run.
    
    Args:
        args: The command arguments. Accepts a single run id argument.
            If no argument is provided then we try to retrieve the id
            from the cache file created during the last training run.
    
    Raises:
        ValueError: If run id argument is not an integer.
        RuntimeError: If no run id argument is provided or found in cache.
    """
    run_id = _fetch_run_id(args, 0, "pix2pixTrainingRunId")
    log("Downloading latest training output image from run {}...".format(
        run_id))
    remote_dir = "runs/{}/output/images".format(run_id)
    if not spell.exists(remote_dir):
        log("No server output directory available yet.")
        return

    def get_output_file():
        listing = spell.ls(remote_dir)
        listing.sort()
        return listing[-2]

    f = get_output_file()
    attempts = 0
    while "output" not in f and attempts < 10:
        f = get_output_file()
        attempts += 1
    if "output" not in f:
        raise RuntimeError("Unable to find an output file on server.")
    local_dir = localfs.filepath(paths["imageslocal"], "pix2pix-results")
    spell.download(remote_dir + "/" + f, local_dir)
    log("Latest output file downloaded to '{}'.".format(
        localfs.filepath(local_dir, f)))
Exemplo n.º 7
0
def _validate_local():
    for d in localfs.ls(paths["imagesBaseLocal"]):
        style_images = localfs.ls(
            localfs.filepath(paths["imagesBaseLocal"], d, "styles"))
        content_images = localfs.ls(
            localfs.filepath(paths["imagesBaseLocal"], d, "content"))
        if not style_images:
            raise FileNotFoundError(
                "Style images folder [{}] is empty.".format(
                    paths["stylesDirLocal"]))
        if not content_images:
            raise FileNotFoundError(
                "Content images folder [{}] is empty.".format(
                    paths["contentDirLocal"]))

        def validate_filenames(names):
            for n in names:
                if " " in n:
                    raise ValueError(
                        "Image file names cannot contain spaces."
                    )  # TODO add non-alphanumeric character checking

        validate_filenames(style_images)
        validate_filenames(content_images)
Exemplo n.º 8
0
def upload(args):
    """
    Runs a BigGAN image upload job on Spell.
    
    """
    log("Preparing to upload images...")
    d = localfs.filepath(paths["datasetLocal"], paths["datasetName"])
    if localfs.isempty(d):
        raise RuntimeError("Missing images in dataset folder "+d)
    def validate_filenames(names):
        for n in names:
            if " " in n:
                raise ValueError("Image file names cannot contain spaces. [{}]".format(n)) # TODO add non-alphanumeric character checking
    validate_filenames(localfs.ls(d))
    log("Uploading. Please wait...")
    spell.upload(paths["datasetLocal"], paths["datasetRemoteDir"])
    log("Upload complete.")
Exemplo n.º 9
0
def extract_subimages(img_path,
                      output_dir_path,
                      subimage_width,
                      subimage_height,
                      num_subimages_x,
                      num_subimages_y,
                      append=False,
                      rotation=0,
                      flip_h=False,
                      flip_v=False):
    if num_subimages_x < 2 or num_subimages_y < 2:
        raise ValueError(
            "number of subimages arguments must be a value greater than 1")
    if not append:
        fs.rm(output_dir_path)
    if not fs.exists(output_dir_path):
        fs.mkdir(output_dir_path)
    img = Image.open(img_path)
    img = rotate(img, rotation)
    img = flip(img, flip_h, flip_v)
    img_width, img_height = img.size
    dx = float(img_width - subimage_width) / (num_subimages_x - 1)
    dy = float(img_height - subimage_height) / (num_subimages_y - 1)
    max_num_subimages = num_subimages_x * num_subimages_y
    counter = len(fs.ls(output_dir_path)) + 1
    for j in range(num_subimages_y):
        for i in range(num_subimages_x):
            xo = int(round(dx * i))
            yo = int(round(dy * j))
            subimage = img.crop(
                (xo, yo, xo + subimage_width, yo + subimage_height))
            num_leading_zeros = len(str(max_num_subimages)) + 1
            filename = ("{:0" + str(num_leading_zeros) +
                        "d}.png").format(counter)
            subimage.save(fs.filepath(output_dir_path, filename))
            counter += 1
Exemplo n.º 10
0
import _thread
import time
import skimage
import os
from app import spell
from app import utils
from app.utils import log
from app import filesystem as localfs


# https://github.com/taki0112/BigGAN-Tensorflow
# ERRORS OUT WITH MEMORY ERROR (posted to Github issues and waiting for reply)


paths = {
    "imagesLocal": localfs.filepath("images"),
    "datasetLocal": localfs.filepath("images", "big-gan-dataset"),
    "datasetName": "images",
    "datasetRemoteDir": "uploads/big-gan-dataset"
}


def upload(args):
    """
    Runs a BigGAN image upload job on Spell.
    
    """
    log("Preparing to upload images...")
    d = localfs.filepath(paths["datasetLocal"], paths["datasetName"])
    if localfs.isempty(d):
        raise RuntimeError("Missing images in dataset folder "+d)
Exemplo n.º 11
0
def image_pairs(args):
    """Builds pairs of images on local computer.
    
    Expects two input images, png or jpg, named A and B in the
    directory images/pix2pix-sources. Exports image pair files to 
    images/pix2pix-dataset.
    
    Args:
        args: The arguments 
            subimage width
            subimage height
            number of subimages in x
            number of subimages in y
            rotate 180 (default False)
            flip horizontal (default False)
            flip vertical (default False)
    
    Raises:
        RuntimeError: If arguments are missing
    """
    log("Preparing to make image pairs...")
    source_dir = paths["sourceslocal"]
    source_a = localfs.findfirst(source_dir, ["A.jpg", "A.jpeg", "A.png"])
    source_b = localfs.findfirst(source_dir, ["B.jpg", "B.jpeg", "B.png"])
    img_path_a = localfs.filepath(source_dir, source_a)
    img_path_b = localfs.filepath(source_dir, source_b)
    log("  Image A: {}".format(img_path_a))
    log("  Image B: {}".format(img_path_b))
    sub_w = getint(args, 0, 0)
    sub_h = getint(args, 1, 0)
    num_x = getint(args, 2, 0)
    num_y = getint(args, 3, 0)
    rotate = getboolean(args, 4)
    flip_h = getboolean(args, 5)
    output_dir_a = localfs.filepath(paths["datasetlocal"], "A")
    output_dir_b = localfs.filepath(paths["datasetlocal"], "B")
    log("Extracting subimages...")
    localfs.rm(paths["datasetlocal"])
    localfs.mkdir(paths["datasetlocal"])

    def process(img_path, out_dir):
        imageutils.extract_subimages(img_path, out_dir, sub_w, sub_h, num_x,
                                     num_y, False, 0)
        if rotate:
            imageutils.extract_subimages(img_path, out_dir, sub_w, sub_h,
                                         num_x, num_y, True, 180)
            if flip_h:
                imageutils.extract_subimages(img_path, out_dir, sub_w, sub_h,
                                             num_x, num_y, True, 180, True)
        elif flip_h:
            imageutils.extract_subimages(img_path, out_dir, sub_w, sub_h,
                                         num_x, num_y, True, 0, True)

    process(img_path_a, output_dir_a)
    process(img_path_b, output_dir_b)
    log("Building image pairs...")
    pairs_dir_path = localfs.filepath(paths["datasetlocal"], "pairs")
    if not localfs.exists(pairs_dir_path):
        localfs.mkdir(pairs_dir_path)
    for a, b in zip(localfs.ls(output_dir_a), localfs.ls(output_dir_b)):
        img_a_path = localfs.filepath(output_dir_a, a)
        img_b_path = localfs.filepath(output_dir_b, b)
        imageutils.create_pair(pairs_dir_path, img_a_path, img_b_path, a, b)
    #localfs.rm(output_dir_a)
    #localfs.rm(output_dir_b)
    for fname in localfs.ls(pairs_dir_path):
        fpath = localfs.filepath(pairs_dir_path, fname)
        fpath_new = localfs.filepath(paths["datasetlocal"], fname)
        localfs.mv(fpath, fpath_new)
    localfs.rm(pairs_dir_path)
    log("Done. Image pairs are in the directory '{}'".format(
        paths["datasetlocal"]))
    log("You can now send the upload command to send the images to Spell.")
Exemplo n.º 12
0
import _thread
import time
import math
from app import spell
from app import utils
from app import imageutils
from app.utils import log
from app.utils import getint, getboolean, argequals
from app import filesystem as localfs

# Expects image pairs in dataset directory
paths = {
    "imageslocal": localfs.filepath("images"),
    "sourceslocal": localfs.filepath("images", "pix2pix-sources"),
    "datasetlocal": localfs.filepath("images", "pix2pix-dataset"),
    "datasetremote": "uploads/pix2pix-dataset"
}

if not localfs.exists(paths["imageslocal"]):
    localfs.mkdir(paths["imageslocal"])

if not localfs.exists(paths["datasetlocal"]):
    localfs.mkdir(paths["datasetlocal"])


def image_pairs(args):
    """Builds pairs of images on local computer.
    
    Expects two input images, png or jpg, named A and B in the
    directory images/pix2pix-sources. Exports image pair files to 
    images/pix2pix-dataset.
Exemplo n.º 13
0
import _thread
import time
import sys
import webbrowser
from app import utils
from app.utils import log, getstr, getint, getfloat, checkint, checknumeric
from app import spell
from app import filesystem as localfs
from app import params

images_local = localfs.filepath("images")
images_base_local = localfs.filepath(images_local, "style-transfer-images")
images_base_remote = "uploads/style-transfer-images"
paths = {
    "imagesLocal": images_local,
    "imagesBaseLocal": images_base_local,
    "resultsDirLocal": localfs.filepath("images", "style-transfer-results"),
    "imagesBaseRemote": images_base_remote,
    "vggFileRemote": "uploads/models/imagenet-vgg-verydeep-19.mat",
    "vggFileRemoteName": "imagenet-vgg-verydeep-19.mat"
}

if not localfs.exists(paths["imagesLocal"]):
    localfs.mkdir(paths["imagesLocal"])
if not localfs.exists(paths["imagesBaseLocal"]):
    localfs.mkdir(paths["imagesBaseLocal"])
if not localfs.exists(paths["resultsDirLocal"]):
    localfs.mkdir(paths["resultsDirLocal"])


def upload():