Repository: lightly-ai/lightly

Issue:
Lightly-magic fails with trainer.max_epochs=0
When trying to use the lightly-magic CLI command without fine-tuning a model the CLI fails because it tries to load a checkpoint during the embedding phase which doesn't exist.

Command to reproduce: `lightly-magic input_dir=raw trainer.max_epochs=0`

Error message: 
```
Training: 0it [00:00, ?it/s]Saving latest checkpoint...
[2020-11-26 15:47:06,327][lightning][INFO] - Saving latest checkpoint...
Training: 0it [00:00, ?it/s]
Best model is stored at: /datasets/videos/lightly_outputs/2020-11-26/15-46-37/
Traceback (most recent call last):
  File "/opt/conda/envs/lightly/lib/python3.7/site-packages/lightly/cli/lightly_cli.py", line 72, in lightly_cli
    return _lightly_cli(cfg)
  File "/opt/conda/envs/lightly/lib/python3.7/site-packages/lightly/cli/lightly_cli.py", line 28, in _lightly_cli
    embeddings = _embed_cli(cfg, is_cli_call)
  File "/opt/conda/envs/lightly/lib/python3.7/site-packages/lightly/cli/embed_cli.py", line 85, in _embed_cli
    checkpoint, map_location=device
  File "/opt/conda/envs/lightly/lib/python3.7/site-packages/torch/serialization.py", line 581, in load
    with _open_file_like(f, 'rb') as opened_file:
  File "/opt/conda/envs/lightly/lib/python3.7/site-packages/torch/serialization.py", line 230, in _open_file_like
    return _open_file(name_or_buffer, mode)
  File "/opt/conda/envs/lightly/lib/python3.7/site-packages/torch/serialization.py", line 211, in __init__
    super(_open_file, self).__init__(open(name, mode))
IsADirectoryError: [Errno 21] Is a directory: '/datasets/videos/lightly_outputs/2020-11-26/15-46-37/'

Set the environment variable HYDRA_FULL_ERROR=1 for a complete stack trace.
```
Lightly-magic fails with trainer.max_epochs=0
When trying to use the lightly-magic CLI command without fine-tuning a model the CLI fails because it tries to load a checkpoint during the embedding phase which doesn't exist.

Command to reproduce: `lightly-magic input_dir=raw trainer.max_epochs=0`

Error message: 
```
Training: 0it [00:00, ?it/s]Saving latest checkpoint...
[2020-11-26 15:47:06,327][lightning][INFO] - Saving latest checkpoint...
Training: 0it [00:00, ?it/s]
Best model is stored at: /datasets/videos/lightly_outputs/2020-11-26/15-46-37/
Traceback (most recent call last):
  File "/opt/conda/envs/lightly/lib/python3.7/site-packages/lightly/cli/lightly_cli.py", line 72, in lightly_cli
    return _lightly_cli(cfg)
  File "/opt/conda/envs/lightly/lib/python3.7/site-packages/lightly/cli/lightly_cli.py", line 28, in _lightly_cli
    embeddings = _embed_cli(cfg, is_cli_call)
  File "/opt/conda/envs/lightly/lib/python3.7/site-packages/lightly/cli/embed_cli.py", line 85, in _embed_cli
    checkpoint, map_location=device
  File "/opt/conda/envs/lightly/lib/python3.7/site-packages/torch/serialization.py", line 581, in load
    with _open_file_like(f, 'rb') as opened_file:
  File "/opt/conda/envs/lightly/lib/python3.7/site-packages/torch/serialization.py", line 230, in _open_file_like
    return _open_file(name_or_buffer, mode)
  File "/opt/conda/envs/lightly/lib/python3.7/site-packages/torch/serialization.py", line 211, in __init__
    super(_open_file, self).__init__(open(name, mode))
IsADirectoryError: [Errno 21] Is a directory: '/datasets/videos/lightly_outputs/2020-11-26/15-46-37/'

Set the environment variable HYDRA_FULL_ERROR=1 for a complete stack trace.
```


Discussion:

Resolving patch:
diff --git a/lightly/api/upload.py b/lightly/api/upload.py
--- a/lightly/api/upload.py
+++ b/lightly/api/upload.py
@@ -9,6 +9,7 @@
 import random
 
 import numpy as np
+import torchvision
 
 from itertools import islice
 
@@ -338,6 +339,7 @@ def upload_images_from_folder(path_to_folder: str,
                               token: str,
                               max_workers: int = 8,
                               mode: str = 'thumbnails',
+                              size: int = -1,
                               verbose: bool = True):
     """Uploads images from a directory to the Lightly cloud solution.
 
@@ -356,6 +358,12 @@ def upload_images_from_folder(path_to_folder: str,
         mode:
             One of [full, thumbnails, metadata]. Whether to upload thumbnails,
             full images, or metadata only.
+        size:
+            Desired output size. If negative, default output size is used.
+            If size is a sequence like (h, w), output size will be matched to 
+            this. If size is an int, smaller edge of the image will be matched 
+            to this number. i.e, if height > width, then image will be rescaled
+            to (size * height / width, size).
 
     Raises:
         ValueError if dataset is too large.
@@ -364,7 +372,11 @@ def upload_images_from_folder(path_to_folder: str,
 
     """
 
-    dataset = LightlyDataset(from_folder=path_to_folder)
+    transform = None
+    if isinstance(size, tuple) or size > 0:
+        transform = torchvision.transforms.Resize(size)
+
+    dataset = LightlyDataset(from_folder=path_to_folder, transform=transform)
     upload_dataset(
         dataset,
         dataset_id,
diff --git a/lightly/cli/lightly_cli.py b/lightly/cli/lightly_cli.py
--- a/lightly/cli/lightly_cli.py
+++ b/lightly/cli/lightly_cli.py
@@ -19,7 +19,10 @@ def _lightly_cli(cfg, is_cli_call=True):
 
     cfg['loader']['shuffle'] = True
     cfg['loader']['drop_last'] = True
-    checkpoint = _train_cli(cfg, is_cli_call)
+    if cfg['trainer']['max_epochs'] > 0:
+        checkpoint = _train_cli(cfg, is_cli_call)
+    else:
+        checkpoint = ''
 
     cfg['loader']['shuffle'] = False
     cfg['loader']['drop_last'] = False
diff --git a/lightly/cli/upload_cli.py b/lightly/cli/upload_cli.py
--- a/lightly/cli/upload_cli.py
+++ b/lightly/cli/upload_cli.py
@@ -28,6 +28,10 @@ def _upload_cli(cfg, is_cli_call=True):
     dataset_id = cfg['dataset_id']
     token = cfg['token']
 
+    size = cfg['resize']
+    if not isinstance(size, int):
+        size = tuple(size)
+
     if not token or not dataset_id:
         print('Please specify your access token and dataset id.')
         print('For help, try: lightly-upload --help')
@@ -36,7 +40,8 @@ def _upload_cli(cfg, is_cli_call=True):
     if input_dir:
         mode = cfg['upload']
         try:
-            upload_images_from_folder(input_dir, dataset_id, token, mode=mode)
+            upload_images_from_folder(
+                input_dir, dataset_id, token, mode=mode, size=size)
         except (ValueError, ConnectionRefusedError) as error:
             msg = f'Error: {error}'
             print(msg)


Test patch: