Repository: autogluon/autogluon

Issue:
Error on demo code execution -- in get_dataset if '.rec' in path: TypeError: argument of type 'NoneType' is not iterable
The following code yields an error. I'm using a Conda environment with Python 3.6 because it is required for the ConfigSpace Python package.

```python
import autogluon as ag
from autogluon import ImageClassification as task

# Load a toy image dataset:
filename = ag.download('http://autogluon-hackathon.s3-website-us-west-2.amazonaws.com/data.zip')
ag.unzip(filename)
dataset = task.Dataset(train_path='data/train')

# Fit classification models:
classifier = task.fit(dataset, epochs=2)

# Evaluate predictions on test data:

test_dataset = task.Dataset('data/test', train=False)
test_acc = classifier.evaluate(test_dataset)
```

This also gives the error:
```python
from autogluon import ImageClassification as task
dataset = task.Dataset(train_path='data/train',
                       test_path='data/test')
classifier = task.fit(dataset,
                      net=ag.space.Categorical('ResNet50_v1b', 'ResNet18_v1b'),
                      time_limits=None,
                      # ngpus_per_trial=1,
                      num_trials = 4)
image = 'data/test/BabyShirt/BabyShirt_323.jpg'
ind, prob = classifier.predict(image)
```

The error:
```
scheduler: FIFOScheduler(
DistributedResourceManager{
(Remote: Remote REMOTE_ID: 0, 
        <Remote: 'inproc://172.18.30.18/28461/1' processes=1 threads=4, memory=7.28 GB>, Resource: NodeResourceManager(4 CPUs, 0 GPUs))
})

Starting Experiments
Num of Finished Tasks is 0
Num of Pending Tasks is 4
 25%|█████████████████████▌                                                                | 1/4 [00:00<00:00,  8.97it/s]Process Process-2:
Traceback (most recent call last):
  File "/home/z/anaconda3/envs/IC2/lib/python3.6/multiprocessing/process.py", line 258, in _bootstrap
    self.run()
  File "/home/z/anaconda3/envs/IC2/lib/python3.6/multiprocessing/process.py", line 93, in run
    self._target(*self._args, **self._kwargs)
  File "/home/z/anaconda3/envs/IC2/lib/python3.6/site-packages/autogluon/scheduler/scheduler.py", line 125, in _worker
    ret = fn(**kwargs)
  File "/home/z/anaconda3/envs/IC2/lib/python3.6/site-packages/autogluon/core/decorator.py", line 52, in __call__
    args = sample_config(args, new_config)
  File "/home/z/anaconda3/envs/IC2/lib/python3.6/site-packages/autogluon/core/decorator.py", line 38, in sample_config
    args_dict[k] = v.init()
  File "/home/z/anaconda3/envs/IC2/lib/python3.6/site-packages/autogluon/core/space.py", line 110, in init
    return self.sample(**config)
  File "/home/z/anaconda3/envs/IC2/lib/python3.6/site-packages/autogluon/core/decorator.py", line 185, in sample
    return self.func(*self.args, **kwargs)
  File "/home/z/anaconda3/envs/IC2/lib/python3.6/site-packages/autogluon/task/image_classification/dataset.py", line 108, in get_dataset
    if '.rec' in path:
TypeError: argument of type 'NoneType' is not iterable

```


Discussion:
@zhanghang1989 Could you respond to this issue?
I believe this issue has been resolved. 
Could you try the newest tutorial?

https://autogluon.mxnet.io/tutorials/image_classification/beginner.html
the error still there with the latest tutorial.
@zhreshold Could you take a look at this?

Resolving patch:
diff --git a/autogluon/task/image_classification/image_classification.py b/autogluon/task/image_classification/image_classification.py
--- a/autogluon/task/image_classification/image_classification.py
+++ b/autogluon/task/image_classification/image_classification.py
@@ -27,33 +27,39 @@ class ImageClassification(BaseTask):
     Classifier = Classifier
 
     @staticmethod
-    def Dataset(*args, **kwargs):
-        """Dataset for AutoGluon image classification tasks. 
-           May either be a :class:`autogluon.task.image_classification.ImageFolderDataset`, :class:`autogluon.task.image_classification.RecordDataset`, 
+    def Dataset(path=None, name=None, train=True, input_size=224, crop_ratio=0.875, *args, **kwargs):
+        """Dataset for AutoGluon image classification tasks.
+           May either be a :class:`autogluon.task.image_classification.ImageFolderDataset`, :class:`autogluon.task.image_classification.RecordDataset`,
            or a popular dataset already built into AutoGluon ('mnist', 'fashionmnist', 'cifar10', 'cifar100', 'imagenet').
 
         Parameters
         ----------
+        path : str, optional
+            The data location. If using :class:`ImageFolderDataset`,
+            image folder`path/to/the/folder` should be provided.
+            If using :class:`RecordDataset`, the `path/to/*.rec` should be provided.
         name : str, optional
             Which built-in dataset to use, will override all other options if specified.
             The options are: 'mnist', 'fashionmnist', 'cifar', 'cifar10', 'cifar100', 'imagenet'
-        train : bool, default = True
+        train : bool, optional, default = True
             Whether this dataset should be used for training or validation.
-        train_path : str
-            The training data location. If using :class:`ImageFolderDataset`,
-            image folder`path/to/the/folder` should be provided. 
-            If using :class:`RecordDataset`, the `path/to/*.rec` should be provided.
         input_size : int
             The input image size.
         crop_ratio : float
             Center crop ratio (for evaluation only).
-        
+
         Returns
         -------
-        Dataset object that can be passed to `task.fit()`, which is actually an :class:`autogluon.space.AutoGluonObject`. 
+        Dataset object that can be passed to `task.fit()`, which is actually an :class:`autogluon.space.AutoGluonObject`.
         To interact with such an object yourself, you must first call `Dataset.init()` to instantiate the object in Python.
         """
-        return get_dataset(*args, **kwargs)
+        if name is None:
+            if path is None:
+                raise ValueError("Either `path` or `name` must be present in Dataset(). "
+                                 "If `name` is provided, it will override the rest of the arguments.")
+        return get_dataset(path=path, train=train, name=name,
+                           input_size=input_size, crop_ratio=crop_ratio,
+                           *args, **kwargs)
 
     @staticmethod
     def fit(dataset,
@@ -116,7 +122,7 @@ def fit(dataset,
         Parameters
         ----------
         dataset : str or :meth:`autogluon.task.ImageClassification.Dataset`
-            Training dataset containing images and their associated class labels. 
+            Training dataset containing images and their associated class labels.
             Popular image datasets built into AutoGluon can be used by specifying their name as a string (options: ‘mnist’, ‘fashionmnist’, ‘cifar’, ‘cifar10’, ‘cifar100’, ‘imagenet’).
         input_size : int
             Size of images in the dataset (pixels).
@@ -141,18 +147,18 @@ def fit(dataset,
             The final returned model may be fit to all of the data (after hyperparameters have been selected).
         time_limits : int
             Approximately how long `fit()` should run for (wallclock time in seconds).
-            `fit()` will stop training new models after this amount of time has elapsed (but models which have already started training will continue to completion). 
+            `fit()` will stop training new models after this amount of time has elapsed (but models which have already started training will continue to completion).
         nthreads_per_trial : int
             How many CPUs to use in each trial (ie. single training run of a model).
         ngpus_per_trial : int
-            How many GPUs to use in each trial (ie. single training run of a model). 
+            How many GPUs to use in each trial (ie. single training run of a model).
         output_directory : str
             Dir to save search results.
         search_strategy : str
-            Which hyperparameter search algorithm to use. 
+            Which hyperparameter search algorithm to use.
             Options include: 'random' (random search), 'skopt' (SKopt Bayesian optimization), 'grid' (grid search), 'hyperband' (Hyperband), 'rl' (reinforcement learner)
         search_options : dict
-            Auxiliary keyword arguments to pass to the searcher that performs hyperparameter optimization. 
+            Auxiliary keyword arguments to pass to the searcher that performs hyperparameter optimization.
         resume : bool
             If a model checkpoint file exists, model training will resume from there when specified.
         dist_ip_addrs : list
@@ -162,16 +168,16 @@ def fit(dataset,
         plot_results : bool
             Whether or not to generate plots summarizing training process.
         visualizer : str
-            Describes method to visualize training progress during `fit()`. Options: ['mxboard', 'tensorboard', 'none']. 
+            Describes method to visualize training progress during `fit()`. Options: ['mxboard', 'tensorboard', 'none'].
         grace_period : int
             The grace period in early stopping when using Hyperband to tune hyperparameters. If None, this is set automatically.
         auto_search : bool
             If True, enables automatic suggestion of network types and hyper-parameter ranges adaptively based on provided dataset.
-        
+
         Returns
         -------
             :class:`autogluon.task.image_classification.Classifier` object which can make predictions on new data and summarize what happened during `fit()`.
-        
+
         Examples
         --------
         >>> from autogluon import ImageClassification as task
diff --git a/autogluon/task/image_classification/nets.py b/autogluon/task/image_classification/nets.py
--- a/autogluon/task/image_classification/nets.py
+++ b/autogluon/task/image_classification/nets.py
@@ -65,7 +65,7 @@ def auto_suggest_network(dataset, net):
     if isinstance(dataset, str):
         dataset_name = dataset
     elif isinstance(dataset, AutoGluonObject):
-        if 'name' in dataset.kwargs:
+        if 'name' in dataset.kwargs and dataset.kwargs['name'] is not None:
             dataset_name = dataset.kwargs['name']
         else:
             return net


Test patch: