diff --git a/DATASETS.md b/DATASETS.md
new file mode 100644
index 0000000..013e58f
--- /dev/null
+++ b/DATASETS.md
@@ -0,0 +1,122 @@
+# How to install datasets
+
+We suggest putting all datasets under the same folder (say `$DATA`) to ease management and following the instructions below to organize datasets to avoid modifying the source code. The file structure looks like
+
+```
+$DATA/
+|–– imagenet/
+|–– caltech-101/
+|–– oxford_pets/
+|–– stanford_cars/
+```
+
+If you have some datasets already installed somewhere else, you can create symbolic links in `$DATA/dataset_name` that point to the original data to avoid duplicate download.
+
+Datasets list:
+
+- [Caltech101](#caltech101)
+- [OxfordPets](#oxfordpets)
+- [StanfordCars](#stanfordcars)
+- [Flowers102](#flowers102)
+- [FGVCAircraft](#fgvcaircraft)
+- [DTD](#dtd)
+- [EuroSAT](#eurosat)
+
+The instructions to prepare each dataset are detailed below. To ensure reproducibility and fair comparison for future work, we provide fixed train/val/test splits for all datasets except ImageNet where the validation set is used as test set. The fixed splits are either from the original datasets (if available) or created by us.
+
+
+### Caltech101
+- Create a folder named `caltech-101/` under `$DATA`.
+- Download `101_ObjectCategories.tar.gz` from http://www.vision.caltech.edu/Image_Datasets/Caltech101/101_ObjectCategories.tar.gz and extract the file under `$DATA/caltech-101`.
+- Download `split_zhou_Caltech101.json` from this [link](https://drive.google.com/file/d/1hyarUivQE36mY6jSomru6Fjd-JzwcCzN/view?usp=sharing) and put it under `$DATA/caltech-101`.
+
+The directory structure should look like
+```
+caltech-101/
+|–– 101_ObjectCategories/
+|–– split_zhou_Caltech101.json
+```
+
+### OxfordPets
+- Create a folder named `oxford_pets/` under `$DATA`.
+- Download the images from https://www.robots.ox.ac.uk/~vgg/data/pets/data/images.tar.gz.
+- Download the annotations from https://www.robots.ox.ac.uk/~vgg/data/pets/data/annotations.tar.gz.
+- Download `split_zhou_OxfordPets.json` from this [link](https://drive.google.com/file/d/1501r8Ber4nNKvmlFVQZ8SeUHTcdTTEqs/view?usp=sharing).
+
+The directory structure should look like
+```
+oxford_pets/
+|–– images/
+|–– annotations/
+|–– split_zhou_OxfordPets.json
+```
+
+### StanfordCars
+- Create a folder named `stanford_cars/` under `$DATA`.
+- Download the train images http://ai.stanford.edu/~jkrause/car196/cars_train.tgz.
+- Download the test images http://ai.stanford.edu/~jkrause/car196/cars_test.tgz.
+- Download the train labels https://ai.stanford.edu/~jkrause/cars/car_devkit.tgz.
+- Download the test labels http://ai.stanford.edu/~jkrause/car196/cars_test_annos_withlabels.mat.
+- Download `split_zhou_StanfordCars.json` from this [link](https://drive.google.com/file/d/1ObCFbaAgVu0I-k_Au-gIUcefirdAuizT/view?usp=sharing).
+
+The directory structure should look like
+```
+stanford_cars/
+|–– cars_test\
+|–– cars_test_annos_withlabels.mat
+|–– cars_train\
+|–– devkit\
+|–– split_zhou_StanfordCars.json
+```
+
+### Flowers102
+- Create a folder named `oxford_flowers/` under `$DATA`.
+- Download the images and labels from https://www.robots.ox.ac.uk/~vgg/data/flowers/102/102flowers.tgz and https://www.robots.ox.ac.uk/~vgg/data/flowers/102/imagelabels.mat respectively.
+- Download `cat_to_name.json` from [here](https://drive.google.com/file/d/1AkcxCXeK_RCGCEC_GvmWxjcjaNhu-at0/view?usp=sharing).
+- Download `split_zhou_OxfordFlowers.json` from [here](https://drive.google.com/file/d/1Pp0sRXzZFZq15zVOzKjKBu4A9i01nozT/view?usp=sharing).
+
+The directory structure should look like
+```
+oxford_flowers/
+|–– cat_to_name.json
+|–– imagelabels.mat
+|–– jpg/
+|–– split_zhou_OxfordFlowers.json
+```
+
+### FGVCAircraft
+- Download the data from https://www.robots.ox.ac.uk/~vgg/data/fgvc-aircraft/archives/fgvc-aircraft-2013b.tar.gz.
+- Extract `fgvc-aircraft-2013b.tar.gz` and keep only `data/`.
+- Move `data/` to `$DATA` and rename the folder to `fgvc_aircraft/`.
+
+The directory structure should look like
+```
+fgvc_aircraft/
+|–– images/
+|–– ... # a bunch of .txt files
+```
+
+### DTD
+- Download the dataset from https://www.robots.ox.ac.uk/~vgg/data/dtd/download/dtd-r1.0.1.tar.gz and extract it to `$DATA`. This should lead to `$DATA/dtd/`.
+- Download `split_zhou_DescribableTextures.json` from this [link](https://drive.google.com/file/d/1u3_QfB467jqHgNXC00UIzbLZRQCg2S7x/view?usp=sharing).
+
+The directory structure should look like
+```
+dtd/
+|–– images/
+|–– imdb/
+|–– labels/
+|–– split_zhou_DescribableTextures.json
+```
+
+### EuroSAT
+- Create a folder named `eurosat/` under `$DATA`.
+- Download the dataset from http://madm.dfki.de/files/sentinel/EuroSAT.zip and extract it to `$DATA/eurosat/`.
+- Download `split_zhou_EuroSAT.json` from [here](https://drive.google.com/file/d/1Ip7yaCWFi0eaOFUGga0lUdVi_DDQth1o/view?usp=sharing).
+
+The directory structure should look like
+```
+eurosat/
+|–– 2750/
+|–– split_zhou_EuroSAT.json
+```
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..e1923e5
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2024 Jihwan Bang
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/README.md b/README.md
index 4e30510..ce2242f 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,52 @@
-## PCB - Official PyTorch Implementation
+# Active Prompt Learning in Visual Language Models
+##
[![Paper](https://img.shields.io/badge/arXiv-2311.11178-b31b1b.svg)](https://arxiv.org/abs/2311.11178) [![Youtube Badge](https://img.shields.io/badge/Youtube-b31b1b?style=round-square&logo=youtube&link=https://www.youtube.com/c/ZipCookResearcher)](https://www.youtube.com/watch?v=JHC9zaDYf5o&ab_channel=%08ZipCookResearcher) [![Citation Badge](https://api.juleskreuer.eu/citation-badge.php?doi=10.48550/arXiv.2311.11178)](https://juleskreuer.eu/citation-badge/) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
+This repository is the official PyTorch implementation of the following paper.
+
+> **Active Prompt Learning in Visual Language Models**
+>Jihwan Bang, Sumyeong Ahn, Jae-Gil Lee
+>CVPR 2024
-We are working on refactoring the code, and we will push our code soon!!
+
-If you are interested in our paper, please star and watch to our repository.
\ No newline at end of file
+
+## Updates
+
+- **[Jun.17th.2024]** First release the code.
+
+## How to Install
+This code is built on the [CoOp repository](https://github.com/KaiyangZhou/CoOp) and it built on top of the awesome toolbox [Dassl.pytorch](https://github.com/KaiyangZhou/Dassl.pytorch). For simply usage, I add the `dassl` directory into our directory, and revise `requirements.txt` to run the code. Hence, you should follow below commands:
+``` bash
+conda create -n pcb python=3.10
+conda activate pcb
+cd pcb
+pip install -r requirements.txt
+```
+
+Next, you should build on the datasets - follow [DATASETS.md](DATASETS.md) to install the datasets.
+
+## How to Run
+To run the code, you need to look into `scripts/alvlm/main.sh`. In this file, you must set parameter `DATA` as the directory path that datasets are stored. After then, you can run the code by following command.
+```bash
+CUDA_VISIBLE_DEVICES=XX sh scripts/alvlm/main.sh [DATASET NAME] [MODEL NAME] [AL METHOD] [SEED NUMBER] [MODE]
+```
+- **DATASET NAME** $\in$ [oxford_flowers, dtd, oxford_pets, caltech101, stanford_cars, eurosat, fgvc_aircraft]
+- **MODEL NAME** $\in$ [RN50, RN101, vit_b32, vit_b16]
+- **AL METHOD** $\in$ [random, entropy, coreset, badge]
+- **SEED**: integer
+- **MODE**: This is for description augmentation $\in$ [none, AS, AE]
+
+
+
+
+## Citation
+If you use this code in your research, please kindly cite the following papers
+
+```bash
+@inproceedings{bang2024active,
+ title={Active Prompt Learning in Vision Language Models},
+ author={Bang, Jihwan and Ahn, Sumyeong and Lee, Jae-Gil},
+ booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},
+ pages={27004--27014},
+ year={2024}
+}
+```
\ No newline at end of file
diff --git a/architecture.png b/architecture.png
new file mode 100644
index 0000000..7d8f45a
Binary files /dev/null and b/architecture.png differ
diff --git a/clip/__init__.py b/clip/__init__.py
new file mode 100755
index 0000000..dcc5619
--- /dev/null
+++ b/clip/__init__.py
@@ -0,0 +1 @@
+from .clip import *
diff --git a/clip/__pycache__/__init__.cpython-310.pyc b/clip/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000..5eb40de
Binary files /dev/null and b/clip/__pycache__/__init__.cpython-310.pyc differ
diff --git a/clip/__pycache__/clip.cpython-310.pyc b/clip/__pycache__/clip.cpython-310.pyc
new file mode 100644
index 0000000..0ae6104
Binary files /dev/null and b/clip/__pycache__/clip.cpython-310.pyc differ
diff --git a/clip/__pycache__/model.cpython-310.pyc b/clip/__pycache__/model.cpython-310.pyc
new file mode 100644
index 0000000..3822927
Binary files /dev/null and b/clip/__pycache__/model.cpython-310.pyc differ
diff --git a/clip/__pycache__/simple_tokenizer.cpython-310.pyc b/clip/__pycache__/simple_tokenizer.cpython-310.pyc
new file mode 100644
index 0000000..3eac1e2
Binary files /dev/null and b/clip/__pycache__/simple_tokenizer.cpython-310.pyc differ
diff --git a/clip/bpe_simple_vocab_16e6.txt.gz b/clip/bpe_simple_vocab_16e6.txt.gz
new file mode 100755
index 0000000..7b5088a
Binary files /dev/null and b/clip/bpe_simple_vocab_16e6.txt.gz differ
diff --git a/clip/clip.py b/clip/clip.py
new file mode 100755
index 0000000..b1e4140
--- /dev/null
+++ b/clip/clip.py
@@ -0,0 +1,221 @@
+import hashlib
+import os
+import urllib
+import warnings
+from typing import Union, List
+
+import torch
+from PIL import Image
+from torchvision.transforms import Compose, Resize, CenterCrop, ToTensor, Normalize
+from tqdm import tqdm
+
+from .model import build_model
+from .simple_tokenizer import SimpleTokenizer as _Tokenizer
+
+try:
+ from torchvision.transforms import InterpolationMode
+ BICUBIC = InterpolationMode.BICUBIC
+except ImportError:
+ BICUBIC = Image.BICUBIC
+
+
+if torch.__version__.split(".") < ["1", "7", "1"]:
+ warnings.warn("PyTorch version 1.7.1 or higher is recommended")
+
+
+__all__ = ["available_models", "load", "tokenize"]
+_tokenizer = _Tokenizer()
+
+_MODELS = {
+ "RN50": "https://openaipublic.azureedge.net/clip/models/afeb0e10f9e5a86da6080e35cf09123aca3b358a0c3e3b6c78a7b63bc04b6762/RN50.pt",
+ "RN101": "https://openaipublic.azureedge.net/clip/models/8fa8567bab74a42d41c5915025a8e4538c3bdbe8804a470a72f30b0d94fab599/RN101.pt",
+ "RN50x4": "https://openaipublic.azureedge.net/clip/models/7e526bd135e493cef0776de27d5f42653e6b4c8bf9e0f653bb11773263205fdd/RN50x4.pt",
+ "RN50x16": "https://openaipublic.azureedge.net/clip/models/52378b407f34354e150460fe41077663dd5b39c54cd0bfd2b27167a4a06ec9aa/RN50x16.pt",
+ "ViT-B/32": "https://openaipublic.azureedge.net/clip/models/40d365715913c9da98579312b702a82c18be219cc2a73407c4526f58eba950af/ViT-B-32.pt",
+ "ViT-B/16": "https://openaipublic.azureedge.net/clip/models/5806e77cd80f8b59890b7e101eabd078d9fb84e6937f9e85e4ecb61988df416f/ViT-B-16.pt",
+}
+
+
+def _download(url: str, root: str = os.path.expanduser("~/.cache/clip")):
+ os.makedirs(root, exist_ok=True)
+ filename = os.path.basename(url)
+
+ expected_sha256 = url.split("/")[-2]
+ download_target = os.path.join(root, filename)
+
+ if os.path.exists(download_target) and not os.path.isfile(download_target):
+ raise RuntimeError(f"{download_target} exists and is not a regular file")
+
+ if os.path.isfile(download_target):
+ if hashlib.sha256(open(download_target, "rb").read()).hexdigest() == expected_sha256:
+ return download_target
+ else:
+ warnings.warn(f"{download_target} exists, but the SHA256 checksum does not match; re-downloading the file")
+
+ with urllib.request.urlopen(url) as source, open(download_target, "wb") as output:
+ with tqdm(total=int(source.info().get("Content-Length")), ncols=80, unit='iB', unit_scale=True) as loop:
+ while True:
+ buffer = source.read(8192)
+ if not buffer:
+ break
+
+ output.write(buffer)
+ loop.update(len(buffer))
+
+ if hashlib.sha256(open(download_target, "rb").read()).hexdigest() != expected_sha256:
+ raise RuntimeError(f"Model has been downloaded but the SHA256 checksum does not not match")
+
+ return download_target
+
+
+def _transform(n_px):
+ return Compose([
+ Resize(n_px, interpolation=BICUBIC),
+ CenterCrop(n_px),
+ lambda image: image.convert("RGB"),
+ ToTensor(),
+ Normalize((0.48145466, 0.4578275, 0.40821073), (0.26862954, 0.26130258, 0.27577711)),
+ ])
+
+
+def available_models() -> List[str]:
+ """Returns the names of available CLIP models"""
+ return list(_MODELS.keys())
+
+
+def load(name: str, device: Union[str, torch.device] = "cuda" if torch.cuda.is_available() else "cpu", jit=False):
+ """Load a CLIP model
+
+ Parameters
+ ----------
+ name : str
+ A model name listed by `clip.available_models()`, or the path to a model checkpoint containing the state_dict
+
+ device : Union[str, torch.device]
+ The device to put the loaded model
+
+ jit : bool
+ Whether to load the optimized JIT model or more hackable non-JIT model (default).
+
+ Returns
+ -------
+ model : torch.nn.Module
+ The CLIP model
+
+ preprocess : Callable[[PIL.Image], torch.Tensor]
+ A torchvision transform that converts a PIL image into a tensor that the returned model can take as its input
+ """
+ if name in _MODELS:
+ model_path = _download(_MODELS[name])
+ elif os.path.isfile(name):
+ model_path = name
+ else:
+ raise RuntimeError(f"Model {name} not found; available models = {available_models()}")
+
+ try:
+ # loading JIT archive
+ model = torch.jit.load(model_path, map_location=device if jit else "cpu").eval()
+ state_dict = None
+ except RuntimeError:
+ # loading saved state dict
+ if jit:
+ warnings.warn(f"File {model_path} is not a JIT archive. Loading as a state dict instead")
+ jit = False
+ state_dict = torch.load(model_path, map_location="cpu")
+
+ if not jit:
+ model = build_model(state_dict or model.state_dict()).to(device)
+ if str(device) == "cpu":
+ model.float()
+ return model, _transform(model.visual.input_resolution)
+
+ # patch the device names
+ device_holder = torch.jit.trace(lambda: torch.ones([]).to(torch.device(device)), example_inputs=[])
+ device_node = [n for n in device_holder.graph.findAllNodes("prim::Constant") if "Device" in repr(n)][-1]
+
+ def patch_device(module):
+ try:
+ graphs = [module.graph] if hasattr(module, "graph") else []
+ except RuntimeError:
+ graphs = []
+
+ if hasattr(module, "forward1"):
+ graphs.append(module.forward1.graph)
+
+ for graph in graphs:
+ for node in graph.findAllNodes("prim::Constant"):
+ if "value" in node.attributeNames() and str(node["value"]).startswith("cuda"):
+ node.copyAttributes(device_node)
+
+ model.apply(patch_device)
+ patch_device(model.encode_image)
+ patch_device(model.encode_text)
+
+ # patch dtype to float32 on CPU
+ if str(device) == "cpu":
+ float_holder = torch.jit.trace(lambda: torch.ones([]).float(), example_inputs=[])
+ float_input = list(float_holder.graph.findNode("aten::to").inputs())[1]
+ float_node = float_input.node()
+
+ def patch_float(module):
+ try:
+ graphs = [module.graph] if hasattr(module, "graph") else []
+ except RuntimeError:
+ graphs = []
+
+ if hasattr(module, "forward1"):
+ graphs.append(module.forward1.graph)
+
+ for graph in graphs:
+ for node in graph.findAllNodes("aten::to"):
+ inputs = list(node.inputs())
+ for i in [1, 2]: # dtype can be the second or third argument to aten::to()
+ if inputs[i].node()["value"] == 5:
+ inputs[i].node().copyAttributes(float_node)
+
+ model.apply(patch_float)
+ patch_float(model.encode_image)
+ patch_float(model.encode_text)
+
+ model.float()
+
+ return model, _transform(model.input_resolution.item())
+
+
+def tokenize(texts: Union[str, List[str]], context_length: int = 77, truncate: bool = False) -> torch.LongTensor:
+ """
+ Returns the tokenized representation of given input string(s)
+
+ Parameters
+ ----------
+ texts : Union[str, List[str]]
+ An input string or a list of input strings to tokenize
+
+ context_length : int
+ The context length to use; all CLIP models use 77 as the context length
+
+ truncate: bool
+ Whether to truncate the text in case its encoding is longer than the context length
+
+ Returns
+ -------
+ A two-dimensional tensor containing the resulting tokens, shape = [number of input strings, context_length]
+ """
+ if isinstance(texts, str):
+ texts = [texts]
+
+ sot_token = _tokenizer.encoder["<|startoftext|>"]
+ eot_token = _tokenizer.encoder["<|endoftext|>"]
+ all_tokens = [[sot_token] + _tokenizer.encode(text) + [eot_token] for text in texts]
+ result = torch.zeros(len(all_tokens), context_length, dtype=torch.long)
+
+ for i, tokens in enumerate(all_tokens):
+ if len(tokens) > context_length:
+ if truncate:
+ tokens = tokens[:context_length]
+ tokens[-1] = eot_token
+ else:
+ raise RuntimeError(f"Input {texts[i]} is too long for context length {context_length}")
+ result[i, :len(tokens)] = torch.tensor(tokens)
+
+ return result
diff --git a/clip/model.py b/clip/model.py
new file mode 100755
index 0000000..f2c95c4
--- /dev/null
+++ b/clip/model.py
@@ -0,0 +1,432 @@
+from collections import OrderedDict
+from typing import Tuple, Union
+
+import numpy as np
+import torch
+import torch.nn.functional as F
+from torch import nn
+
+
+class Bottleneck(nn.Module):
+ expansion = 4
+
+ def __init__(self, inplanes, planes, stride=1):
+ super().__init__()
+
+ # all conv layers have stride 1. an avgpool is performed after the second convolution when stride > 1
+ self.conv1 = nn.Conv2d(inplanes, planes, 1, bias=False)
+ self.bn1 = nn.BatchNorm2d(planes)
+
+ self.conv2 = nn.Conv2d(planes, planes, 3, padding=1, bias=False)
+ self.bn2 = nn.BatchNorm2d(planes)
+
+ self.avgpool = nn.AvgPool2d(stride) if stride > 1 else nn.Identity()
+
+ self.conv3 = nn.Conv2d(planes, planes * self.expansion, 1, bias=False)
+ self.bn3 = nn.BatchNorm2d(planes * self.expansion)
+
+ self.relu = nn.ReLU(inplace=True)
+ self.downsample = None
+ self.stride = stride
+
+ if stride > 1 or inplanes != planes * Bottleneck.expansion:
+ # downsampling layer is prepended with an avgpool, and the subsequent convolution has stride 1
+ self.downsample = nn.Sequential(OrderedDict([
+ ("-1", nn.AvgPool2d(stride)),
+ ("0", nn.Conv2d(inplanes, planes * self.expansion, 1, stride=1, bias=False)),
+ ("1", nn.BatchNorm2d(planes * self.expansion))
+ ]))
+
+ def forward(self, x: torch.Tensor):
+ identity = x
+
+ out = self.relu(self.bn1(self.conv1(x)))
+ out = self.relu(self.bn2(self.conv2(out)))
+ out = self.avgpool(out)
+ out = self.bn3(self.conv3(out))
+
+ if self.downsample is not None:
+ identity = self.downsample(x)
+
+ out += identity
+ out = self.relu(out)
+ return out
+
+
+class AttentionPool2d(nn.Module):
+ def __init__(self, spacial_dim: int, embed_dim: int, num_heads: int, output_dim: int = None):
+ super().__init__()
+ self.positional_embedding = nn.Parameter(torch.randn(spacial_dim ** 2 + 1, embed_dim) / embed_dim ** 0.5)
+ self.k_proj = nn.Linear(embed_dim, embed_dim)
+ self.q_proj = nn.Linear(embed_dim, embed_dim)
+ self.v_proj = nn.Linear(embed_dim, embed_dim)
+ self.c_proj = nn.Linear(embed_dim, output_dim or embed_dim)
+ self.num_heads = num_heads
+
+ def forward(self, x):
+ x = x.reshape(x.shape[0], x.shape[1], x.shape[2] * x.shape[3]).permute(2, 0, 1) # NCHW -> (HW)NC
+ x = torch.cat([x.mean(dim=0, keepdim=True), x], dim=0) # (HW+1)NC
+ x = x + self.positional_embedding[:, None, :].to(x.dtype) # (HW+1)NC
+ x, _ = F.multi_head_attention_forward(
+ query=x, key=x, value=x,
+ embed_dim_to_check=x.shape[-1],
+ num_heads=self.num_heads,
+ q_proj_weight=self.q_proj.weight,
+ k_proj_weight=self.k_proj.weight,
+ v_proj_weight=self.v_proj.weight,
+ in_proj_weight=None,
+ in_proj_bias=torch.cat([self.q_proj.bias, self.k_proj.bias, self.v_proj.bias]),
+ bias_k=None,
+ bias_v=None,
+ add_zero_attn=False,
+ dropout_p=0,
+ out_proj_weight=self.c_proj.weight,
+ out_proj_bias=self.c_proj.bias,
+ use_separate_proj_weight=True,
+ training=self.training,
+ need_weights=False
+ )
+
+ return x[0]
+
+
+class ModifiedResNet(nn.Module):
+ """
+ A ResNet class that is similar to torchvision's but contains the following changes:
+ - There are now 3 "stem" convolutions as opposed to 1, with an average pool instead of a max pool.
+ - Performs anti-aliasing strided convolutions, where an avgpool is prepended to convolutions with stride > 1
+ - The final pooling layer is a QKV attention instead of an average pool
+ """
+
+ def __init__(self, layers, output_dim, heads, input_resolution=224, width=64):
+ super().__init__()
+ self.output_dim = output_dim
+ self.input_resolution = input_resolution
+
+ # the 3-layer stem
+ self.conv1 = nn.Conv2d(3, width // 2, kernel_size=3, stride=2, padding=1, bias=False)
+ self.bn1 = nn.BatchNorm2d(width // 2)
+ self.conv2 = nn.Conv2d(width // 2, width // 2, kernel_size=3, padding=1, bias=False)
+ self.bn2 = nn.BatchNorm2d(width // 2)
+ self.conv3 = nn.Conv2d(width // 2, width, kernel_size=3, padding=1, bias=False)
+ self.bn3 = nn.BatchNorm2d(width)
+ self.avgpool = nn.AvgPool2d(2)
+ self.relu = nn.ReLU(inplace=True)
+
+ # residual layers
+ self._inplanes = width # this is a *mutable* variable used during construction
+ self.layer1 = self._make_layer(width, layers[0])
+ self.layer2 = self._make_layer(width * 2, layers[1], stride=2)
+ self.layer3 = self._make_layer(width * 4, layers[2], stride=2)
+ self.layer4 = self._make_layer(width * 8, layers[3], stride=2)
+
+ embed_dim = width * 32 # the ResNet feature dimension
+ self.attnpool = AttentionPool2d(input_resolution // 32, embed_dim, heads, output_dim)
+
+ def _make_layer(self, planes, blocks, stride=1):
+ layers = [Bottleneck(self._inplanes, planes, stride)]
+
+ self._inplanes = planes * Bottleneck.expansion
+ for _ in range(1, blocks):
+ layers.append(Bottleneck(self._inplanes, planes))
+
+ return nn.Sequential(*layers)
+
+ def forward(self, x):
+ def stem(x):
+ for conv, bn in [(self.conv1, self.bn1), (self.conv2, self.bn2), (self.conv3, self.bn3)]:
+ x = self.relu(bn(conv(x)))
+ x = self.avgpool(x)
+ return x
+
+ x = x.type(self.conv1.weight.dtype)
+ x = stem(x)
+ x = self.layer1(x)
+ x = self.layer2(x)
+ x = self.layer3(x)
+ x = self.layer4(x)
+ x = self.attnpool(x)
+
+ return x
+
+
+class LayerNorm(nn.LayerNorm):
+ """Subclass torch's LayerNorm to handle fp16."""
+
+ def forward(self, x: torch.Tensor):
+ orig_type = x.dtype
+ ret = super().forward(x.type(torch.float32))
+ return ret.type(orig_type)
+
+
+class QuickGELU(nn.Module):
+ def forward(self, x: torch.Tensor):
+ return x * torch.sigmoid(1.702 * x)
+
+
+class ResidualAttentionBlock(nn.Module):
+ def __init__(self, d_model: int, n_head: int, attn_mask: torch.Tensor = None):
+ super().__init__()
+
+ self.attn = nn.MultiheadAttention(d_model, n_head)
+ self.ln_1 = LayerNorm(d_model)
+ self.mlp = nn.Sequential(OrderedDict([
+ ("c_fc", nn.Linear(d_model, d_model * 4)),
+ ("gelu", QuickGELU()),
+ ("c_proj", nn.Linear(d_model * 4, d_model))
+ ]))
+ self.ln_2 = LayerNorm(d_model)
+ self.attn_mask = attn_mask
+
+ def attention(self, x: torch.Tensor):
+ self.attn_mask = self.attn_mask.to(dtype=x.dtype, device=x.device) if self.attn_mask is not None else None
+ return self.attn(x, x, x, need_weights=False, attn_mask=self.attn_mask)[0]
+
+ def forward(self, x: torch.Tensor):
+ x = x + self.attention(self.ln_1(x))
+ x = x + self.mlp(self.ln_2(x))
+ return x
+
+
+class Transformer(nn.Module):
+ def __init__(self, width: int, layers: int, heads: int, attn_mask: torch.Tensor = None):
+ super().__init__()
+ self.width = width
+ self.layers = layers
+ self.resblocks = nn.Sequential(*[ResidualAttentionBlock(width, heads, attn_mask) for _ in range(layers)])
+
+ def forward(self, x: torch.Tensor):
+ return self.resblocks(x)
+
+
+class VisionTransformer(nn.Module):
+ def __init__(self, input_resolution: int, patch_size: int, width: int, layers: int, heads: int, output_dim: int):
+ super().__init__()
+ self.input_resolution = input_resolution
+ self.output_dim = output_dim
+ self.conv1 = nn.Conv2d(in_channels=3, out_channels=width, kernel_size=patch_size, stride=patch_size, bias=False)
+
+ scale = width ** -0.5
+ self.class_embedding = nn.Parameter(scale * torch.randn(width))
+ self.positional_embedding = nn.Parameter(scale * torch.randn((input_resolution // patch_size) ** 2 + 1, width))
+ self.ln_pre = LayerNorm(width)
+
+ self.transformer = Transformer(width, layers, heads)
+
+ self.ln_post = LayerNorm(width)
+ self.proj = nn.Parameter(scale * torch.randn(width, output_dim))
+
+ def forward(self, x: torch.Tensor):
+ x = self.conv1(x) # shape = [*, width, grid, grid]
+ x = x.reshape(x.shape[0], x.shape[1], -1) # shape = [*, width, grid ** 2]
+ x = x.permute(0, 2, 1) # shape = [*, grid ** 2, width]
+ x = torch.cat([self.class_embedding.to(x.dtype) + torch.zeros(x.shape[0], 1, x.shape[-1], dtype=x.dtype, device=x.device), x], dim=1) # shape = [*, grid ** 2 + 1, width]
+ x = x + self.positional_embedding.to(x.dtype)
+ x = self.ln_pre(x)
+
+ x = x.permute(1, 0, 2) # NLD -> LND
+ x = self.transformer(x)
+ x = x.permute(1, 0, 2) # LND -> NLD
+
+ x = self.ln_post(x[:, 0, :])
+
+ if self.proj is not None:
+ x = x @ self.proj
+
+ return x
+
+
+class CLIP(nn.Module):
+ def __init__(self,
+ embed_dim: int,
+ # vision
+ image_resolution: int,
+ vision_layers: Union[Tuple[int, int, int, int], int],
+ vision_width: int,
+ vision_patch_size: int,
+ # text
+ context_length: int,
+ vocab_size: int,
+ transformer_width: int,
+ transformer_heads: int,
+ transformer_layers: int
+ ):
+ super().__init__()
+
+ self.context_length = context_length
+
+ if isinstance(vision_layers, (tuple, list)):
+ vision_heads = vision_width * 32 // 64
+ self.visual = ModifiedResNet(
+ layers=vision_layers,
+ output_dim=embed_dim,
+ heads=vision_heads,
+ input_resolution=image_resolution,
+ width=vision_width
+ )
+ else:
+ vision_heads = vision_width // 64
+ self.visual = VisionTransformer(
+ input_resolution=image_resolution,
+ patch_size=vision_patch_size,
+ width=vision_width,
+ layers=vision_layers,
+ heads=vision_heads,
+ output_dim=embed_dim
+ )
+
+ self.transformer = Transformer(
+ width=transformer_width,
+ layers=transformer_layers,
+ heads=transformer_heads,
+ attn_mask=self.build_attention_mask()
+ )
+
+ self.vocab_size = vocab_size
+ self.token_embedding = nn.Embedding(vocab_size, transformer_width)
+ self.positional_embedding = nn.Parameter(torch.empty(self.context_length, transformer_width))
+ self.ln_final = LayerNorm(transformer_width)
+
+ self.text_projection = nn.Parameter(torch.empty(transformer_width, embed_dim))
+ self.logit_scale = nn.Parameter(torch.ones([]) * np.log(1 / 0.07))
+
+ self.initialize_parameters()
+
+ def initialize_parameters(self):
+ nn.init.normal_(self.token_embedding.weight, std=0.02)
+ nn.init.normal_(self.positional_embedding, std=0.01)
+
+ if isinstance(self.visual, ModifiedResNet):
+ if self.visual.attnpool is not None:
+ std = self.visual.attnpool.c_proj.in_features ** -0.5
+ nn.init.normal_(self.visual.attnpool.q_proj.weight, std=std)
+ nn.init.normal_(self.visual.attnpool.k_proj.weight, std=std)
+ nn.init.normal_(self.visual.attnpool.v_proj.weight, std=std)
+ nn.init.normal_(self.visual.attnpool.c_proj.weight, std=std)
+
+ for resnet_block in [self.visual.layer1, self.visual.layer2, self.visual.layer3, self.visual.layer4]:
+ for name, param in resnet_block.named_parameters():
+ if name.endswith("bn3.weight"):
+ nn.init.zeros_(param)
+
+ proj_std = (self.transformer.width ** -0.5) * ((2 * self.transformer.layers) ** -0.5)
+ attn_std = self.transformer.width ** -0.5
+ fc_std = (2 * self.transformer.width) ** -0.5
+ for block in self.transformer.resblocks:
+ nn.init.normal_(block.attn.in_proj_weight, std=attn_std)
+ nn.init.normal_(block.attn.out_proj.weight, std=proj_std)
+ nn.init.normal_(block.mlp.c_fc.weight, std=fc_std)
+ nn.init.normal_(block.mlp.c_proj.weight, std=proj_std)
+
+ if self.text_projection is not None:
+ nn.init.normal_(self.text_projection, std=self.transformer.width ** -0.5)
+
+ def build_attention_mask(self):
+ # lazily create causal attention mask, with full attention between the vision tokens
+ # pytorch uses additive attention mask; fill with -inf
+ mask = torch.empty(self.context_length, self.context_length)
+ mask.fill_(float("-inf"))
+ mask.triu_(1) # zero out the lower diagonal
+ return mask
+
+ @property
+ def dtype(self):
+ return self.visual.conv1.weight.dtype
+
+ def encode_image(self, image):
+ return self.visual(image.type(self.dtype))
+
+ def encode_text(self, text):
+ x = self.token_embedding(text).type(self.dtype) # [batch_size, n_ctx, d_model]
+
+ x = x + self.positional_embedding.type(self.dtype)
+ x = x.permute(1, 0, 2) # NLD -> LND
+ x = self.transformer(x)
+ x = x.permute(1, 0, 2) # LND -> NLD
+ x = self.ln_final(x).type(self.dtype)
+
+ # x.shape = [batch_size, n_ctx, transformer.width]
+ # take features from the eot embedding (eot_token is the highest number in each sequence)
+ x = x[torch.arange(x.shape[0]), text.argmax(dim=-1)] @ self.text_projection
+
+ return x
+
+ def forward(self, image, text):
+ image_features = self.encode_image(image)
+ text_features = self.encode_text(text)
+
+ # normalized features
+ image_features = image_features / image_features.norm(dim=-1, keepdim=True)
+ text_features = text_features / text_features.norm(dim=-1, keepdim=True)
+
+ # cosine similarity as logits
+ logit_scale = self.logit_scale.exp()
+ logits_per_image = logit_scale * image_features @ text_features.t()
+ logits_per_text = logit_scale * text_features @ image_features.t()
+
+ # shape = [global_batch_size, global_batch_size]
+ return logits_per_image, logits_per_text
+
+
+def convert_weights(model: nn.Module):
+ """Convert applicable model parameters to fp16"""
+
+ def _convert_weights_to_fp16(l):
+ if isinstance(l, (nn.Conv1d, nn.Conv2d, nn.Linear)):
+ l.weight.data = l.weight.data.half()
+ if l.bias is not None:
+ l.bias.data = l.bias.data.half()
+
+ if isinstance(l, nn.MultiheadAttention):
+ for attr in [*[f"{s}_proj_weight" for s in ["in", "q", "k", "v"]], "in_proj_bias", "bias_k", "bias_v"]:
+ tensor = getattr(l, attr)
+ if tensor is not None:
+ tensor.data = tensor.data.half()
+
+ for name in ["text_projection", "proj"]:
+ if hasattr(l, name):
+ attr = getattr(l, name)
+ if attr is not None:
+ attr.data = attr.data.half()
+
+ model.apply(_convert_weights_to_fp16)
+
+
+def build_model(state_dict: dict):
+ vit = "visual.proj" in state_dict
+
+ if vit:
+ vision_width = state_dict["visual.conv1.weight"].shape[0]
+ vision_layers = len([k for k in state_dict.keys() if k.startswith("visual.") and k.endswith(".attn.in_proj_weight")])
+ vision_patch_size = state_dict["visual.conv1.weight"].shape[-1]
+ grid_size = round((state_dict["visual.positional_embedding"].shape[0] - 1) ** 0.5)
+ image_resolution = vision_patch_size * grid_size
+ else:
+ counts: list = [len(set(k.split(".")[2] for k in state_dict if k.startswith(f"visual.layer{b}"))) for b in [1, 2, 3, 4]]
+ vision_layers = tuple(counts)
+ vision_width = state_dict["visual.layer1.0.conv1.weight"].shape[0]
+ output_width = round((state_dict["visual.attnpool.positional_embedding"].shape[0] - 1) ** 0.5)
+ vision_patch_size = None
+ assert output_width ** 2 + 1 == state_dict["visual.attnpool.positional_embedding"].shape[0]
+ image_resolution = output_width * 32
+
+ embed_dim = state_dict["text_projection"].shape[1]
+ context_length = state_dict["positional_embedding"].shape[0]
+ vocab_size = state_dict["token_embedding.weight"].shape[0]
+ transformer_width = state_dict["ln_final.weight"].shape[0]
+ transformer_heads = transformer_width // 64
+ transformer_layers = len(set(k.split(".")[2] for k in state_dict if k.startswith(f"transformer.resblocks")))
+
+ model = CLIP(
+ embed_dim,
+ image_resolution, vision_layers, vision_width, vision_patch_size,
+ context_length, vocab_size, transformer_width, transformer_heads, transformer_layers
+ )
+
+ for key in ["input_resolution", "context_length", "vocab_size"]:
+ if key in state_dict:
+ del state_dict[key]
+
+ convert_weights(model)
+ model.load_state_dict(state_dict)
+ return model.eval()
diff --git a/clip/simple_tokenizer.py b/clip/simple_tokenizer.py
new file mode 100755
index 0000000..0a66286
--- /dev/null
+++ b/clip/simple_tokenizer.py
@@ -0,0 +1,132 @@
+import gzip
+import html
+import os
+from functools import lru_cache
+
+import ftfy
+import regex as re
+
+
+@lru_cache()
+def default_bpe():
+ return os.path.join(os.path.dirname(os.path.abspath(__file__)), "bpe_simple_vocab_16e6.txt.gz")
+
+
+@lru_cache()
+def bytes_to_unicode():
+ """
+ Returns list of utf-8 byte and a corresponding list of unicode strings.
+ The reversible bpe codes work on unicode strings.
+ This means you need a large # of unicode characters in your vocab if you want to avoid UNKs.
+ When you're at something like a 10B token dataset you end up needing around 5K for decent coverage.
+ This is a signficant percentage of your normal, say, 32K bpe vocab.
+ To avoid that, we want lookup tables between utf-8 bytes and unicode strings.
+ And avoids mapping to whitespace/control characters the bpe code barfs on.
+ """
+ bs = list(range(ord("!"), ord("~")+1))+list(range(ord("¡"), ord("¬")+1))+list(range(ord("®"), ord("ÿ")+1))
+ cs = bs[:]
+ n = 0
+ for b in range(2**8):
+ if b not in bs:
+ bs.append(b)
+ cs.append(2**8+n)
+ n += 1
+ cs = [chr(n) for n in cs]
+ return dict(zip(bs, cs))
+
+
+def get_pairs(word):
+ """Return set of symbol pairs in a word.
+ Word is represented as tuple of symbols (symbols being variable-length strings).
+ """
+ pairs = set()
+ prev_char = word[0]
+ for char in word[1:]:
+ pairs.add((prev_char, char))
+ prev_char = char
+ return pairs
+
+
+def basic_clean(text):
+ text = ftfy.fix_text(text)
+ text = html.unescape(html.unescape(text))
+ return text.strip()
+
+
+def whitespace_clean(text):
+ text = re.sub(r'\s+', ' ', text)
+ text = text.strip()
+ return text
+
+
+class SimpleTokenizer(object):
+ def __init__(self, bpe_path: str = default_bpe()):
+ self.byte_encoder = bytes_to_unicode()
+ self.byte_decoder = {v: k for k, v in self.byte_encoder.items()}
+ merges = gzip.open(bpe_path).read().decode("utf-8").split('\n')
+ merges = merges[1:49152-256-2+1]
+ merges = [tuple(merge.split()) for merge in merges]
+ vocab = list(bytes_to_unicode().values())
+ vocab = vocab + [v+'' for v in vocab]
+ for merge in merges:
+ vocab.append(''.join(merge))
+ vocab.extend(['<|startoftext|>', '<|endoftext|>'])
+ self.encoder = dict(zip(vocab, range(len(vocab))))
+ self.decoder = {v: k for k, v in self.encoder.items()}
+ self.bpe_ranks = dict(zip(merges, range(len(merges))))
+ self.cache = {'<|startoftext|>': '<|startoftext|>', '<|endoftext|>': '<|endoftext|>'}
+ self.pat = re.compile(r"""<\|startoftext\|>|<\|endoftext\|>|'s|'t|'re|'ve|'m|'ll|'d|[\p{L}]+|[\p{N}]|[^\s\p{L}\p{N}]+""", re.IGNORECASE)
+
+ def bpe(self, token):
+ if token in self.cache:
+ return self.cache[token]
+ word = tuple(token[:-1]) + ( token[-1] + '',)
+ pairs = get_pairs(word)
+
+ if not pairs:
+ return token+''
+
+ while True:
+ bigram = min(pairs, key = lambda pair: self.bpe_ranks.get(pair, float('inf')))
+ if bigram not in self.bpe_ranks:
+ break
+ first, second = bigram
+ new_word = []
+ i = 0
+ while i < len(word):
+ try:
+ j = word.index(first, i)
+ new_word.extend(word[i:j])
+ i = j
+ except:
+ new_word.extend(word[i:])
+ break
+
+ if word[i] == first and i < len(word)-1 and word[i+1] == second:
+ new_word.append(first+second)
+ i += 2
+ else:
+ new_word.append(word[i])
+ i += 1
+ new_word = tuple(new_word)
+ word = new_word
+ if len(word) == 1:
+ break
+ else:
+ pairs = get_pairs(word)
+ word = ' '.join(word)
+ self.cache[token] = word
+ return word
+
+ def encode(self, text):
+ bpe_tokens = []
+ text = whitespace_clean(basic_clean(text)).lower()
+ for token in re.findall(self.pat, text):
+ token = ''.join(self.byte_encoder[b] for b in token.encode('utf-8'))
+ bpe_tokens.extend(self.encoder[bpe_token] for bpe_token in self.bpe(token).split(' '))
+ return bpe_tokens
+
+ def decode(self, tokens):
+ text = ''.join([self.decoder[token] for token in tokens])
+ text = bytearray([self.byte_decoder[c] for c in text]).decode('utf-8', errors="replace").replace('', ' ')
+ return text
diff --git a/configs/datasets/caltech101.yaml b/configs/datasets/caltech101.yaml
new file mode 100755
index 0000000..4d3465f
--- /dev/null
+++ b/configs/datasets/caltech101.yaml
@@ -0,0 +1,2 @@
+DATASET:
+ NAME: "Caltech101"
diff --git a/configs/datasets/dtd.yaml b/configs/datasets/dtd.yaml
new file mode 100755
index 0000000..8e4b052
--- /dev/null
+++ b/configs/datasets/dtd.yaml
@@ -0,0 +1,2 @@
+DATASET:
+ NAME: "DescribableTextures"
diff --git a/configs/datasets/eurosat.yaml b/configs/datasets/eurosat.yaml
new file mode 100755
index 0000000..88e9b83
--- /dev/null
+++ b/configs/datasets/eurosat.yaml
@@ -0,0 +1,2 @@
+DATASET:
+ NAME: "EuroSAT"
diff --git a/configs/datasets/fgvc_aircraft.yaml b/configs/datasets/fgvc_aircraft.yaml
new file mode 100755
index 0000000..fa72f46
--- /dev/null
+++ b/configs/datasets/fgvc_aircraft.yaml
@@ -0,0 +1,2 @@
+DATASET:
+ NAME: "FGVCAircraft"
diff --git a/configs/datasets/oxford_flowers.yaml b/configs/datasets/oxford_flowers.yaml
new file mode 100755
index 0000000..769ecfa
--- /dev/null
+++ b/configs/datasets/oxford_flowers.yaml
@@ -0,0 +1,2 @@
+DATASET:
+ NAME: "OxfordFlowers"
\ No newline at end of file
diff --git a/configs/datasets/oxford_pets.yaml b/configs/datasets/oxford_pets.yaml
new file mode 100755
index 0000000..14ea509
--- /dev/null
+++ b/configs/datasets/oxford_pets.yaml
@@ -0,0 +1,2 @@
+DATASET:
+ NAME: "OxfordPets"
\ No newline at end of file
diff --git a/configs/datasets/stanford_cars.yaml b/configs/datasets/stanford_cars.yaml
new file mode 100755
index 0000000..0362aff
--- /dev/null
+++ b/configs/datasets/stanford_cars.yaml
@@ -0,0 +1,2 @@
+DATASET:
+ NAME: "StanfordCars"
diff --git a/configs/med_config.json b/configs/med_config.json
new file mode 100644
index 0000000..49d64f8
--- /dev/null
+++ b/configs/med_config.json
@@ -0,0 +1,21 @@
+{
+ "architectures": [
+ "BertModel"
+ ],
+ "attention_probs_dropout_prob": 0.1,
+ "hidden_act": "gelu",
+ "hidden_dropout_prob": 0.1,
+ "hidden_size": 768,
+ "initializer_range": 0.02,
+ "intermediate_size": 3072,
+ "layer_norm_eps": 1e-12,
+ "max_position_embeddings": 512,
+ "model_type": "bert",
+ "num_attention_heads": 12,
+ "num_hidden_layers": 12,
+ "pad_token_id": 0,
+ "type_vocab_size": 2,
+ "vocab_size": 30524,
+ "encoder_width": 768,
+ "add_cross_attention": true
+ }
\ No newline at end of file
diff --git a/configs/trainers/ALVLM/rn101.yaml b/configs/trainers/ALVLM/rn101.yaml
new file mode 100755
index 0000000..c67838f
--- /dev/null
+++ b/configs/trainers/ALVLM/rn101.yaml
@@ -0,0 +1,29 @@
+DATALOADER:
+ TRAIN_X:
+ BATCH_SIZE: 32
+ TEST:
+ BATCH_SIZE: 100
+ NUM_WORKERS: 8
+
+INPUT:
+ SIZE: (224, 224)
+ INTERPOLATION: "bicubic"
+ PIXEL_MEAN: [0.48145466, 0.4578275, 0.40821073]
+ PIXEL_STD: [0.26862954, 0.26130258, 0.27577711]
+ TRANSFORMS: ["random_resized_crop", "random_flip", "normalize"]
+
+OPTIM:
+ NAME: "sgd"
+ LR: 0.002
+ MAX_EPOCH: 200
+ LR_SCHEDULER: "cosine"
+ WARMUP_EPOCH: 1
+ WARMUP_TYPE: "constant"
+ WARMUP_CONS_LR: 1e-5
+
+TRAIN:
+ PRINT_FREQ: 5
+
+MODEL:
+ BACKBONE:
+ NAME: "RN101"
\ No newline at end of file
diff --git a/configs/trainers/ALVLM/rn50.yaml b/configs/trainers/ALVLM/rn50.yaml
new file mode 100755
index 0000000..7638b1b
--- /dev/null
+++ b/configs/trainers/ALVLM/rn50.yaml
@@ -0,0 +1,29 @@
+DATALOADER:
+ TRAIN_X:
+ BATCH_SIZE: 32
+ TEST:
+ BATCH_SIZE: 100
+ NUM_WORKERS: 8
+
+INPUT:
+ SIZE: (224, 224)
+ INTERPOLATION: "bicubic"
+ PIXEL_MEAN: [0.48145466, 0.4578275, 0.40821073]
+ PIXEL_STD: [0.26862954, 0.26130258, 0.27577711]
+ TRANSFORMS: ["random_resized_crop", "random_flip", "normalize"]
+
+OPTIM:
+ NAME: "sgd"
+ LR: 0.002
+ MAX_EPOCH: 200
+ LR_SCHEDULER: "cosine"
+ WARMUP_EPOCH: 1
+ WARMUP_TYPE: "constant"
+ WARMUP_CONS_LR: 1e-5
+
+TRAIN:
+ PRINT_FREQ: 5
+
+MODEL:
+ BACKBONE:
+ NAME: "RN50"
\ No newline at end of file
diff --git a/configs/trainers/ALVLM/vit_b16.yaml b/configs/trainers/ALVLM/vit_b16.yaml
new file mode 100755
index 0000000..00e1df5
--- /dev/null
+++ b/configs/trainers/ALVLM/vit_b16.yaml
@@ -0,0 +1,29 @@
+DATALOADER:
+ TRAIN_X:
+ BATCH_SIZE: 32
+ TEST:
+ BATCH_SIZE: 100
+ NUM_WORKERS: 8
+
+INPUT:
+ SIZE: (224, 224)
+ INTERPOLATION: "bicubic"
+ PIXEL_MEAN: [0.48145466, 0.4578275, 0.40821073]
+ PIXEL_STD: [0.26862954, 0.26130258, 0.27577711]
+ TRANSFORMS: ["random_resized_crop", "random_flip", "normalize"]
+
+OPTIM:
+ NAME: "sgd"
+ LR: 0.002
+ MAX_EPOCH: 200
+ LR_SCHEDULER: "cosine"
+ WARMUP_EPOCH: 1
+ WARMUP_TYPE: "constant"
+ WARMUP_CONS_LR: 1e-5
+
+TRAIN:
+ PRINT_FREQ: 5
+
+MODEL:
+ BACKBONE:
+ NAME: "ViT-B/16"
\ No newline at end of file
diff --git a/configs/trainers/ALVLM/vit_b32.yaml b/configs/trainers/ALVLM/vit_b32.yaml
new file mode 100755
index 0000000..9919840
--- /dev/null
+++ b/configs/trainers/ALVLM/vit_b32.yaml
@@ -0,0 +1,29 @@
+DATALOADER:
+ TRAIN_X:
+ BATCH_SIZE: 32
+ TEST:
+ BATCH_SIZE: 100
+ NUM_WORKERS: 8
+
+INPUT:
+ SIZE: (224, 224)
+ INTERPOLATION: "bicubic"
+ PIXEL_MEAN: [0.48145466, 0.4578275, 0.40821073]
+ PIXEL_STD: [0.26862954, 0.26130258, 0.27577711]
+ TRANSFORMS: ["random_resized_crop", "random_flip", "normalize"]
+
+OPTIM:
+ NAME: "sgd"
+ LR: 0.002
+ MAX_EPOCH: 200
+ LR_SCHEDULER: "cosine"
+ WARMUP_EPOCH: 1
+ WARMUP_TYPE: "constant"
+ WARMUP_CONS_LR: 1e-5
+
+TRAIN:
+ PRINT_FREQ: 5
+
+MODEL:
+ BACKBONE:
+ NAME: "ViT-B/32"
\ No newline at end of file
diff --git a/configs/trainers/CoOp/rn101.yaml b/configs/trainers/CoOp/rn101.yaml
new file mode 100755
index 0000000..c67838f
--- /dev/null
+++ b/configs/trainers/CoOp/rn101.yaml
@@ -0,0 +1,29 @@
+DATALOADER:
+ TRAIN_X:
+ BATCH_SIZE: 32
+ TEST:
+ BATCH_SIZE: 100
+ NUM_WORKERS: 8
+
+INPUT:
+ SIZE: (224, 224)
+ INTERPOLATION: "bicubic"
+ PIXEL_MEAN: [0.48145466, 0.4578275, 0.40821073]
+ PIXEL_STD: [0.26862954, 0.26130258, 0.27577711]
+ TRANSFORMS: ["random_resized_crop", "random_flip", "normalize"]
+
+OPTIM:
+ NAME: "sgd"
+ LR: 0.002
+ MAX_EPOCH: 200
+ LR_SCHEDULER: "cosine"
+ WARMUP_EPOCH: 1
+ WARMUP_TYPE: "constant"
+ WARMUP_CONS_LR: 1e-5
+
+TRAIN:
+ PRINT_FREQ: 5
+
+MODEL:
+ BACKBONE:
+ NAME: "RN101"
\ No newline at end of file
diff --git a/configs/trainers/CoOp/rn101_ep50.yaml b/configs/trainers/CoOp/rn101_ep50.yaml
new file mode 100755
index 0000000..a291895
--- /dev/null
+++ b/configs/trainers/CoOp/rn101_ep50.yaml
@@ -0,0 +1,29 @@
+DATALOADER:
+ TRAIN_X:
+ BATCH_SIZE: 32
+ TEST:
+ BATCH_SIZE: 100
+ NUM_WORKERS: 8
+
+INPUT:
+ SIZE: (224, 224)
+ INTERPOLATION: "bicubic"
+ PIXEL_MEAN: [0.48145466, 0.4578275, 0.40821073]
+ PIXEL_STD: [0.26862954, 0.26130258, 0.27577711]
+ TRANSFORMS: ["random_resized_crop", "random_flip", "normalize"]
+
+OPTIM:
+ NAME: "sgd"
+ LR: 0.002
+ MAX_EPOCH: 50
+ LR_SCHEDULER: "cosine"
+ WARMUP_EPOCH: 1
+ WARMUP_TYPE: "constant"
+ WARMUP_CONS_LR: 1e-5
+
+TRAIN:
+ PRINT_FREQ: 5
+
+MODEL:
+ BACKBONE:
+ NAME: "RN101"
\ No newline at end of file
diff --git a/configs/trainers/CoOp/rn50.yaml b/configs/trainers/CoOp/rn50.yaml
new file mode 100755
index 0000000..7638b1b
--- /dev/null
+++ b/configs/trainers/CoOp/rn50.yaml
@@ -0,0 +1,29 @@
+DATALOADER:
+ TRAIN_X:
+ BATCH_SIZE: 32
+ TEST:
+ BATCH_SIZE: 100
+ NUM_WORKERS: 8
+
+INPUT:
+ SIZE: (224, 224)
+ INTERPOLATION: "bicubic"
+ PIXEL_MEAN: [0.48145466, 0.4578275, 0.40821073]
+ PIXEL_STD: [0.26862954, 0.26130258, 0.27577711]
+ TRANSFORMS: ["random_resized_crop", "random_flip", "normalize"]
+
+OPTIM:
+ NAME: "sgd"
+ LR: 0.002
+ MAX_EPOCH: 200
+ LR_SCHEDULER: "cosine"
+ WARMUP_EPOCH: 1
+ WARMUP_TYPE: "constant"
+ WARMUP_CONS_LR: 1e-5
+
+TRAIN:
+ PRINT_FREQ: 5
+
+MODEL:
+ BACKBONE:
+ NAME: "RN50"
\ No newline at end of file
diff --git a/configs/trainers/CoOp/rn50_ctxv1.yaml b/configs/trainers/CoOp/rn50_ctxv1.yaml
new file mode 100755
index 0000000..e902b56
--- /dev/null
+++ b/configs/trainers/CoOp/rn50_ctxv1.yaml
@@ -0,0 +1,33 @@
+DATALOADER:
+ TRAIN_X:
+ BATCH_SIZE: 32
+ TEST:
+ BATCH_SIZE: 100
+ NUM_WORKERS: 8
+
+INPUT:
+ SIZE: (224, 224)
+ INTERPOLATION: "bicubic"
+ PIXEL_MEAN: [0.48145466, 0.4578275, 0.40821073]
+ PIXEL_STD: [0.26862954, 0.26130258, 0.27577711]
+ TRANSFORMS: ["random_resized_crop", "random_flip", "normalize"]
+
+OPTIM:
+ NAME: "sgd"
+ LR: 0.002
+ MAX_EPOCH: 200
+ LR_SCHEDULER: "cosine"
+ WARMUP_EPOCH: 1
+ WARMUP_TYPE: "constant"
+ WARMUP_CONS_LR: 1e-5
+
+TRAIN:
+ PRINT_FREQ: 5
+
+MODEL:
+ BACKBONE:
+ NAME: "RN50"
+
+TRAINER:
+ COOP:
+ CTX_INIT: "a photo of a"
diff --git a/configs/trainers/CoOp/rn50_ep100.yaml b/configs/trainers/CoOp/rn50_ep100.yaml
new file mode 100755
index 0000000..fd0968f
--- /dev/null
+++ b/configs/trainers/CoOp/rn50_ep100.yaml
@@ -0,0 +1,29 @@
+DATALOADER:
+ TRAIN_X:
+ BATCH_SIZE: 32
+ TEST:
+ BATCH_SIZE: 100
+ NUM_WORKERS: 8
+
+INPUT:
+ SIZE: (224, 224)
+ INTERPOLATION: "bicubic"
+ PIXEL_MEAN: [0.48145466, 0.4578275, 0.40821073]
+ PIXEL_STD: [0.26862954, 0.26130258, 0.27577711]
+ TRANSFORMS: ["random_resized_crop", "random_flip", "normalize"]
+
+OPTIM:
+ NAME: "sgd"
+ LR: 0.002
+ MAX_EPOCH: 100
+ LR_SCHEDULER: "cosine"
+ WARMUP_EPOCH: 1
+ WARMUP_TYPE: "constant"
+ WARMUP_CONS_LR: 1e-5
+
+TRAIN:
+ PRINT_FREQ: 5
+
+MODEL:
+ BACKBONE:
+ NAME: "RN50"
diff --git a/configs/trainers/CoOp/rn50_ep50.yaml b/configs/trainers/CoOp/rn50_ep50.yaml
new file mode 100755
index 0000000..8d7ef34
--- /dev/null
+++ b/configs/trainers/CoOp/rn50_ep50.yaml
@@ -0,0 +1,29 @@
+DATALOADER:
+ TRAIN_X:
+ BATCH_SIZE: 32
+ TEST:
+ BATCH_SIZE: 100
+ NUM_WORKERS: 8
+
+INPUT:
+ SIZE: (224, 224)
+ INTERPOLATION: "bicubic"
+ PIXEL_MEAN: [0.48145466, 0.4578275, 0.40821073]
+ PIXEL_STD: [0.26862954, 0.26130258, 0.27577711]
+ TRANSFORMS: ["random_resized_crop", "random_flip", "normalize"]
+
+OPTIM:
+ NAME: "sgd"
+ LR: 0.002
+ MAX_EPOCH: 50
+ LR_SCHEDULER: "cosine"
+ WARMUP_EPOCH: 1
+ WARMUP_TYPE: "constant"
+ WARMUP_CONS_LR: 1e-5
+
+TRAIN:
+ PRINT_FREQ: 5
+
+MODEL:
+ BACKBONE:
+ NAME: "RN50"
\ No newline at end of file
diff --git a/configs/trainers/CoOp/rn50_ep50_ctxv1.yaml b/configs/trainers/CoOp/rn50_ep50_ctxv1.yaml
new file mode 100755
index 0000000..5bf06f9
--- /dev/null
+++ b/configs/trainers/CoOp/rn50_ep50_ctxv1.yaml
@@ -0,0 +1,33 @@
+DATALOADER:
+ TRAIN_X:
+ BATCH_SIZE: 32
+ TEST:
+ BATCH_SIZE: 100
+ NUM_WORKERS: 8
+
+INPUT:
+ SIZE: (224, 224)
+ INTERPOLATION: "bicubic"
+ PIXEL_MEAN: [0.48145466, 0.4578275, 0.40821073]
+ PIXEL_STD: [0.26862954, 0.26130258, 0.27577711]
+ TRANSFORMS: ["random_resized_crop", "random_flip", "normalize"]
+
+OPTIM:
+ NAME: "sgd"
+ LR: 0.002
+ MAX_EPOCH: 50
+ LR_SCHEDULER: "cosine"
+ WARMUP_EPOCH: 1
+ WARMUP_TYPE: "constant"
+ WARMUP_CONS_LR: 1e-5
+
+TRAIN:
+ PRINT_FREQ: 5
+
+MODEL:
+ BACKBONE:
+ NAME: "RN50"
+
+TRAINER:
+ COOP:
+ CTX_INIT: "a photo of a"
\ No newline at end of file
diff --git a/configs/trainers/CoOp/rn50_val.yaml b/configs/trainers/CoOp/rn50_val.yaml
new file mode 100755
index 0000000..6b0e97e
--- /dev/null
+++ b/configs/trainers/CoOp/rn50_val.yaml
@@ -0,0 +1,17 @@
+DATALOADER:
+ TRAIN_X:
+ BATCH_SIZE: 200
+ TEST:
+ BATCH_SIZE: 200
+ NUM_WORKERS: 8
+
+INPUT:
+ SIZE: (224, 224)
+ INTERPOLATION: "bicubic"
+ PIXEL_MEAN: [0.48145466, 0.4578275, 0.40821073]
+ PIXEL_STD: [0.26862954, 0.26130258, 0.27577711]
+ TRANSFORMS: ["random_resized_crop", "random_flip", "normalize"]
+
+MODEL:
+ BACKBONE:
+ NAME: "RN50"
\ No newline at end of file
diff --git a/configs/trainers/CoOp/vit_b16.yaml b/configs/trainers/CoOp/vit_b16.yaml
new file mode 100755
index 0000000..00e1df5
--- /dev/null
+++ b/configs/trainers/CoOp/vit_b16.yaml
@@ -0,0 +1,29 @@
+DATALOADER:
+ TRAIN_X:
+ BATCH_SIZE: 32
+ TEST:
+ BATCH_SIZE: 100
+ NUM_WORKERS: 8
+
+INPUT:
+ SIZE: (224, 224)
+ INTERPOLATION: "bicubic"
+ PIXEL_MEAN: [0.48145466, 0.4578275, 0.40821073]
+ PIXEL_STD: [0.26862954, 0.26130258, 0.27577711]
+ TRANSFORMS: ["random_resized_crop", "random_flip", "normalize"]
+
+OPTIM:
+ NAME: "sgd"
+ LR: 0.002
+ MAX_EPOCH: 200
+ LR_SCHEDULER: "cosine"
+ WARMUP_EPOCH: 1
+ WARMUP_TYPE: "constant"
+ WARMUP_CONS_LR: 1e-5
+
+TRAIN:
+ PRINT_FREQ: 5
+
+MODEL:
+ BACKBONE:
+ NAME: "ViT-B/16"
\ No newline at end of file
diff --git a/configs/trainers/CoOp/vit_b16_ctxv1.yaml b/configs/trainers/CoOp/vit_b16_ctxv1.yaml
new file mode 100755
index 0000000..ba61e32
--- /dev/null
+++ b/configs/trainers/CoOp/vit_b16_ctxv1.yaml
@@ -0,0 +1,33 @@
+DATALOADER:
+ TRAIN_X:
+ BATCH_SIZE: 32
+ TEST:
+ BATCH_SIZE: 100
+ NUM_WORKERS: 8
+
+INPUT:
+ SIZE: (224, 224)
+ INTERPOLATION: "bicubic"
+ PIXEL_MEAN: [0.48145466, 0.4578275, 0.40821073]
+ PIXEL_STD: [0.26862954, 0.26130258, 0.27577711]
+ TRANSFORMS: ["random_resized_crop", "random_flip", "normalize"]
+
+OPTIM:
+ NAME: "sgd"
+ LR: 0.002
+ MAX_EPOCH: 200
+ LR_SCHEDULER: "cosine"
+ WARMUP_EPOCH: 1
+ WARMUP_TYPE: "constant"
+ WARMUP_CONS_LR: 1e-5
+
+TRAIN:
+ PRINT_FREQ: 5
+
+MODEL:
+ BACKBONE:
+ NAME: "ViT-B/16"
+
+TRAINER:
+ COOP:
+ CTX_INIT: "a photo of a"
diff --git a/configs/trainers/CoOp/vit_b16_ep100.yaml b/configs/trainers/CoOp/vit_b16_ep100.yaml
new file mode 100755
index 0000000..31bd7bc
--- /dev/null
+++ b/configs/trainers/CoOp/vit_b16_ep100.yaml
@@ -0,0 +1,29 @@
+DATALOADER:
+ TRAIN_X:
+ BATCH_SIZE: 32
+ TEST:
+ BATCH_SIZE: 100
+ NUM_WORKERS: 8
+
+INPUT:
+ SIZE: (224, 224)
+ INTERPOLATION: "bicubic"
+ PIXEL_MEAN: [0.48145466, 0.4578275, 0.40821073]
+ PIXEL_STD: [0.26862954, 0.26130258, 0.27577711]
+ TRANSFORMS: ["random_resized_crop", "random_flip", "normalize"]
+
+OPTIM:
+ NAME: "sgd"
+ LR: 0.002
+ MAX_EPOCH: 100
+ LR_SCHEDULER: "cosine"
+ WARMUP_EPOCH: 1
+ WARMUP_TYPE: "constant"
+ WARMUP_CONS_LR: 1e-5
+
+TRAIN:
+ PRINT_FREQ: 5
+
+MODEL:
+ BACKBONE:
+ NAME: "ViT-B/16"
\ No newline at end of file
diff --git a/configs/trainers/CoOp/vit_b16_ep100_ctxv1.yaml b/configs/trainers/CoOp/vit_b16_ep100_ctxv1.yaml
new file mode 100755
index 0000000..d749953
--- /dev/null
+++ b/configs/trainers/CoOp/vit_b16_ep100_ctxv1.yaml
@@ -0,0 +1,33 @@
+DATALOADER:
+ TRAIN_X:
+ BATCH_SIZE: 32
+ TEST:
+ BATCH_SIZE: 100
+ NUM_WORKERS: 8
+
+INPUT:
+ SIZE: (224, 224)
+ INTERPOLATION: "bicubic"
+ PIXEL_MEAN: [0.48145466, 0.4578275, 0.40821073]
+ PIXEL_STD: [0.26862954, 0.26130258, 0.27577711]
+ TRANSFORMS: ["random_resized_crop", "random_flip", "normalize"]
+
+OPTIM:
+ NAME: "sgd"
+ LR: 0.002
+ MAX_EPOCH: 100
+ LR_SCHEDULER: "cosine"
+ WARMUP_EPOCH: 1
+ WARMUP_TYPE: "constant"
+ WARMUP_CONS_LR: 1e-5
+
+TRAIN:
+ PRINT_FREQ: 5
+
+MODEL:
+ BACKBONE:
+ NAME: "ViT-B/16"
+
+TRAINER:
+ COOP:
+ CTX_INIT: "a photo of a"
diff --git a/configs/trainers/CoOp/vit_b16_ep50.yaml b/configs/trainers/CoOp/vit_b16_ep50.yaml
new file mode 100755
index 0000000..786b980
--- /dev/null
+++ b/configs/trainers/CoOp/vit_b16_ep50.yaml
@@ -0,0 +1,29 @@
+DATALOADER:
+ TRAIN_X:
+ BATCH_SIZE: 32
+ TEST:
+ BATCH_SIZE: 100
+ NUM_WORKERS: 8
+
+INPUT:
+ SIZE: (224, 224)
+ INTERPOLATION: "bicubic"
+ PIXEL_MEAN: [0.48145466, 0.4578275, 0.40821073]
+ PIXEL_STD: [0.26862954, 0.26130258, 0.27577711]
+ TRANSFORMS: ["random_resized_crop", "random_flip", "normalize"]
+
+OPTIM:
+ NAME: "sgd"
+ LR: 0.002
+ MAX_EPOCH: 50
+ LR_SCHEDULER: "cosine"
+ WARMUP_EPOCH: 1
+ WARMUP_TYPE: "constant"
+ WARMUP_CONS_LR: 1e-5
+
+TRAIN:
+ PRINT_FREQ: 5
+
+MODEL:
+ BACKBONE:
+ NAME: "ViT-B/16"
\ No newline at end of file
diff --git a/configs/trainers/CoOp/vit_b16_ep50_ctxv1.yaml b/configs/trainers/CoOp/vit_b16_ep50_ctxv1.yaml
new file mode 100755
index 0000000..3c81ba7
--- /dev/null
+++ b/configs/trainers/CoOp/vit_b16_ep50_ctxv1.yaml
@@ -0,0 +1,33 @@
+DATALOADER:
+ TRAIN_X:
+ BATCH_SIZE: 32
+ TEST:
+ BATCH_SIZE: 100
+ NUM_WORKERS: 8
+
+INPUT:
+ SIZE: (224, 224)
+ INTERPOLATION: "bicubic"
+ PIXEL_MEAN: [0.48145466, 0.4578275, 0.40821073]
+ PIXEL_STD: [0.26862954, 0.26130258, 0.27577711]
+ TRANSFORMS: ["random_resized_crop", "random_flip", "normalize"]
+
+OPTIM:
+ NAME: "sgd"
+ LR: 0.002
+ MAX_EPOCH: 50
+ LR_SCHEDULER: "cosine"
+ WARMUP_EPOCH: 1
+ WARMUP_TYPE: "constant"
+ WARMUP_CONS_LR: 1e-5
+
+TRAIN:
+ PRINT_FREQ: 5
+
+MODEL:
+ BACKBONE:
+ NAME: "ViT-B/16"
+
+TRAINER:
+ COOP:
+ CTX_INIT: "a photo of a"
diff --git a/configs/trainers/CoOp/vit_b32.yaml b/configs/trainers/CoOp/vit_b32.yaml
new file mode 100755
index 0000000..9919840
--- /dev/null
+++ b/configs/trainers/CoOp/vit_b32.yaml
@@ -0,0 +1,29 @@
+DATALOADER:
+ TRAIN_X:
+ BATCH_SIZE: 32
+ TEST:
+ BATCH_SIZE: 100
+ NUM_WORKERS: 8
+
+INPUT:
+ SIZE: (224, 224)
+ INTERPOLATION: "bicubic"
+ PIXEL_MEAN: [0.48145466, 0.4578275, 0.40821073]
+ PIXEL_STD: [0.26862954, 0.26130258, 0.27577711]
+ TRANSFORMS: ["random_resized_crop", "random_flip", "normalize"]
+
+OPTIM:
+ NAME: "sgd"
+ LR: 0.002
+ MAX_EPOCH: 200
+ LR_SCHEDULER: "cosine"
+ WARMUP_EPOCH: 1
+ WARMUP_TYPE: "constant"
+ WARMUP_CONS_LR: 1e-5
+
+TRAIN:
+ PRINT_FREQ: 5
+
+MODEL:
+ BACKBONE:
+ NAME: "ViT-B/32"
\ No newline at end of file
diff --git a/configs/trainers/CoOp/vit_b32_ep50.yaml b/configs/trainers/CoOp/vit_b32_ep50.yaml
new file mode 100755
index 0000000..cf9f8e1
--- /dev/null
+++ b/configs/trainers/CoOp/vit_b32_ep50.yaml
@@ -0,0 +1,29 @@
+DATALOADER:
+ TRAIN_X:
+ BATCH_SIZE: 32
+ TEST:
+ BATCH_SIZE: 100
+ NUM_WORKERS: 8
+
+INPUT:
+ SIZE: (224, 224)
+ INTERPOLATION: "bicubic"
+ PIXEL_MEAN: [0.48145466, 0.4578275, 0.40821073]
+ PIXEL_STD: [0.26862954, 0.26130258, 0.27577711]
+ TRANSFORMS: ["random_resized_crop", "random_flip", "normalize"]
+
+OPTIM:
+ NAME: "sgd"
+ LR: 0.002
+ MAX_EPOCH: 50
+ LR_SCHEDULER: "cosine"
+ WARMUP_EPOCH: 1
+ WARMUP_TYPE: "constant"
+ WARMUP_CONS_LR: 1e-5
+
+TRAIN:
+ PRINT_FREQ: 5
+
+MODEL:
+ BACKBONE:
+ NAME: "ViT-B/32"
\ No newline at end of file
diff --git a/cupl/descriptors_caltech101.json b/cupl/descriptors_caltech101.json
new file mode 100644
index 0000000..4af5287
--- /dev/null
+++ b/cupl/descriptors_caltech101.json
@@ -0,0 +1,3266 @@
+{
+ "gerenuk": [
+ "A gerenuk is a type of antelope that is native to Africa and Asia.",
+ "A gerenuk is a lanky, long-necked gazelle with narrow, somewhat pointed horns that curve downward.",
+ "A gerenuk is a long-necked antelope with thin legs and large ears.",
+ "A gerenuk is a tall, slender antelope with long, thin legs.",
+ "A gerenuk is a type of antelope with a long neck and limbs.",
+ "A gerenuk is a long-necked antelope with a narrow body and long, thin legs.",
+ "A gerenuk is a thin, long-necked antelope with legs that are unusually long for its body.",
+ "A gerenuk is a thin, long-necked antelope with short, spindly legs.",
+ "A gerenuk is a slender, antelope-like creature with a long neck and legs.",
+ "The gerenuk is a long-necked, short-horned antelope with a relatively small head, long legs, and a long neck.",
+ "A common name for the gerenuk is the \"giraffe gazelle\".",
+ "In the photo, a gerenuk stands in tall grass, its long neck stretched up to nibble at the leaves of a tree.",
+ "A gerenuk is a long-necked antelope found in East Africa.",
+ "This photo shows a gerenuk, an antelope species that is sometimes called a giraffe antelope or a Waller's gazelle.",
+ "In the photo, there is a gerenuk standing on its hind legs, its front legs extended out in front of it.",
+ "A gerenuk is a type of antelope that is native to Africa.",
+ "A female gerenuk is standing on her hind legs to reach leaves from a tree.",
+ "The photo is of a pale-brown gerenuk standing in tall grass.",
+ "A gerenuk is a type of antelope that is found in Africa.",
+ "The gerenuk is a species of antelope found in dry, arid habitats in East Africa.",
+ "The gerenuk is a long-necked, slender-bodied antelope with a small head.",
+ "A gerenuk is a small, slender antelope found in dry Brushland and woodlands in Africa.",
+ "Gerenuks have a long neck, which they use to reach high branches, and long, thin legs.",
+ "Gerenuks are slender, long-necked gazelles that are native to Africa.",
+ "A gerenuk is a type of antelope that is native to Africa.",
+ "The gerenuk is a long-necked, gazelle-like antelope found in dry thornbush scrub and woodlands in much of East Africa.",
+ "The gerenuk is a type of antelope that is found in Africa.",
+ "A gerenuk is a species of antelope that is native to Africa and Asia.",
+ "A gerenuk is a type of antelope that is found in Africa.",
+ "The gerenuk is a thin, long-necked antelope with distinctive large eyes."
+ ],
+ "background": [
+ " in terms of lightA background is typically darker than the subject in the foreground.",
+ "A background looks like an image or color behind the main focus of a piece.",
+ "A background looks like the area behind the main subject of an image.",
+ "A background usually has a certain color or pattern.",
+ "A background is an image or color that appears behind the main content on a screen.",
+ "A background generally refers to the parts of an image that are farthest from the viewer.",
+ "A background is the part of an image that appears furthest from the viewer.",
+ "A background looks like a scene behind the main subject of an image.",
+ "This question is difficut to answer without more information.",
+ "A background looks like the area behind the main subject of an image.",
+ "This background photo is of a white picket fence with a bright blue sky overhead.",
+ "In the photo, there is a large field with tall grass.",
+ " with hillsI see a background with hills that are different shades of green.",
+ "The background in this photo is a cloudy sky.",
+ " that looks as if it could be from a movieA photo of a background that looks as if it could be from a movie might show a cityscape at night, with bright lights and tall buildings.",
+ " with a rockThe photo is of a large, gray rock with a rough surface.",
+ "In the photo, there is a background of a cloudy sky.",
+ "A background photo is typically a picture that is taken of a scene behind the main subject of a photo.",
+ "In the photo, there is a blurred image of a cityscape in the background.",
+ "In the photo, there is a mountainside in the background with a few trees and patches of snow.",
+ "There is no definitive answer to this question as backgrounds can vary greatly in appearance, depending on the style of the piece, the location of the subject, and the artist's preference.",
+ "A background may be a color or an image.",
+ "There is no one answer to this question as backgrounds can vary greatly depending on the subject matter, tone, and style of a piece.",
+ "A background is usually a solid color or an image.",
+ "A background can be any color or image.",
+ "A background typically looks like a plain white or gray wall.",
+ "There are many possible answers to this question, as the appearance of a background can vary greatly depending on the situation.",
+ "A background is typically a single color or an image.",
+ "A background can look like many things.",
+ "A background can look like anything."
+ ],
+ "hawksbill": [
+ "A hawksbill sea turtle has a narrow head with a hawk-like beak.",
+ "A hawksbill sea turtle has a hawk-like beak, which is where it gets its name.",
+ "A hawksbill looks like a small, thin turtle with a long neck and a beak-like mouth.",
+ "A hawksbill looks like a small turtle with a long, pointed beak.",
+ "A hawksbill sea turtle is a small to medium-sized turtle that can grow up to about 3 feet long.",
+ "The hawksbill sea turtle is a turtle that has a hawk-like beak.",
+ "A hawksbill sea turtle is a small to medium sized turtle.",
+ "A hawksbill turtle is a medium-sized turtle found throughout the world's tropical oceans.",
+ "The hawksbill sea turtle is a beautiful turtle that has a beak-like mouth and is covered in a hard shell.",
+ "The hawksbill sea turtle is a beautiful turtle with a hawk-like beak.",
+ " turtleThis photo is of a hawksbill turtle in the ocean.",
+ " turtleThe photo is of a hawksbill turtle swimming in the ocean.",
+ " turtleThe photo is of a hawksbill turtle swimming near the surface of the water.",
+ " turtleI see a large, brown turtle with a long neck and a pointy beak.",
+ " turtleA hawksbill turtle is in the photo swimming near some coral.",
+ " turtleHawksbill turtles are a species of turtle found in tropical and subtropical waters around the globe.",
+ " turtleThe hawksbill turtle is a medium-sized turtle with a long neck and pointed beak.",
+ " turtleA photo of a hawksbill turtle would likely show a turtle swimming in the ocean or lying on a beach.",
+ " turtleA hawksbill turtle is a sea turtle with a hawk-like beak.",
+ " turtleThis is a photo of a hawksbill turtle in its natural habitat.",
+ "The hawksbill is a sea turtle with a hawk-like beak.",
+ "A hawksbill sea turtle is a medium-sized turtle with a broad, flattened carapace and a narrow head.",
+ "A hawksbill looks like a hawk.",
+ "A hawksbill looks like a small hawk.",
+ "The hawksbill turtle gets its name from its narrow, pointed beak.",
+ "A hawksbill looks like a large turtle with a beak-like mouth.",
+ "The hawksbill sea turtle has a hawk-like beak and flipper-like limbs.",
+ "A hawksbill looks like a small hawk with a long, narrow beak.",
+ "Hawksbills are a type of turtle with a beak-like mouth.",
+ "The hawksbill is a sea turtle that looks like it has a shield on its head."
+ ],
+ "headphone": [
+ "A headphone typically consists of two small speakers that are attached to a headband.",
+ "A headphone consists of two small loudspeakers, called earphones, that are attached to a band that goes over the head, or a set of earphones that fit in the ear.",
+ "A headphone is a small speakers that you can wear on your head.",
+ "A headphone is a small pair of speakers that fit over a person's ears.",
+ "A headphone typically consists of a pair of small speakers that are placed over the ears.",
+ "Most headphones are designed to go over your ears.",
+ "A headphone is a small pair of speakers that are held close to a person's ears, typically using a strap or band around the head.",
+ "A headphone is a wearable device that covers or goes inside a person's ear to allow the person to hear music or other audio without outside distractions.",
+ "A headphone is a small speaker that you can wear on your head.",
+ "A headphone typically has two earpieces connected by a band or frame.",
+ "One headphone is lying on a yellow pillow on a bed.",
+ "In the photo, there is a person wearing black headphones over their ears.",
+ "The headphone is a black and silver color.",
+ "The headphone is a black and silver color.",
+ "The photo is of a black headphone with a white wire.",
+ "This is a photo of a headphone.",
+ "A headphone is a set of earphones that are connected by a headband.",
+ "This is a photo of a black headphone.",
+ "The headphone is a popular gadget that is used to listen to music, movies, and games.",
+ "In the photo, there is a black headphone on a white surface.",
+ "A headphone typically consists of a pair of small speakers that are held close to the ears, either by a headband or ear clips.",
+ "A headphone is a small set of speakers that go over a person's ears.",
+ "A headphone typically consists of a pair of small speakers that are worn on or around the head, although some models can be attached to hearing aids.",
+ "A headphone typically consists of a pair of small speakers that are attached to a headband or earclips.",
+ "A headphone typically consists of two small speakers that are attached to a headband or earpiece.",
+ "A headphone typically consists of a pair of small loudspeakers, or earphones, that are worn on or around the head over a user's ears.",
+ "A headphone is a smooth, rounded device that is placed over the ear.",
+ "A headphone consists of a pair of ear cups, each with a driver (speaker) in it, connected by a headband.",
+ "A headphone is a small speaker that sits close to your ear.",
+ "A headphone is typically a small, oval-shaped piece of plastic with a small metal rod attached to one side."
+ ],
+ "ant": [
+ "A ant is small, black, and has six legs.",
+ "The ant is a small, black creature with six legs.",
+ "A ant is a small, black insects with six legs.",
+ "A typical ant is about 2.",
+ "A ant typically has a dark brown or black body with a narrow waist.",
+ "Ants vary in size, but are usually between 2 and 20 mm in length.",
+ "A ant is a small, black insect that lives in colonies.",
+ "A typical ant is small, dark, and has six legs.",
+ "A ant is a small, black insects that live in colonies.",
+ "The body of an ant is divided into three main parts: the head, the thorax, and the abdomen.",
+ "This photo is of a large, black ant.",
+ "A photo of an ant may show the ant walking along the ground, climbing up a stalk of a plant, or flying through the air.",
+ "arctic glacierThe photo shows a large glacier in the Antarctic with a backdrop of mountains.",
+ "This photo shows an ant crawling on the ground.",
+ "A photo of an ant would likely show a small, dark-colored insect crawling on the ground.",
+ "A photo of an ant would typically show a small, hard-bodied creature with six legs, a tiny waist and a large head.",
+ "The photo is of an ant on a white background.",
+ "The photo is of an ant crawling on a twig.",
+ "arctic expeditionThe photo is of a group of people in bulky coats and hats, standing on a sea of ice.",
+ "The photo is of a small black ant crawling on a blade of grass.",
+ "A small, hard-bodied creature with six legs and a pair of long, antennae.",
+ "A ant looks like an insect with six legs.",
+ "A ant is a small, black insect with six legs.",
+ "A ant looks like a small, black insect with six legs.",
+ "A small, black ant.",
+ "A ant looks like a small, black creature with six legs and a long antennae.",
+ "Most ants are small, ranging in size from 2 to 25 mm.",
+ "A ant is a small, hard-bodied creature with six legs.",
+ "A ant looks like a small, six-legged creature with a hard exoskeleton.",
+ "A ant looks like an insect with six legs and a hard outer shell."
+ ],
+ "butterfly": [
+ "Most butterflies have brightly colored wings with intricate patterns.",
+ "A butterfly typically has two large wings that are decorated with brightly colored scales.",
+ "Most butterflies have brightly colored wings, and many of them are decorated with patterns made up of small black spots, lines, and swirls.",
+ "Most butterflies have brightly colored wings, with patterns made up of tiny scales.",
+ "A butterfly is a flying insect.",
+ "A butterfly has brightly colored wings and a long thin body.",
+ "A butterfly typically has two pairs of wings that are covered in colorful scales.",
+ "Most butterflies are brightly colored with large scales on their wings.",
+ "A butterfly is a slender, beautiful insect with large, delicate wings.",
+ "A butterfly is a flying insect that has two pairs of wings that are covered in tiny scales.",
+ "This photo is of a beautiful blue butterfly with black and white markings.",
+ "This photo is of a beautiful butterfly with large, bright wings.",
+ "This photo depicts a butterfly with brightly-colored wings.",
+ "This butterfly is black and yellow with long, slender wings.",
+ "This photo is of a blue and black butterfly.",
+ "A photo of a butterfly might show the insect's brightlycolored wings, delicate structure, and slender body.",
+ "The butterfly has large, brightly colored wings.",
+ "The photo shows a butterfly with its wings spread.",
+ "You see a beautiful butterfly with its wings wide open.",
+ "This photo shows a butterfly with its wings open.",
+ "Most butterflies have brightly colored wings with patterns made up of small dots, lines, or both.",
+ "Most butterflies have brightly colored wings with distinctive patterns.",
+ "butterflies vary in size, shape, and color, but most have wings with a colorful pattern.",
+ "A butterfly has two large wings that are covered in scales.",
+ "Most butterflies have brightly colored wings with patterns made up of small scales.",
+ "Butterflies are colorful insects with two pairs of wings.",
+ "Butterflies vary in size, shape and color, but most have wings with distinctive patterns.",
+ "A butterfly has two large, colorful wings.",
+ "A butterfly has two pairs of large wings that are covered in scales.",
+ "Most butterflies are brightly colored."
+ ],
+ "lamp": [
+ "A lamp is a household appliance that is used to illuminate a room.",
+ "When most people think of a lamp, they think of a light bulb on a stand with a shade.",
+ "A lamp is a household appliance that consists of a light bulb inside a housing, which is usually made of glass.",
+ "A lamp looks like a small lightbulb on a metal stand.",
+ "A lamp is a device that contains an electric light bulb and is used to produce light.",
+ "A lamp is typically a cylindrical object with a base and a neck, and a lightbulb at the top.",
+ "A lamp typically contains a light bulb that is surrounded by a glass cover.",
+ "A lamp is typically a light fixture that uses an electric bulb to produce light.",
+ "A lamp is a light fixture that uses an electric light bulb as its light source.",
+ "A lamp, such as a desk lamp, is a small electrical appliance that consists of a base, a stem, a shade, and a light bulb.",
+ "A lamp is a light fixture that is powered by electricity.",
+ "In the photo, there is a lamp on a table.",
+ "The photo shows a lamp on a table.",
+ "This photo is of a lamp on a desk.",
+ "I see a lamp with a white base and a slender white pole.",
+ "This is a clear photo of a silver lamp with a white shade.",
+ "The photo is of a lamp on a table.",
+ "A lamp is a photo of an object that emits light.",
+ "This is a black and white photo of a lamp on a table.",
+ "The lamp is on a table next to a window.",
+ "A lamp usually consists of a light bulb inside of a glass case, with a metal or plastic base.",
+ "A lamp typically looks like a vase with a wide opening at the top and a narrow opening at the bottom.",
+ "A lamp is a tall object with a base that you can put a light bulb in.",
+ "A lamp is an object that produces light.",
+ "A lamp typically looks like a lightbulb on top of a stand, with a switch on the stand that turns the lightbulb on and off.",
+ "Most lamps have a light bulb in the center, with a metal or plastic base.",
+ "A lamp typically looks like a light bulb on a metal stand.",
+ "A lamp usually consists of a lightbulb inside of a glass or metal enclosure.",
+ "A lamp is a device that generates light.",
+ "A lamp is a household appliance that consists of a light bulb inside a glass or metal housing."
+ ],
+ "strawberry": [
+ "A strawberry is a fruit that is generally red, although some varieties are yellow, white, or light green.",
+ "A strawberry is a small, red, spherical fruit with a seed-studded surface.",
+ "A strawberry is a small red fruit with a seed-covered surface.",
+ "A strawberry is a small, red fruit that is covered in tiny seeds.",
+ "A strawberry typically has a bright red exterior with small seeds on the surface.",
+ "A strawberry is a small, red fruit with a green stem.",
+ "A strawberry is small fruit that is red and has a seed on the outside.",
+ "A strawberry is a small red fruit that has a green stem and leaves.",
+ "A strawberry is a small, red, cone-shaped fruit with a green stem.",
+ "A strawberry is typically red and has a small green stem sticking out of the top.",
+ "The photo is of a single, bright red strawberry with a green stem.",
+ "The photo is of a strawberries on a plant.",
+ "The photo is of a single, bright red strawberry with a stem attached.",
+ "The photo is of a strawberry on a white plate.",
+ "This strawberry looks ripe and delicious! It's a deep red color with a small green stem, and it's covered in tiny seeds.",
+ "The photo is of a large, red strawberry with a small green stem.",
+ "The photo is of a ripe, red strawberry with a green stem.",
+ "The photo is of a ripe strawberry with a stem still attached.",
+ "In the photo, there is a ripe, red strawberry sitting on a white plate.",
+ "A photo of a strawberry might show a ripe, red strawberry with its green stem still attached.",
+ "A strawberry is a small, red fruit with a seed-studded surface.",
+ "A strawberry looks like a small red fruit with a green stem and small seeds on the outside.",
+ "A strawberry is a small, red fruit that grows on a plant.",
+ "A strawberry is typically red and heart-shaped with small seeds on the surface.",
+ "A strawberry looks like a small red fruit with a green stem.",
+ "A strawberry has a red flesh with small seeds on the outside.",
+ "A strawberry has a red, fleshy exterior with small seeds on the surface.",
+ "A strawberry is a small, red, soft fruit with seeds on the surface.",
+ "A strawberry is red, round, and has a small green stem.",
+ "A strawberry is small, red, and has a stem and leaves on the top."
+ ],
+ "chandelier": [
+ "A chandelier is a type of light fixture that hangs from the ceiling and has multiple lightbulbs or candles.",
+ "A chandelier is typically a decorative light fixture that hangs from the ceiling.",
+ "A chandelier is a type of light fixture that hangs from the ceiling and has multiple lights.",
+ "A chandelier is a decorative ceiling fixture that typically has multiple arms with lightbulbs or candles.",
+ "A chandelier is a decorative ceiling-mounted light fixture.",
+ "A chandelier is a type of light fixture that is hung from the ceiling.",
+ "A chandelier is a ceilings light with multiple arms that hold lightbulbs or candles.",
+ "A chandelier is a type of light fixture that hangs from the ceiling and has multiple lights.",
+ "A chandelier is a decorative ceiling light fixture.",
+ "A chandelier is a type of light fixture that hangs from the ceiling and has multiple arms that hold light bulbs or candles.",
+ "The photo is of a large, ornate chandelier hanging from the ceiling.",
+ "This photograph features a close-up of a cascading chandelier.",
+ "This photo shows a close-up view of a gold chandelier.",
+ "A chandelier is a type of lighting fixture that hangs from the ceiling.",
+ "The chandelier is a large, decorative light fixture that hangs from the ceiling.",
+ "This photo shows a chandelier hanging from a ceiling.",
+ "I am not sure what you are asking.",
+ "A chandelier is a decorative light fixture that is often hung from the ceiling.",
+ "The photo is of a large, ornate chandelier hanging from a ceiling.",
+ "The photo of the chandelier is of an ornate, beautifully crafted light fixture hanging from the ceiling.",
+ "A chandelier typically consists of a metal or wooden frame with a central support and arms or branches extending from the support.",
+ "A chandelier is a type of light fixture that has multiple lights and hangs from the ceiling.",
+ "A chandelier is a decorative light fixture that hangs from the ceiling.",
+ "A chandelier is a decorative light fixture that is hung from the ceiling.",
+ "A typical chandelier is an ornate, multi-armed fixture suspended from a ceiling by a chain or metal rod.",
+ "A chandelier is a decorative light fixture that is often hung from the ceiling.",
+ "A chandelier is a light fixture that hangs from a ceiling.",
+ "A chandelier is a type of light fixture that hangs from the ceiling and has multiple lightbulbs.",
+ "A chandelier is a type of light fixture that consists of multiple light bulbs or candles arranged in a decorative way.",
+ "A chandelier is a type of lighting fixture that hangs from the ceiling."
+ ],
+ "yin yang": [
+ "A yin and yang symbol looks like a circle with a black curve and white curve intersecting at a point in the center.",
+ "A yin and yang symbol contains a black yin side and a white yang side.",
+ "A Yin and Yang symbol consists of a circle divided into two halves by a curved line.",
+ "A yin and yang symbol consists of a black and white circle, with a black Yin on the left and a white Yang on the right.",
+ "A yin and yang symbol is a circle that is divided into two halves.",
+ "A yin and yang symbol has a black side and a white side.",
+ "The yin and yang symbol consists of a circle divided into two equal parts by a curved line.",
+ "The yin and yang symbol is a circle divided into two halves, one black and one white.",
+ "A yin and yang symbol looks like a black and white circle with a flowing S shape connecting the two colors.",
+ "A yin and yang symbol is a circle divided into two sections by a curved line.",
+ "A yin and yang symbol is a photo of a circle split into two equal parts by a curved line.",
+ "A photo of the yin and yang symbol would show a black and white spiral circle with a dot of the opposite color in the center of each side.",
+ "A yin and yang symbol is a photo of a circle that is split into two halves.",
+ "The photo is of a Yin and Yang symbol.",
+ "In the photo, there is a black and white circular symbol with a curved line dividing the two colors.",
+ "A yin and yang symbol is a photo of a circle that is divided into two halves.",
+ "The photo is of a black and white circle, with a white spiral in the black half and a black spiral in the white half.",
+ "A yin and yang symbol is a photo of a circle that is divided into two equal parts by a curved line.",
+ "A yin and yang symbol is a photo of a circle that is divided into two equal parts.",
+ "A yin and yang symbol is a black and white circle with a curved line dividing them.",
+ "A yin and yang symbol consists of two teardrop-shaped halves, one white and one black.",
+ "A black and white spiral.",
+ "The yin and yang symbol consists of two teardrop-shaped sections, one black and one white, which are slightly offset from each other.",
+ "The yin and yang symbol is a representation of the duality of opposites in the universe.",
+ "A yin and yang symbol is a circle that is divided into two equal parts.",
+ "The yin and yang symbol is a circle divided into two equal parts by a curved line.",
+ "The yin and yang symbol is a circle split in half by a curved line.",
+ "A yin and yang symbol is a black and white circle that is divided by a curved line.",
+ "A yin and yang symbol is a circle that is divided in half by a curved line.",
+ "A yin and yang symbol is a black and white circle with a small curve in each."
+ ],
+ "dragonfly": [
+ "A dragonfly is a flying insect that has a long body and large wings.",
+ "The dragonfly is a flying insect that has a long thin body and two pairs of wings.",
+ "A dragonfly is a predatory insect that is found near water.",
+ "A dragonfly has a long thin body with large wings.",
+ "A dragonfly typically has a long, thin body with four wings that are spread out at rest.",
+ "A dragonfly is a flying insect that has a long thin body and four wings.",
+ "A dragonfly is a type of insect that is usually thin and has four wings.",
+ "A dragonfly is a flying insect that has a long thin body with six legs.",
+ "A dragonfly has a long thin body and four thin wings.",
+ "A dragonfly typically has two pairs of elongated, membranous wings that are essentially clear.",
+ "This photo shows a dragonfly with its wings outstretched.",
+ "I see a dragonfly with a long, slender body and four wings that are each multi-colored and have a pattern of dots.",
+ "The photo is of a dragonfly perched on a branch.",
+ "The photo shows a brightly colored dragonfly with wings spread out.",
+ "This photo is of a dragonfly up close.",
+ "In the photo, a dragonfly is perched on a reed, its wings spread out.",
+ "The photo is of a brightly-colored dragonfly with its wings spread out.",
+ "A photograph of a dragonfly would typically show a medium to large sized insect with four wings.",
+ "The photo is of a yellow dragonfly perched on a blade of grass.",
+ "The photo is of a dragonfly with its long, thin body and large wings.",
+ "A dragonfly is a type of insect with two pairs of wings.",
+ "A dragonfly is a predatory insect that is noted for its large size, its brilliant colors, and its distinctive shape.",
+ "A dragonfly looks like a small, flying insect.",
+ "A dragonfly is a predatory insect that has a long, thin body with two pairs of large, transparent wings.",
+ "A dragonfly looks like an insect with two pairs of wings.",
+ "A dragonfly is a type of insect.",
+ "A dragonfly generally has a long and narrow body with large wings.",
+ "A dragonfly is a flying insect that has two large, transparent wings.",
+ "A dragonfly has a long, narrow body with two pairs of wings.",
+ "A dragonfly looks like a flying insect with long wings and a long body."
+ ],
+ "crab": [
+ "A crab is a crustacean with five pairs of legs and a broad, flat carapace.",
+ "A crab is a marine crustacean with a hard shell.",
+ "A crab is a small, hard-shelled creature with eight legs and two large claws.",
+ "A crab is a small, hard-shelled creature that lives in the water.",
+ "A crab has a hard, shell-like exoskeleton, four pairs of legs, and two large claws.",
+ "A crab has a hard, round shell.",
+ "Crabs are small, lobster-like animals with shells that protect their bodies.",
+ "A crab typically has a large, hard carapace that covers the animal's cephalothorax.",
+ "A crab looks like an ocean-dwelling creature with eight legs, two large claws, and a hard shell.",
+ "A crab is a small, hard-shelled creature with eight legs and two large claws.",
+ "I saw a crab in my friend's photo.",
+ "This photo is of a crab that is on the beach.",
+ "The photo is of a crab on a plate.",
+ "This photo is of a crab crawling on the beach.",
+ "A crab is a photo of an animal with a hard shell and eight legs.",
+ "In the photo, there is a crab lying on its back on a beach.",
+ "This photo is of a crab against a blue background.",
+ "The photo is of a crab sitting on a rock.",
+ "A crab is a photo of an animal with a hard shell and ten legs.",
+ "This could be a photo of a crab on the beach, in the water, or in a store.",
+ "A crab looks like a small, hard-shelled animal with eight legs.",
+ "A crab looks like a small, hard-shelled creature with eight legs.",
+ "The body of a crab is flattened, and it has a pair of large pincers, or claws, on its front.",
+ "A crab is an aquatic creature with a hard shell and eight legs.",
+ "A crab is an invertebrate animal that has a hard shell and eight legs.",
+ "A crab typically has a rounded body with a hard shell.",
+ "A crab is an invertebrate animal that has a hard shell and legs that are pointed inwards.",
+ "A crab typically has a wide, flat body with a short tail, and four pairs of legs.",
+ "A crab is a small, hard-shelled creature with six legs and two large claws.",
+ "A crab looks like a medium-sized to large seafood with a hard shell and five pairs of legs, the first of which are larger pincers."
+ ],
+ "pagoda": [
+ "A pagoda is a tall, tiered structure with a square or rectangular base, often built of wood or stone and used as a shrine or temple.",
+ "A pagoda is a tiered tower with eaves and cornices, with a stairway leading up to the main floor.",
+ "A pagoda is typically a tiered structure with multiple eaves, built in traditional Chinese architectural style.",
+ "A pagoda is a tiered structure of wood, brick, or stone with a steep, pointy roof.",
+ "A pagoda is a type of tiered tower with multiple eaves common in Eastern architectural traditions.",
+ "A pagoda is a tall, multi-tiered structure with an upward-curving roof, typically founded on a square or rectangular platform.",
+ "A pagoda is a tiered tower with an ornate roof, originating from East Asia.",
+ "A pagoda is a tiered tower with multiple eaves, traditionally built in East Asian architectural styles.",
+ "A pagoda is a tall, ornate, spire-like structure found in Buddhist temples.",
+ "A pagoda is a tall, tiered structure with a steep, pointed roof that is built to honor a god or ancestor.",
+ "A pagoda is a tiered, Asia-inspired roofed structure that is often built around a central pole.",
+ "A pagoda is a tiered structure with multiple eaves, originating from ancient China.",
+ "A pagoda can be any tiered tower, usually with an odd number of Stories, originating in ancient India.",
+ "A pagoda is a tiered structure with an upright central pillar and a roof composed of layers of progressively receding eaves.",
+ "The pagoda is a tiered structure with a pointed top, common in Asian architecture.",
+ "A pagoda is a tiered Tower with an eaves, originating from ancient China.",
+ "This is a photo of a pagoda in Japan.",
+ "A pagoda is a tiered tower with multiple eaves, built in traditional Chinese architectural style.",
+ "A pagoda is a tiered tower with several eaves, typically built in East Asia or South Asia as a part of a Buddhist temple complex.",
+ "A pagoda is a tiered, ornamental tower typically found in East Asian cultures.",
+ "A pagoda is a tiered Buddhist shrine that typically has an odd number of levels.",
+ "A traditional pagoda is a tiered tower with an odd number of eaves, built in stages with stairs leading up to each level.",
+ "A pagoda may vary in appearance, but is typically a tiered structure with multiple eaves, built in traditional Chinese architectural style.",
+ "A pagoda is a type of building that has multiple tiers of roofs.",
+ "A pagoda is a tiered structure with an ornamental roof, typically found in Asian cultures, that may or may not be used for religious purposes.",
+ "A pagoda is a type of tower with many floors.",
+ "A traditional pagoda has a tiered, pyramid-like structure with an ornate roof.",
+ "A pagoda is a tiered structure typically with an odd number of tiers.",
+ "A pagoda typically has an octagonal or circular base, with several tiers leading up to a point at the top.",
+ "A pagoda typically has a square or rectangular base with multiple tiers that gradually taper up to a point, and often has elaborate decorative details."
+ ],
+ "emu": [
+ "An emu is a flightless bird that is native to Australia.",
+ "The emu is a large flightless bird native to Australia.",
+ "An emu is a large, flightless bird with gray-brown plumage, long legs, and a long neck.",
+ "The emu is the largest bird in Australia and the second-largest bird in the world after the ostrich.",
+ "A emu is a large, flightless bird.",
+ "An emu is a large, flightless bird native to Australia.",
+ "A emu is a large, flightless bird that is native to Australia.",
+ "An emu is a large, flightless bird that looks like a cross between a ostrich and a dinosaur.",
+ "A emu is a large bird with brown feathers and a long neck.",
+ "An emu is a tall, flightless bird that is native to Australia.",
+ "The photo is of a large, flightless bird with long legs and a long neck.",
+ "The photo shows an emu in a natural setting, with green grass and trees in the background.",
+ "The photo is of a large, flightless bird with long legs and neck.",
+ "A photo of an emu typically shows a large, flightless bird with long legs, a long neck, and a small head.",
+ "An emu is a large, flightless bird native to Australia.",
+ "The emu is a large, flightless bird native to Australia.",
+ "A photo of an emu would show a large, flightless bird with long legs and a long neck.",
+ "The photo is of a large, flightless bird with long legs.",
+ "A large, flightless bird with long legs, a long neck, and a small head.",
+ "TheEmu is a large, flightless bird native to Australia.",
+ "An emu is a large, flightless bird native to Australia.",
+ "An emu is a large bird with a long neck and legs.",
+ "An emu is a large, flightless bird native to Australia.",
+ "An emu is a large bird with brown and gray feathers.",
+ "A male emu can reach up to 6.",
+ "An emu is a bird that looks like a small ostrich.",
+ "A male emu can be up to 6.",
+ "A emu is a flightless bird that is native to Australia.",
+ "An emu is a tall, flightless bird that is native to Australia.",
+ "A emu looks like a large, flightless bird with long legs, a long neck, and a small head."
+ ],
+ "platypus": [
+ "A platypus is a small, furry mammal with a long, thin snout.",
+ "A platypus is a small, furry mammal with a beak and webbed feet.",
+ "A platypus is a semi-aquatic mammal found in eastern Australia.",
+ "A platypus has a duck-like bill and body, webbed feet, and a tail like a beaver.",
+ " Platypuses are small, aquatic mammals with furry bodies, short limbs, and long, flat tails.",
+ "There is no one definitive answer to this question, as platypuses vary in appearance.",
+ "They have a bill like a duck, a beaver-like tail, otter-like feet, and a venomous spur on their hind legs.",
+ "A platypus has a streamlined body with webbed feet and a broad, flat tail.",
+ "A platypus looks like a small, furry mammal with a long, beaver-like tail, webbed feet, and a bill like a duck's.",
+ "A platypus is a small, egg-laying mammal found in eastern Australia, including Tasmania.",
+ "A platypus is a small, furry mammal with a bill like a duck.",
+ "It's a platypus.",
+ "A platypus is a small, egg-laying mammal found in eastern Australia, including Tasmania.",
+ "The photo is of a platypus swimming in water.",
+ "The photo is of a platypus swimming through a river.",
+ "This photo is of a platypus swimming through water.",
+ "This photo shows a platypus swimming in water.",
+ "The photo shows a platypus swimming in water.",
+ "In the photo, a platypus is swimming in a river with reeds in the background.",
+ "A platypus is a small, furry creature with a long, beaver-like tail and a duck-like bill.",
+ "=) A platypus is a semi-aquatic mammal found in eastern Australia, including Tasmania.",
+ "A platypus looks like a cross between a beaver and an otter.",
+ "A platypus is a medium sized animal with a bill like a duck, brown fur, and a flat tail.",
+ "The platypus is a small, semiaquatic, egg-laying mammal native to eastern Australia, including Tasmania.",
+ "A platypus is a small, furry mammal with a long, pointy beak.",
+ "A platypus is an animal that is unique because it has both fur and webbed feet.",
+ "A platypus has a bill like a duck, a furry body like an otter, and webbed feet like a frog.",
+ "A platypus is a small, semiaquatic mammal found in eastern Australia, including Tasmania.",
+ "A platypus has a beaver-like body with a wide, flat tail.",
+ "A platypus is an aquatic mammal with a duck-like bill and furry body."
+ ],
+ "dalmatian": [
+ "A dalmatian is a Spotty Dog.",
+ "A dalmatian is a breed of medium-sized dog with a short, stiff coat of unspotted black or liver-colored hair.",
+ "A dalmatian is a dog breed that is easily recognized by its unique black or liver spotted coat.",
+ "A dalmatian is a medium sized, short-haired breed of dog with black or liver spots on a white coat.",
+ "A dalmatian is a medium-sized, short-haired, spotted dog.",
+ "A dalmatian is a medium-sized dog with short, stiff hair that is usually black with white spots.",
+ "A dalmatian has a short, stiff coat of spotted black hair.",
+ "A dalmatian is a black-and-white spotted dog.",
+ "\"Dalmatian\" describes a coat pattern found in many different breeds of dogs, not just one specific breed.",
+ "A dalmatian is a large dog with a short, stiff coat of white fur with black spots.",
+ "In the photo, there is a dalmatian with black spots on a white coat standing in a green field.",
+ "A dalmatian is a black and white spotted dog.",
+ "A dalmatian is a spotted dog breed.",
+ "A dalmatian is a breed of medium-sized dog, noted for its unique black or liver spotted coat.",
+ "A dalmatian is a dog with black and white spots.",
+ "A dalmatian is a breed of dog that is usually white with black spots.",
+ "The photo is of a black and white dalmatian.",
+ "The photo is of a dalmatian sitting on a grassy field.",
+ "A dalmatian is a dog with black or liver spots on a white coat.",
+ "The photo is of a Dalmatian whose coat is mostly white with large black spots.",
+ "A Dalmatian is a white dog with large black spots all over its body.",
+ "A dalmatian is a medium size dog with a short coat that is either black with white spots or liver with white spots.",
+ "A dalmatian is a breed of dog that is white with black spots.",
+ "Dalmatians are large, muscular dogs that are most commonly known for their unique black and white coat.",
+ "A dalmatian is a black and white spotted dog.",
+ "A dalmatian is a white dog with black spots.",
+ "A dalmatian is a large, white dog with black spots.",
+ "A dalmatian is a short-haired dog with a black-and-white spotted coat.",
+ "A Dalmatian is a large breed of dog with a short coat of black or liver spotted hair and pronounced black spots on their body.",
+ "A dalmatian is a medium-sized, short-coated dog."
+ ],
+ "cup": [
+ "A cup is a container typically used to hold liquids such as water, coffee, or tea.",
+ "A cup is generally a small, round, open container used to hold liquid.",
+ "A cup is a small bowl with a handle that is used to hold liquids.",
+ "A cup is a small container used to hold liquids.",
+ "A cup typically has a cylindrical shape with a handle, and a brim for holding liquids.",
+ "A cup typically has a cylindrical shape with a handle, and a lip for drinking.",
+ "A typical cup is cylindrical in shape and has a handle.",
+ "A cup typically has a cylindrical shape with a flat base and a flared top.",
+ "A cup is typically a small, round vessel with a flat bottom and a lip, used for drinking hot or cold beverages.",
+ "A cup is a receptacle that is used to hold liquid.",
+ "The photo is of a cup on a wooden table.",
+ "This photo is of a cup on a table.",
+ "This photo is of a ceramic coffee cup on a saucer.",
+ " of coffeeThe photo is of a small, white cup of coffee with a dark brown liquid inside.",
+ "cakeI see a delicious cupcake with pink frosting and sprinkles on top.",
+ " of coffeeA cup of coffee is sitting on a table.",
+ "This is a photo of a white cup with a green straw sticking out of the top.",
+ "The photo is of a cup against a white background.",
+ " of coffeeA cup of coffee is on a table with a light brown background.",
+ "cakeThis cupcake has a light pink frosting with sprinkles on top.",
+ "A cup is typically cylindrical in shape with a flat bottom and a rim that curves outward.",
+ "A cup looks like a container that has a base and a lip that curves inward.",
+ "A cup typically has a round or oval-shaped bottom, and a cylindrical shape that tapers up to a smaller diameter at the top.",
+ "A cup typically has a circular base and a flared sides.",
+ "A cup is a container with a handle and a lip, used to hold liquids.",
+ "A cup is typically shaped like a cylinder with a handle, or like a truncated cone with a flared lip.",
+ "A cup can look like many different things.",
+ "A cup is typically a cylindrical shape with a handle.",
+ "A cup is usually a cylindrical shape with a handle.",
+ "A cup is a small, round object that is typically used for drinking."
+ ],
+ "off-center face": [
+ "A face that is not symmetrical.",
+ "A face that is not symmetrical; one side is different from the other.",
+ "A face that is not completely symmetrical.",
+ "A face that is not symmetrical.",
+ "One eye may be lower than the other, the nose may be off to one side, and the mouth may be crooked.",
+ "A off-center face looks like it has been pushed to one side, or is not level.",
+ "A off-center face looks like a face that is not centered perfectly on the head.",
+ "A face that is not symmetrical.",
+ "A face that is not symmetrical; one side may be higher or lower than the other, the nose may be off-center, etc.",
+ "\"Off-center\" can mean different things to different people, but generally, an \"off-center\" face means that the features on the face are not symmetrical.",
+ "A photo of an off-center face would be a picture where the person's face is not in the center of the frame.",
+ "A photo of a face that is not perfectly aligned in the center of the frame.",
+ "The subject's face is not in the center of the frame, and their gaze is directed off-center, towards the edge of the photo.",
+ "A person's face is not centered in the photo and their head is tilted to the side.",
+ "The photo is of a woman with long, dark hair.",
+ "In the photo, there is a woman's face that is slightly off-center.",
+ "A photo of an off-center face is a photo where the face is not in the center of the frame.",
+ "The photo is of a woman's face that is slightly off-center.",
+ "The image is of a woman, likely in her mid-20s, with long dark hair.",
+ "A photo of a face that is not centerd in the frame.",
+ "A face that is not symmetrical.",
+ "There is no definitive answer to this question since everybody's face is different.",
+ "A face that is not symmetrical or evenly balanced.",
+ "There is no definitive answer to this question as it depends on the individual's facial features and how far off-center they are.",
+ "A face that is not symmetrical.",
+ "There is no definitive answer to this question since \"off-center\" can mean different things to different people.",
+ "A face that is not symmetrical; one side may be higher or lower than the other, the eyes may not be level, or the nose may be crooked.",
+ "Off-center faces look asymmetrical.",
+ "A face that is not symmetrical; one side may be larger or higher than the other.",
+ "A face that is not symmetrical."
+ ],
+ "car side": [
+ "One side of a car typically has four doors, two windows, and a wheel.",
+ "A side view of a car includes the side door, the car's windows, and the wheel.",
+ "A side of a car looks like a rectangle with four wheels.",
+ "One side of a car looks like a long, metallic object with four round, black objects at the bottom.",
+ "A side of a car looks like one half of the car.",
+ "A side of a car typically has four panels: two doors, a window, and a quarter panel.",
+ "A side of a car looks like a metal sheet with windows and doors.",
+ "A side of a car is typically composed of four panels: the two doors, the quarter panel, and the side panel.",
+ "A side of a car usually has four doors and windows.",
+ "A typical side of a car has four main panels: the two doors, the side panel between the doors, and the rear quarter panel.",
+ "The side of a car is typically metal and has four tires.",
+ "This photo is of the side of a black car.",
+ "The photo is of the side of a car.",
+ "The photograph shows the side of a car that is parked on a city street.",
+ "One side of a black car is visible in the photo.",
+ "This is a photo of the side of a car.",
+ "A side of a car is typically a photo of the car from the side.",
+ "The photo is of the side of a black car.",
+ "The car is a white sedan with four doors.",
+ "This car is blue with silver stripes on the side.",
+ "A side of a car looks like a silhouette of the vehicle from the side.",
+ "The side of a car typically has four components: the door, the side panel, the wheel well, and the quarter panel.",
+ "A side view of a car typically includes the car's door, windows, wheels, and headlights.",
+ "A side view of a car shows the left and right sides of the vehicle.",
+ "The side of a car typically has four panels: the two front doors, the rear door, and the panel between the rear door and the trunk.",
+ "A side of a car is typically a metal panel that runs from the front door to the back door.",
+ "One side of a car typically has the door, the window, the side view mirror, and the wheel.",
+ "This is a difficult question.",
+ "A side view of a car includes the car's doors, windows, wheels, and sideview mirrors.",
+ "A side view of a car includes the headlights, taillights, windows, and door."
+ ],
+ "trilobite": [
+ "Trilobites were a type of extinct animal that had a hard shell and three body lobes.",
+ "A trilobite is a prehistoric animal that was similar to a bug.",
+ "A trilobite looks like an extinct type of arthropod that had a segmented body with a hard exoskeleton.",
+ "A trilobite is a fossilized animal that lived millions of years ago.",
+ "A trilobite is an extinct type of arthropod that had a hard exoskeleton.",
+ "A trilobite is a segmented, hard-shelled creature that lived in the ancient seas.",
+ "A trilobite is a segmented, hard-shelled creature that lived during the Paleozoic era.",
+ "The word 'trilobite' means 'three lobes' and refers to the three parts that make up the fossilized exoskeleton of these extinct creatures.",
+ "Trilobites are extinct arthropods that lived in the sea.",
+ "A trilobite is a prehistoric creature that looked like a modern-day lobster or shrimp.",
+ "A trilobite is an extinct, hard-shelled animal that had a segmented body and a triangular head.",
+ "A trilobite is an extinct marine arthropod that dates back to the Cambrian period.",
+ "A trilobite is a extinct marine arthropod that forms an important part of the fossil record.",
+ "A photo of a trilobite would typically show a fossilized example of this extinct creature.",
+ "A trilobite is a prehistoric creature that lived in the sea.",
+ "The photo is of a fossilized trilobite.",
+ "I cannot see the photo.",
+ "This is a photo of a fossilized trilobite.",
+ "The image shows a fossil of a trilobite, an extinct marine arthropod.",
+ "A trilobite is a extinct arthropod that lived during the Paleozoic era.",
+ "Trilobites were a type of extinct arthropod.",
+ "A trilobite is a primitive arthropod that lived during the Paleozoic era.",
+ "Trilobites vary greatly in size, shape, and appearance.",
+ "Trilobites were hard-shelled, segmented animals that lived during the Paleozoic Era.",
+ "A trilobite is a type of fossil that looks like a small, hard-shelled creature with three lobes down its back.",
+ "Today's trilobites are very different from the trilobites that lived millions of years ago.",
+ "A trilobite is a primitive, extinct arthropod that had a hard, segmented exoskeleton and a three-lobed body.",
+ "A trilobite is a flat, segmented creature with three projecting lobes.",
+ "Trilobites are extinct arthropods that lived in the sea.",
+ "A trilobite is a primitive, extinct animal that had a hard outer shell."
+ ],
+ "brontosaurus": [
+ "A brontosaurus is a large, four-legged, plant-eating dinosaur that has a long neck and tail.",
+ "Brontosaurus are large, long-necked, four-legged herbivorous dinosaurs.",
+ "The brontosaurus was a large, plant-eating dinosaur.",
+ "The brontosaurus is a large, long-necked, plant-eating dinosaur.",
+ "The brontosaurus is a large, long-necked, four-legged herbivore.",
+ "A brontosaurus looks like a large, long-necked dinosaur.",
+ "A brontosaurus is a large, plant-eating dinosaur that lived during the Late Jurassic period, about 155 to 150 million years ago.",
+ "The brontosaurus is a large, herbivorous dinosaur that lived during the Jurassic period.",
+ "A brontosaurus is a large herbivorous dinosaur with a long neck and tail.",
+ "The brontosaurus is a large, herbivorous dinosaur that lived during the Jurassic period.",
+ "This is a photo of a brontosaurus.",
+ "The photo is of a brontosaurus walking through a swamp.",
+ "The photo is of a brontosaurus standing in a field of tall grass.",
+ "The photo is of a large, long-necked dinosaur called a brontosaurus.",
+ "The photo shows a huge brontosaurus dinosaur in a green field.",
+ "This photo shows a brontosaurus in a natural setting, with trees and plants in the background.",
+ "This photo is of a brontosaurus.",
+ "A massive brontosaurus rears up on its hind legs, its long neck stretching skyward as it lets out a fearsome roar.",
+ "A photo of a brontosaurus would show a large, long-necked dinosaur with a small head.",
+ "This is a photo of a brontosaurus.",
+ "The brontosaurus is a large, long-necked, plant-eating dinosaur.",
+ "Brontosaurus looked similar to other sauropods, with a long neck, small head, and a long, whip-like tail.",
+ "Brontosaurs were large, long-necked, quadrupedal animals with relatively small heads.",
+ "A brontosaurus is a huge, plant-eating dinosaur that lived during the Jurassic period.",
+ "A brontosaurus is a large dinosaur that lived during the Jurassic period.",
+ "A brontosaurus is a large, herbivorous dinosaur with a long neck, small head, and a long, whip-like tail.",
+ "A brontosaurus is a large, long-necked, plant-eating dinosaur.",
+ "Brontosaurus look like large, green, four-legged dinosaurs with long tails and long necks.",
+ "A brontosaurus is a large, plant-eating dinosaur that lived during the Jurassic period.",
+ "A brontosaurus looks like a large, green, four-legged dinosaur with a long neck and head."
+ ],
+ "pigeon": [
+ "Pigeons are birds that are usually gray with some light and dark markings.",
+ "A pigeon is a small, greasy bird with a flat beak.",
+ "Pigeons are small, gray birds with wingspans of about a foot.",
+ "A pigeon is a medium sized bird with a short neck and a round body.",
+ "A pigeon is a small, gray bird with a white chest.",
+ "A pigeon has a round body and a short neck.",
+ "Pigeons are stout-bodied birds with short necks and short, slender bills.",
+ "Pigeons are small, gray-colored birds.",
+ "A pigeon is a plump bird with a short neck and a short, blunt beak.",
+ "A pigeon typically has gray feathers and a white belly.",
+ "A pigeon is a plump, gray bird with a white belly.",
+ "A pigeon is perched on a windowsill, looking out at the cityscape.",
+ "This is a photo of a pigeon perched on a windowsill.",
+ "A pigeon is a gray bird with a white chest.",
+ "A photo of a pigeon would generally show a small, grey bird with a white belly.",
+ "A grey pigeon with a long beak sits on a windowsill.",
+ "This photo is of a single pigeon perched atop a short section of brick wall.",
+ "This is a photo of a pigeon perched on a railing.",
+ "This is a photo of a pigeon that is sitting on top of a building.",
+ "A photo of a pigeon might show a bird perched on a building or other structure, or it might show the bird in flight.",
+ "Pigeons are small, stocky birds with short necks and round heads.",
+ "A pigeon is a plump bird with a short neck and a head that is larger in proportion to its body.",
+ "A pigeon is a bird that typically has grey plumage.",
+ "A pigeon is a plump, grey bird with a long tail.",
+ "A pigeon looks like a gray bird with a white belly.",
+ "A pigeon is a type of bird.",
+ "A pigeon looks like a small, gray bird with a long tail.",
+ "A pigeon is a small, gray bird.",
+ "Pigeons are medium-sized, gray birds with white patches on their wings.",
+ "Pigeons are typically gray or blue with white undersides and have long tails."
+ ],
+ "dolphin": [
+ "A dolphin is a mammals that typically have a long beak-like snout, enclosed by a blowhole on top of their head.",
+ "A dolphin is a mammal that is related to whales and porpoises.",
+ "A dolphin is a marine mammal that typically has a long, curved body, an elongated beak, and flippers.",
+ "A dolphin is a mammal that lives in the water.",
+ "A dolphin typically has a blue-grey body with white underneath.",
+ "A dolphin is a mammalian creature that lives in the water.",
+ "A dolphin is a mammal that lives in the water.",
+ "A dolphin is a large, intelligent aquatic mammal.",
+ "Dolphins are a type of aquatic mammal.",
+ "A dolphin is a mammalian creature that lives in the ocean.",
+ "This photo is of a dolphin swimming through the water.",
+ "A photo of a dolphin is typically a close up of the dolphin's face with its mouth open.",
+ "This photo is of a dolphin breaching out of the water.",
+ "A dolphin photo typically contains one or more dolphins swimming in a body of water.",
+ "A dolphin is a marine mammal that is closely related to whales and porpoises.",
+ "In this photo, a bottlenose dolphin is leaping out of the water.",
+ "In the photo, a dolphin is swimming through the water with its mouth open.",
+ "This is a photo of a happy dolphin surfing in the waves.",
+ "The dolphin is swimming in the ocean and is jumped out of the water.",
+ "This is a photo of a dolphin leaping out of the water.",
+ "A dolphin is a marine mammal that is closely related to whales and porpoises.",
+ "A dolphin looks like a fish with a long nose.",
+ "dolphins are small to medium-sized cetaceans.",
+ "Dolphins are long, sleek mammals with pointed noses.",
+ "Dolphins are a type of marine mammal that are closely related to whales and porpoises.",
+ "Dolphins are a type of mammal known as cetaceans.",
+ "A dolphin is a mammal that lives in the water.",
+ "A dolphin has a large head, a long beak, two small eyes on the sides of its head, and many sharp teeth.",
+ "Dolphins are a type of marine mammal that is closely related to whales.",
+ "A dolphin has a long nose, called a beak, and a large, curved dorsal fin."
+ ],
+ "wrench": [
+ "The wrench is a L-shaped tool with a long handle and a jaws that open and close.",
+ "A wrench looks like a metal tool with a handle that is used for turning bolts or nuts.",
+ "A wrench is a tool that is used to turn objects.",
+ "A wrench is a tool that is used to tighten or loosen bolts and nuts.",
+ "A wrench is a hand tool that has a long handle and a metal head.",
+ "A wrench is a hand tool that looks like a pair of pliers with a long handle.",
+ "A wrench is a long, thin metal rod with a handle on one end and a raised, angled head on the other.",
+ "a wrench is typically a metal or hard plastic rod with a grip on one end and a socket on the other end, used for turning bolts and nuts.",
+ "A wrench is a tool that is used to grip and turn objects.",
+ "Most wrenches have a long metal handle with a cylindrical head at one end.",
+ "The photo is of a silver wrench with a black handle.",
+ "This is a metal wrench with a long handle and a short, thick body.",
+ "The wrench is a hand tool used to grip and turn objects such as screws, nuts, pipes and bolts.",
+ "A wrench is a hand tool used to grip and turn objects such as bolts and pipes.",
+ "This is a photo of a wrench.",
+ "A wrench is a tool used to turn a bolt.",
+ "The photo is of a wrench that is lying on a table.",
+ "The wrench is a tool that is used to turn or hold a fastener, such as a nut or bolt.",
+ "The wrench is a common tool that is used to turn objects.",
+ "The photo is of a wrench lying on a white background.",
+ "A wrench is a tool that is used to turn bolts and nuts.",
+ "A wrench is a L-shaped tool with a long handle and a short, thick head.",
+ "Most wrenches have a long handle with a metal head at one end.",
+ "A typical wrench looks like a \"T\" shape, with a long handle and a shorter head.",
+ "A wrench is typically a hand tool that is used to turn objects.",
+ "A wrench is a tool that typically has a long handle and a head that can be adjusted to fit different sizes of nuts and bolts.",
+ "A wrench looks like an L shaped metal tool.",
+ "A wrench is a type of hand tool that consists of a handle and a jaws that open and close.",
+ "A wrench is a hand tool that is used to grip and turn objects, such as nuts and bolts.",
+ "A wrench looks like a \"T\" shape with a long handle and a short, stubby arm perpendicular to the handle."
+ ],
+ "scorpion": [
+ "A scorpion has a long, thin body and eight legs.",
+ "A scorpion is a small arachnid with a long tail that is tipped with a poisonous stinger.",
+ "Scorpions are arachnids, and they look like a small crab with a long, curved tail.",
+ "Scorpions are large insects that have long tails and pincers.",
+ "Scorpions have a long, segmented body and two large claws.",
+ "Scorpions are arachnids, and are closely related to spiders and mites.",
+ "Scorpions are arachnids, which means they have eight legs, two claws (called pedipalps), and a long, segmented tail that usually ends in a stinger.",
+ "A scorpion tends to be dark brown or black in color and has a sleek, segmented body.",
+ "A scorpion is a predatory arachnid with a tail that is tipped with a stinger.",
+ "A scorpion is a small arachnid that has a long tail with a stinger at the end.",
+ "This photo depicts a scorpion in the wild.",
+ "The photo is of a scorpion on a rock in a desert.",
+ "A scorpion is a small, dark creature with a long tail and large claws.",
+ "This is a photo of a scorpion.",
+ "A scorpion is a predatory arachnid with a long, segmented body and a narrow, curved tail tipped with a poisonous stinger.",
+ "This photo is of a scorpion on a desert floor.",
+ "The photo is of a scorpion on a desert floor.",
+ "This photo shows a scorpion with its large claws extended.",
+ "The photo is of a scorpion on a light background.",
+ "A scorpion photo might feature a close-up of the creature's stinger, its segmented body, or its large claws.",
+ "Most scorpions are dark brown, but some are yellow, tan, or almost black.",
+ "A scorpion has a long, segmented body and a pair of long pincers.",
+ "A scorpion has a thin body with a long tail that has a stinger on the end.",
+ "A scorpion's body is divided into two main parts: the cephalothorax, which contains the head and the first pair of legs, and the abdomen, which contains the remaining pairs of legs and the stinger.",
+ "A scorpion is a small arachnid that has eight legs and a long tail that ends in a stinger.",
+ "A scorpion has a small body with a large tail that curves over its back.",
+ "A scorpion looks like a small crab with a long tail.",
+ "A scorpion is a small arachnid with a long, thin body and tail.",
+ "A scorpion is a small arachnid that has a long body and a long tail that is tipped with a Venomous stinger.",
+ "A scorpion has a long body and a tail with a stinger."
+ ],
+ "grand piano": [
+ "A grand piano is a large, classical piano that has a horizontal shape and a timbre that is suited for orchestral and other large-scale performances.",
+ "A grand piano is a large piano usually measuring 9 feet or more in length.",
+ "A grand piano typically has a long, narrow body with a lid that can be raised to filter the sound.",
+ "A grand piano is a large, usually black, piano with a long curved body and a lid that can be raised to reveal the strings and hammers.",
+ "A grand piano is a large musical instrument that has a long black body with a white and black keyboard on the front.",
+ "A grand piano is a large musical instrument that is played by pressing the keys on the keyboard.",
+ "A grand piano is a large, vertical piano that has a long, curved body and a lid that can be opened or closed.",
+ "A grand piano typically has a frontal area of more than 1.",
+ "A piano that is 6 feet or longer is considered a grand piano.",
+ "A grand piano is a musical instrument with a long horizontal body, typically supported by three legs, that contains 88 keys.",
+ "The grand piano is a large and complex musical instrument.",
+ "This is a photo of a grand piano in a room with light wood floors and walls.",
+ "A grand piano stands in the middle of a room with its lid open.",
+ "The photo is of a grand piano in a living room.",
+ "This photo is of a grand piano in a music room.",
+ "This photo is of a grand piano in a large room.",
+ "In the photo, there is a grand piano in the middle of a room with hardwood floors.",
+ "This grand piano is finsihed in a high gloss black and has a full 88 key keyboard.",
+ "The photo is of a grand piano in a living room.",
+ "The photo is of a glossy black grand piano with shining silver hardware.",
+ "grand pianos are large, black, and have many keys.",
+ "A grand piano typically has a polished wood exterior and a keyboard with 88 black and white keys.",
+ "A grand piano has a much longer frame than a regular piano.",
+ "A grand piano is a large piano that is typically played in a concert setting.",
+ "A grand piano has a long, rectangular shape and a lid that can be opened and closed.",
+ "Typically, a grand piano is about nine feet long and has three pedals.",
+ "A grand piano is about 9 feet long and has three pedals.",
+ "A grand piano typically has a longer body than a traditional upright piano and includes three pedals located at the base.",
+ "A grand piano typically has a long, narrow body with a rectangular shape.",
+ "A grand piano is a piano that is much larger than a regular piano."
+ ],
+ "crocodile head": [
+ "A head of a crocodile can look like a long, narrow snout with large teeth.",
+ "A head of a crocodile looks like a big reptile head with sharp teeth.",
+ "A head of a crocodile looks like a long snout with teeth.",
+ "A head of a crocodile looks like a long, narrow snout with sharp teeth.",
+ "A head of a crocodile looks like a long, curved snout with many sharp teeth.",
+ "A crocodile head is long and narrow with sharp teeth.",
+ "A head of a crocodile is long with a snout.",
+ "Acrocoid heads are large and tend to be broader than they are long, with a long, thick snout and a large mouth.",
+ "A crocodile's head is long and triangular, with two sets of teeth in the front.",
+ "The head of a crocodile is large, with a long snout.",
+ "The photo appears to be of the head of a crocodile, most likely taken in the wild.",
+ "In the photo, the head of a crocodile is poking out of the water.",
+ "This is a photo of a head of a crocodile.",
+ "The photo is of a large crocodile with its mouth open.",
+ "This photo is of a head of a crocodile.",
+ "A crocodile's head is large, with a long, thick snout.",
+ "A crocodile's head is large and boat-shaped, with wide jaws filled with sharp teeth.",
+ "A photo of a head of a crocodile would show the scaly skin, large teeth and eyes, and long snout of the reptile.",
+ "The photo shows the head of a crocodile poking out of the water.",
+ "The photo of a head of a crocodile is a headshot of a crocodile with its mouth open, revealing its sharp teeth.",
+ "A crocodile's head is large and elongated, with razor-sharp teeth.",
+ "A crocodile's head is long, pointy, and has many sharp teeth.",
+ "A head of a crocodile looks like a cone with two eyes on top and a mouth full of sharp teeth.",
+ "A head of a crocodile looks like a long, pointed snout with sharp teeth.",
+ "A head of a crocodile looks like a nose with two eyes on top of it.",
+ "A crocodile's head is large, flat, and triangular.",
+ "The head of a crocodile is large, flat, and triangular.",
+ "A head of a crocodile looks like a large, scaly head with sharp teeth.",
+ "A head of a crocodile looks like a long, narrow, sinuous snout with rows of sharp teeth.",
+ "A crocodile's head is large, flat, and has ridges on the top."
+ ],
+ "nautilus": [
+ "A nautilus is a small, spiral-shaped mollusc.",
+ "A nautilus typically has a slightly spiral-shaped shell with a series of septa, or internal partitions, dividing the shell into chambers.",
+ "A nautilus is a large, predatory sea snail with a shell that is coiled in a spiral shape.",
+ "A nautilus is a cephalopod that has a spiral shell.",
+ "A nautilus is a cephalopod with a spiral-shaped shell.",
+ "A nautilus is a cephalopod mollusc with a characteristic spiral shell.",
+ "A nautilus is a small, spiral-shaped animal that has a hard shell on the outside.",
+ "A nautilus is a cephalopod who's shell is spiral in shape.",
+ "A nautilus looks like a spiral-shaped sea creature with a hard shell.",
+ "A nautilus is a cephalopod mollusc with a spiral shell.",
+ "The nautilus is a cephalopod mollusc with a spiral shell.",
+ "A photo of a nautilus would show a spiral-shaped shell with brown and white stripes.",
+ "A nautilus is a snail-like creature with a coiled shell.",
+ "The photo is of a nautilus shell.",
+ "A nautilus is a cephalopod with a spiral shell.",
+ "A nautilus is a predatory sea creature with a coiled shell.",
+ "A nautilus is a sea creature with a hard shell.",
+ "The photo shows a nautilus shell with its characteristic spiral shape.",
+ "This photo shows a nautilus shell with its characteristic spiral shape.",
+ "A nautilus is a large sea creature with a hard shell.",
+ "The nautilus is a cephalopod mollusc with a coiled spiral shell.",
+ "A nautilus is a cephalopod mollusc with a spiral shell.",
+ "Nautiluses are marine creatures with soft bodies and hard shells.",
+ "A nautilus is a cephalopod mollusc that has a coiled shell.",
+ "A nautilus is a type of shellfish that has a spiral shell.",
+ "The nautilus is a marine animal with a spiral shell.",
+ "A nautilus is a shell that looks like a spiral.",
+ "A nautilus is a type of invertebrate animal that has a spiral shell.",
+ "The nautilus is a mollusc that has a spiral shell.",
+ "A nautilus is a small, crescent-shaped mollusk that has a spiral shell."
+ ],
+ "accordion": [
+ "An accordion is a portable, fretted and stringed instrument, consisting of a narrow, rectangular wood box with a folding lid, supported by metal reeds.",
+ "An Accordion is a musical instrument, of which there are many varieties.",
+ "A typical accordion has multiple buttons or tabs, each corresponding to a different section of content.",
+ "A accordion is a musical instrument that has a rectangular shape and is made of wood.",
+ "A accordion is a musical instrument that has a rectangular shape with a series of folds.",
+ "A accordion is a musical instrument that has a lot of different notes that you can play.",
+ "A accordion looks like a small, rectangular box with a handle on the top and a series of compartments inside.",
+ "An accordion is a musical instrument with a series of reeds of different lengths, played by pressing keys on a keyboard.",
+ "An accordion consists of a series of connected panels that can be opened and closed.",
+ "An accordion is a musical instrument with a series of flat surfaces called keys, which the player presses with their fingers.",
+ "This is a photo of an accordion.",
+ "A photo of an accordion would show a rectangular shaped instrument with two rows of buttons on the front.",
+ "An accordion is a type of musical instrument that has a rectangular shape and is played by pressing buttons or keys.",
+ "An accordion is a musical instrument with a series of metal reeds that vibrate when air is forced through them.",
+ "This photo is of a black and white accordion on a white background.",
+ "In the photo, there is a person holding a black accordion.",
+ "A photo of an accordion would show a rectangular shaped instrument with black and white keys on the front.",
+ "The photo is of a black and white accordion with silver and gold details.",
+ "A man is playing an accordion in front of a brick building.",
+ "This is a photo of a black and white accordion on a stand.",
+ "An accordion has a rectangular shape with two folding halves.",
+ "A accordion is a musical instrument that has a rectangular body with a series of folding bellows.",
+ "An accordion typically has a rectangular shape and is made of wood or plastic.",
+ "A traditional accordion is a rectangular box-shaped instrument with a keyboard on one end and front and side buttons on the other.",
+ "An accordion is a musical instrument that consists of a rectangular box with a keyboard on one end and a set of bellows on the other.",
+ "A accordion looks like a musical instrument with a rectangular shape.",
+ "A accordion is a type of portable musical instrument.",
+ "An accordion is a rectangular box-shaped musical instrument with a folding bellows in the center.",
+ "An accordion is a musical instrument that has a rectangular shape.",
+ "A accordion is a type of musical instrument that has a keyboard and a series of bellows that are used to create sound."
+ ],
+ "pyramid": [
+ "A pyramid has a triangular shape and a point at the top.",
+ "A pyramid is a three-dimensional shape with a polygonal base and triangular sides.",
+ "A pyramid is a geometric shape with a triangular base and four sides that meet at a point, or apex.",
+ "A pyramid is a geometric solid with a square base and four triangular sides.",
+ "A pyramid has a wide, flat base and four sloping sides that come to a point at the top.",
+ "A pyramid is a pyramid-shaped structure with a square or rectangular base and sloping sides that meet in a point at the top.",
+ "A pyramid is a geometric three-dimensional solid with a polygonal base and triangular sides.",
+ "A pyramid is a three-dimensional geometric shape that has a square or rectangular base and four triangular sides that meet at a point.",
+ "A pyramid looks like a triangle with a square on top.",
+ "A pyramid is a geometric shape with four sides that meet in a point at the top, and a flat base.",
+ "A photo of a pyramid would likely show a large, triangular structure with a pointed top.",
+ "The photo shows a large pyramid with a pointed top.",
+ "The image is of a large, ancient looking pyramid.",
+ "The photo is of a large pyramid made of stone.",
+ "A pyramid is a triangular-shaped structure with a flat top and base.",
+ "This pyramid is located in Egypt and is one of the Seven Wonders of the Ancient World.",
+ "The photo is of a pyramid shaped mountain.",
+ "A photo of a pyramid would likely show a large, triangular structure made of stone or bricks.",
+ "A photo of a pyramid might show a large, triangular structure with a smooth, sloping exterior and a pointed top.",
+ "A photo of a pyramid shows a large, triangular-shaped structure with a small entrance at the base.",
+ "A pyramid is a three-dimensional structure with a triangular base and sides that meet at a point.",
+ "A pyramid is a geometric shape with four sides that meet at a point, called the apex.",
+ "Pyramids have a square or rectangular base and four triangular sides that meet at a point, or apex.",
+ "A pyramid looks like a stack of squares or rectangles, with the largest one at the bottom and the smallest one at the top.",
+ "Most pyramids are roughly pyramid-shaped.",
+ "A pyramid is a triangular shaped structure with a flat top and sides that taper up to a point.",
+ "A pyramid is a triangular shape with a pointy top.",
+ "A pyramid typically has a square or rectangular base, and four triangular sides that meet at a point (the apex).",
+ "A pyramid looks like a large triangle.",
+ "A pyramid has a base and four triangular sides."
+ ],
+ "camera": [
+ "A camera is a handheld device that is used to take pictures and videos.",
+ "A camera is a small, portable device that is used to take pictures.",
+ "A camera has a lens that captures light and focuses it onto film or a digital sensor.",
+ "A camera is a small, handheld device that is used to take pictures.",
+ "A camera is a rectangular device with a lens on one end.",
+ "A camera is an instrument used to capture images, either as still photographs or as sequences of moving images (video).",
+ "A camera is a black box with a lens on the front.",
+ "A camera is a small, portable device used to take pictures.",
+ "A camera typically has a lens on the front, a viewfinder on the back, and a trigger in the middle.",
+ "A digital camera is a small, hand-held electronic device that is used to take photographs or videos.",
+ "A camera is a device used to capture photographs or videos.",
+ "This photo is of a black and silver digital camera.",
+ "A camera is a black rectangular box with a large lens on the front.",
+ "This photo is of a Canon DSLR camera.",
+ "A camera is a photographic device used to capture images.",
+ "The photo is of a black camera on a tripod.",
+ "One photo of a camera is of a small, black and silver digital camera.",
+ "The photo of the camera is a black and white image of a camera on a tripod.",
+ "In the photo, there is a camera on a tripod pointing towards a mountain range in the distance.",
+ "This is a photo of a camera.",
+ "There are many types and styles of cameras, but most have a lens on the front, a viewfinder or screen on the back, and a shutter button on the top.",
+ "A camera generally has a rectangular shape with a large lens on the front.",
+ "A camera typically consists of a body and lens.",
+ "A camera is a small, portable device that is used to take photographs.",
+ "A basic camera consists of a lens, a shutter, and a light-sensitive film or digital sensor.",
+ "Most digital cameras look like small rectangular boxes with a lens on one side and a screen on the other.",
+ "A camera typically contains a lens and a shutter, and is used to capture light and create an image.",
+ "A camera looks like a rectangular box with a lens on the front.",
+ "A perspective drawing of a camera would show a black rectangle with a small circle in the middle.",
+ "A digital camera looks like a small rectangular box with a lens on the front."
+ ],
+ "barrel": [
+ "A barrel is a large, cylindrical container that is used to store and transport liquids and other materials.",
+ "A typical wood wine barrel has a capacity of 59 gallons and is crafted from American or French Oak.",
+ "A barrel is a large, cylindrical container that is used to hold liquids, such as oil or wine.",
+ "A barrel is a large, cylindrical container made of wood, metal, or plastic.",
+ "A barrel is a large, often cylindrical, container with a flat top and bottom.",
+ "A barrel generally has a diameter of around 2 to 3 feet and is around 2 to 3 feet tall.",
+ "A barrel is a large cylindrical container with a rounded bottom and a narrow opening at the top.",
+ "A barrel is a cylindrical container with a capacity of about 200 liters (53 gallons).",
+ "A barrel is a large, round, wooden container that holds liquids, such as oil or beer.",
+ "A barrel is a large, round, often wooden container with a flat top and bottom.",
+ "A barrel is a round, hollow container used to hold oil, wine, or other liquids.",
+ " raceA barrel race is a rodeo event in which a horse and rider attempt to complete a cloverleaf pattern around three barrels in the fastest time possible.",
+ "In the photo, there is a large, metal barrel lying on its side on a concrete floor.",
+ "A barrel is a wooden or metal container with a rounded top and bottom, used for storing food and other items.",
+ "A photo of a barrel would show a cylindrical container with a curved top and bottom, typically made of wood or metal.",
+ " of applesThis photo is of a large, wooden barrel filled to the brim with fresh, red apples.",
+ "The photo is of a large, metal barrel.",
+ "The photo is of a large, brown barrel with a small metal handle on the side.",
+ "A large wooden barrel is sitting in the middle of a room.",
+ "This is a photo of a barrel.",
+ "A barrel is a large, cylindrical container used for storing liquids or dry goods.",
+ "A barrel typically has a round shape and is made of wood or metal.",
+ "A barrel is a large, cylindrical container with a flat top and bottom.",
+ "A barrel is a cylindrical container with a curved top and bottom.",
+ "A barrel is a large, cylindrical container that is used to store liquids or dry goods.",
+ "a barrel generally has a round shape and is often used to store liquids or other substances.",
+ "A barrel looks like a large wooden storage container with a curved shape.",
+ "The most common type of barrel is a cylindrical drum made of metal, plastic, or wood.",
+ "A barrel is a large, usually cylindrical container with a flat top and bottom.",
+ "A barrel is a large, cylindrical container made of wood or metal, with a flat top and bottom."
+ ],
+ "leopard": [
+ "A leopard has a short, stocky body with long legs and a long tail.",
+ "A leopard is a heavily built cat with short, round ears, long legs, and a long tail.",
+ "A leopard has a yellow coat with black spots.",
+ "A leopard has a coat of short, black spots on a background of pale yellow to deep gold.",
+ "The leopard is a spotted big cat that is closely related to the lion, tiger, and jaguar.",
+ "Leopards have a spotted coat with rosettes, which are clusters of spots surrounded by darker fur.",
+ "A leopard is a big cat that has a brown coat with black spots.",
+ "A leopard is a big cat with a yellowish to light brown coat and black spots.",
+ "A leopard has a yellow coat with black spots.",
+ "A leopard is a member of the Felidae family and the smallest of the four \"big cats\", the other three being the tiger, lion and jaguar.",
+ "This photo shows a leopard lounging in a tree.",
+ "A leopard is a large, carnivorous cat with a spotted coat.",
+ "The photo is of a leopard lying down on some rocks in a Savannah.",
+ "This photo is of a very large and muscular leopard with its mouth open in a roar.",
+ "The photo is of a leopard that is lying down on a tree branch.",
+ "Jaguar on the prowl in Pantanal, Brazil.",
+ "This photo shows a leopard resting in a tree.",
+ "The photo is of a leopard that is up in a tree.",
+ "A leopard is a large, spotted cat.",
+ "In the photo, a leopard is perched atop a tree branch, its body facing the camera with head turned to the side.",
+ "A leopard is a large, wild cat that has a spotted coat, long legs, and a long tail.",
+ "A leopard is a large, wild cat that has a spotted coat.",
+ "A leopard is a large, predatory cat with a spotted coat.",
+ "A leopard is a medium-sized, spotted cat.",
+ "A leopard is a large, spotted cat.",
+ "A leopard is a yellowish-brown to grayish-black spotted or rosetted cat with short, black-tipped ears.",
+ "A leopard is a large spotted cat.",
+ "A leopard is a type of big cat that is closely related to the lion, tiger, and jaguar.",
+ "The leopard is a spotted cat that is similar in appearance to a jaguar.",
+ "Leopards have short, yellow-gold fur with black spots."
+ ],
+ "schooner": [
+ "A schooner is a tall, narrow sailing ship with at least two masts, typically rigged with fore-and-aft sails.",
+ "A schooner is a type of sailing vessel that has two or more masts, with the foremast being shorter than the mainmast.",
+ "A schooner usually has two or more masts, with the foremast being shorter than the mainmast.",
+ "A schooner is a type of sailing vessel with fore-and-aft sails on two or more masts, the foremast being shorter than the main and no taller than the mizzenmast.",
+ "A schooner is a type of sailing vessel with fore-and-aft sails on two or more masts, the foremast being shorter than the main and no taller than the mizzen.",
+ "A schooner is a type of sailing vessel with fore-and-aft sails on two or more masts.",
+ "A schooner is a sailboat with two or more tall masts.",
+ "A schooner is a type of sailboat with at least two masts, the foremast and the mainmast, with the mainmast being taller than the foremast.",
+ "A schooner is a sailing vessel with two or more masts, typically with fore-and-aft rigs.",
+ "A schooner typically has two or more masts, with the foremast being shorter than the mainmast.",
+ "This photo is of a schooner sailing on the water.",
+ "The schooner is a traditional sailing vessel with two or more masts.",
+ "The photo is of a large wooden sailing vessel with tall white sails.",
+ "The photo is of a large, sailboat with multiple levels.",
+ "In the photo, the schooner is sailing on the open sea.",
+ "A photo of a schooner would show a tall, narrow sailing ship with multiple masts.",
+ "A schooner is a yacht with at least two masts, the foremost of which is usually taller than the after mast.",
+ "The photo is of a schooner sailing on the open sea.",
+ "The photo shows a three-masted schooner sailing on the open sea.",
+ "A schooner is a type of sailing vessel with two or more masts.",
+ "A schooner is a sailboat with two or more masts.",
+ "A schooner typically has two or more masts, with the foremast being shorter than the mainmast.",
+ "The classic schooner has two masts, with sails on each.",
+ "A schooner is a type of sailing ship with two or more masts.",
+ "A schooner typically has two or more masts, with the foremast being shorter than the mainmast.",
+ "A classic schooner has two masts, with the forward mast being shorter than the aft mast.",
+ "There is no one answer to this question as the appearance of a schooner can vary depending on its purpose, size, and history.",
+ "A schooner typically has two or more masts, with the foremast being shorter than the mainmast.",
+ "A schooner typically has two or more masts, with the foremast being shorter than the mainmast.",
+ "A schooner is a sailing vessel with two or more masts."
+ ],
+ "cellphone": [
+ "A cellphone typically has a rectangular shape with a touchscreen display.",
+ "A cellphone typically has a touchscreen display, a buttons or keypad, a microphone, a speaker, and a slot for a SIM card.",
+ "A cellphone is a small, hand-held electronic device that has a screen, a keyboard, and a number of other input and output devices.",
+ "A cellphone typically has a large screen on the front that is used for viewing and interacting with apps, a small button on the front that is used for returning to the home screen, and a back button on the side that is used for going.",
+ "Most cell phones have a rectangular shape with a color screen.",
+ "Small, rectangular device that is typically held in the hand.",
+ "A cellphone typically has a rectangular shape with a color screen.",
+ "A cellphone is a handheld, portable device that allows you to make and receive phone calls.",
+ "A cellphone typically has a bright display screen, a keyboard or touchpad for entering information, and a variety of buttons for making phone calls and accessing apps.",
+ "A cellphone is a handheld personal communication device that has a display screen, keypad, and microphone.",
+ "This is a photo of a white iPhone on a marble counter.",
+ "The photo is of a cellphone.",
+ "This photo is of a modern cellphone.",
+ "The photo is of a Samsung Galaxy S20 Ultra smartphone in the color black.",
+ "In the photo, there is a rose-gold colored cellphone with a dark screen.",
+ "This is a photo of a phone with a light blue case.",
+ "The photo is of a woman holding a cellphone up to her ear.",
+ "The phone is a light blue color with a black screen.",
+ "A photo of a cellphone may show the phone itself, or it may show someone using the phone.",
+ "This photo shows a basic, rectangular cellphone with a keypad on the front.",
+ "Cellphones come in a variety of shapes and sizes, but they all have a few things in common.",
+ "Most cellphones these days have a touch screen and look like a mini computer.",
+ "A cellphone is a small rectangular device that is typically held in the hand.",
+ "A cellphone is a small hand-held device that has a keypad or touchscreen for dialing and a receiver for holding to your ear.",
+ "A typical cellphone is a small, handheld device with a flat screen.",
+ "Most cellphones have a touch screen and an on/off button.",
+ "A cellphone typically has a small screen on the front of the device, with a keyboard underneath.",
+ "A cellphone typically consists of a small display screen, a keypad or touchscreen for input, and one or more antennas.",
+ "A cellphone can look like a handheld computer, a small television, or a cordless telephone.",
+ "A cellphone usually has a display screen where you can see what you are typing, playing, or watching."
+ ],
+ "panda": [
+ "Panda bears are large, bear-like animals with black and white fur.",
+ "Pandas are large, bear-like animals with black and white fur.",
+ "A panda is a large, black and white bear-like creature with short forelegs and a long hind leg.",
+ "A panda is a large, bear-like creature with black and white fur.",
+ "A panda is a bear that has white fur with black patches around its eyes, ears, and body.",
+ "A panda is a large, black-and-white bear-like mammal with a round body, short legs, and a long tail.",
+ "Panda bears typically have black and white fur.",
+ "A panda is a large, black and white bear-like mammal with short front legs and a long tail.",
+ "A panda has black fur on its ears, eye patches, muzzle, legs, and arms.",
+ "A panda is a black and white bear.",
+ "A panda is eating bamboo in a forest.",
+ "This photo is of a panda bear that is eating bamboo.",
+ "In the photo, a panda is eating bamboo in a forest.",
+ "There is a large panda in the center of the photo lying down on its stomach.",
+ "The photo is of a panda standing in a bamboo forest.",
+ "In the photo, a panda is lounging on a tree branch.",
+ "This panda is eating bamboo in its natural habitat.",
+ "a panda with black and white fur is eating bamboo in a forest.",
+ "In this photo, there is a panda lying on its back in the grass.",
+ "The photo is of a panda eating bamboo in a forest.",
+ "Question is too vague, and there are different types of pandas.",
+ "A panda is a bear-like mammal with white and black fur.",
+ "A panda looks like a large black and white bear.",
+ "A panda looks like a bear with black fur and white patches.",
+ "A panda looks like a bear with black and white fur.",
+ "A panda has black and white fur, and looks like a bear.",
+ "A panda is a bear-like mammal with heavy black fur and white patches around the eyes, over the ears, and across the body.",
+ "A panda looks like a bear with black and white fur.",
+ "A giant panda has a black and white coat.",
+ "A panda looks like a black and white bear."
+ ],
+ "revolver": [
+ "A revolver typically has a cylindrical chamber that revolves around a central axis and is capable of holding six or more rounds of ammunition.",
+ "A revolver is a cylindrical device with a handle that contains six chambers.",
+ "A handgun that has a rotating cylinder containing six or seven cartridges.",
+ "A revolver typically has a cylindrical chamber that rotates along with the barrel.",
+ "A revolver looks like a handgun with a cylindrical chamber that revolves around a central axis.",
+ "A revolver typically has a cylindrical chamber that revolves around a central axis in the body of the gun.",
+ "A revolver typically has a cylindrical chamber that rotates to align the cartridges with the barrel.",
+ "A revolver is a handgun with a cylinder that contains the gun's chambers.",
+ "A revolver typically has a cylindrical chamber that revolves around a central axis and is filled with cartridges.",
+ "A revolver is a hand-held, cylinder-shaped gun that contains a rotating drum of six or more bullets.",
+ "The photo is of a black revolver with a silver barrel.",
+ "A revolver is a handgun that has a rotating cylinder containing six or seven chambers.",
+ "The photo shows a revolver lying on a bed of grass.",
+ "In the photo, there is a silver revolver with a black grip.",
+ "A revolver is a hand gun that has a cylindrical chamber that rotates to align the bullet with the barrel.",
+ "The photo is of a silver revolver with a black grip.",
+ "The photo is of a revolver pistol on a white background.",
+ "This photo is of a revolver.",
+ "The photo is of a black revolver with a silver handle.",
+ "The revolver is a black and silver handgun with a cylindrical chamber that holds six bullets.",
+ "A revolver is a type of handgun that has a cylinder with multiple chambers for holding ammunition.",
+ "A revolver is a type of handgun that has a rotating cylinder with several chambers.",
+ "A revolver is a cylindrical handgun with a revolving chamber of bullets.",
+ "A revolver generally looks like a handgun, with a cylindrical chamber that holds the bullets.",
+ "A revolver typically has a cylindrical chamber into which the round is inserted and a barrel through which the round is fired.",
+ "A revolver typically has a cylindrical shape with a handle attached to one side.",
+ "A revolver is a handgun with a revolving cylinder.",
+ "There are many types of revolvers, but they all have a few things in common.",
+ "A revolver typically looks like a handgun with a cylindrical chamber that revolves around a central axis.",
+ "A revolver typically has a cylindrical shape and contains anywhere from 2 to 9 chambers that each hold a bullet."
+ ],
+ "cougar face": [
+ "A cougar cat's face is typically long and slender, with high cheekbones, a pointed chin, and large, almond-shaped eyes.",
+ "A cougar cat has a face that is long and slim with large ears that sit high on its head.",
+ "The face of a cougar cat looks like a small, pointed face with big ears.",
+ "A cougar's face is long and thin, with large ears and long whiskers.",
+ "A face of a cougar cat looks like a house cat with somewhat pointy ears, whiskers, and a short tail.",
+ "The face of a cougar is long and slender, with pointed ears and a short muzzle.",
+ "A cougar cat's face is similar to that of a house cat, but with some distinct differences.",
+ "The face of a cougar cat looks like a long, narrow face with small, pointed ears.",
+ "A cougar has a long, round head with erect ears and large, powerful hind legs.",
+ "Cougar cats have large, round heads with small, pointed ears.",
+ "The photo is of a close-up of a cougar's face.",
+ "This photo shows the face of a cougar cat.",
+ "The photo shows a close-up of a cougar's face, with its sharp features and intense gaze.",
+ "A cougar cat has a large head, long body, and short legs.",
+ "This photo shows the face of a cougar cat up close.",
+ "A cougar cat has a long, slender face with sharp features.",
+ "The photo is of a cougar cat's face looking to the side with its mouth slightly open.",
+ "This photo depicts the face of a cougar cat.",
+ "A cougar cat has a long, thin face with a pointed nose.",
+ "The photo is of a cougar cat's face with its mouth open.",
+ "A cougar cat's face looks like a typical domestic cat's face, but with some distinct differences.",
+ "There is no set answer for what a cougar's face looks like since there is a wide variety of cougar subspecies.",
+ "A cougar cat's face is typically long and narrow.",
+ "The face of a cougar cat looks like the face of a house cat, except that it is much larger.",
+ "A cougar has a slightly longer head and narrower face than a domestic cat.",
+ "The face of a cougar cat is typically long and slender, with large eyes and sharp features.",
+ "Cougars have a wide range in size, but they are typically smaller than lions or tigers.",
+ "There is not just one look for a cougar cat's face, as there is a lot of variation in the way they can look.",
+ "There is no definitive answer to this question as the appearance of cougar cats can vary greatly depending on their individual genetics and where they are from.",
+ "A cougar cat looks like a small lion."
+ ],
+ "lobster": [
+ "A lobster is a large seafood creature that has a hard shell, long legs, and big claws.",
+ "Lobsters are large crustaceans with long bodies and large claws.",
+ "A lobster is a large, hard-shelled seafood creature with long legs and large claws.",
+ "A lobster has a hard, spiny shell and two large claws.",
+ "Lobsters are large, 10-legged crustaceans with a hard shell.",
+ "A lobster is a large, hard-shelled, crab-like creature with two large claws.",
+ "A lobster is a large, marine crustacean with a hard shell and long, mobile claws.",
+ "A lobster is a marine crustacean that has a hard shell and eight legs.",
+ "A lobster is a shellfish that has a long body with jointed legs.",
+ "A lobster is a crustacean that has a hard shell and is often green, blue, or brown in color.",
+ "This photo is of a large lobster that is cooked and ready to be eaten.",
+ "The photo is of a lobster on a plate.",
+ "In the photo, a lobster is shown from above, with its large claws raised in the air.",
+ "The photo shows a lobster in a pot of boiling water.",
+ "A lobster is a sea creature with a hard shell.",
+ "A lobster photo would show a large, crustacean-like creature with two large claws, eight smaller legs, and a long tail.",
+ "This is a photo of a lobster.",
+ "This photo shows a lobster on a white plate with a lemon wedge.",
+ "This is a photo of a lobster.",
+ "The photo is of a lobster on a white plate.",
+ "A lobster looks like a red, black, and white crab.",
+ "A lobster looks like a large, dark-colored crab.",
+ "Lobsters are red and have large claws.",
+ "A lobster looks like a large sea creature with two big claws, a hard shell, and a long tail.",
+ "A lobster typically has two large claws, an elongated body, and a hard outer shell.",
+ "A lobster is a type of shellfish that has a hard outer shell and 10 legs.",
+ "A lobster is a large crustacean with eight legs and two large pincers.",
+ "A lobster is a large, shellfish with eight legs.",
+ "A lobster looks like a large, dark-colored freshwater or saltwater crustacean with large claws.",
+ "A lobster looks like a large, red and black crustacean with large claws."
+ ],
+ "menorah": [
+ "A menorah has seven candles (or eight, depending on the holiday) that are each set in a holder.",
+ "A menorah is a seven-branched candelabra used in the Jewish temple.",
+ "A menorah is a candelabra with nine candles, used in the Jewish holiday of Hanukkah.",
+ "A menorah is a Jewish candelabrum with eight or nine branches.",
+ "A menorah is a seven-branched candelabrum that is lit during the eight-day holiday of Hanukkah.",
+ "A menorah is a candlestick that has eight branches.",
+ "A menorah is a seven-branched candelabra that is used to light Hanukkah candles.",
+ "A menorah is an ancient Jewish lamp that has nine candles, one for each night of Hanukkah.",
+ "A menorah is a nine-branched candelabra used to light candles on Hanukkah.",
+ "The menorah looks like a nine-branched candelabra.",
+ "The photo is of a silver menorah with eight branches.",
+ "A menorah is a seven-branched candelabra used in the religious ritual of Hanukkah.",
+ "A menorah is a nine-branched candelabra used during the eight-day Jewish holiday of Hanukkah.",
+ "A menorah is a nine-branched candelabra used by Jews during the eight-day holiday of Hanukkah.",
+ "The photo is of a menorah that is lit.",
+ "The photo shows a menorah with seven branches.",
+ "A menorah is a nine-branched candelabra used in the celebration of Hanukkah.",
+ "The photo shows a nine-branched menorah in front of a white background.",
+ "This is a photo of a traditional menorah.",
+ "This is a photo of a menorah.",
+ "A menorah is a nine-branched candelabrum used during the eight-day Jewish holiday of Hanukkah.",
+ "A menorah typically has nine branches, and is in the shape of a candelabra.",
+ "A menorah is a seven-branched candelabrum that is lit during the eight-day holiday of Hanukkah.",
+ "A menorah is a candelabra with seven or nine branches that is used in the Jewish holiday of Hanukkah.",
+ "A menorah is a type of candelabra that has seven or nine arms.",
+ "A menorah is a nine-branched candelabra that was used in the ancient temple in Jerusalem.",
+ "A menorah is a nine-branched candelabra that is used to lightHanukkah candles.",
+ "A menorah has seven branches, each one with a holder for a candle.",
+ "A menorah is a seven-branched candelabrum used in the Jewish holiday of Hanukkah.",
+ "A menorah is a candelabrum with nine branches, each of which holds a candle."
+ ],
+ "lotus": [
+ "A lotus is a beautiful flower that has petals that are usually pink, red, or white.",
+ "A lotus is a flower that has a long stem and large petals.",
+ "A lotus is a beautiful flower that grows in ponds and has large, green leaves.",
+ "A lotus flower is typically white or pink and has a large blossom with several petals.",
+ "A lotus is a large, flowering aquatic plant that can grow up to three feet in height.",
+ "A lotus is a flower that has a long stem and large pedals that are usually white or pink.",
+ "A lotus (Nelumbo nucifera) is a water plant with large, showy flowers that floats on the water's surface.",
+ "A lotus flower is a beautiful, white flower that has a long stem and grows in water.",
+ "The lotus is a flower that has a large petal in the center and smaller petals around it.",
+ "A lotus is a beautiful pink flower that has large petals and a long stem.",
+ " flowerThe photo is of a pink lotus flower with green leaves and a yellow center.",
+ "In the photo, there is a lotus flower in a pond with its pedals reaching up towards the sky.",
+ " flowerIn the photo, there is a lotus flower with several large pedals.",
+ "The photo is of a bright pink lotus in a field of green leaves.",
+ " flowerA Lotus flower is a beautiful flower that has long stem and big pedals.",
+ "A lotus is a beautiful flower that grows in murky water and rises above the surface to bloom in the sunlight.",
+ " flowerThe photo is of a pink lotus flower in a pond.",
+ " flowerThe photo shows a lotus flower in full bloom, with its petals open to reveal the pistil and stamens in the center of the flower.",
+ "In this photo, a lotus flower is blooming in a pond.",
+ "The photo is of a lotus flower in a pond.",
+ "There is no one answer to this question as the lotus flower can come in a variety of colors, including pink, white, blue, and yellow.",
+ "A lotus is a flower that has a big center and petals that go around it.",
+ "The lotus flower is a beautiful pinkish color and has a very unique shape.",
+ "A lotus flower is a beautiful, traditional flower that is often used in religious ceremonies and as a decoration.",
+ "A lotus is a flower with a large center and petals that curl back.",
+ "A lotus typically has large, thick leaves that float on the water's surface.",
+ "A lotus is a flower that has a round, flat center with petals that curl up around the sides.",
+ "A lotus typically has large, flat leaves that float on the water's surface.",
+ "A lotus typically has large, oval-shaped leaves and large flowers that bloom in a range of colors, including pink, white, yellow, blue, and purple.",
+ "A lotus is a flower that has petals that are large and wide, and the center of the flower is often a deep yellow or orange color."
+ ],
+ "stapler": [
+ "A stapler is a small device used to join pieces of paper together by fastening them with metal staples.",
+ "Most staplers are silver or grey and made of metal.",
+ "A stapler is a handheld device used to push metal staples through paper and fasten them in place.",
+ "A stapler is a small hand-operated machine that joins pages of paper together by driving metal staples through them.",
+ "A stapler is a small machine that is used to join pieces of paper together by pushing staples through them.",
+ "A stapler is a device that fastens together sheets of paper by pushing a thin metal strip through the top sheet and bending the strip back on itself.",
+ "A typical stapler is a hand-operated device that joins pages of paper or similar material by driving steel staples through the sheets and folding their ends.",
+ "A stapler is a metal or plastic handheld device used to join sheets of paper or other thin material by driving a thin metal staple through the sheets and bending the ends.",
+ "A stapler is a small handheld tool used to fasten sheets of paper together by driving staples into them.",
+ "A stapler is a small hand-operated machine that is used to fasten together sheets of paper by pressing a thin metal strip through the top sheet and folding the ends down to hold the sheets together.",
+ "The stapler is on a desk with several other office supplies.",
+ "A staple is a thin metal wire with sharp ends that is used to fasten sheets of paper together.",
+ "I see a black stapler on a white surface.",
+ "This is a photo of a black stapler.",
+ "In the photo, there is a stapler atop a white piece of paper.",
+ "The stapler is a small, hand-held device used for fastening papers together.",
+ "A stapler is a small hand-held mechanical device used to fasten papers together.",
+ "This is a photo of a stapler.",
+ "A stapler held in a human hand.",
+ "A stapler is a small mechanical device that joins pages of paper together by driving metal staples into the pages.",
+ "A stapler is typically a small hand-held device with a small anvil on one end.",
+ "The picture below is of a stapler.",
+ "A stapler looks like a small hand-held machine with a long handle.",
+ "Image result for what does a stapler look like.",
+ "A stapler looks like a small hand-held device with a long nose.",
+ "A stapler typically has a rectangular base and a cylindrical body.",
+ "A stapler typically consists of a base and a long arm.",
+ "A stapler looks like a small hand-held machine with a handle on one end and a rectangular base on the other end.",
+ "A stapler looks like a small hand-held machine with a small hole in the front.",
+ "Most staplers have a similar rectangular shape with a curved handle on the top and a flat base on the bottom."
+ ],
+ "crocodile": [
+ "Most crocodiles are dark green in color, with a lighter underbelly.",
+ "A crocodile is a reptile with a long, muscular body, a long tail, and a squid-like head with sharp teeth.",
+ "A crocodile is a large reptile that has a long snout, a heavy body, and a long tail.",
+ "Crocodiles are large, reptilian predators with long bodies, short legs, and long tails.",
+ "A crocodile is a large reptile with a long, narrow snout and sharp teeth.",
+ "A crocodile has a long, narrow snout and 4 short legs.",
+ "Crocodiles are large reptiles that live in fresh water rivers and lakes in tropical areas.",
+ "A crocodile is a large, scaly reptile with a long tail, sharp teeth, and a triangular head.",
+ "A crocodile is a large reptile that has a long body, a long tail, and a head with sharp teeth.",
+ "A crocodile is a legless, reptilian creature with scaly skin and a long tail.",
+ "This photo is of a crocodile that is stretching out on the ground.",
+ "The photo is of a large crocodile with its mouth open, revealing its sharp teeth.",
+ "The photo shows a large crocodile with its mouth open, revealing sharp teeth.",
+ "In the photo, a crocodile is swiming in a river.",
+ "In this photo, a crocodile is sunning itself on a riverbank.",
+ "This photo is of a large crocodile with its mouth open.",
+ "The crocodile is a large reptile that lives in rivers and swamps in tropical areas.",
+ "A crocodile is a large, gray-green reptile with a long snout, sharp teeth, and a long, thick tail.",
+ "In the photo, there is a large crocodile lying in the sun near the water's edge.",
+ "The photo is of a large crocodile lying on the ground with its mouth open.",
+ "A crocodile is a large reptile that has a long snout, a long tail, and short legs.",
+ "A crocodile has a long, thin body with short legs.",
+ "Big and scaly with sharp teeth.",
+ "A crocodile is a large, scaly reptile with a long, narrow snout.",
+ "A crocodile is a large reptile with a long snout, sharp teeth, and a hard, scaly skin.",
+ "A crocodile is a semi-aquatic reptile with a long, slender snout, sharp teeth, and a scaly hide.",
+ "A crocodile is a large reptile with a long snout and a scaly hide.",
+ "Crocodiles are typically dark green or brown in color.",
+ "Crocodiles are long, green reptiles with sharp teeth.",
+ "A crocodile has a long snout, four short legs, and a long tail."
+ ],
+ "chair": [
+ "A chair is typically a piece of furniture with a raised surface supported by legs, used to seat a single person.",
+ "A chair is typically a piece of furniture with a raised surface supported by legs, designed to seat one person.",
+ "A chair typically has four legs, a back, and a seat.",
+ "A chair typically has four legs, a back, and a seat.",
+ "A chair is a piece of furniture that is meant to be sat in.",
+ "A chair typically has four legs and a backrest.",
+ "A chair is typically a piece of furniture with a raised surface supported by legs, used for sitting.",
+ "A chair usually has four legs, a back, and a seat.",
+ "Chairs have four legs and a back.",
+ "A chair typically has four legs, a seat, and a back.",
+ "This chair is made of wood and has a cushion on the seat.",
+ "This photo is of a blue chair with a white cushion.",
+ "This chair is brown and has a curved back.",
+ "The photo is of a blue chair with a white cushion.",
+ "This chair is made of wood and is a simple design.",
+ "A photo of a chair may show a close up of the fabric on the seat, or it may show the chair from a distance, in a room with other furniture.",
+ "A photo of a chair might feature a close-up of the fabric on the seat or the wood grain on the legs.",
+ "This chair is made of wood and has a cushion on the seat.",
+ "The chair in the photo is a brown leather armchair with a high back.",
+ "A white plastic chair with a curved backrest.",
+ "Most chairs have four legs, a back, and a seat.",
+ "An ordinary chair has four legs, a seat, and a back.",
+ "The standard chair has four legs, a backrest, and a seat.",
+ "A chair typically has four legs, a back, and a seat.",
+ "A chair typically has four legs, a back, and a seat.",
+ "This is a difficult question.",
+ "A chair typically has four legs, a back, and a seat.",
+ "A chair typically has four legs, a back, and a seat.",
+ "A chair looks like a piece of furniture with a back and seat that is meant for sitting in.",
+ "A chair generally has four legs, a back, and a seat."
+ ],
+ "water lilly": [
+ "A water lily is a flower that grows in water.",
+ "A water lilly is a floating aquatic plant with large, round, flat leaves that are attached to a long stem.",
+ "A water lily is a flower that grows in water.",
+ "A water lily has large, round, green leaves that float on the surface of the water.",
+ "A water lily has large, round leaves that float on the surface of the water and a long stem that grows down into the depths of the pond.",
+ "A water lily is a flowering plant that grows in shallow water.",
+ "A water lily is a flower that has a lotus-like appearance and float on the water's surface.",
+ "A water lily has large, glossy green leaves and a beautiful white or pink flower.",
+ "A water lily has large, round, green leaves that float on the surface of the water.",
+ "A water lily is typically a white or yellow flower that floats on the surface of water.",
+ "The water lilly is floating in a pond with its green leaves spread out around it.",
+ "One could see a water lily in a pond with its leaves floating on the surface of the water.",
+ "This is a beautiful photo of a water lily in a blue pond.",
+ "A water lily is a large, flat flower that floats on top of a pond or lake.",
+ "A water lily is a flower that floats on the surface of a pond.",
+ "This photo is of a lone water lily in a small pond.",
+ "The photo is of a water lily in a pond.",
+ "A water lily is a floating plant with large, round leaves that lay flat on the water's surface.",
+ "A water lilly is a plant with large, soft leaves that float on the surface of water.",
+ "A photo of a water lily shows a beautiful flower floating in a serene pond.",
+ "A water lily is a white or yellow flower that floats on water.",
+ "A water lily is a floating aquatic plant with large, webbed leaves and showy flowers.",
+ "Water lilies are large, round flowers that float on the surface of ponds and lakes.",
+ "A water lily typically has large, round petals that are attached to a central point.",
+ "Water lilies are a type of aquatic plant that have large, flat leaves that float on the surface of the water.",
+ "A water lily is a flower that grows in water.",
+ "A water lily is a large, floating plant with a round, green leaves and a white or yellow flower.",
+ "Water lillies have large, flat leaves that float on the water's surface.",
+ "A water lilly can either be white or blue and has a big petal that goes around the outside.",
+ "A water lily is a flower that typically has a yellow or white petal with a green stalk."
+ ],
+ "helicopter": [
+ "A helicopter typically has one or two large rotors that spin around to lift the vehicle into the air.",
+ "Helicopters have long, slender bodies with rotors on top.",
+ "A helicopter typically has one large rotor blade on top and a smaller rotor blade on the tail.",
+ "A helicopter is a rotary-wing aircraft that flies by taking advantage of the lift produced by one or more horizontal rotors.",
+ "A helicopter has one large rotor blade on top and one smaller rotor blade on the back.",
+ "A helicopter typically has a single rotar blade on top and two landing skids or wheels.",
+ "A helicopter is a large machine with metal blades that rotate on top.",
+ "A helicopter typically has one large rotor blade on top and a smaller rotor blade on the tail.",
+ "A helicopter typically has one or two large rotors that spin horizontally.",
+ "A helicopter is a type of aircraft that has large rotors that lift it into the air.",
+ "In the photo, a helicopter is flying over a cityscape.",
+ "The photo is of a helicopter flying over a green landscape.",
+ "This photo is of a helicopter flying over a body of water.",
+ "\":\"A photo of a helicopter would show the helicopter in the air with its blades spinning.",
+ "This photo is of a helicopter landing on a helipad.",
+ "The photo is of a sleek, modern helicopter with aHmm blue and silver paint job.",
+ "The photo is of a helicopter.",
+ "This photo shows a helicopter flying in the sky.",
+ " A helicopter is a type of rotorcraft in which lift and thrust are supplied by rotors.",
+ "This photo is of a large, sleek helicopter with a long body and wide rotor blades.",
+ "A helicopter has a large set of rotors on top, and sometimes a smaller set of rotors on the back.",
+ "Most helicopters have a Rotor above the cockpit that spins around.",
+ "A helicopter generally looks like a small, flying car.",
+ "A helicopter looks like an airplane with blades on top.",
+ "A helicopter typically has one or two large rotors that spin to lift and propel the machine through the air.",
+ "A helicopter typically has one large rotor blade on top and one smaller rotor blade on the back.",
+ "A helicopter is a large aircraft with one or more long blades that rotate above it.",
+ "Most helicopters have a turbine engine with a rotor on top.",
+ "A helicopter has a large rotor blade on top and usually two smaller rotor blades on the side.",
+ "\nMost helicopters have a single large rotor blade on top, and a smaller rotor blade on the bottom."
+ ],
+ "inline skate": [
+ "A inline skate consists of a boot with wheels attached to the bottom.",
+ "Inline skates generally have two to five polyurethane wheels arranged in a single line by metal frames.",
+ "A pair of inline skates typically consists of a pair of boots with two to five polyurethane wheels bolted to the bottom.",
+ "A inline skate has a boot that is attached to a frame.",
+ "Inline skates look like regular shoes with blades attached to the bottom.",
+ "Inline skates typically have two to five polyurethane wheels arranged in a single row and mounted on a metal or plastic frame.",
+ "A inline skate typically has three to five wheels arranged in a single line down the center of the foot platform, with the front and back wheels typically larger than the middle wheels.",
+ "Inline skates look like traditional ice skates, but with the blade attached to the boot in a single line, rather than two parallel lines.",
+ "A inline skate is a type of roller skate that has four to five wheels arranged in a line instead of the more traditional two rows of two or three wheels.",
+ "A typical inline skate has a shoe with a boot attached to a metal frame that holds four or five wheels in a straight line.",
+ "A woman is skating down a city street.",
+ "boardThe photo shows a person inline skating on a city street.",
+ "boarderThe skater is wearing black and white shoes with brightly colored laces.",
+ "boardThe photo is of a black and red inline skateboard.",
+ "The photo is of a person inline skating on a sidewalk.",
+ "The photo is of a person standing on inline skates.",
+ "The photo is of a black inline skate with a white and blue checkerboard pattern on the top.",
+ "Inline skating is a type of roller skating where the skater's boots are attached to a single, long blade.",
+ "boarderThe photo is of a man inline skating down a concrete path.",
+ "boarderA photo of an inline skateboarder might show someone skating down a sidewalk or street, doing tricks in a skate park, or competing in a race or competition.",
+ "Inline skates look like skates with only two wheels.",
+ "The inline skate consists of a boot with a frame that holds four or five wheels in a straight line.",
+ "inline skate - noun - a shoe with a blade attached to the bottom, used for skating on pavement or other hard surfaces.",
+ "Inline skates look like a pair of normal shoes with two to five wheels in a line attached to the bottom of the shoe.",
+ "Inline skates look like normal shoes, except that they have a row of wheels in the middle of the sole.",
+ "Inline skates look like regular roller skates, except that the wheels are in a line instead of being in pairs.",
+ "Inline skates look like a mix between a regular shoe and a skate.",
+ "A inline skate is a type of roller skate that has wheels in a line, rather than in pairs.",
+ "A inline skate consists of a boot with three to five wheels attached to the bottom.",
+ "They look like regular shoes, but with wheels attached to the bottom."
+ ],
+ "minaret": [
+ "A minaret is an Islamic architectural feature that is tall and slender, and typically serves as a lookout or an entrance to a mosque.",
+ "A minaret typically has a tall, slender shaft with a conical or onion-shaped crown.",
+ "A minaret looks like a slender tower attached to a mosque.",
+ "A minaret is a slender tower with an balcony, typically part of a mosque, from which a muezzin calls Muslims to prayer.",
+ "A minaret is typically a slender, tall tower that is attached to a mosque.",
+ "A minaret typically has a square or octagonal base, and is often tall and slender.",
+ "A minaret typically has a square or octagonal base, and is tall and slender, with an arched or conical roof.",
+ "A tall, slender tower with a balcony from which a muezzin calls Muslims to prayer five times a day.",
+ "A minaret is a tall, thin spire that is typically found on top of a mosque.",
+ "A minaret is a slim, tall tower that is attached to a mosque.",
+ "A minaret is a type of architectural feature that is most commonly associated with Islamic mosques.",
+ "A minaret is a tall, slender tower typically found next to mosques.",
+ "A minaret is a tall, slender tower that is part of a mosque.",
+ "I see a photo of a minaret with its beautiful architecture.",
+ "A photo of a minaret shows a tall, slender tower that is typically part of a mosque.",
+ "A minaret is a tall, narrow, cylindrical tower that is part of a mosque.",
+ "A minaret is a slender tower that is attached to a mosque.",
+ "A minaret is a tall, slender tower that is part of a mosque.",
+ "The photo is of a tall, slender, cylindrical tower with a pointed top.",
+ "The photo is of a minaret, a tall, slender tower that is part of a mosque.",
+ "A minaret looks like a tall, thin tower with a round balcony near the top.",
+ "A minaret is a tall, slender tower that is typically part of a mosque.",
+ "A minaret is an iconic part of a mosque, and is typically a tall, slender spire with a balcony from which a muezzin calls Muslims to prayer.",
+ "A minaret is a tall, slender tower that is part of a mosque.",
+ "A minaret is a tall, slender tower that is attached to a mosque.",
+ "A minaret is a tall, slender tower that is part of a mosque.",
+ "A minaret is a tall, slender tower that is typically part of a mosque.",
+ "A minaret is a tall, slender tower that is part of a mosque.",
+ "A minaret is a tall, slender tower that is part of a mosque.",
+ "A minaret typically has a square or octagonal base, and is much taller than it is wide."
+ ],
+ "starfish": [
+ "A starfish typically has five arms and is covered in small spikes.",
+ "A starfish is typically red, orange, or brown and has five arms that radiate from a central disk.",
+ "A starfish has a disc-shaped body with five or more arms that radiate from the center.",
+ "Starfish are usually red, orange, or brown, but some species are blue, gray, black, or purple.",
+ "A starfish is a small, star-shaped animal that lives in the ocean.",
+ "A starfish typically has five arms, and each arm has small tubed feet.",
+ "A starfish is usually red, orange, or brown and has five arms that come out from a central point.",
+ "A starfish is a marine invertebrate with a radial symmetry.",
+ "A starfish typically has five arms, although some species can have many more.",
+ "Starfish have a radial symmetry and five arms.",
+ "The photo is of a starfish on a beach.",
+ "The photo is of a starfish against a black background.",
+ "The photo is of a starfish on a sandy beach.",
+ "This photo is of a blue starfish on a sandy beach.",
+ "This starfish is a vivid orange color with small black spots dotting its surface.",
+ "The photo shows a large, orange starfish on a coral reef.",
+ "This photo shows a close-up of a starfish, with its five arms extended.",
+ "The photo is of a starfish on a sandy beach with waves crashing in the background.",
+ "A photo of a starfish might show a close-up of the starfish's colorful body, or it might show the starfish in its natural habitat, like a coral reef.",
+ "A photo of a starfish might show a closeup of the creature's textured skin, its five arms, and its central mouth.",
+ "A starfish can come in many different shapes, colors, and sizes, but they all have five arms and are found in the ocean.",
+ "A starfish is a five-armed creature that has a disk-shaped body.",
+ "A starfish usually has five arms and is a red, orange, or brown color.",
+ "A starfish typically has five arms and is covered in small spines.",
+ "A starfish typically has five arms, although some species can have more.",
+ "Some starfish look like a regular star, while some look more like a circle with arms sticking out.",
+ "A starfish is a type of sea creature that has a hard, spiny outer body and five arms that radiate out from a central point.",
+ "A starfish is a small, spiny creature that typically has five arms and lives in the ocean.",
+ "A starfish looks like a star with five arms.",
+ "A starfish typically has five arms and is a creamy color with orange spots."
+ ],
+ "ketch": [
+ "A ketch is a sailboat with two masts.",
+ "A ketch is a two-masted sailing vessel with the larger, mainmast in front of the smaller, mizzenmast.",
+ "A ketch is a sailing vessel with two masts.",
+ "A ketch is a sailboat with two masts, a mainmast and a mizzenmast.",
+ "A ketch is a sailboat with two masts, a larger one in front and a smaller one in back.",
+ "A ketch is a sailing vessel used for pleasure, sailing, or racing.",
+ "A ketch is a sailboat with two masts.",
+ "A ketch is a two-masted sailing vessel, with the aft mast taller than the forward mast.",
+ "A ketch is a sailing vessel with two masts, typically the mainmast is taller than the mizzenmast.",
+ "There is no one definitive answer to this question, as ketches can come in a wide variety of shapes and sizes.",
+ "The photo shows a white ketch sailing on blue water with mountains in the background.",
+ "A ketch is a sailboat with two masts, usually with the mizzen mast stepped forward of the rudderpost.",
+ "A ketch is a sailboat with two masts, typically with the mizzenmast located behind the rudderpost and smaller than the mainmast.",
+ "This is a photo of a sailboat called a ketch.",
+ "A ketch is a two-masted sailing vessel.",
+ "A ketch is a two-masted sailing vessel.",
+ "A ketch is a two-masted sailing vessel.",
+ "A ketch is a two-masted sailing vessel.",
+ "A ketch is a two-masted sailing vessel.",
+ " (sailing vessel)The photo shows a ketch sailing vessel with two masts.",
+ "A ketch typically has two masts, with the aft mast being smaller than the forward mast.",
+ "A ketch is a two or three masted vessel, with the sternmost mast being the shorter of the two or three.",
+ "A ketch is a traditional sailing vessel with two masts.",
+ "A ketch usually has two masts, with the aft mast being shorter than the main mast.",
+ "A ketch typically has two masts, with the aft mast being shorter than the main mast.",
+ "A ketch is a type of sailboat with two masts, a mainmast and a mizzenmast, and is typically rigged such that the mizzenmast is taller than the mainmast.",
+ "A ketch is a sailboat with two masts.",
+ "A ketch looks like a small yacht with two masts.",
+ "A ketch is a type of sailboat that has two masts, with the smaller mast in front.",
+ "There is no definitive answer to this question as the appearance of a ketch can vary greatly depending on the specific vessel in question."
+ ],
+ "motorbike": [
+ "A motorbike typically has two wheels, a seat for the rider, handlebars, and a gas pedal.",
+ "A motorcycle typically has two wheels, a seat for the rider, handlebars, and an engine.",
+ "A motorbike typically has two wheels, a seat for the rider, handlebars, and a motor.",
+ "A motorbike typically has two wheels, a seat for the rider, handlebars, and a motor.",
+ "A motorbike is a two-wheeled vehicle that typically has a seat for the rider and an engine.",
+ "A motorbike typically has two wheels and a seat for the rider.",
+ "A motorcycle is a two-wheeled motor vehicle.",
+ "A typical motorbike has two wheels, a seat for the rider, handlebars, and a motor.",
+ "A motorbike typically has two wheels, a seat for the rider, handlebars, and a gas pedal.",
+ "A motorbike is a vehicle with two wheels and a motor.",
+ "The photo is of a black motorbike with a red seat.",
+ "A motorbike is a two-wheeled vehicle that is powered by a motor.",
+ "In the photo, there is a motorbike with a person in a green jacket sitting on it.",
+ "A motorbike is a two-wheeled vehicle powered by an engine.",
+ "The bike is a silver Honda CBR600RR.",
+ "This is a motorbike.",
+ "The photo is of a motorbike leaning on its kickstand with the rider sitting on the seat.",
+ "The photo might show a motorbike speeding down a road with the wind blowing in the rider's hair.",
+ "The photo is of a motorcycle.",
+ "A motorbike is a two-wheeled vehicle that has an engine and can be ridden without a license in some states.",
+ "A typical motorbike has two wheels, a seat for the rider, and handlebars for steering.",
+ "Motorcycles come in many different shapes and sizes, but they all have two wheels and a seat for the rider.",
+ "A motorbike typically has two wheels, a seat for the rider, handlebars for steering, and a gas pedal.",
+ "A motorbike typically has two wheels and a seat.",
+ "A motorcycle typically has two wheels, though some models have three or even four.",
+ "A motorbike typically has two wheels, a seat for the rider, handlebars, and a gas pedal.",
+ "Motorcycles come in a wide variety of shapes and sizes, but most will have two wheels and a seat for the rider.",
+ "A motorcycle typically has two wheels, a seat for the rider, and handlebars for steering.",
+ "A motorbike typically has two wheels, a seat for the rider, and handlebars for steering.",
+ "A cruiser motorcycle typically has a laid-back riding posture, large displacements, and heavy weights."
+ ],
+ "mayfly": [
+ "A mayfly is a small, delicate insect with two pairs of wings.",
+ "A mayfly is a small, delicate fly with large wings.",
+ "A mayfly is a small, delicate fly with two large wings.",
+ "A mayfly looks like a general insect with six legs, two antennae, and wings.",
+ "Adult mayflies have two large wings that are almost clear.",
+ "A mayfly is a small, delicate insect that is found near water.",
+ "A mayfly is a small flying insect that has two wings and three tails.",
+ "A mayfly is a small, delicate fly with two pairs of wings.",
+ "The mayfly is a small, delicate insect with two large wings.",
+ "A mayfly is a tiny, delicate insect with two large, gauzy wings.",
+ "This mayfly photo shows a close-up of a mayfly in midair, with its long, slender body and delicate wings visible.",
+ "The mayfly is a small, delicate insect with two large wings.",
+ "In the photo, there is a mayfly perched on a blade of grass.",
+ "The photo is of a mayfly in mid-air.",
+ "A mayfly is a small, fragile-winged insect that is found near water.",
+ "A mayfly is a small, delicate insect with clear wings and a long, thin body.",
+ "I cannot see the photo.",
+ "This photo shows a mayfly in mid-air.",
+ "A mayfly is a small, delicate insect with two long, thin wings.",
+ "The mayfly is perched on a blade of grass with its wings spread out.",
+ "The mayfly has a long, narrow body with six legs.",
+ "The mayfly is a small, delicate insect that is found near water.",
+ "Mayflies are small, thin insects with two pairs of wings.",
+ "Mayflies are small insects that have long, thin bodies and two pairs of wings.",
+ "Mayflies have two wings that are mostly clear, with a few veins running through them.",
+ "Mayflies vary in appearance, but most have two pairs of wings and resemble miniature dragons.",
+ "The mayfly has a short lifespan, spending most of its time in the larval and nymph stage.",
+ "A mayfly looks like a small insect with two wings.",
+ "Unsure.",
+ "A mayfly is a small, delicate insect with two pairs of wings."
+ ],
+ "wheelchair": [
+ "A wheelchair is a chair with wheels that is used by people who cannot walk.",
+ "A wheelchair is a chair with four wheels that is used by people who cannot walk.",
+ "A wheelchair is a chair with wheels that is used by people who are unable to walk.",
+ "A wheelchair typically has four large wheels, two located in the front and two in the back.",
+ "A wheelchair is a chair with wheels that is used by someone who cannot walk.",
+ "Wheelchairs are motorized or manually propelled devices used to support the weight of a person who cannot walk because of an injury or disability.",
+ "A wheelchair is a seat with wheels that is used to propel a person who cannot walk.",
+ "A wheelchair is a chair with wheels that is used by someone who cannot walk or who has difficulty walking.",
+ "A typical wheelchair has a seat, four large wheels, and two metal footplates protruding from the front of the chair.",
+ "A wheelchair is a chair with wheels that is specifically designed for people who are unable to walk.",
+ "The photo is of a wheelchair with a person in it.",
+ "In the photo, there is a woman in a wheelchair with a large book in her lap.",
+ "A wheelchair is a chair with wheels designed for people who cannot walk or who have difficulty walking.",
+ "The photo shows a person in a wheelchair with a blue blanket over their lap.",
+ "This photo shows a young man in a wheelchair who is smiling and surrounded by friends.",
+ "The photo is of a young boy in a wheelchair.",
+ "The wheelchair is drab and metal, with large wheels and a small seat.",
+ "This photo is of a woman in a wheelchair.",
+ "The photo may show a wheelchair with a person in it, or it may be a close-up of just the wheelchair.",
+ "This photo is of a wheelchair in a hospital room.",
+ "There are many different types and models of wheelchairs, but they all typically have four large wheels, two small wheels at the front, and a seat.",
+ "There are lots of different types of wheelchairs, but they all have four wheels, a seat, and a footrest.",
+ "A wheelchair is a chair with wheels that is used by someone who cannot walk.",
+ "A wheelchair is a chair with wheels that is used by people who cannot walk or who have difficulty walking.",
+ "A wheelchair typically has four large wheels, two small wheels in the front, and a seat with a backrest.",
+ "There is no one specific design for a wheelchair, as they come in many different shapes and sizes to accommodate various needs.",
+ "A wheelchair is a chair with wheels that is used by people who are unable to walk.",
+ "A wheelchair is a chair with wheels that is used by someone who is unable to walk.",
+ "A wheelchair is a chair with wheels that is used by people who cannot walk.",
+ "A wheelchair may look like a regular chair with wheels, or it may look like a motorized scooter."
+ ],
+ "bass": [
+ "A bass is a type of freshwater fish that can be found in lakes and rivers.",
+ "Bass typically have large, wide mouths with sharp teeth.",
+ "A bass is a type of fish that is typically dark in color with a white belly.",
+ "A bass is a type of fish that typically has a dark green or brown back, and lighter colored sides.",
+ "Bass are typically characterized by their long bodies and large mouths.",
+ "A bass is a freshwater fish that typically has dark green or brownish coloration.",
+ "A bass is a large, dark-colored fish with long fins.",
+ "A bass is a type of fish that is typically dark in color with a large mouth.",
+ "Most bass have an elongated body, large mouth, and two dorsal fins.",
+ "A bass is a fish that typically has dark green scales, a largemouth, and can grow to be around 20-25 inches long.",
+ "This photo is of a bass fish.",
+ " guitarIn the photo, there is a black bass guitar on a stand.",
+ "A bass is a type of fish that is typically dark in color with a streamlined body.",
+ "The photo is of a bass that was caught by a fisherman.",
+ " playerThe bass player is standing in front of a microphone, playing the bass.",
+ "This is a photo of a bass guitar.",
+ "istThe photo is of a bassist playing their instrument.",
+ " playerThis photo shows a bass player in a band.",
+ " playerThis photo is of a bass player in a band performing on stage.",
+ " guitarThe PHOTO is of a black and whitebass guitar on a stand with the neck pointing up.",
+ "A bass looks like a large, dark-colored fish.",
+ "A bass looks like a large fish.",
+ "A bass is a type of fish that typically has a greenish-brown color.",
+ "A bass is a type of fish that typically has a dark green or brown body with lighter coloration on the belly.",
+ "Basses can vary in appearance depending on the specific subspecies, but in general they have large mouths, long bodies, and wide tails.",
+ "The bass is a large, long-bodied fish with two dorsal fins and a forked tail.",
+ "A bass is a type of fish that typically has a dark green or brown body with light-colored stripes running down the sides.",
+ "A bass is a type of fish.",
+ "A bass is a fish with a long body, a large mouth, and two fins on its back.",
+ "The bass is a freshwater fish that can be found in lakes and rivers."
+ ],
+ "stop sign": [
+ "A stop sign is an octagon-shaped sign with the word \"STOP\" written in large letters.",
+ "Most stop signs are octagonal, red with white letters.",
+ "A stop sign is a red octagon with the word \"STOP\" written in white.",
+ "A stop sign is typically octagonal, red, and has the word \"STOP\" written in white letters.",
+ "A stop sign is a red octagon with a white border.",
+ "Most stop signs are octagons and are red with white lettering.",
+ "A stop sign is an octagonal red sign with the word \"STOP\" written in white letters.",
+ "A stop sign is a red octagon with a white border and the word \"STOP\" in white letters.",
+ "A stop sign is typically octagonal, red, and has the word \"STOP\" written in white letters.",
+ "A stop sign is an octagonal red sign with the word \"STOP\" written in white.",
+ "A stop sign is a red octagon with the word \"STOP\" written in white letters.",
+ "A photo of a stop sign would show a red octagon with the word \"STOP\" written in white letters.",
+ "In the photo, there is a stop sign with the word \"STOP\" printed in large, white letters on a red background.",
+ "A stop sign is a red octagon with a white border and the word \"STOP\" in all capital letters.",
+ "The photo is of a stop sign against a blue sky.",
+ "This is a photo of a typical stop sign.",
+ "A stop sign is a red octagon with a white border and the word \"STOP\" written in white letters.",
+ "This photo is of a red octagonal stop sign.",
+ "The photograph is of a stop sign with the word \"STOP\" written in large, white letters on a red background.",
+ "The photo is of a red octagonal stop sign with the word \"STOP\" in white letters.",
+ "The stop sign is a red octagon with the word \"STOP\" in white letters.",
+ "Red octagon with the word \"stop\" written in white letters.",
+ "A stop sign is red with white letters saying \"STOP.",
+ "A stop sign is octagonal with the word \"STOP\" written in large letters on each side.",
+ "A stop sign is designed to look like an octagon with the word \"STOP\" written in white letters on a red background.",
+ "A stop sign looks like a red octagon with a white border.",
+ "A stop sign is a red octagon with the word \"STOP\" written in white letters.",
+ "Most stop signs are octagonal, red, and white.",
+ "A stop sign is a red octagon with the word STOP in white letters.",
+ "A stop sign is an octagonal sign that is red with white letters that say \"STOP."
+ ],
+ "dollar bill": [
+ "A dollar bill looks like a rectangular piece of paper with green ink on one side and pictures of important people on the other side.",
+ "A dollar bill is a rectangular piece of paper with a greenish-white color.",
+ "A dollar bill has a portrait of George Washington on the front and the Great Seal of the United States on the back.",
+ "A dollar bill is a piece of paper money that is worth one dollar.",
+ "A one dollar bill is green and has a portrait of George Washington on the front.",
+ "A dollar bill is green and has the image of George Washington on the front.",
+ "One side of a dollar bill has the face of President George Washington.",
+ "A dollar bill is a rectangular piece of paper with a greenish-gray color.",
+ "A dollar bill is a paper bill that is printed with green ink on one side and has a portrait of George Washington on the other side.",
+ "A one dollar bill is green, with a picture of George Washington on the front, and the back is green with a one in the middle.",
+ "A photo of a dollar bill shows the front and back of a one dollar bill.",
+ "The photo is of a one dollar bill.",
+ "A photo of a dollar bill shows a portrait of George Washington on the front and a pyramid with the all-seeing eye on the back.",
+ "A photo of a dollar bill would show a portrait of George Washington on the front and an image of the American bald eagle on the back.",
+ "A president is featured on one side of the dollar bill, with the Lincoln Memorial featured on the reverse side.",
+ "A photo of a dollar bill would most likely depict the front side of the bill, which features George Washington in the center.",
+ "This photo is of a one dollar bill.",
+ "This photo is of a dollar bill sitting on a counter.",
+ "The photo is of a one dollar bill.",
+ "The photo is of a dollar bill on a table.",
+ "A US dollar bill is a piece of paper money.",
+ "The front of a dollar bill has a portrait of George Washington.",
+ "A dollar bill is a bill that has the value of one dollar.",
+ "A dollar bill looks like a small, rectangular piece of paper with \"One Dollar\" written on the front.",
+ "The Abraham Lincoln dollar coin is a one-dollar coin that was struck by the United States Mint in 2009.",
+ "A dollar bill looks like a small, rectangular piece of paper with \"ONE\" written in the center.",
+ "A dollar bill is a small, rectangular piece of paper with crisp edges.",
+ "The front of a dollar bill has the face of President George Washington.",
+ "A dollar bill looks like a rectangular piece of paper with a greenish-gray background and a portrait of George Washington in the center.",
+ "A dollar bill looks like a small, rectangular piece of paper with a greenish-gray coloration."
+ ],
+ "saxophone": [
+ "A saxophone is a woodwind instrument that looks like a cross between a clarinet and a flute.",
+ "A saxophone is a musical instrument that looks like a long, curved tube.",
+ "The saxophone is a straight-sided, conical instrument with a brass bell.",
+ "A saxophone is a woodwind instrument that looks like a long, curved tube.",
+ "A Saxophone is long and thin with a curved body and a big bell at the end.",
+ "A saxophone is a long, thin, brass instrument with a curved mouthpiece.",
+ "The saxophone is a conical brass instrument with a single-reed mouthpiece.",
+ "The saxophone is a Wind instrument with a conical metal body and a curved brass mouthpiece.",
+ "A saxophone is a musical instrument that is shaped like a tall, thin tube.",
+ "A saxophone is a musical instrument that consists of a conical tube with a flared bell.",
+ "The photo is of a saxophone on a stand in front of a microphone.",
+ "A saxophone is a wind instrument that is played by blowing into a reed mouthpiece, producing a sound that is unique among other instruments.",
+ "A saxophone is a musical instrument that is part of the woodwind family.",
+ "This photo is of a yellow saxophone on a white background.",
+ "A saxophone is a musical instrument that is part of the woodwind family.",
+ "In the photo, a saxophone rests on a tan carpet.",
+ "The photo is of a gold saxophone on a black background.",
+ "This photo is of a yellow saxophone on a black background.",
+ "The photo is of a classic looking saxophone in a deep blue color.",
+ "The photo is of a saxophone on a stand.",
+ "A saxophone is a musical instrument that looks like a long, narrow tube with a curved mouthpiece.",
+ "A saxophone is a musical instrument that is shaped like a long, narrow tube.",
+ "A saxophone looks like a long, curved metal instrument with a mouthpiece on one end.",
+ "A saxophone is a brass wind instrument with a reed and a conical brass body.",
+ "Saxophones are long, thin, and curved with a wide bell at the end.",
+ "A saxophone is a brass instrument that looks like a trumpet but has a wider, conical mouthpiece.",
+ "The saxophone is a brass instrument that has a long, narrow body and a curved neck.",
+ "A saxophone is a brass wind instrument that is played with a single-reed mouthpiece.",
+ "A saxophone is a long, thin, curved brass instrument with a narrow mouthpiece.",
+ "A saxophone is a brass musical instrument with a single-reed mouthpiece, a conical body, and a flared bell."
+ ],
+ "beaver": [
+ "Beavers are brown animals that live in water.",
+ "A beaver has a reddish-brown fur, a long, flat tail, and a large, round head.",
+ "Beavers are large, semiaquatic rodents.",
+ "A beaver is a mammal that lives in freshwater habitats.",
+ "Beavers are large, nocturnal rodents.",
+ "A beaver typically has dark brown fur, a large flat tail, and webbed hind feet.",
+ "A beaver is a rodent with a large, flat tail.",
+ "A beaver is a rodent with a large, flat tail and big incisor teeth.",
+ "A beaver is a large rodent with a long tail.",
+ "A beaver looks like a large rodent with a flat tail.",
+ "In the photo, a beaver is swimming in a river with its large, flat tail visible behind it.",
+ "A beaver is a large, dam-building, nocturnal rodent.",
+ "The photo shows a beaver swimming in a river with its tail trailing behind it in the water.",
+ "The beaver is a large, brown rodent that inhabits freshwater streams and rivers in North America.",
+ "There is a beaver in the photo swimming in a river.",
+ "The photo is of a beaver swimming in a river.",
+ "The photo is of a beaver lying on its back in a body of water.",
+ "In the photo, a beaver is standing on its hind legs in front of a large tree.",
+ "The photo is of a beaver swimming in a river.",
+ "In the photo, a beaver is swimming in a river with its large, flat tail visible behind it.",
+ "A beaver has a large, dark brown body with a small head and round, furry ears.",
+ "A beaver is a large, semiaquatic rodent.",
+ "A beaver is a large, brown rodent with a wide, flat tail.",
+ "Beavers are large rodents with thick brown fur.",
+ "A beaver has a reddish-brown fur, a large flat tail, and a round body.",
+ "Beavers are large brown rodents with webbed hind feet.",
+ "A beaver has a large, flat, paddle-shaped tail.",
+ "A beaver is a rodent with a large, flat tail.",
+ "A beaver is a rodents with a large, flat tail.",
+ "A beaver has a broad, flat tail, and webbed hind feet."
+ ],
+ "flamingo head": [
+ "A head of a flamingo looks like a long neck with a small head on the end.",
+ "A head of a flamingo looks like a pink bird with a long neck and a long beak.",
+ "A head of a flamingo looks like a big, pink, curved beak.",
+ "The head of a flamingo looks like a cartoonish explosion of feathers.",
+ "A head of a flamingo looks like a long, thin neck with a small head on the end.",
+ "A head of a flamingo looks like a curved beak with a long neck attached.",
+ "A head of a flamingo looks like a long neck with a small head on top.",
+ "A head of a flamingo looks like a long thin neck with a small head on the end.",
+ "A head of a flamingo looks like a pink bird with a long neck and a beak.",
+ "A head of a flamingo typically looks like a long neck with a small head attached.",
+ "A head of a flamingo is a photo of a bird with a long neck and pink feathers.",
+ "This photo portrays the head of a flamingo with its long neck and curved beak.",
+ "In the photo, there is a head of a flamingo that is facing to the left side.",
+ "This photo depicts the head of a flamingo.",
+ "The photo is of a head of a flamingo with its long neck curved inward and its beak tucked down.",
+ "This photo is of a head of a flamingo.",
+ "The photo is of a bright pink flamingo with its long neck tilted up towards the sky.",
+ "The photo shows a close-up of the head of a flamingo, with its long neck curved up and its beak open.",
+ "This photo shows the head of a flamingo with its long, curved neck and bright pink feathers.",
+ "This photo shows the head of a flamingo in profile.",
+ "head of a flamingo looks like a pink triangle.",
+ "A head of a flamingo looks like a pink bird with a long neck and a pointy beak.",
+ "A head of a flamingo looks like a head of a bird.",
+ "A head of a flamingo looks like a large, colorful, bird's head.",
+ "A head of a flamingo looks like a curved beak with two nostrils.",
+ "The head of a flamingo looks like a long, curved beak.",
+ "The head of a flamingo is small, with a long, thin neck.",
+ "A head of a flamingo looks like a head of any other bird, with a beak, eyes, and a head.",
+ "The head of a flamingo is gray with a long, curved neck.",
+ "The head of a flamingo is long and thin."
+ ],
+ "mandolin": [
+ "A mandolin is typically a small, round, stringed instrument with four strings.",
+ "A mandolin typically has 8 strings in 4 courses of 2.",
+ "A mandolin is a small, eight-stringed musical instrument.",
+ "A mandolin is a small, eight-stringed musical instrument that is played with a pick.",
+ "A mandolin typically has eight strings in four courses of two, although some variants have as many as twelve or fewer.",
+ "A mandolin is a small, guitar-like stringed instrument with a fretted neck and a body that tapers towards the waist.",
+ "A mandolin is a string instrument that has a pear-shaped body and a fretted neck.",
+ "A mandolin typically has a teardrop-shaped body with a removable belly plate, though some models have a solid body.",
+ "A mandolin is a small, typically eight-stringed, musical instrument played with a plectrum or pick.",
+ "A mandolin is typically a small, thin, fretted instrument with four strings.",
+ "The photo is of a mandolin resting on a table.",
+ "A mandolin is a small, guitar-like stringed instrument.",
+ "The photo is of a mandolin on a stand.",
+ "The mandolin in the photo is a yellow and brown color.",
+ "The photo is of a mandolin on a white background.",
+ "The photo is of a blue mandolin on a white background.",
+ "This is a photo of a mandolin.",
+ "A mandolin is a stringed musical instrument with a Pear-shaped body and a fretted neck.",
+ "In the photo, there is a mandolin sitting on a table.",
+ "The photo is of a brown mandolin with white strings.",
+ "A mandolin is a small, flat-bodied, stringed instruments with a fretted neck.",
+ "A mandolin looks like a small, acoustic guitar.",
+ "A mandolin is a stringed musical instrument in the lute family and is usually plucked with a plectrum.",
+ "A mandolin looks like a small, flat, acoustic guitar.",
+ "A mandolin looks like a small, eight-stringed guitar.",
+ "A mandolin is a stringed musical instrument with a typically teardrop-shaped body and eight strings tuned in pairs.",
+ "A mandolin has a fretted neck and a flat, gut-stringed body.",
+ "A mandolin is a small, fretted instrument that is played with a pick.",
+ "A mandolin is a stringed musical instrument with a fretted neck and a body that tapers towards the waist.",
+ "A mandolin is a musical instrument in the lute family."
+ ],
+ "wild cat": [
+ "A wild cat looks like a small, sleek, and muscular cat with pointy ears.",
+ "A wild cat has short fur that is usually striped or spotted.",
+ "A wild cat is a small to medium sized cat that has a medium to long fur coat.",
+ "A wild cat has pointy ears, a long tail, and sharp claws.",
+ "A wild cat is a small to medium sized feline that is found in the wild.",
+ "A wild cat is a member of the Felidae family, which includes all cats.",
+ "Wild cats are small to medium sized carnivores.",
+ "Wild cats are covered in fur.",
+ "A wild cat has a long body, a short tail, and sharp claws.",
+ "A wild cat is typically a small to medium-sized cat that looks like a domestic house cat.",
+ "I can't see the photo.",
+ "This photo is of a wild cat called a serval.",
+ "A wild cat is a photo of a small to medium sized cat that is not domesticated.",
+ "A photo of a wild cat might show a large, furry animal with sharp claws and teeth.",
+ "The photo shows a wildcat crouching in the grass, waiting to pounce on its prey.",
+ "The wild cat is a small, predators cat.",
+ "This photo shows a wild cat crouched down in the grass, ready to pounce on its prey.",
+ "This wild cat is a tiger.",
+ "The photo is of a wild cat that is crouching down on a rock in a grassy area.",
+ "The photo shows a brown and white wild cat crouched down on a rock.",
+ "Wild cats come in a variety of shapes and sizes, but most are smaller than domestic cats.",
+ "There is no one answer to this question because there are many different kinds of wild cats.",
+ "A wild cat is typically a small to medium sized animal with fur.",
+ "A wild cat looks like a smaller version of a lion.",
+ "A wild cat looks like a small to medium sized cat with pointed ears and a long tail.",
+ "A wild cat is typically a small to medium sized cat, with a long tail and retractable claws.",
+ "Wild cats vary in size and appearance, but they all have certain features in common, such as retractable claws, sharp teeth, and powerful muscles.",
+ "There are many different types of wild cats, but they typically have sharp claws, big teeth, and fur.",
+ "A wild cat looks like a small to medium sized cat with wild features.",
+ "Wild cats vary in appearance, but all have certain characteristics in common."
+ ],
+ "sea horse": [
+ "I have provided an image of a sea horse for reference.",
+ "A sea horse is a small horse-like creature that lives in the water.",
+ "The seahorse is a small marine creature that is related to the pipefish and the stickleback.",
+ "Sea horses are small, marine fish with a distinctive horse-like head.",
+ "A seahorse is a small horse-shaped marine creature with a long snout, a stubby tail, and small fins.",
+ "A sea horse is a marine creature that has a head and body resembling that of a horse, and a tail like a dragon or scorpion.",
+ "They are small, colorful fish with a seahorse-shaped head.",
+ "A sea horse is a small, unique-looking creature that lives in the ocean.",
+ "A seahorse is a fish that has a horse-shaped head.",
+ "A sea horse is a small, horse-like creature that lives in the ocean.",
+ "This photo is of a sea horse with a long, curved body and a tail.",
+ "This photo shows a sea horse swimming in the ocean.",
+ "A sea horse is a type of fish that has a horse-like head and a long snout.",
+ "This photo is of a beautiful sea horse with long, flowing tail.",
+ "This photo is of a playful sea horse frolicking in the waves.",
+ "A photo of a sea horse typically features a brightly colored creature with a long, curved body and a horse-like head.",
+ "The photo is of a sea horse swimming in the ocean.",
+ "This photo depicts a sea horse among some coral.",
+ "The photo is of a sea horse with a long diagonally-striped tail, curving around a brown coral.",
+ "A photo of a sea horse usually shows a brightly colored creature with a long snout and a curled tail.",
+ "A sea horse looks like a horse with a long snout and a tail.",
+ "A sea horse looks like a fish with a horse-like head.",
+ "A sea horse looks like a horse with a fish tail.",
+ "A sea horse is a small penguin-like creature with a long snout and a horse-like tail.",
+ "A sea horse is a small, horse-shaped creature that lives in the water.",
+ "A sea horse is a type of fish that has a long snout and a horse-like head.",
+ "A seahorse is a small, horse-like creature that lives in the sea.",
+ "A sea horse looks like a horse with a fish tail.",
+ "Sea horses are small, equine-like animals that live in salt water.",
+ "A sea horse is a small marine creature that looks like a horse."
+ ],
+ "bonsai": [
+ "A bonsai is a tree or shrub that has been trained and pruned to stay small and to grow in a specific shape.",
+ "A bonsai tree is a miniature tree that is planted in a small pot or tray.",
+ "A bonsai typically has a very small, stunted trunk with a lot of branches coming off of it.",
+ "A bonsai is a miniature tree that is planted in a shallow pot.",
+ "A bonsai is a tree or shrub that has been cultured to stay small.",
+ "A bonsai is a miniature tree or shrub that is artificially dwarfed by pruning and root reduction, and isgrown in a pot or other container.",
+ "A bonsai tree is a miniature tree that has been trimmed and shaped to look like a full-size tree.",
+ "A bonsai is a tree that has been trained to grow in a small pot.",
+ "A bonsai generally refers to a tree or shrub that has been miniaturized and is grown in a pot.",
+ "A bonsai is a dwarf plant or tree that is grown in a pot and shaped to look like a full-size tree.",
+ "The photo shows a small tree in a pot.",
+ "A bonsai is a small tree or shrub that has been carefully trained and pruned to produce a miniature replica of a full-size tree.",
+ "This photo is of a small bonsai tree in a pot.",
+ "This photo shows a bonsai in a small black pot.",
+ " treeThis photo is of a small tree in a pot.",
+ " treeA bonsai tree is a small tree that is carefully pruned and shaped to remain small.",
+ " treeThis photo is of a small bonsai tree in a pot.",
+ " treeThe photo is of a small tree in a pot.",
+ " treeThis photo is of a Japanese bonsai tree.",
+ "The photo is of a small tree in a pot.",
+ "A bonsai looks like a miniature tree that has been trained and shaped over many years to look like a full-size tree.",
+ "The following is an example of a bonsai:.",
+ "A bonsai is a miniature tree that is planted in a small pot or tray.",
+ "My bonsai is a dwarf Leyland cypress.",
+ "A bonsai looks like a tiny tree in a pot.",
+ "Bonsai trees are miniature trees that are grown in small pots or trays.",
+ "A bonsai is a miniature tree that is grown in a pot.",
+ "A bonsai is a miniature tree that is planted in a small pot.",
+ "A bonsai tree is a miniature tree that is grown in a pot.",
+ "There is no one answer to this question since bonsai can vary greatly in appearance."
+ ],
+ "ibis": [
+ "Ibis are wading birds with long necks, down-curved bills, and long legs.",
+ "A ibis is a long-legged wading bird with a long, down-curved bill.",
+ "a ibis is a large, white bird with a long neck, legs, and bill.",
+ "A ibis is a long-legged water bird with a long, downcurved bill.",
+ "The ibis is a long-legged wading bird with a long, downward-curving bill.",
+ "Ibis are large, long-legged, long-necked wading birds with long, curved bills.",
+ "Ibis are long-legged, long-necked wading birds with long, down curved bills.",
+ "The ibis is a wading bird with a long downcurved bill.",
+ "A ibis is a white bird with a black head and neck.",
+ "A ibis is a small, thin bird with a long beak.",
+ "The photo is of a white ibis on a sandy beach.",
+ "A photo of a ibis would show a large, white bird with a long, curved neck and a long, curved bill.",
+ "The photo is of a white ibis standing in water.",
+ " birdIn the photo, an ibis bird stands on a long, thin leg in a shallow body of water.",
+ "The photo shows a white ibis with its long, curved neck and long legs.",
+ "The bird in the photo is an ibis.",
+ "The photo is of a ibis in flight.",
+ "A photo of an ibis might show a bird with a long, curved neck and a long, thin beak.",
+ "A photo of a ibis would show a white bird with long legs and a long, curved beak.",
+ " birdThis is a photo of a white ibis bird.",
+ "The ibis is a wading bird with a long, down-curved bill.",
+ "A white ibis is a bird with white feathers and a long, curved beak.",
+ "IBISes are wading birds with long necks, legs, and curved beaks.",
+ "A contemporary Ibis is a long legged wading bird with a down-curved bill.",
+ "The ibis is a bird with a long, curved beak and long legs.",
+ "Ubis (plural of ibis) are wading birds with long, down-curved bills.",
+ "A ibis is a large wading bird with a long, down-curved bill.",
+ "The ibis is a wading bird in the family Threskiornithidae.",
+ "A ibis is a bird with a long, curved neck, and a long, down-curved bill.",
+ "A common ibis is a wading bird with a long, down-curved bill."
+ ],
+ "windsor chair": [
+ "A windsor chair has spindles for a backrest, and arms that are attached to the backrest with stretchers.",
+ "A windsor chair typically has a tall backrest with spindles, and a seat made of interwoven rushing or leather.",
+ "A windsor chair is a type of chair that has a solid wood seat and backrest, spindled legs, and arm rests.",
+ "A windsor chair is a type of chair that has a solid wood seat and back, with spindles that extend from the back of the chair down to the seat.",
+ "A windsor chair is a type of chair that has a seat and back made of wood, and typically has three or four tapered spindles on each side.",
+ "A windsor chair typically has a spindle back and seat, turned legs, and stretchers.",
+ "A windsor chair typically has a spindle back and turned legs.",
+ "A windsor chair has a back and seat made of wood that are connected by spindles.",
+ "A windsor chair has a spindle back and legs, and arms that are attached to the back spindles.",
+ "A windsor chair has a back made of many thin slats of wood, a seat made of woven cords, and vertical spindles that are attached to the back and seat.",
+ "A windsor chair is a type of chair with a solid wood seat and spindles for legs and back.",
+ "A windsor chair is a type of chair that has a solid seat and spindles for a back and arms.",
+ "A windsor chair is a chair with a spindle back and seat made of interlocking wood rods.",
+ "A Windsor chair is typically a wooden chair with a high, carved back and spindled legs.",
+ "A windsor chair is a type of chair with a spindle back and saber-shaped legs.",
+ "A windsor chair is a type of chair with a wooden seat and backrest.",
+ "A Windsor chair is a type of chair typically made from wood that has a spindle back and legs.",
+ "A Windsor chair is a chair with a spindle back and arms, created in the late 17th century.",
+ "A windsor chair is a chair with a spindle back and arms.",
+ "A windsor chair is a chair with a spindle back and saber-shaped legs.",
+ "A windsor chair looks like a chair with a wooden seat and back.",
+ "There are many types of Windsor chairs, but the most common features are curved arms and spindles, a contoured seat, and raked back legs.",
+ "A windsor chair has a spindle back and wheat-shaped back splat.",
+ "A windsor chair is a chair with a Windsor-style back, where the back splat consists of several slats that are attached to the rear legs and joined by a turned stretcher.",
+ "A windsor chair has a Sack-back, meaning the back is upholstered in a separate piece from the seat.",
+ "A windsor chair typically has a spindle back and turned legs.",
+ "A windsor chair is a type of chair that has a back made of vertical slats and a seat made of a woven straw.",
+ "A windsor chair typically has a spindle back, arms that are attached to the seat, and turned front legs.",
+ "A windsor chair typically has a spindle back, upright slat seat, and turned legs.",
+ "A windsor chair is a type of chair with a solid seat and spindled back."
+ ],
+ "soccer ball": [
+ "A soccer ball is a round, black-and-white ball that is used in the sport of soccer.",
+ "A soccer ball is a large, round, leather-covered ball.",
+ "A soccer ball typically has a black and white checkered pattern and is made of an inflated leather casing.",
+ "A soccer ball is usually a sphere with octagonal panels made of leather or synthetic materials.",
+ "A soccer ball is typically a sphere with a black and white checkered surface.",
+ "A soccer ball looks like a black and white ball with a checkered pattern.",
+ "A soccer ball is a round object that is typically made of leather or synthetic materials.",
+ "A soccer ball have a black and white pentagon and hexagon pattern.",
+ "A soccer ball generally has a black-and-white pentagon design.",
+ "A soccer ball is a black and white, or green and white, spherical object.",
+ "This photo is of a black and white soccer ball.",
+ "This is a photo of a well-used soccer ball.",
+ "A soccer ball is a ball used in the sport of soccer.",
+ "A soccer ball is a black-and-white ball with a hexagonal pattern.",
+ "The photo is of a white soccer ball on a green field.",
+ "A soccer ball is a ball that is used in the sport of soccer.",
+ "The photo is of a soccer ball on a green field with white lines.",
+ "This photo is of a black and white soccer ball.",
+ "This photo is of a soccer ball on a white background.",
+ "This soccer ball is red and white and made of leather.",
+ "A soccer ball is typically a black and white ball that is made out of plastic or leather.",
+ "A soccer ball is typically a round, black-and-white or red-and-white ball that is used in the game of soccer.",
+ "A soccer ball generally has a black and white checkered pattern.",
+ "A soccer ball is a round object that is usually black and white.",
+ "A soccer ball looks like a traditional black and white ball with a hexagon-shaped pattern.",
+ "A soccer ball typically has a black and white checkered design.",
+ "The traditional soccer ball is round and has a black and white pentagonal panel design.",
+ "A soccer ball looks like a sphere with a black and white pentagon pattern.",
+ "A soccer ball is a spherical ball made of latex, rubber, or PVC.",
+ "A soccer ball is a round object that is typically black and white."
+ ],
+ "electric guitar": [
+ "A electric guitar looks like a acoustic guitar but with pickups and electrical components.",
+ "An electric guitar looks like a traditional six-string guitar, except that it has a pick-up in the middle that amplified the sound of the strings.",
+ "An electric guitar is a type of guitar that typically uses one or more pickups to convert the vibration of its strings into electrical signals.",
+ "An electric guitar typically has a solid, semi-hollow, or hollow body, a longneck with frets, and one or more pickups.",
+ "An electric guitar is a guitar that uses one or more pickups to convert the vibration of its strings into electrical impulses.",
+ "An electric guitar is a string instrument that has a neck with frets and Tuners at the headstock, pickups, a bridge and a strings.",
+ "A electric guitar has a body with a long neck that has strings running along it.",
+ "A basic electric guitar has a body with a flat top and a rounded back, a neck with a flat fretted fingerboard, one or more pickups, machines heads for adjusting the tension of the strings, and either a stop tailpiece or.",
+ "An electric guitar typically has six strings and a fretted neck, similar in appearance to an acoustic guitar.",
+ "A electric guitar has a body that is typically made of wood.",
+ "The photo is of a glossy black electric guitar with white pickguard.",
+ "In the photo, there is a electric guitar that is close up and in focus.",
+ "The photo is of a black electric guitar with a white pickguard.",
+ "A electric guitar is a type of guitar that uses electronic amplification to produce a sound.",
+ "This photo is of a electric guitar on a stand in front of an amplifier.",
+ "In the photo you can see a black electric guitar with white strings.",
+ "The photo is of a black electric guitar on a white background.",
+ "The guitar is a blue electric guitar with a black and white pickguard.",
+ "This photo is of a cherry red electric guitar with black and white checkered pickguard.",
+ "The guitar is electric and has a black body with a white pickguard.",
+ "An electric guitar has a hollow body with a hole in the center, a fretboard attached to the neck, tuning pegs at the headstock, and strings.",
+ "A electric guitar typically has a solid body, with a neck leading up to the headstock.",
+ "a electric guitar looks like a acoustic guitar but it has a cord coming out of it and it is plugged into an amp.",
+ "That depends on the specific guitar, as there are many different designs.",
+ "A electric guitar is typically a solidbody guitar, with a hardwood body and metal strings.",
+ "A electric guitar typically has 6 strings, a fretboard, a bridge, a neck, a body, and two pickups.",
+ "A guitar can come in many different shapes and sizes, but a traditional electric guitar has a body that is slightly larger than a acoustic guitar, has six strings, and has metal \"frets\" on the neck that the player presses their fingers.",
+ " differing styles, but typically have 6 strings, a body, a neck, and frets.",
+ "An electric guitar looks like a traditional guitar, but with electrical pickups added to the body.",
+ "A electric guitar typically has a solid body with a fretted neck."
+ ],
+ "airplane": [
+ "A airplane looks like a long tube with two wings sticking out the sides.",
+ "A modern airplane typically has either a tube-shaped fuselage or a pod-like fuselage, wings, one or more engines, landing gear, and a tail.",
+ "The Wright brothers' plane was a Wright Flyer.",
+ "A airplane is a large metal object that has wings and can fly.",
+ "An airplane has a long body with wings attached to the sides.",
+ "A airplane is a large metal object that has wings and engines.",
+ "A airplane is a large metal bird that flies through the air.",
+ "A plane is typically a long, metal tube with wings.",
+ "An airplane typically has two wings and a tail.",
+ "A airplane is a long, narrow object with wings.",
+ "A large metal airplane is sitting on a runway with its wheels down.",
+ "The photo is of a large airplane in the sky.",
+ "The photo is of an airplane flying in the sky.",
+ "This photo is of a small, silver airplane flying through a blue sky.",
+ "In the photo, there is an airplane flying in the sky with a few clouds around it.",
+ "The photo is of an airplane flying through the sky.",
+ "In the photo, an airplane is seen flying in the sky.",
+ "A large airplane is flying through the sky.",
+ "This is a photo of a small, single-engine airplane flying over water.",
+ "This photo is of an airplane flying in the sky.",
+ "A airplane looks like a long tubular body with two wings on either side.",
+ "An airplane generally has two wings and a tail.",
+ "An airplane typically has two wings and a tail.",
+ "A airplane looks like a large metal bird with two wings and many windows.",
+ "An airplane primarily consists of wings, a fuselage, and an empennage.",
+ "Aeroplanes typically have wings and engines.",
+ "An airplane looks like a small, metal, bird-like object with two large metal wings.",
+ "An airplane typically has two wings and a body.",
+ "A plane is a metal, winged machine that is used for transportation.",
+ "A large metal tube with wings and engines attached."
+ ],
+ "kangaroo": [
+ "A kangaroo is a marsupial with a long tail, short fore limbs, and powerful hind limbs for leaping.",
+ "A kangaroo is a mammal that is indigenous to Australia.",
+ "A kangaroo is a marsupial from Australia.",
+ "A kangaroo is a marsupial from the family Macropodidae.",
+ "A kangaroo is a marsupial with a long tail, short forelegs, and long hind legs.",
+ "A kangaroo is a marsupial from Australia.",
+ "A kangaroo is a marsupial from the family Macropodidae, which includes wallabies, wallaroos, and quokkas.",
+ "A kangaroo is a an Australian marsupial.",
+ "A kangaroo is a marsupial from the family Macropodidae.",
+ "Kangaroos are medium-sized marsupials that are found in Australia and New Guinea.",
+ "A kangaroo is a marsupial from the family Macropodidae.",
+ "A kangaroo is a marsupial from the family Macropodidae.",
+ "A kangaroo is a large marsupial from Australia.",
+ "The photo is of a kangaroo in a grassy field.",
+ "The photo is of a kangaroo in a field.",
+ "A kangaroo is a mammal of the family Macropodidae, native to Australia.",
+ "This photograph appears to show a kangaroo in mid-jump, its powerful hind legs fully extended as its long tail helps to balance its body in the air.",
+ "A kangaroo is a marsupial from Australia.",
+ "The photo is of a kangaroo standing in a grassy field.",
+ "This is a photo of a small red kangaroo looking off into the distance.",
+ "A kangaroo is a marsupial from the family Macropodidae (macropods, meaning \"large foot\").",
+ "A kangaroo is a marsupial from the family Macropodidae.",
+ "A kangaroo is a marsupial with a furry body, powerful legs, large feet, and a long tail.",
+ "A kangaroo is a marsupial with a long tail, powerful hind legs, large feet, and a small head.",
+ "An adult kangaroo is typically between 2 and 6 feet tall, with a tail that is between 2 and 4 feet long.",
+ "A kangaroo is a marsupial from the family Macropodidae.",
+ "A kangaroo is an Australian marsupial.",
+ "A kangaroo is a marsupial from Australia.",
+ "A kangaroo is a marsupial from the family Macropodidae.",
+ "A kangaroo is a marsupial from the family Macropodidae (macropods, meaning \"large foot\")."
+ ],
+ "stegosaurus": [
+ "A stegosaurus is a medium-sized herbivorous dinosaurs with a long tail and large plates on its back.",
+ "A stegosaurus is a large dinosaur that had a long neck, a small head, and a long, thick tail.",
+ "A stegosaurus is a large, plant-eating dinosaur that has a row of plates running down its back.",
+ "A stegosaurus looks like a plant-eating dinosaur with a row of large plates running down its back and a long tail.",
+ "A mass of green scales, a long neck and a whip-like tale are telltale signs of the stegosaurus.",
+ "A stegosaurus looks like a large, four-legged, lizard-like dinosaur with a long tail.",
+ "A stegosaurus is a large, plant-eating dinosaur that has a small head, a long tail, and large plates along its back.",
+ "A stegosaurus is a large, herbivorous, quadrupedal dinosaur that lived in the Late Jurassic period, 155-150 million years ago.",
+ "A stegosaurus is a large, plant-eating dinosaur that has two rows of plates running down its back.",
+ "A stegosaurus is a large, plant-eating dinosaur that had a row of sharp plates along its back and four spikes on its tail.",
+ "The photo is of a stegosaurus walking through a jungle.",
+ "The photo is of a stegosaurus in a field.",
+ "The photo is of a large, green stegosaurus with a long tail.",
+ "A stegosaurus is a large, herbivorous dinosaur with a long tail and spikes on its back.",
+ "The photo is of a stegosaurus walking through a jungle.",
+ "This photo is of a stegosaurus statue in front of a museum.",
+ "A stegosaurus is a large, plant-eating dinosaur with a row of plates running down its back.",
+ "In the photo, a stegosaurus is standing in a forest.",
+ "The photo is of a stegosaurus walking through a forest.",
+ "The photo is of a stegosaurus that is in a museum.",
+ "A stegosaurus looks like a large dinosaur that is covered in spikes.",
+ "A stegosaurus looks like a four-legged dinosaur with a long tail and large, flat plates along its back.",
+ "A stegosaurus looks like a large green dinosaur with a long neck, small head, and a back covered in large, sharp plates.",
+ "A stegosaurus is a large, plant-eating dinosaur with a long tail and spikes down its back.",
+ "A stegosaurus is a large, plant-eating dinosaur that has a row of plates running down its back.",
+ "A stegosaurus is a large, plant-eating dinosaur that has a double row of plates running down its back.",
+ "A stegosaurus looks like a large, slow-moving, four-legged reptile with a long tail and large plates on its back.",
+ "The stegosaurus is a large, plant-eating dinosaur that lived during the Jurassic Period, about 155 to 150 million years ago.",
+ "A stegosaurus is a large, plant-eating dinosaur that lived during the Jurassic period, 150-200 million years ago.",
+ "A stegosaurus is a dinosaur that has a long neck, small head, and a tail with spikes on the end."
+ ],
+ "ferry": [
+ "A large boat that is used to transport people and vehicles across a body of water.",
+ "A ferry is a boat or a ship that carries passengers and vehicles across a body of water.",
+ "A ferry looks like a sailboat with a large, flat deck that is typically used to transport people and vehicles across a body of water.",
+ "A ferry is a large boat that is used to transport people and vehicles across a body of water.",
+ "A ferry is a boat that carries people and vehicles across a body of water.",
+ "A typical ferry is a large, flat boat that is used to transport people and vehicles across a body of water.",
+ "A ferry is a boat that transports passengers and vehicles across a body of water.",
+ "A large boat that carries passengers and vehicles across a body of water.",
+ "A ferry is a large boat that is used to transport people and vehicles across a body of water.",
+ "A ferry is a boat that is used to transport people or vehicles across a body of water.",
+ "The photo is of a large white ferry with blue trim.",
+ "This photo shows a ferry crossing a body of water.",
+ "A ferry is a boat or a ship that carries passengers and vehicles across a body of water.",
+ "A ferry is a boat or ship that carries passengers, and sometimes their vehicles, across a body of water.",
+ "The photo is of a large, white ferryboat with blue trim.",
+ "The photo might show the ferry boat leaving the dock with passengers aboard, or passengers waiting to board the ferry.",
+ "The ferry is large and white, with many windows.",
+ "In the photo, there is a large white ferry docked at a pier.",
+ "One photo of a ferry shows the vessel docked at a pier, with passengers disembarking.",
+ "This photo is of a large ferryboat with multiple levels.",
+ "A ferry typically looks like a large boat with multiple levels.",
+ "A ferry looks like a large boat with a flat back.",
+ "A ferry is a boat that carries people or vehicles across a body of water.",
+ "A ferry can either look like a boat or a ship.",
+ "Most large ferries resemble cruise ships and have multiple levels, restaurants, and shops.",
+ "Most ferries are large, flat boats that can hold many cars and passengers.",
+ "A ferry boat is a boat that carries passengers and vehicles across a body of water.",
+ "A ferry is typically a large boat that can hold many passengers and vehicles.",
+ "A ferry is a water vessel that is used to transport people or vehicles across a body of water.",
+ "There is no one answer to this question as there are many different types and sizes of ferry boats."
+ ],
+ "umbrella": [
+ "A umbrella is a Rain Shedding Device that is suspended over the head and has a canopy that is usually made of fabric or some kind of waterproof material.",
+ "A umbrella is a device that is used to protect a person from the rain or sun.",
+ "A umbrella is a medium-sized, lightweight, portable canopy supported by metal or wooden ribs, which is usually covered with fabric.",
+ "Umbrellas protect you from the rain by covering you with a waterproof canopy.",
+ "An umbrella is a device used for protection from the weather.",
+ "A umbrella is a handheld, portable device used to provide shade or protection from the weather.",
+ "A umbrella is a rain protection device that is composed of a handle, a rod and a canopy.",
+ "A umbrella is a portable canopy that is used to protect a person from the sun or rain.",
+ "A umbrella is a device used for protection from the rain.",
+ "A umbrella is a folding canopy supported by wooden or metal ribs, which is usually pointed.",
+ "The photo is of a large umbrella.",
+ "The photo is of a umbrella that is mostly blue with a white top.",
+ "There is a umbrella in the photo.",
+ "The photograph is of a traditional looking umbrella.",
+ "A customer is holding a red umbrella overhead.",
+ "A large yellow umbrella is shielding a small boy and girl from the rain.",
+ " in a stormIn the photo, there is a brightly colored umbrella up against a gray background.",
+ "The umbrella is red and blue with white polka dots.",
+ "In the photo, there is a blue umbrella with a white handle.",
+ "The photo is of a black and white umbrella with a design of a snake coiled around the handle.",
+ "An umbrella is a handheld collapsible canopy supported by metal or wooden ribs, which is usually covered with fabric.",
+ "A typical umbrella is composed of a fabric canopy stretched over metal ribs.",
+ "An umbrella is a portable collapsible canopy supported by wooden or metal ribs, which is usually pointed.",
+ "A typical umbrella looks like a stick with a circular canopy attached to the top.",
+ "A umbrella looks like a cylinder with a pointed top.",
+ "A umbrella typically has a cylindrical shape with a handle, and is made of cloth or plastic that is designed to block out the sun or rain.",
+ "Most umbrellas are designed to include a central opening in the fabric canopy, so that they can be inverted without filling with water\u2014this prevents the umbrella from becoming waterlogged or heavy and difficult to open when wet.",
+ "An umbrella is a portable, hand-held canopy that is used to protect a person from the sun or rain.",
+ "A basic umbrella is composed of a metal or wooden rod that supports a fabric canopy.",
+ "An umbrella is a plastic or fabric canopy supported by a metal or plastic frame."
+ ],
+ "rhino": [
+ "A rhino is a big, gray animal with a horn on its nose.",
+ "A rhinoceros is a large, herbivorous mammal with a thick hide and short legs.",
+ "A rhino is a large mammal with a thick, gray skin.",
+ "A rhino is a large, gray mammal with thick skin and horns on its nose.",
+ "A rhino is a large mammal with a thick, gray skin.",
+ "A rhino is a large mammal with thick, gray skin.",
+ "A rhinoceros is a large, grayish-brown herbivorous mammal with one or two horns on its snout.",
+ "A rhinoceros is a large, dark-colored mammal with a thick hide.",
+ "A rhino is a large, gray mammal with big horns on its face.",
+ "A rhino is a large mammal with a thick, grey skin.",
+ "The photo shows a rhino with its massive body and great horn.",
+ "This photo shows a rhino standing in a field.",
+ "A rhino is a large mammal with thick skin and a horn on its nose.",
+ "The photo is of a rhino in profile, its thick, gray skin wrinkled around its eyes and mouth.",
+ "The photo is of a large, gray rhino.",
+ "A rhino is a large, grey mammal with a short neck, a wide body, and two horns on its nose.",
+ "The rhino is a massive animal with thick, gray skin.",
+ "This is a photo of a rhino in its natural habitat, which is a grassland.",
+ "The photo is of a rhino charging towards the camera.",
+ "The photo is of a large, gray rhino.",
+ "These animals are massive with a capital M.",
+ "A rhino looks like a large, gray mammal with a thick hide and horns on its nose.",
+ "A rhinoceros is a large, four-legged mammal that has a thick skin and a long, horn-like structure on its nose.",
+ "A rhino is a large gray or white animal with a thick hide and a horn on its nose.",
+ "A rhinoceros is a large, herbivorous mammal with thick skin and one or two horns on its snout.",
+ "A rhino looks like a large, gray mammal with a horn on its nose.",
+ "A rhino looks like a large, gray mammal with a horn on its nose.",
+ "A rhinoceros is a large, grayish-brown mammal with one or two horns on its snout.",
+ "A rhinoceros is a large, grayish-brown mammal with one or two horns on its snout.",
+ "A rhino looks like a huge, grey, four-legged mammal with a big horn on its nose."
+ ],
+ "joshua tree": [
+ "The Joshua tree is a species of yucca that is native to the Mojave Desert in the southwestern United States.",
+ "The Joshua tree is a native plant to the Mojave Desert.",
+ "A joshua tree is a yucca plant that can grow up to 40 feet tall.",
+ "A Joshua tree is a Yucca brevifolia tree that is native to the Mojave Desert.",
+ "A joshua tree is a type of yucca plant that is native to the southwestern United States.",
+ "A joshua tree is a species of yucca that is native to the southwestern United States.",
+ "A joshua tree is a species of yucca plant that is native to the southwestern United States.",
+ "A joshua tree is a type of yucca plant that grows in the Mojave Desert.",
+ "A Joshua tree is a type of yucca plant that is native to the Mojave Desert.",
+ "A Joshua tree is a tall, spindly tree with long, sharp leaves.",
+ "The photo is of a joshua tree in the middle of a desert.",
+ "The image is of a large, green tree in the middle of a open, brown field.",
+ "The photo is of a tall, spindly tree with small leaves protruding from its branches.",
+ "A photo of a joshua tree might feature the desert plant against a blue sky, with its spiky leaves and branches reaching up towards the sun.",
+ "The photo shows a joshua tree with its long, spiky leaves in the foreground, and a rocky landscape in the background.",
+ "A photo of a joshua tree might show a desert landscape with a lone tree in the foreground.",
+ "A joshua tree is a large, evergreen tree that is native to North America.",
+ "A Joshua tree is a type of tree that is native to the Mojave Desert in the southwestern United States.",
+ "A Joshua tree is a type of tree that is native to the Mojave Desert.",
+ "The Joshua tree is a species of yucca that is native to the Mojave Desert in the southwestern United States.",
+ "A Joshua tree is a tall tree that has long, thin branches and small leaves.",
+ "A Joshua tree is a distinctive type of yucca tree that is native to the southwestern United States.",
+ "A Joshua tree looks like a tree with long, spiky leaves.",
+ "A joshua tree is a species of yucca plant that is native to the southwestern United States.",
+ "A Joshua tree has a long, thin trunk with very spiky leaves.",
+ "The Joshua tree is a member of the yucca family and is indigenous to the American Southwest.",
+ "The Joshua tree is a unique and interesting looking tree.",
+ "A Joshua tree looks like a tree with long, spindly branches growing out of a thick trunk.",
+ "-A joshua tree is a drought-resistant evergreen tree that can grow to be up to 40 feet tall.",
+ "The Joshua tree is a species of yucca that is native to the Mojave Desert in the southwestern United States."
+ ],
+ "okapi": [
+ "A okapi has a reddish brown coat and vertical stripes on its legs.",
+ "An okapi is a reddish-brown mammal with striped legs and neck.",
+ "A okapi is a mammal that looks like a cross between a zebra and a deer.",
+ "The Okapi is a long-necked, reddish brown creature that lives in the forests of the Congo Basin.",
+ "The okapi is a mammal native to the Ituri Forest in the northeast of the Democratic Republic of the Congo, in Central Africa.",
+ "The okapi is a medium-sized mammal native to the Ituri Rainforest in the northeast of the Democratic Republic of Congo in Central Africa.",
+ "An okapi has a long neck, a reddish coat, and striped legs.",
+ "The okapi has a long neck, shaggy fur, and a reddish brown coat.",
+ "A okapi is a mammal that looks like a cross between a zebra and a giraffe.",
+ "The okapi has a long neck, round head, and large eyes.",
+ "This okapi photo features a close-up of the animal's head, with its distinctive stripes and large ears.",
+ "The okapi is a dark brown, giraffe-like creature with zebra stripes on its legs.",
+ "The photo shows an okapi standing in a forest.",
+ "This photo is of an okapi, a mammal native to the Democratic Republic of Congo in Africa.",
+ "In the photo, there is an okapi standing in a forest.",
+ "In the photo, there is an okapi standing in a forest.",
+ "This is a photo of an okapi, a forest giraffe that lives in the tropical rainforests of central Africa.",
+ "This photo is of a okapi in the wild.",
+ "A okapi is a mammal native to the Ituri Rainforest in the northeast of the Democratic Republic of Congo, in Central Africa.",
+ "The photo is of an okapi, a mammal native to the Ituri Rainforest in the Congo Basin.",
+ "A okapi looks like a cross between a zebra and a giraffe.",
+ "A okapi is a medium-sized mammal that resembles a cross between a zebra and a giraffe.",
+ "Okapis are the closest living relative to giraffes.",
+ "A okapi looks like a zebra with a long neck and legs.",
+ "The okapi is a dark-colored, furry mammal that looks like a cross between a zebra and a giraffe.",
+ "A okapi has a reddish brown coat, with white horizontal stripes on the hindquarters and white vertical stripes on the front legs.",
+ "A okapi has a reddish brown coat and long neck.",
+ "A okapi has a long neck, a long tongue, and long, thin legs.",
+ "A okapi looks like a zebra with a long neck and no stripes.",
+ "A okapi looks like a zebra with a long neck and tongue."
+ ],
+ "watch": [
+ "A watch is a small timepiece that is typically worn on the wrist.",
+ "A watch is a small, portable timepiece, typically worn on the wrist.",
+ "A watch is a small, round device that is worn on the wrist.",
+ "A watch is typically a small, round device that is worn on the wrist.",
+ "A watch is a small, portable device that tells time.",
+ "A watch looks like a small, flat device that is worn on the wrist.",
+ "A watch typically has a round or rectangular face with a glass or plastic window.",
+ "Some watches have a metal band and some have a leather band.",
+ "A watch has a round face with hours and minutes marked on the dial.",
+ "The watch has a circular face with hour markings and hands.",
+ "A round, silver watch with a black leather band.",
+ "A watch is a small timepiece meant to be worn on the wrist, with a strap or bracelet.",
+ "A watch is a timepiece that is typically worn on the wrist.",
+ "The watch in the photo is a silver watch with a black leather band.",
+ "This watch has a black leather strap and a round, silver face.",
+ "The watch is a silver color with a black face.",
+ "The photo is of a yellow watch with a black strap.",
+ "The watch in the photo is a round gold watch with a black leather band.",
+ "The watch is white with a black strap.",
+ "A silver watch with a black leather strap is pictured.",
+ "The most common type of watch has a circular face with hour, minute, and second hands.",
+ "A watch typically has a round face with markings for the hours, minutes, and often seconds.",
+ "A watch can take many different forms, but the most common type has a round face with a strap or bracelet.",
+ "A watch is a small, round, handheld timepiece.",
+ "A watch typically has a round face with hour, minute, and second markings.",
+ "A watch is a small, round device that is typically worn on the wrist.",
+ "A watch typically has a round or oval face with a glass or plastic cover.",
+ "A watch typically has a round face with hour and minute markers, and a hand or hands that point to the current time.",
+ "A watch typically has a face with hour and minute markings, and a strap or bracelet.",
+ "A watch looks like a small clock that you wear on your wrist."
+ ],
+ "brain": [
+ "A brain looks like a grayish colored mass with a wrinkled texture.",
+ "A brain looks like a walnut.",
+ "The brain is a soft, spongy tissue that is white and grey in color.",
+ "A brain looks like a human brain.",
+ "A brain looks like a three-pound, walnut-shaped mass of tissue.",
+ "A brain looks like a pink and white, spongy mass.",
+ "A brain looks similar to a walnut and is a deep reddish-brown color.",
+ "A brain looks like a three-pound, neocortex-shaped, mushy, pink-tan organ.",
+ "A brain looks like a three-pound mass of jelly that is pale pink and tan in color.",
+ "A brain looks like a large, grey, spongy mass.",
+ "There is a photo of a brain on a table with various instruments around it.",
+ "A brain is a mass of nerve tissue that is the control center of the nervous system.",
+ "This brain photo shows the exterior of a human brain.",
+ "The brain is a complex and interesting organ.",
+ "The photo is of a brain that has been cut in half so that the inside is visible.",
+ "The brain is a mass of gray and white matter that is encased in the skull.",
+ "The photo is of a brain that has been cut in half down the middle.",
+ "The photo is of a brain that has been sectioned so that different areas can be seen.",
+ "This is a photo of a human brain.",
+ "The photo is of a brain on a white background.",
+ "A brain looks like a greyish-pink, spongy mass with many folds.",
+ "The brain is a complex organ that is composed of many different types of cells.",
+ "A brain looks like a three-pound, pinkish-gray, walnut-shaped organ.",
+ "A brain looks like a three-pound mass of jelly.",
+ "A brain looks like a walnut.",
+ "The brain looks like a wrinkled gray mass.",
+ "The brain looks like a three-pound mass of jelly.",
+ "What do you mean by \"look like?\" A brain can be seen through an MRI or CT scan, but it looks like a blob of gray and white matter.",
+ "A brain looks like a mass of pinkish-white matter with protruding folds.",
+ "The brain is a mass of gray and white matter."
+ ],
+ "gramophone": [
+ "A gramophone is a musical instrument that looks like a large horn.",
+ "A gramophone is a mechanical device for playing back recorded sound.",
+ "A gramophone is a machine used to play records.",
+ "A gramophone is an early type of record player.",
+ "A gramophone is a machine that is used to play music by amplifying the sound vibrations of a disc, which are converted into electrical signals by a microphone, and then passed through a speaker.",
+ "A gramophone is a device that is used to play records.",
+ "Gramophones are large, box-shaped machines that were once a common sight in homes across the world.",
+ "A gramophone is a machine that plays records.",
+ "A gramophone is a machine that is used to play records.",
+ "A gramophone typically consists of a turntable, tonearm, and cartridge, which contain a stylus that reads the record grooves.",
+ "This photo is of an old gramophone on a dusty shelf.",
+ "The photo is of an old, antique gramophone.",
+ "A gramophone is a machine that plays records.",
+ "The photo is of an old fashioned gramophone.",
+ "The photo is of an old gramophone with a large horn.",
+ "The photo depicts a gramophone on a wooden table.",
+ "The photo is of a gramophone on a table.",
+ "A gramophone is a machine used to play records.",
+ "This photo is of an old gramophone.",
+ "The gramophone is an antique record player.",
+ "A gramophone is a machine from the late 1800s that was used to play music recorded on a disc.",
+ "A gramophone looks like a small, rectangular box with a handle on the side.",
+ "A typical gramophone from the late 19th century to the early 20th century would have had a large horn to amplify the sound coming from the turntable.",
+ "A basic gramophone has a turntable, tonearm, and cartridge on which a needle is placed.",
+ "A gramophone typically looks like a large, upright cabinet with a handle on the front.",
+ "a gramophone typically looks like an old-fashioned record player, with a large circular turntable and a horn-shaped speaker.",
+ "A Gramophone is a device that plays vinyl records.",
+ "A gramophone has a large horn to amplify the sound and a turntable to play the record.",
+ "There are many types and styles of gramophones, but they all have a few things in common.",
+ "A gramophone looks like a broken record player."
+ ],
+ "scissors": [
+ "A scissors is an instrument used for cutting, typically consisting of a pair of metal blades with sharpened edges that are brought together to cut materials such as paper, hair, or cloth.",
+ "A scissors has two blades attached at a pivot point in the middle.",
+ "A scissors has a handle and two blades that meet in the middle.",
+ "A pair of scissors is two blades connected at a pivot point.",
+ "A scissors is a small, hand-operated cutting tool.",
+ "A scissors is a cutting tool composed of a pair of blades connected at the middle by a pivot.",
+ "A scissors is a handheld tool with two sharp blades that come together in the middle.",
+ "A scissors has two blades that come together in the middle and hinge at one end so they can open and close.",
+ "A scissors is a handheld cutting tool with two blades attached at a pivot point.",
+ "A scissors is a tool that is used for cutting.",
+ "A photo of a scissors usually features the sharp blades of the instrument and the handle.",
+ "The scissors in the photo are sharp and look like they can cut through anything.",
+ "The photo is of a scissors against a white background.",
+ "The scissors in the photo are metal with a black handle.",
+ "The scissors are on a white background and are opened.",
+ "A photo of a scissors shows a household tool that is used for cutting paper, fabric, and other materials.",
+ "The photo is of a pair of scissors with the blades open.",
+ "In the photo, there is a pair of scissors with one blade longer than the other.",
+ "The photo is of a pair of scissors laying on a white background.",
+ "This photo is of a scissors.",
+ "A scissors is a handheld cutting tool with two sharp blades that come together at a point.",
+ "A scissor is two metal blades with a hole in the middle for your finger.",
+ "A scissors looks like two blades connected in the middle by a hinge.",
+ "A Basic ScissorsA scissors is a hand-operated cutting tool.",
+ "A scissors is a small cutting tool that has two metal blades that are sharpened at the ends.",
+ "A scissor is a cutting tool with two blades.",
+ "A scissors is two blades connected at the middle by a hinge.",
+ "A scissors is a household tool that consists of two metal blades attached at a hinge.",
+ "A scissors has two blades that are attached in the middle by a hinge.",
+ "A pair of scissors consists of a pair of metal blades attached at the middle by a rivet, with handles on each end."
+ ],
+ "ceiling fan": [
+ "A ceiling fan has blades that rotate around a central motor.",
+ "A ceiling fan typically consists of four or five blades attached to a motor.",
+ "A ceiling fan typically has 3-5 blades that attach to a central motor.",
+ "A ceiling fan is a type of electrical fan that is mounted on the ceiling of a room.",
+ "A ceiling fan typically has four blades that are attached to a central motor.",
+ "A ceiling fan looks like a large propeller suspended from the ceiling.",
+ "A ceiling fan is a large, circular fan that hangs from the ceiling of a room and spins around to create a cool breeze.",
+ "A ceiling fan looks like a long rod with a round blade on each end.",
+ "A ceiling fan typically contains three to five blades that are held in place by a metal hub.",
+ "A ceiling fan has a central hub with blades attached.",
+ "The photo shows a ceiling fan with four blades.",
+ "The photo is of a ceiling fan that is spinning.",
+ "The photo is of a ceiling fan with three wooden blades.",
+ "A ceiling fan is a mechanical fan mounted on the ceiling of a room or space, usually electrically powered, that circulates air via blades attached to a central hub.",
+ "The photo is of a ceiling fan with three blades.",
+ "The photo shows a ceiling fan with four blades.",
+ "The photo is of a ceiling fan with three blades.",
+ "The photo is of a ceiling fan with three blades.",
+ "The photo is of a ceiling fan that is hanging from the ceiling.",
+ "A ceiling fan is a motorized device with blades attached to it.",
+ "A ceiling fan typically has four metal blades attached to a central motor and mounted to a circular base.",
+ "A ceiling fan is a type of fan that is mounted on the ceiling of a room.",
+ "A ceiling fan typically has four or five blades and a light fixture attached.",
+ "Most ceiling fans have four metal blades that are attached to a central fixture.",
+ "Ceiling fans look like large, paddle-shaped blades attached to a central motor.",
+ "A typical ceiling fan is a circular fan with blades attached to a central hub.",
+ "A ceiling fan is a fan that is attached to the ceiling.",
+ "A ceiling fan is a device suspended from the ceiling of a room that uses an electric motor to rotate a set of blades, thus circulating the air in the room.",
+ "A ceiling fan typically has a circular base with 3 or more blades extending out from the base.",
+ "A ceiling fan typically looks like a large propeller, with blades that spin around a central hub."
+ ],
+ "rooster": [
+ "A rooster is a male chicken.",
+ "A rooster is a chicken that is male.",
+ "A rooster is a male chicken.",
+ "A rooster is a chicken that is male.",
+ "A rooster has a red wattle and comb on its head, long pointed feathers on its back, and large tail feathers.",
+ "A rooster is a male chicken who has reached sexual maturity.",
+ "A rooster is a chicken that is male.",
+ "A rooster is a chicken that is male.",
+ "A rooster is a chicken that is male.",
+ "Roosters are usually red, orange, or gold with black feathers on their back and tail.",
+ "A rooster is a male chicken.",
+ "The photo is of a rooster with its head held high and its tail feathers spread out.",
+ "A photo of a rooster may show the rooster standing in a barnyard with other farm animals, or it may simply be a close-up of the bird's colorful plumage.",
+ "This rooster is likely a Rhode Island Red, a popular American breed of chicken.",
+ "A rooster is a chicken that is typically male.",
+ "This photo is of a rooster on a farm.",
+ "A rooster is a male chicken.",
+ "This photo is of a rooster with its head turned to the side.",
+ "This photo shows a beautiful rooster with red, yellow, and green feathers.",
+ "A photo of a rooster shows the animal standing in a field with its head tilted back and its orange and black feathers ruffled in the wind.",
+ "A rooster is a male chicken with a large, protruding, orange-red comb on its head and long, pointed feathers on its back and tail.",
+ "A rooster is a male chicken.",
+ "A rooster is a chicken that is male.",
+ "A rooster is a chicken that is male.",
+ "A rooster is a male chicken.",
+ "A rooster is a male chicken.",
+ "A rooster is a chicken that is male.",
+ "A rooster is a male chicken.",
+ "A rooster looks like a chicken with a comb on its head.",
+ "A rooster looks like a chicken, but with a longer tail and brighter plumage."
+ ],
+ "cannon": [
+ "A cannon is a large gun with a long barrel that is mounted on a carriage.",
+ "A cannon is a large, often barrel-shaped object that is used to shoot projectiles at high speeds.",
+ "A cannon is a large, cylindrical gun that fires heavy projectiles.",
+ "A cannon is a large, shoulder-fired gun that is usually mounted on a carriage.",
+ "A cannon is a large artillery piece that is mounted on a carriage and has a long barrel.",
+ "A cannon is a large, heavy gun that is mounted on a platform and fires large projectiles.",
+ "A cannon is a large, muzzle-loaded gun that is fired from a fixed position.",
+ "A cannon is a large, cylindrical gun that is mounted on wheels.",
+ "A cannon is a large gun that is mounted on a platform and is used to fire projectiles at a target.",
+ "A cannon is typically a large, cylindrical device that fires projectiles at a high speed.",
+ "A cannon is a large, military firearm that is typically mounted on a carriage.",
+ "A cannon is a large, often cylindrical, firearm that is capable of firing a heavy projectile over a long distance.",
+ "In the photo, there is a cannon in the foreground pointing towards the sky.",
+ "The cannon is a large, metal, cylindrical object with a large, round opening at one end.",
+ "This cannon is situated on a cliff overlooking a vast body of water.",
+ "The photo is of a large, gray cannon.",
+ "A cannon is a large, heavy gun mounted on a carriage for firing heavy projectiles at long range.",
+ "A cannon is a large, powerful gun that is used to fire heavy projectiles at a target.",
+ "In the photo, there is a cannon that is pointing up at a slight angle.",
+ "The photo is of a large cannon that is mounted on a stone platform.",
+ "There are many types of cannons, but they generally look like a large metal tube on a wheeled carriage.",
+ "A cannon is a large, often ceremonial gun typically used for ceremonial purposes such as salutes.",
+ "A cannon is a large, mounted gun that is used to fire heavy projectiles over long distances.",
+ "Cannons are large guns that are used in warfare.",
+ "A cannon is a large, heavy gun that is mounted on a carriage.",
+ "A cannon is a large, cylindrical gun that fires heavy projectiles known as shells.",
+ "A cannon is a large weapon that is typically mounted on a platform and fires a large projectile.",
+ "A cannon typically has a long barrel and is mounted on a carriage.",
+ "A cannon is large, tube-shaped weapon that fires heavy metal balls or shells.",
+ "A cannon looks like a large metal tube that is mounted on a carriage."
+ ],
+ "binocular": [
+ "Binoculars are two small telescopes attached side-by-side.",
+ "A binocular is a small, portable telescope with two eyepieces, used for viewing distant objects.",
+ "A binocular consists of two separate telescopes that are side-by-side and mounted on a single frame.",
+ "Binoculars are two telescopes that are connected side-by-side, allowing you to see objects that are far away.",
+ "A binocular is a two-lens telescope that you hold up to your eyes to see things that are far away.",
+ "A binocular typically consists of two separate telescopes that are mounted on a single frame.",
+ "Binoculars are two telescopes joined together so that you can look through them with both eyes.",
+ "A binocular belongs to a class of instruments known as optical viewers, magnifiers, or simply viewers, which are used for two eyes viewing.",
+ "A binocular is a keyhole-shaped instrument consisting of two telescopes mounted side-by-side and aligned to point in the same direction.",
+ "A binocular is a handheld optical instrument with two telescopes mounted side by side.",
+ " K.",
+ "The photo shows a black binocular on a white background.",
+ "The photo is of a black binocular on a white background.",
+ "A photographer captures a picture of a person looking through a pair of Identical, convex lenses that are supported by a frame.",
+ "In the binocular photo, two cylindrical lenses are connected by a frame.",
+ "The photograph shows a black binocular on a white background.",
+ "The binocular is a devices that have two telescopes side-by-side.",
+ "The photo shows a pair of black binoculars on a green background.",
+ "A binocular is a pair of small telescopes that are mounted together and a photo of a binocular would show the two small telescopes side by side.",
+ "A photo of a binocular might show someone looking through the lens of the binocular at a distant object.",
+ "A binocular typically looks like two small telescopes side-by-side, with an eyepiece for each one.",
+ "A binocular will have two elevated lenses that are side-by-side.",
+ "A binocular is two small telescopes that are attached together.",
+ "A binocular looks like a pair of small telescopes that are connected together.",
+ "A binocular is a two-lensed optical instrument used for viewing distant objects.",
+ "A binocular typically has two eyepieces, with each eyepiece containing a lens.",
+ "The simplest form of a binocular would be two telescopes side-by-side aimed in the same direction.",
+ "A binocular looks like a small microscope with two eyepieces.",
+ "A binocular is a pair of small telescopes that are mounted side-by-side and aligned so that they can be used together as a single instrument.",
+ "A binocular is typically a handheld, two-lensed optical instrument used for viewing distant objects."
+ ],
+ "anchor": [
+ "An anchor is generally a metal, hook-shaped object that is used to hold a ship in place.",
+ "An anchor is a large, heavy object that is used to hold a ship in place.",
+ "A anchor is typically a metal object that is used to hold a ship in place.",
+ "An anchor is a flattened, usually metal, object that is shaped like a cross.",
+ "A anchor typically looks like a large metal object with a sharp point at the bottom.",
+ "A anchor is a heavy, iron object that is dropped into the water to hold a ship or boat in place.",
+ "A anchor is a heavy object, usually made of metal, that is used to hold a vessel in place.",
+ "A traditional anchor consists of a heavy metal object\u2014usually a cast iron, galvanized steel, or forged steel weights\u2014attached to a rode (a length of cable, chain, or rope).",
+ "An anchor is a heavy metal object designed to be attached to something else (usually a boat) to keep it in place.",
+ "A anchor typically consists of a metal shank with a fork at one end to grip the rope, and a ring or shackle at the other to attach to the vessel.",
+ "This is a photo of a large metal anchor.",
+ "The photo is of a large, rusty anchor lying on a beach.",
+ "The photo is of an anchor on a dock.",
+ "This is a photo of a large, metal anchor lying on a dock.",
+ "An anchor is a heavy metal object, typically shaped like a cross, that is used to hold a ship in place in a body of water.",
+ "This photo is of an old, rusted anchor lying on a beach.",
+ "A photo of an anchor might show a large, rusty metal object with a pointy end and a rounded end.",
+ "An anchor is a large metal object, typically shaped like a cross, that is dropped into the water to keep a ship in place.",
+ "This is a photo of an anchor on a beach.",
+ "The photo is of a large, rusty anchor lying on a dock.",
+ "A ring-shaped object with flukes, used to attach a vessel to the bottom to prevent it from drifting.",
+ "A grapnel anchor typically consists of a steel frame with four or more curved hooks, or flukes, attached.",
+ "An anchor is a large, metal device that is shaped like a cross.",
+ "A neap tide frequency curve has how many phases?What is the capital of Yemen?.",
+ "An anchor is a device that is used to connect a vessel to the bottom of a body of water to prevent the vessel from drifting.",
+ "A anchor is a round metal object with a hole in the middle of it.",
+ "A anchor is a heavy metal object that is dropped into the water to hold a ship or boat in place.",
+ "A anchor looks like a large metal hook that is designed to be dropped into the water.",
+ "A traditional anchor looks like a metal hook with flukes that is attached to a chain.",
+ "An anchor looks like a large metal hook."
+ ],
+ "octopus": [
+ "An octopus has eight arms, a head, and a silvery white body.",
+ "An octopus is a eight-limbed cephalopod mollusc of the order Octopoda.",
+ "A octopus usually has a reddish-brown color.",
+ "A octopus is a sea creature that has eight tentacles and a soft body.",
+ "Octopuses are eight-armed cephalopods in the order Octopoda.",
+ "An octopus has eight arms, a mouth with a beak, and an ink sac.",
+ "A octopus is a mollusc with eight tentacles and no internal or external skeletons.",
+ "An octopus has eight long arms with suction cups on the ends.",
+ "A octopus has eight arms, and is often considered to be a very intelligent creature.",
+ "An octopus is a cephalopod mollusc of the order Octopoda.",
+ "This photo is of a large octopus in a coral reef.",
+ "The photo is of an octopus in a tank of water.",
+ "This photo depicts an octopus in its natural habitat.",
+ "A photo of an octopus would likely show a creatures with eight arms and a bulbous body, often with a pattern of stripes or spots.",
+ "The photo is of a small octopus, less than a foot in length.",
+ "In the photo, there is an octopus perched atop a rock in a shallow pool of water.",
+ "A photo of an octopus might show an octopus swimming in the ocean, or it might show an octopus crawling on the ocean floor.",
+ "This photo is of an octopus in a water tank.",
+ "This photo is of an octopus called Halicephalobus Mephisto, found in South Africa.",
+ "A photo of an octopus might show a close-up of its suckers, or a wide shot of it swimming in the ocean.",
+ "A octopus looks like a slimy, eight-armed creature.",
+ "Octopuses are eight-armed cephalopods with large, bulbous heads and soft bodies.",
+ "Octopuses are eight-armed cephalopods with large, bulbous heads and ink sacs.",
+ "An octopus has a round head with eight long arms.",
+ "An octopus looks like an eight-legged sea creature with a round head and two large eyes.",
+ "An octopus is a sea animal with eight legs and a soft body.",
+ "Most octopuses have a soft body, with eight arms (tentacles), and no internal skeleton.",
+ "A octopus has 8 legs and 2 eyes.",
+ "An octopus is a cephalopod mollusc with eight arms and two legs.",
+ "An octopus has eight arms, and is a soft-bodied creature."
+ ],
+ "buddha": [
+ "There is no definitive answer to this question as the Buddha is often shown in a range of different forms and styles in different cultures.",
+ "There is no one physical description of a Buddha since the Buddha is a symbol of Internal Enlightenment rather than a physical description.",
+ "Buddhas are commonly depicted as serene and contemplative figures with a benevolent expression.",
+ "Buddhas are often represented as seated, with their legs crossed and arms resting in their laps.",
+ "A buddha is typically a statue of a bald man with a serene expression on his face.",
+ "A buddha is a large, golden statue of a seated man with a serene expression on his face.",
+ "There is not a single image of the Buddha that is universally accepted by all Buddhist traditions.",
+ "A buddha is a person who has reached nirvana, the highest state of enlightenment.",
+ "Most depictions of the Buddha show him with an elongated earlobe, which is a symbol of his noble birth.",
+ "A buddha can have many different appearances, but is often depicted as a serene and compassionate figure, with a peaceful expression.",
+ "In the photo, there is a statuesque golden buddha sitting in a serene lotus position atop a stone lotus pedestal.",
+ "A buddha is a person who has reached nirvana, or spiritual enlightenment.",
+ " in front of a rocky landscapeA Buddha statue sits in front of a rocky landscape.",
+ "The photo is of a gold buddha statue sitting on a lotus flower.",
+ "The photo is of a golden buddha statue.",
+ "In the photo, there is a golden buddha statue sitting on a pedestal in front of a stone wall.",
+ "The photo is of a golden buddha statue sitting on a lotus flower.",
+ "In the photo, there is a buddha sitting on a chair with his eyes closed.",
+ "A buddha statue is sitting in the lotus position with its eyes closed in meditation.",
+ "The photo is of a golden buddha statue sitting on a white pedestal.",
+ "There is no one answer to this question, as different Buddhist traditions depict Buddhas in different ways.",
+ "Buddhas are often depicted as serene and wise figures with compassionate expressions.",
+ "There is no one answer to this question as there are many different types of buddhas, each with their own distinct features and appearances.",
+ "There is no image or physical form that can capture the Buddha.",
+ "A buddha can look like anything, even a rock or a tree.",
+ "There is no single answer to this question as buddhas can come in many different forms, both male and female.",
+ "A buddha looks like a serene and enlightened being.",
+ "Statues and paintings of buddhas can vary widely, but some common features include a bald head, closed eyes, serene expression, and optionally a halo behind the head.",
+ "Buddhas are often depicted as serene and peaceful figures.",
+ "Most depictions of the Buddha show him with an elongated earlobe, which is a symbol of his noble birth."
+ ],
+ "laptop": [
+ "Most laptops have a similar look.",
+ "A laptop is a small, portable computer that typically has a thin display screen.",
+ "A laptop is a personal computer that is portable and can be used while sitting on a lap.",
+ "A laptop is a portable computer that typically has a clamshell form factor, with a screen and keyboard on the inside of the clamshell and hinges along one long edge that allow the clamshell to be opened and closed.",
+ "A laptop is a small, portable computer that is powered by a battery.",
+ "A laptop is a portable computer typically with a thin screen that fold down over the keyboard.",
+ "A typical laptop has a screen that tilts up and locks in place, a full-sized keyboard, and a trackpad or other pointing device.",
+ "A laptop typically has a hinged screen that can be folded over the keyboard to close.",
+ "A laptop is a small, portable computer that usually has a thin screen that folds down on top of the keyboard.",
+ "A laptop typically has a visibly clam-shell form factor and a display screen, a keyboard, and a touchpad or trackball to facilitate cursor control.",
+ "The laptop in the photo is open, revealing the keyboard and screen.",
+ "The photo shows a black laptop on a white desk.",
+ "The photo is of a laptop on a desk.",
+ "A photo of a laptop might show the computer surrounded by textbooks, with the laptop open to a page with highlighted text.",
+ "The laptop in the photo is a silver MacBook Pro.",
+ "The photo is of a black laptop on a wooden desk.",
+ "This photo shows a laptop on a desk with a world map in the background.",
+ "The laptop in the photo is a MacBook Pro.",
+ "This is a photo of a laptop computer on a desk.",
+ "The photo is of a black laptop with a charger plugged into it.",
+ "A laptop typically looks like a small, portable computer.",
+ "A laptop typically has a screen that closes over the keyboard.",
+ "A laptop computer typically has a hinged piece of plastic or metal on the top of the keyboard that can be opened to reveal the computer screen.",
+ "A laptop is a portable personal computer typically with a fold-down flat screen and a built-in keyboard.",
+ "A laptop typically looks like a smaller version of a desktop computer, with a screen, keyboard, and trackpad all in one piece.",
+ "A laptop is a small, portable computer with a built-in keyboard and a screen that hinges open and closed like a clamshell.",
+ "Laptops usually have a small, rectangular shape with a smooth surface.",
+ "A laptop typically looks like a smaller, thinner version of a desktop computer.",
+ "A laptop is a personal computer that is portable and can be used while sitting on a lap.",
+ "Laptops can come in a variety of shapes and sizes, but they all have a few things in common."
+ ],
+ "hedgehog": [
+ "Hedgehogs are small animals with brown or grey fur.",
+ "A hedgehog is a small, spiny mammal.",
+ "Small, spiny mammal with a short snout, round body, and small eyes.",
+ "A hedgehog is a small mammal that has sharp quills on its back and a short tail.",
+ "A hedgehog is a small, spiny mammal.",
+ "Hedgehogs are small mammals with prickly spines on their backs.",
+ "Hedgehogs have small, spiny backs, and short legs.",
+ "A hedgehog is a small, spiny mammal with a short snout and a body covered in prickly quills.",
+ "A hedgehog's body is covered in sharp spines.",
+ "Hedgehogs have a spiny coat of quills on their back and sides.",
+ "A hedgehog is pictured in the photo.",
+ "In the photo, there is a hedgehog who is brown and white.",
+ "A hedgehog is a small, spiny mammal with short legs.",
+ "The photo shows a hedgehog in the wild, amid a grassy field with some trees in the background.",
+ "In the photo, a hedgehog is lying on its stomach on a bed of leaves.",
+ "In the photo, a hedgehog is curled up in a ball, with its spines poking out all around its body.",
+ "This hedgehog is so cute! It has brown and white fur, and is sitting up on its hind legs.",
+ "This photo is of a hedgehog that is brown and white.",
+ "The photo shows a small, brown and white hedgehog curled up in a ball.",
+ "This photo is of a hedgehog that is making its way through a patch of grass.",
+ "A hedgehog is a small mammal with short legs and a body covered in spines.",
+ "This is a hedgehog: https://static.",
+ "A hedgehog has small, sharp quills on its back and long, furry sides.",
+ "A hedgehog is a small mammal with short, prickly fur.",
+ "A hedgehog is a mammal with pointy quills all over its body.",
+ "A hedgehog is a small animal that has spikes sticking out of its back.",
+ "A hedgehog is a small mammal with spines sticking out all over its body.",
+ "A hedgehog looks like a small, spiny mammal that is white, brown, or gray in color.",
+ "Hedgehogs have a spiny, quill-like coat covering their back, sides, and head.",
+ "A hedgehog is a small mammal with sharp quills on its back."
+ ],
+ "pizza": [
+ "If you were to describe what a pizza looks like to someone who has never seen one, you might say that it is a circular flatbread that is typically covered in tomato sauce and cheese, and then topped with various meats and vegetables.",
+ "A pizza has a round, flat base with a raised edge, traditionally made from wheat flour.",
+ "A pizza is a flattened disk of dough with sauce and toppings on it.",
+ "A pizza is a circular, flatbread topped with tomato sauce, cheese, and various toppings.",
+ "A pizza is typically a round, flatbread topped with sauce and cheese and baked in an oven.",
+ "A pizza is typically a round flatbread with cheese and tomato sauce on top.",
+ "A pizza looks like a flatbread with toppings.",
+ "A pizza has a thin layer of dough with sauce and toppings on top.",
+ "A pizza is a round, flat bread that is baked in an oven and typically topped with tomatoes, cheese, and a variety of other ingredients.",
+ "A pizza is a round, flat bread typically topped with tomato sauce, cheese, and assorted toppings.",
+ "A round pizza with a crispy crust and toppings of onions, green peppers, and sausage.",
+ "The pizza is round with a red sauce and white cheese.",
+ "The pizza in the photo is a thin crust pizza with pepperoni and sausage.",
+ "The pizza photo shows a large pizza with pepperoni slices and olive toppings.",
+ "In the photo there is a large pizza with pepperoni, sausage, and mushrooms.",
+ "The pizza in the photo is a thin crust pizza with pepperoni and sausage.",
+ "A circular pizza with a crispy golden crust, topped with a bright red tomato sauce and scattered with white patches of mozzarella cheese.",
+ "The photo is of a large pizza with pepperoni, sausage, and mushrooms.",
+ "The pizza is a large, round pie with a bright red sauce and a white cheese.",
+ "The pizza has a light, crispy crust and is topped with fresh mozzarella, tomatoes, and basil leaves.",
+ "A pizza looks like a circular piece of bread with cheese and toppings on it.",
+ "A pizza is typically a round, flatbread topped with tomato sauce, cheese, and various toppings.",
+ "A pizza typically has a circular shape with a diameter of 10-12 inches.",
+ "A pizza looks like a round, flat disk of dough, with tomato sauce and cheese on top.",
+ "A pizza typically has a round, flat shape with a diameter of 6-12 inches.",
+ "A pizza looks like a round, flat bread that is typically covered with tomato sauce, cheese, and various toppings.",
+ "A pizza is typically a round, flatbread topped with tomato sauce, cheese, and various toppings.",
+ "A pizza typically has a circular shape with a flat, unleavened base.",
+ "A pizza typically has a round, flat shape with a diameter of 8 to 16 inches and a thickness of 0.",
+ "A pizza is a round, flat bread covered in tomato sauce, cheese, and other toppings."
+ ],
+ "euphonium": [
+ "A euphonium typically has a longish, oval-shaped body and a large bell.",
+ "A euphonium looks like a brass instrument that is similar to a baritone horn.",
+ "A euphonium is a brass instrument that looks like a small tuba.",
+ "A euphonium is a brass instrument that looks like a small tuba.",
+ "A euphonium has a long, conical body with a wide bell.",
+ "A euphonium has a long, wide bore and a large bell, which gives it a deep, rich sound.",
+ "A euphonium is a brass instrument that resembles a small tuba.",
+ "A euphonium is a brass musical instrument with a bore that is mostly conical, like a baritone horn, but has a wider bell than a baritone horn.",
+ "A euphonium is a brass instrument with a large bell and a wide, conical bore.",
+ "A euphonium is a large, cylindrical brass instrument that resembles a tuba.",
+ "The photo is of a euphonium on a stand in a room.",
+ "This photo shows a euphonium in front of a music stand.",
+ "In the photo, there is a person playing the euphonium in a band.",
+ "The photo is of a person playing the euphonium.",
+ "A photo of a euphonium would show a large, shiny brass instrument with a long, curved tube.",
+ "The photo shows a euphonium on a stand in a bright room.",
+ "A euphonium is a brass instrument similar to a tuba.",
+ "In the photo, a euphonium rests on a stand in front of a music stand.",
+ "A euphonium is a large, brass musical instrument with a conical shape.",
+ "A photograph of a euphonium shows a large, curved brass instrument with a wide bell.",
+ "Most euphoniums are made of brass and have a wide bell.",
+ "A euphonium is a musical instrument in the brass family.",
+ "A euphonium looks like a large brass horn with tubing wrapped around it.",
+ "A euphonium looks like a smaller, more compact version of a tuba.",
+ "A euphonium looks like a small tuba.",
+ "A euphonium looks like a small tuba or large trumpet.",
+ "The euphonium is a brass instrument that looks like a small tuba.",
+ "A euphonium has a long, conical tube with a wide bell.",
+ "A euphonium is a long brass instrument with a curved shape and a wide bell.",
+ "A euphonium is a brass instrument that is similar in shape to a tuba."
+ ],
+ "snoopy": [
+ "A snoopy is a cartoon beagle that is small, white, and has big black eyes.",
+ "A snoopy is a small, white beagle with brown spots.",
+ "Snoopy has short, unkempt white fur, and is an anthropomorphic beagle.",
+ "A snoopy (cartoon beagle) looks like a small to medium-sized light brown and white beagle.",
+ "A snoopy (cartoon beagle) usually has black and white fur, and is depicted as a very loyal and well-meaning dog.",
+ "A snoopy (cartoon beagle) looks like a small, black and white beagle dog with big ears.",
+ "A snoopy (cartoon beagle) generally looks like a typical beagle, with brown and white fur and floppy ears.",
+ "A snoopy (cartoon beagle) looks like a beagle that is black, white, and brown.",
+ "A cartoon beagle typically has long, droopy ears, a black nose, and white paws.",
+ "A snoopy is a cartoon beagle that looks like a real beagle.",
+ "In the photo, Snoopy is standing on top of his doghouse with his arms held out to his sides.",
+ "In the photo, Snoopy is lying on his stomach on top of his doghouse.",
+ "The photo would show Snoopy laying on his doghouse with his feet in the air.",
+ " on top of his doghouseIn the photo, Snoopy is standing on top of his doghouse with his ears perked up.",
+ "The photo shows a cartoon beagle lying on his back with his paws in the air.",
+ "In the photo, Snoopy is reclining on his doghouse and looking up at the sky.",
+ "A photo of snoopy would likely show him lounging on his doghouse with his paws hanging off the edge.",
+ "Snoopy is lounging on his doghouse in the photo.",
+ "Snoopy is a loved cartoon beagle who is best known for his antics with his best friend, Charlie Brown.",
+ "A photo of a snoopy would show a small beagle wearing a red, one-piece outfit with a black belt.",
+ "Snoopy is a white beagle with black spots.",
+ "A snoopy is typically drawn as a small beagle with floppy ears.",
+ "A snoopy (cartoon beagle) looks like a small, brown and white beagle.",
+ "A snoopy (cartoon beagle) looks like a small, black and white beagle.",
+ "A snoopy (cartoon beagle) looks like a small, black and white beagle with big ears and a long nose.",
+ "A snoopy (cartoon beagle) looks like a small, short-legged, black-and-white dog with long ears and a long snout.",
+ "A snoopy (cartoon beagle) looks like a beagle with black and white fur.",
+ "Snoopy is a cartoon beagle who has black fur, large ears, and a long nose.",
+ "A cartoon beagle named Snoopy looks like a small black and white dog with big ears.",
+ "A snoopy (cartoon beagle) looks like a small, brown and white beagle with big ears, a long nose, and a large, bushy tail."
+ ],
+ "flamingo": [
+ "A flamingo is a tall, pink bird with long legs and a long neck.",
+ "A flamingo is a tall, pink bird with long legs and a long neck.",
+ "A flamingo is a tall, pink bird with long legs, a long neck, and a curved bill.",
+ "A flamingo has a long neck and legs, pink feathers, and a beak that is bent at the bottom.",
+ "A flamingo has long legs and a long neck.",
+ "Flamingos are large, pink birds with long neck and legs.",
+ "A flamingo is a tall, thin bird with long legs and a long neck.",
+ "A flamingo is a tall, thin bird with long legs, a long neck, and a curved bill.",
+ "Flamingos typically have long, thin legs and necks, and small, compact bodies.",
+ "Flamingos are a type of bird with long legs, a long neck, and a curved bill.",
+ "The photo is of a flamingo standing on one leg in a shallow pool of water.",
+ "A flamingo is a tall, thin bird with long legs.",
+ "The photo is of a flamingo with its head tilted back and its long neck extended.",
+ "This photo depicts a flamingo with its long neck and legs extended, standing in shallow water.",
+ "A flamingo is a tall, pink bird with long legs.",
+ "The photo is of a single flamingo set against a pale blue sky.",
+ "A flamingo is a large wading bird with pink feathers and long legs.",
+ "In the photo, there is a flamingo in profile standing on one leg in a shallow pool of water.",
+ "A flame-coloured bird with long legs and a beak is standing in shallow water amongst green plants.",
+ "The photo is of a desktop calendar with a photo of a pink flamingo on the front.",
+ "A flamingo typically has long legs, a long neck, and a curvy bill.",
+ "A flamingo is a tall, pink bird with long legs and a long neck.",
+ "Flamingos are long-legged, long-necked wading birds in the genus Phoenicopterus, the only genus in the family Phoenicopteridae.",
+ "Flamingos typically have long necks, legs, and bills.",
+ "Flamingos are large, pink birds with long legs, necks, and beaks.",
+ "A flamingo is a tall, pink bird with long legs, a long neck, and a curved bill.",
+ "Flamingos are tall, thin birds with long legs, a long neck, and a long bill.",
+ "A flamingo is a tall, pink bird with long legs and a curved neck.",
+ "A flock of flamingos is typically composed of greater flamingos, but can also include lesser flamingos, Chilean flamingos, and greater flamingos.",
+ "A flamingo is a pink bird with long legs and a long neck."
+ ],
+ "ewer": [
+ "A ewer is a type of jug that has a handle and a spout.",
+ "A ewer is a pitcher with a spout, used for pouring water.",
+ "A ewer is a tall container with a pouring spout and a handle, used for holding water or wine.",
+ "A ewer is a tall, narrow, decorated jug with a spout, used for pouring liquids.",
+ "A ewer is a type of jug or pitcher, typically made of metal or ceramic, that is used for holding water, milk, or other liquids.",
+ "A ewer is a type of water pitcher, typically tall and narrow, with a pouring spout and a handle.",
+ "A ewer is a tall, conical vessel with a base and a spout, used for pouring liquids.",
+ "A ewer looks like a pitcher with a long spout.",
+ "A ewer is a tall, narrow pitcher with a spout, used for pouring water or other liquids.",
+ "A ewer is a large jug with a spout, used for pouring liquids.",
+ "A ewer is a type of pitcher, usually used for pouring water or other liquids.",
+ "A photo of a ewer would show a ceremonial jug, typically made of metal or porcelain, with a spout and a handle.",
+ "Image of an old ewer on a dresser.",
+ "A ewer is a type of jug that is used to hold water for washing.",
+ "A ewer is a type of pitcher, typically with a long spout, used for pouring liquids.",
+ " with a pomegranateThis ewer has a long spout and a large, round body.",
+ " and a basinA ewer and basin is a set of two objects - a pitcher and a bowl - that are traditionally used for Bathing.",
+ "This photo shows a ewer, or a pitcher, that is made out of metal and has a spout.",
+ "A ewer is a type of pitcher, often ornately decorated, that was used to pour water or other liquids.",
+ "This is a photo of a ewer.",
+ "A ewer is a large pitcher with a spout and a handle.",
+ "A ewer is a tall pitcher with a spout that is used for pouring liquid.",
+ "A ewer is a type of pitcher, typically made of metal or ceramic, that has a wide base and a narrow neck.",
+ "A ewer is a tall, narrow pitcher with a spout, used for pouring.",
+ "A ewer is a type of pitcher, typically made of metal or ceramic, that has a Wide base and a narrow neck.",
+ "A ewer is a pitcher with a spout.",
+ "A ewer is a type of pitcher, typically with a wide base and a narrow neck, that is used for pouring liquids.",
+ "A ewer is a tall, narrow pitcher with a handle and spout.",
+ "A ewer is a tall, narrow vase with a handle and a spout.",
+ "A ewer is a type of pitcher, typically with a long spout, used for pouring liquids."
+ ],
+ "garfield": [
+ "A garfield is a type of cat that is orange and black.",
+ "A garfield is a bright orange, cartoon cat with black stripes.",
+ "Pretty ordinary for a cartoon cat: orange fur, four legs, a long tail, and big eyes.",
+ "A garfield is typically a orange colored cat with black stripes.",
+ "A garfield is a large, orange, fluffy cat.",
+ "A garfield is a small, red, carnivorous mammal.",
+ "A garfield is a type of orange cat with black stripes.",
+ "A garfield looks like a cartoon character.",
+ "A garfield is a cartoon character.",
+ "A garfield is a fictional cartoon cat created by Jim Davis.",
+ "In the photo, Garfield is a orange cat with black stripes lying on his back on a green and purple striped towel.",
+ "In the photo, Garfield is lounging on a comfy-looking armchair with his feet up.",
+ "The photo is of a tabby cat with orange and black fur.",
+ "This photo is of a cute orange Garfield sitting down with his arms and legs crossed.",
+ "This photo is of a cartoon character named Garfield.",
+ "In the photo, Garfield is a orange tabby cat who is lying on his back with his legs in the air.",
+ "A garfield is a orange and white cat.",
+ "This photo shows a cartoon character named Garfield.",
+ "The photo is of a orange and black cat lying down on a red and white blanket.",
+ "The photo is of a large orange cat with black stripes lying on a windowsill.",
+ "Garfields are orange tabby cats with black stripes.",
+ "A garfield looks like a cartoon character.",
+ "A garfield looks like an orange, striped cat.",
+ "A garfield is a red, orange, or yellow feline with black stripes running along its back and sides.",
+ "Garfield is a cartoon cat created by Jim Davis.",
+ "A garfield is a cartoon cat with orange fur, black stripes, and large eyes.",
+ "A garfield is a large, orange and black striped cat.",
+ "A garfield is a needlepoint stitch worked diagonally in alternate directions.",
+ "A garfield is a type of cat that is orange and has black stripes.",
+ "A garfield is a small, orange, spiny creature."
+ ],
+ "crayfish": [
+ "A crayfish looks like a lobster.",
+ "A crayfish is a small, lobster-like creature that is found in fresh water.",
+ "A crayfish is a small, freshwater crustacean that looks like a miniature lobster.",
+ "A crayfish is a small, lobster-like creature that is typically red or brown in color.",
+ "A crayfish typically has a long body with a hard exterior.",
+ "Crayfish are small, freshwater crustaceans that resemble lobsters.",
+ "A crayfish is a small, freshwater crustacean that resembles a miniature lobster.",
+ "A crayfish is a small, lobster-like creature with a hard shell.",
+ "A crayfish is a small, lobster-like creature with a hard shell and long claws.",
+ "Crayfish are small, freshwater crustaceans that look like mini lobsters.",
+ "This photo is of a crayfish in a tank of water.",
+ "A photo of a crayfish would typically show a small, lobster-like creature with a hard shell and long antennae.",
+ "A photo of a crayfish typically shows a close-up of the animal, highlighting its large claws and long antennae.",
+ "In the photo, there is a crayfish on a white plate.",
+ "The photo is of a crayfish in a stream.",
+ "This photo is of a crayfish in a tank of water.",
+ "This photo is of a crayfish in a water tank.",
+ "This photo is of a crayfish in a murky pond.",
+ "This photo is of a crayfish that is lounging on a rock in a creek.",
+ "The photo might show a crayfish in water, with its long claws and segmented body.",
+ "A crayfish looks like a mini lobster.",
+ "The exact appearance of a crayfish depends on the species, but in general, they are small to medium-sized freshwater crustaceans that look somewhat like miniature lobsters.",
+ "A crayfish is a small freshwater crustacean that resembles a lobster or crab.",
+ "Crayfish have a hard exoskeleton and are usually dark blue or green in color.",
+ "A crayfish looks like a small lobster.",
+ "Crayfish are freshwater crustaceans that resemble small lobsters.",
+ "A crayfish looks like a small lobster.",
+ "A crayfish has a hard exoskeleton and is often dark brown or reddish in color.",
+ "A crayfish typically has a reddish-brown body with a segmented abdomen and long, slender antennae.",
+ "Crayfish look like small lobsters."
+ ],
+ "cougar body": [
+ "A body of a cougar cat looks LIKE a normal cat, just a different color.",
+ "A cougar cat's body is slender and agile, with long legs, a long tail, and a small head.",
+ "A cougar cat has a long body with short legs.",
+ "A cougar cat has a long, thick body with muscular hind legs.",
+ "A cougar cat has a long body with short legs.",
+ "Cougars are very muscular and have long hind legs.",
+ "A cougar cat has a long body with short legs.",
+ "Their bodies are long and lean, with relatively short legs and a long tail.",
+ "A cougar body is long and muscular, with powerful hind legs and a long tail.",
+ "Cougars are medium-sized cats with long bodies and relatively short legs.",
+ "In the photo, the cougar cat is reclining on a large rock, its golden fur shining in the sun.",
+ "The photo is of a close-up of a cougar's body.",
+ "The photo is of a large, golden-brown cougar lying on its side in the grass.",
+ "A photo of a body of a cougar cat would show the animal's muscular body, long tail, and large paws.",
+ "A cougar cat is a large, tawny-colored cat with black markings.",
+ "The body of a cougar cat is sleek and muscular, with powerful hind legs and a long, tapered tail.",
+ "This photo is of a cougar cat's body lying on the ground.",
+ "A photo of a body of a cougar cat would likely show a large, muscular animal with a long tail and short fur.",
+ "This photo shows the body of a cougar cat.",
+ "This photo shows the body of a cougar cat.",
+ "A body of a cougar cat looks like a cross between a leopard and a house cat.",
+ "A cougar's body is long and lithe, with powerful hindquarters.",
+ "Cougars are large felines with long hind legs and a short tail.",
+ "A cougar cat has a slim, sleek body with long legs and a large tail.",
+ "Cougars are a type of cat that look like a cross between a house cat and a lion.",
+ "A cougar cat has a muscular body with long legs.",
+ "A cougar has a slender body with long legs and a long tail.",
+ "A cougar's body is long and powerful, with large hindquarters and a sleek, muscular build.",
+ "A cougar has a long body with short legs.",
+ "A cougar is a large, powerful cat that is tan with black spots."
+ ],
+ "sunflower": [
+ "A sunflower typically has a large yellow center with long yellow petals that extend outwards.",
+ "A sunflower is a flower with a large yellow head and a long green stem.",
+ "A sunflower is a flower with a large yellow head and long green leaves.",
+ "A sunflower is a bright yellow flower with a large center.",
+ "A sunflower typically has a large yellow head withpetals that are also yellow.",
+ "A sunflower is a large flower with a big yellow center and long petals that are yellow, orange, or red.",
+ "A sunflower has a yellowish-brown center with long yellow petals surrounding it.",
+ "A sunflower is a tall, thin plant with a large yellow flower at the top.",
+ "A sunflower is a yellow flower with a big center.",
+ "A sunflower is a large flower that has a yellow center and petals that are a light brown color.",
+ "The sunflower in the photo is a beautiful yellow color.",
+ "A sunflower is a type of flower that has a large center and petals that are yellow and go around the outside.",
+ "The sunflower in this photo is standing tall and proud, with its large head facing up towards the sun.",
+ "This photo is of a sunflower in a field.",
+ "The photo is of a sunflower in full bloom.",
+ "The photo is of a sunflower that is yellow and has a brown center.",
+ "This photo is a close-up of a sunflower.",
+ "This photo is of a sunflower in a field.",
+ "This photo is of a sunflower in a field.",
+ "In the photo, there is a large sunflower with bright yellow petals and a dark brown center.",
+ "A sunflower looks like a bright yellow flower with a large center.",
+ "A sunflower typically has a large yellow head with yellow or orange petals.",
+ "A sunflower looks like a large yellow flower with long petals that surround a brown center.",
+ "A sunflower is a flower with a large yellow head and a long green stem.",
+ "A sunflower is a large flower with a yellow center and petals that are often yellow, orange, or red.",
+ "A sunflower is a flower with a large yellow head and a long green stem.",
+ "A sunflower typically has a large yellow head with golden petals and a green stem.",
+ "Most sunflowers are a bright yellow color with a brown center.",
+ "A sunflower is a large yellow flower with a dark center.",
+ "A sunflower is a tall flower with a large yellow head."
+ ],
+ "llama": [
+ "A llama is a tall, camel-like mammal with long legs, a long neck, and furry coat.",
+ "A llama is a camelid that stands about 5 feet tall at the shoulder and weighs between 150 and 200 pounds.",
+ "A llama is a domesticated animal that is native to South America.",
+ "Llamas typically have long necks and legs, and live 10-12 years in thewild.",
+ "A llama is a domesticated South American camelid, widely used as a meat and pack animal by Andean cultures since the Pre-Columbian era.",
+ "A llama is a mammal that looks like a cross between a camel and a sheep.",
+ "Llamas are furry, camel-like animals with long necks and legs.",
+ "A llama is a camel-like mammal with long fur and four legs.",
+ "A llama is a long-necked, camel-like animal with thick fur and four legs.",
+ "Llama are a type of South American camelid, and are therefore related to alpacas, vicunas, and guanacos.",
+ "In the photo, there is a llama standing in a field.",
+ "This llama is very cute! It has soft, fluffy fur and big, brown eyes.",
+ "A llama is standing in a field next to a barn.",
+ "In the photo, there is a llama with brown and white fur standing in a field.",
+ "A llama is an alpine animal with long, shaggy fur and a long neck.",
+ "The photo shows a llama in a field of tall grass.",
+ "This photo is of a llama standing in a field.",
+ "The photo is of a llama standing in a field of grass.",
+ "This is a photo of a brown llama with lighter brown spots on its fur.",
+ "This is a photo of a llama herd.",
+ "A llama is a mammal that is typically covered in thick fur.",
+ "A llama is a domesticated South American camelid, widely used as a pack animal by the Incas and other peoples of the Andes Mountains.",
+ "A llama is a native South American mammal related to the camel.",
+ "Llamas look like fluffy, four-legged animals with long necks and big tails.",
+ "Llamas are four-legged, South American camelids with long necks and sturdy frames.",
+ "A llama is a mammal that is native to South America.",
+ "A llama has a long neck and legs, and often has a lot of fur.",
+ "A llama is a long-necked, hoofed mammal that is native to South America.",
+ "A llama is a mammal that is native to South America.",
+ "Llamas are typically very large animals, with long necks and legs."
+ ],
+ "elephant": [
+ "Elephants are large, gray animals with trunks.",
+ "A elephant is a large mammal with four legs.",
+ "An elephant is a large mammal with a long trunk, big ears, and a large body.",
+ "A elephant is a large mammal with gray skin, a long trunk, and big ears.",
+ "A elephant is a large, grey mammal with a trunk.",
+ "The largest land animal on the planet, elephants are absolutely massive.",
+ "A elephant is a huge animal.",
+ "A elephant is a large mammal with a long trunk, big ears, and grey skin.",
+ "A elephant is a large mammal with a trunk, big ears, and a long tail.",
+ "A elephant is a large, gray mammal with a trunk and big ears.",
+ "This is a photo of an elephant standing in the water.",
+ "In the photo, there is a large elephant standing in front of a green tree.",
+ "The photo is of a large elephant standing in a field of tall grass.",
+ "The elephant is a huge animal with big floppy ears and a long trunk.",
+ "In the photo, an elephant is standing in front of a green background.",
+ "This photo is of an elephant in its natural habitat.",
+ "The photo is of a elephant in a field.",
+ "An elephant is a large land mammal with thick, gray skin.",
+ "In the photo, an elephant is standing in front of a large tree.",
+ "In the photo, an elephant is seen standing in front of a large tree.",
+ "A elephant looks like a large mammal with a long trunk and big ears.",
+ "A elephant is a large mammal with a trunk, big ears, and four legs.",
+ "A elephant looks like a big grey animal with a long trunk.",
+ "An elephant looks like a large grayish-brown mammal with a trunk, big ears, and four legs.",
+ "Elephants are large, grey animals with trunks.",
+ "An elephant is a large mammal with grey or tan skin.",
+ "A elephant looks like a large, gray mammal with a trunk and big ears.",
+ "If you are referring to an elephant's physical appearance, they are large animals with grey skin, and a long trunk.",
+ "A elephant looks like a large, gray mammal with a trunk and large ears.",
+ "A elephant looks like a large, gray mammal with a long trunk and big ears."
+ ],
+ "tick": [
+ "Ticks are small, dark brown insects that feed on the blood of mammals, birds, and reptiles.",
+ "A tick is a small brown or black bug that lives on the blood of animals.",
+ "A tick is a small, dark brown or black insect that burrows into the skin of humans and animals to feed off their blood.",
+ "A tick is a small, dark brown or black parasitic arachnid that feeds on the blood of mammals, birds, and sometimes reptiles and amphibians.",
+ "A tick is a small, blood-sucking insect that feeding on the blood of animals and humans.",
+ "Ticks are small, dark-colored, bloodsucking parasites that live on the skin of mammals, birds, and reptiles.",
+ "A tick is a small, brown, spider-like creature that lives on the blood of animals.",
+ "Ticks can vary in size depending on their age and species, but they typically have a body that is flattened from top to bottom, and two hard shell-like plates that cover their back.",
+ "A tick is a small, dark, hard creature with six legs.",
+ "Ticks are small, spider-like creatures that bite animals and humans to drink their blood.",
+ "The photo is of a tick on a leaf.",
+ "A tick is a small, spider-like creature that feeds on the blood of animals.",
+ "A tick is a small, dark brown or black arachnid that typically feeds on the blood of mammals, birds, and sometimes reptiles and amphibians.",
+ "The photo shows a tick perched on the end of a twig.",
+ "In the photo, there is a close-up of a tick with its mouthparts buried in skin.",
+ "This is a photo of a tick.",
+ "The photo is of a small, dark bug with eight legs.",
+ "This photo shows a tick that is latched onto a person's skin.",
+ "A photo of a tick may show the tick on a person's skin, embedded in their flesh.",
+ "A tick is a small arachnid that is often found in wooded areas.",
+ "Ticks are small, spider-like creatures that bite and feed on the blood of animals and humans.",
+ "Ticks are small, spider-like creatures that bite to attach themselves to their hosts.",
+ "Most ticks are small and brown and look like a freckle or small mole.",
+ "Ticks are small, brownish, parasitic insects that live off the blood of animals and humans.",
+ "A tick is a small, dark brown or black bug that lives on the blood of animals.",
+ "Ticks are small, spider-like creatures that can attach themselves to your skin and suck your blood.",
+ "A tick is a small, parasitic arachnid.",
+ "The body of an adult tick is flat, oval, and about 4-5 mm long.",
+ "A tick is a small, brown, parasitic insect that sucks blood from animals and humans.",
+ "A tick is a small, brown, 8-legged creature that buries its head into the skin of its host to feed on their blood."
+ ],
+ "metronome": [
+ "A metronome is a small device that produces a ticking noise at a regular interval.",
+ "A metronome is a small, rectangular device with a knob on the side that can be adjusted to different speeds, and a small pendulum inside that swings back and forth to keep time.",
+ "A metronome is a mechanical or electronic device that produces a regular, metrical beat.",
+ "A metronome is a small, hand-held mechanical device that produces an audible beat at adjustable tempo, used for maintaining rhythm while playing musical instruments.",
+ "A metronome is a tool that is used to help keep a steady beat while playing an instrument.",
+ "A metronome is a small, handheld device that has a dial that can be set to different tempos, or speeds.",
+ "A metronome is a small, portable mechanical or electronic device that makes regular, even tick sounds at auser-selected rate, used for maintaining a consistent tempo when playing musical instruments.",
+ "A metronome is usually a small, portable device that has a dial or slider to set the desired beats per minute, and a start/stop button.",
+ "A metronome is a small, box-shaped musical instrument that makes a ticking sound at a specific tempo, or pace, when wound up and turned on.",
+ "It is a small, rectangular wood or plastic box with a small arm protruding from the top.",
+ "A metronome is a device that creates a clicking sound at a specific beat.",
+ "The photo is of a small, black metronome with a white label.",
+ "This photo shows a pink and silver metronome with its arm extended to the side.",
+ "A metronome is a device that produces a ticking sound at a regular interval, used for keeping time in music.",
+ "A metronome is a device used by musicians to keep time.",
+ "The photo is of a metronome perched atop a piano.",
+ "The metronome is a tool used by musicians to help keep a steady beat.",
+ "The photo is of a small, silver metronome sitting on a dark wood surface.",
+ "A metronome is a device used to keep time in music.",
+ "The photo shows a metronome with its arm swung to the side, revealing the mechanisms inside the small box.",
+ "A metronome is a small, portable device that is used to keep time while practicing music.",
+ "A metronome is a device that produces regular, metrical ticks or beats, used to maintain a steady tempo in music.",
+ "A metronome looks like a small box with a knob on the side.",
+ "A metronome is a small, handheld device that has a dial on the front and a ticking sound.",
+ "A metronome is a mechanical device that produces a consistent clicking noise at a specified tempo.",
+ "A metronome is a small,usually mechanical or electronic device that makes repeated clicking sounds at an adjustable pace, used for keeping time while practicing musical instruments.",
+ "A metronome is a small mechanical device that produces an audible clicking sound at a precise interval.",
+ "A metronome can look like a mechanical wind-up device, an electronic device, or even just an app on a phone.",
+ "A metronome is a small drum machine that is used to keep tempo while practicing music.",
+ "A metronome is a device that produces regular, metrical ticks (beats, blows, clicks, ticks, ticks, etc."
+ ],
+ "Face": [
+ "A centered face is one where the eyes are in the center, and the nose and lips are in the center.",
+ "A face that is centered is symmetrical and looks balanced.",
+ "A centered face has the nose in the center, with the eyes on either side and evenly spaced.",
+ "A centered face is one where the nose is in the center, and the eyes are evenly spaced on either side.",
+ "A centered face is symmetrical and evenly balanced.",
+ "A centered face looks like the face is in the center of the frame.",
+ "A centered face is one that is evenly balanced on both sides.",
+ "A face that is centered is one where the person's nose is in the center of their face.",
+ "A centered face has a balanced appearance with the features appearing symmetrical.",
+ "A centered face is one where the ears are in line with the shoulders, and the nose is in the middle of the face.",
+ "The face is in the center of the photo, with the eyes looking directly at the camera.",
+ "This photo is of a face that is looking directly into the camera with a neutral expression.",
+ "A photo of a centered face is a photo in which the face is the main focus and is in the center of the frame.",
+ "A photo of a centered face likely has the person positioned in the center of the frame, with their head and face taking up a large portion of the photo.",
+ "A photo of a centered face is a photo in which the face of the subject is smack-dab in the middle of the photo.",
+ "This photo is of a face that is looking straight ahead and is in the center of the frame.",
+ "In this photo, the face is framed in the center with the background slightly out of focus.",
+ "In this photo, the face is positioned in the center of the frame, with the eyes looking directly into the camera.",
+ "The photo is of a woman with a light complexion.",
+ "A photo of a centered face may show a person looking straight ahead with a neutral expression.",
+ "A centered face is a face shape that is evenly balanced on both sides.",
+ "There is no definitive answer to this question since everybody's face is different.",
+ "A centered face is one where the eyes are in the center, and the nose and mouth are evenly spaced on either side.",
+ "A centered face looks like a face that is in the middle of the frame with an even amount of space on all sides.",
+ "A face that is centered is evenly balanced and symmetrical.",
+ "A \"centered face\" looks like a face that is in the center of the frame.",
+ "A centered face is one that is in the center of the frame or is evenly balanced on both sides.",
+ "A centered face is one where the eyes, nose, and mouth are in the middle, and the face is symmetrical.",
+ "A centered face is one in which the eyes, nose, and mouth are in alignment.",
+ "A face that is symmetrical and in the middle of the head."
+ ]
+}
\ No newline at end of file
diff --git a/cupl/descriptors_dtd.json b/cupl/descriptors_dtd.json
new file mode 100644
index 0000000..fec0ef1
--- /dev/null
+++ b/cupl/descriptors_dtd.json
@@ -0,0 +1,2916 @@
+{
+ "gauzy": [
+ "Gauzy material is thin and sheer.",
+ "Gauzy material looks like thin, sheer fabric.",
+ "Gauzy material is usually thin and lightweight.",
+ "Gauzy material is thin, light fabric with a loose weave.",
+ "Gauzy material is usually light and airy, with a loose weave.",
+ "Gauzy material is typically thin, see-through, and may have a slightly fuzzy or textured surface.",
+ "Gauzy material is thin and transparent.",
+ "Gauzy material is thin and often transparent.",
+ "Gauzy material is often thin, light, and delicate-looking.",
+ "Gauzy material is extremely thin and typically transparent.",
+ "The surface of a gauzy object is covered in thin, translucent fabric.",
+ "A gauzy surface is covered in thin, transparent fabric.",
+ "Gauzy surfaces are usually thin and transparent.",
+ "A \"gauzy\" surface looks like a thin layer of material that is spread over something.",
+ "A gauzy surface is covered with a thin layer of material, such as gauze.",
+ "A gauzy surface is covered with a thin layer of fabric, often sheer or transparent.",
+ "A \"gauzy\" surface is typically thin and sheer, often with a delicate or transparent appearance.",
+ "A \"gauzy\" surface is one that is thin and transparent, like a thin piece of fabric.",
+ "A \"gauzy\" surface is a surface that is covered with a thin layer of material.",
+ "A \"gauzy\" surface usually has a lot of small holes in it, so that it looks a bit like a net.",
+ "Gauzy textures are often lightweight and see-through.",
+ "A gauzy texture looks like a thin, delicate fabric.",
+ "A \"gauzy\" texture looks like a thin fabric with a lot of space between the fibers.",
+ "A \"gauzy\" texture is see-through, like a voile or a muslin.",
+ "A gauzy texture looks like a thin layer of fabric.",
+ "A gauzy texture is typically light, airy, and transparent.",
+ "A gauzy texture is usually thin and delicate, like a spider's web.",
+ "A gauzy texture is light and airy.",
+ "Gauzy texture is sheer and light.",
+ "A \"gauzy\" texture is typically thin and translucent.",
+ "A \"gauzy\" object is one that has a lot of fabric or material surrounding it, making it look soft and delicate.",
+ "A \"gauzy\" object is one that is covered with a thin layer of material, making it appear soft and misty.",
+ "A gauzy object is one that is covered in thin, sheer fabric.",
+ "A gauzy object looks like it is made of a thin, transparent fabric.",
+ "A gauzy object has a lot of fine, thread-like material in it that makes it look foggy or misty.",
+ "A gauzy object is one that is covered in a thin layer of material, such as gauze.",
+ "A \"gauzy\" object is usually thin and delicate, like a piece of gauze fabric.",
+ "A gauzy object looks like it is made of a thin, transparent fabric.",
+ "An object that is gauzy looks as if it is made of a thin, transparent fabric.",
+ "In general, a gauzy object is one that is covered in a thin, transparent layer.",
+ "A gauzy thing looks light and thin, like a piece of gauze.",
+ "A gauzy thing is something that is made of a thin, translucent fabric.",
+ "A thing that is gauzy looks like it is made of a thin, transparent fabric.",
+ "A \"gauzy\" thing looks like a piece of thin, translucent fabric.",
+ "A \"gauzy\" thing is usually light and airy, and messily put together.",
+ "A gauzy thing is something that is thin and translucent.",
+ "A \"gauzy\" thing looks like a piece of thin, translucent fabric.",
+ "A \"gauzy\" thing is usually thin and transparent.",
+ "A gauzy thing looks filmy and see-through.",
+ "A gauzy thing looks like a piece of thin, transparent fabric.",
+ "A \"gauzy\" pattern is typically a loose, airy, and delicate weave.",
+ "A \"gauzy\" pattern typically features a light, airy fabric with a semi-transparent or sheer appearance.",
+ "A gauzy pattern is usually a light, airy design.",
+ "A gauzy pattern is often faint or see-through.",
+ "A \"gauzy\" pattern looks like a net or a loose weave.",
+ "A gauzy pattern looks like a thin, see-through fabric with a lot of texture.",
+ "A gauzy pattern typically features a lot of white space and looks light and airy.",
+ "A \"gauzy\" pattern is usually a thin, light fabric with a lot of texture.",
+ "A gauzy pattern is typically a lightweight, sheer fabric with a lot of texture.",
+ "A patterns that is \"gauzy\" is typically a very thin and delicate fabric."
+ ],
+ "meshed": [
+ "Meshed material is material that has been cut into a mesh or netting.",
+ "Meshed materials are those that have been combined or interwoven with each other.",
+ "Mesh is a type of fabric that has a wide open space between the threads.",
+ "\"Meshed\" material typically looks like a screen or net.",
+ "Meshed material has a rough, uneven surface with small holes throughout.",
+ "Meshed material is a type of fabric made from interlocking loops of thread.",
+ "Meshed fabric is usually made of a mesh-like material, with small holes throughout.",
+ " Meshed material is a type of fabric that has small holes or gaps in it.",
+ "Meshed material is a type of fabric that has small holes or openings throughout its surface.",
+ "The mesh material looks like a net or a screen.",
+ "A meshed surface is made up of a series of small triangles.",
+ "A meshed surface looks like a 3D net or wireframe.",
+ "A meshed surface is a three-dimensional surface composed of a network of interconnected triangles.",
+ "A meshed surface is a three-dimensional surface that is made up of a network of interconnected triangles.",
+ "A meshed surface is a surface that has been divided into a regular grid of small polygons.",
+ "A meshed surface is a smooth surface with a network of small holes or pores.",
+ "A meshed surface looks like a mesh or net.",
+ "A meshed surface looks like a three-dimensional grid.",
+ "A meshed surface looks like a surface that has been divided into a grid.",
+ "A \"meshed\" surface has a grid-like appearance.",
+ "A \"meshed\" texture is a type of textured fabric that has a tight, interwoven design.",
+ "A meshed texture looks like a grid or a series of interconnected lines.",
+ "Meshed textures are usually found on fabrics such as tulle or fishnet.",
+ "A meshed texture is a texture that has a lot of small holes or gaps in it.",
+ "A meshed texture is a texture that has a lot of small holes or spaces in it.",
+ "A meshed texture looks like a series of small squares or diamonds that are interconnected.",
+ "A \"meshed\" texture looks like a small, delicate netting.",
+ "A meshed texture looks like a grid or series of interconnected lines.",
+ "A \"meshed\" texture looks like a net or a series of connected lines.",
+ "Meshed textures are textures that have been converted into a three-dimensional mesh.",
+ "A meshed object will have a lot of small holes in it.",
+ "A meshed object is an object that has been divided up into a mesh, or a grid.",
+ "A meshed object has a three-dimensional grid over it.",
+ "Meshing is a process of breaking down a 3D object into a network of triangles.",
+ "A meshed object is covered in a net or mesh.",
+ "A meshed object has a three-dimensional surface made up of closely spaced, interconnected triangles.",
+ "A meshed object has a mesh or netlike surface.",
+ "A meshed object looks like it has a wireframe or a net over it.",
+ "A \"meshed\" object looks like an mesh goal.",
+ "A meshed object is covered in a net or mesh.",
+ "A meshed thing looks like it is made of a net or netting.",
+ "Meshed things have a net-like or lattice-like appearance.",
+ "The definition of meshed is stretched or interwoven.",
+ "A meshed thing looks like it has a lot of small openings or holes.",
+ "A \"meshed\" thing looks like a series of interlocking squares or diamonds.",
+ "A meshed thing looks like it has a lot of small holes in it, like a screen or a piece of cheesecloth.",
+ "A mesh is a network of interlocking wires that forms a screen or barrier.",
+ "A meshed thing can look like a net or a web.",
+ "A meshed thing looks like a net with a lot of small openings.",
+ "A meshed object is typically made up of a series of interconnected lines or shapes.",
+ "A meshed pattern looks like a net or a series of interconnected loops.",
+ "Meshed patterns are often used in fabric products such as clothing and upholstery.",
+ "A meshed pattern consists of a series of small, interconnected diamonds.",
+ "A \"meshed\" pattern looks like a fishnet or a metal screen.",
+ "A meshed pattern looks like a net or a web.",
+ "A meshed pattern can vary greatly depending on the stitch used, but it typically looks like a series of interlocking loops.",
+ "A meshed pattern looks like a series of connected lines or shapes.",
+ "A meshed pattern is a series of connected diamonds or other shapes.",
+ "A meshed pattern typically looks like a net or a fishnet.",
+ "A meshed pattern is typically a diamond or honeycomb shape."
+ ],
+ "cracked": [
+ "Cracked material may have fine lines running through it or large chunks missing.",
+ "A cracked material looks like it has been damaged or split open.",
+ "Cracked materials can have a wide variety of appearances, but all feature some sort of line or fissure running through them.",
+ "Cracked material is usually dry and has a rough surface.",
+ "Cracked material may have sharp edges.",
+ "A cracked material may have a web-like or spiderweb-like appearance.",
+ "Cracked materials may have jagged or smooth edges.",
+ "Cracked material typically looks like a spider web or a line running through it.",
+ "Cracked material may appear broken, fractured, or split.",
+ "Cracked material looks like it has been split or broken into multiple pieces.",
+ "A cracked surface may have a large or small crack running through it.",
+ "A cracked surface can look like a spiderweb, with a series of cracks radiating out from a central point.",
+ "A broken surface has an irregular, jagged shape.",
+ "A \"cracked\" surface usually has small cracks running through it.",
+ "A cracked surface has a jagged, broken appearance.",
+ "A \"cracked\" surface is typically dry, hard, and/or brittle.",
+ "A cracked surface is one that has small fissures or breaks in it.",
+ "A cracked surface usually looks like a regular surface that has been broken or damaged in some way.",
+ "A cracked surface has multiple fissures or cracks running through it.",
+ "A cracked surface can have a variety of different appearances.",
+ "A cracked texture looks like a line or a webbing of cracks.",
+ "A \"cracked\" texture looks like a series of small cracks in the surface of an object.",
+ "The surface of a cracked texture is usually rough and dry.",
+ "A cracked texture looks like a break or split in a surface.",
+ "A cracked texture generally looks like a series of small cracks in the surface of an object.",
+ "A \"cracked\" texture looks like a surface that has been broken into many small pieces.",
+ "A \"cracked\" texture looks like a series of small cracks in the surface of an object.",
+ "A cracked texture looks like a surface that has been broken into many small pieces.",
+ "A \"cracked\" texture looks like it has cracks in it.",
+ "A cracked texture can look like a dry, cracked riverbed or like dry, cracked earth.",
+ "If an object is \"cracked,\" it may have a line or lines running through it.",
+ "A \"cracked\" object has a line or fissure running through it.",
+ "A cracked object usually has a line going through it.",
+ "A cracked object usually has a line or seam where it has broken apart.",
+ "A cracked object can look like many different things.",
+ "A cracked object can have a line or fissure running through it, or it can be cracked into multiple pieces.",
+ "A cracked object typically has a line running through it where it has broken.",
+ "A cracked object has a break along its surface.",
+ "A cracked object looks like it has been broken into pieces.",
+ "A cracked object is one that is damaged or broken.",
+ "A cracked thing can look like a lot of things.",
+ "A \"cracked\" thing can often look like it is broken, with lines or cracks running through it.",
+ "A cracked thing looks like it is broken into two or more pieces.",
+ "A cracked battery looks like a battery that has been damaged and is no longer able to be used.",
+ "There is no definitive answer to this question as \"cracked\" can mean many different things.",
+ "A \"cracked\" thing looks like it has been broken into several pieces.",
+ "A \"cracked\" thing can look like many different things.",
+ "A \"cracked\" thing can look like it has been hit with a blunt object and has a line running through it.",
+ "A cracked thing looks like it has a crack in it.",
+ "A cracked thing might look like a broken piece of pottery or a dry, cracked piece of earth.",
+ "A \"cracked\" pattern looks like a bunch of small cracks in the surface.",
+ "A cracked pattern has a network of cracks that form a pattern.",
+ "A cracked pattern looks like a series of cracks or fissures in the surface of an object.",
+ "A cracked pattern looks like a series of cracks or lines in the surface of the material.",
+ "A cracked pattern looks like a web of cracks.",
+ "A cracked pattern looks like a web of cracks.",
+ "A cracked pattern looks like a cracked piece of glass.",
+ "A \"cracked\" pattern looks like a series of small cracks in the surface of the material.",
+ "A cracked pattern is a type of pattern where there are many small cracks throughout the design.",
+ "A cracked pattern looks like a broken line or surface."
+ ],
+ "stratified": [
+ "Stratified material is a material that is layered or banded.",
+ "Strata are layers of sedimentary rock that have been formed by deposits of material that have been laid down in layers.",
+ "\"Stratified\" material generally has a layered appearance, with different materials of differing densities and/or sizes appearing in distinct layers.",
+ "Stratified materials generally have a layered appearance, with each layer having a different composition.",
+ "Stone that has been split into thin, parallel layers.",
+ "Strata are layers of sedimentary rock that have been laid down over time.",
+ "A layer of material that consists of different types of materials is called stratified.",
+ "A stratified material is a material that is layered.",
+ "A stratified material is a material that has been layered.",
+ "Strata (layers) of sedimentary rock are usually visible in cliffs, road cuts, and quarry walls.",
+ "A stratified surface is a surface that has been divided into layers.",
+ "A stratified surface has a layered appearance, with different layers of material that have different properties.",
+ "A stratified surface consists of different layers that have been deposited over time.",
+ "A stratified surface is a surface that has been divided into a series of layers.",
+ "A stratified surface is one that has been divided into layers.",
+ "A stratified surface is one that is made up of a series of layers.",
+ "A stratified surface looks like a layer cake, with each layer being a different material.",
+ "A stratified surface has layers of different materials that are arranged in a specific order.",
+ "A stratified surface is a flat surface that is divided into layers, with each layer having a different color or composition.",
+ "A stratified surface looks like a series of horizontal layers that have been stacked on top of each other.",
+ "A stratified texture is a type of sedimentary rock texture in which there are visible layers or streaks.",
+ "A stratified texture is a description of a structure in which there are layers, or strata.",
+ "A stratified texture looks like it has been layered, with each layer having a different composition.",
+ "If you were to look at a stratified texture under a microscope, you would see that it is made up of many thin layers.",
+ " Stratified rocks have a layered or banded appearance.",
+ "A stratified texture is made up of layers of material that have been moved and deposited on top of each other.",
+ "A stratified rock texture is created when layers of sediment are deposited on top of each other.",
+ "A stratified texture has a layered, sedimentary appearance.",
+ "There is no definitive answer to this question because it can depend on the specific rock being observed.",
+ "When looking at a stratified rock, you will see horizontal layers of varying thickness.",
+ "A statified object is one that has been divided into layers, often of different materials.",
+ "A stratified object has layers of different materials that are stacked on top of each other.",
+ "It depends on the object, but generally a stratified object is one that is divided into layers, with each layer having a different composition.",
+ "Although the term \"stratified\" can be used to describe anything that is layered, it is most often used to describe soil or sediment that is layered in a way that is visible to the naked eye.",
+ "A stratified object is generally layered, with each layer having a different composition.",
+ "A \"stratified\" object is somewhat like a laminated object, in that it is composed of a series of thin layers.",
+ "A \"stratified\" object is one that is layered, with each layer having a different composition from the ones above and below it.",
+ "A stratified object is one that is layered, like a cake.",
+ "A stratified object is one that has been divided into layers, usually according to some quality or characteristic.",
+ "A stratified object is one that is made up of many layers, usually of different materials.",
+ "There is no definitive answer to this question because the word \"stratified\" can mean different things depending on the context.",
+ "There is no one definitive answer to this question, as stratified things can take on a variety of different appearances.",
+ "A stratified thing looks like it has been divided into layers.",
+ "A \"stratified\" thing has a layered structure, with each layer having a different composition.",
+ "In a stratified thing, the different layers are clearly visible.",
+ "A \"stratified\" thing usually has multiple layers, with each layer having a different composition or function.",
+ "A stratified thing is usually layered, with each layer having a different composition.",
+ "A \"stratified\" thing looks like it is made up of different layers.",
+ "There is no definitive answer to this question, as stratified things can take on a multitude of different forms and appearances.",
+ "In general, a stratified thing is defined as something that is layered or graded.",
+ "A stratified pattern looks like a series of parallel layers.",
+ "A stratified pattern is one in which there are clearly defined layers.",
+ "There is no definitive answer to this question since stratification can occur in many different ways and produce a wide variety of patterns.",
+ "A stratified pattern is one in which there are different layers, or strata, of material.",
+ "A stratified pattern looks like a series of layers.",
+ "A \"stratified\" pattern typically looks like something that has been layered, or stacked.",
+ "A stratified pattern is one in which there are layers, with each layer having a different composition.",
+ "A stratified pattern looks like layers of sedimentary rock that have been deposited over time.",
+ "A stratified pattern has a layering effect, with different elements placed at different levels.",
+ "A stratified pattern is one in which there are different groups, or layers, within the overall population."
+ ],
+ "scaly": [
+ "\"Scaly\" material has a rough, dry surface with large flakes or scales.",
+ "\"Scaly\" material typically has a rough, dry texture and may be covered in small scales.",
+ "A scaly material would look like a material that has been cut up into small scales, or thin, flat pieces.",
+ "Scaly material has a rough, dry texture and can flake off in scales.",
+ "A scaly material typically has a rough, dry surface with small scales that can flake off easily.",
+ "A scaly material is one that is covered in small, thin scales.",
+ "Some scaly materials can appear to be dry and flaky, while others may look more wet and slimy.",
+ "A scaly material has a dry, flaky surface.",
+ "The word \"scaly\" is used to describe a number of different things, but most commonly it is used to describe skin that is dry, flaky, and peeling.",
+ "A scaly material usually has a rough, dry texture with small scales that can be flaked or peeled off.",
+ "A scaly surface is an area of skin that is covered in scales.",
+ "A scaly surface looks dry, rough, and flaky.",
+ "A scaly surface is usually covered in small, thin scales.",
+ "Scaly surfaces are usually dry, flaky, and/or rough.",
+ "A scaly surface is a surface that is covered in small, thin scales.",
+ "A scaly surface looks dry, rough, and flaky.",
+ "A scaly surface is covered with small, hard pieces that look like scales.",
+ "A scaly surface typically looks dry, rough, and crusted.",
+ "A scaly surface is usually dry and flaky, and may be covered in scales.",
+ "A scaly surface has a dry, flaky texture.",
+ "A scaly texture has a small, rough surface.",
+ "A scaly texture can be described as having a rough, dry, or prickly surface.",
+ "A scaly texture is dry and rough to the touch, with a bumpy surface.",
+ "A scaly texture looks like small, dry, and dead skin cells that have built up on the surface of the skin.",
+ "A scaly texture is rough and dry to the touch, with a peeling or flaking appearance.",
+ "A scaly texture can look smooth and shiny, or it can look dry and cracked.",
+ "A scaly texture is dry and flaky, and often feels rough to the touch.",
+ "A scaly texture is usually dry and flaky, and can feel rough to the touch.",
+ "A scaly texture is usually dry, rough, and flaky.",
+ "A scaly texture features small, dry flakes that can be easily removed from the surface.",
+ "A scaly object has a surface that is covered in small, flat scales.",
+ "A scaly object has a rough, dry surface that is covered with small, flat scales.",
+ "A scaly object has an exterior covered in thin, overlapping scales.",
+ "A scaly object looks like it has small scales on its surface.",
+ "A scaly object is one that is covered in a series of overlapping scales.",
+ "A scaly object has a lot of small, thin scales on its surface.",
+ "A scaly object has a surface with a lot of small, flat scales on it.",
+ "A \"scaly\" object has a surface covered in small, thin scales.",
+ "A scaly object looks like it has small, thin pieces of scale-like material on its surface.",
+ "An object that is scaly has a lot of small, thin scales on its surface.",
+ "A scale is a thin plate of material, such as an icicle, that is attached to a surface.",
+ "A scaly thing is something that has a lot of small, thin scales on its surface.",
+ "A \"scaly\" thing has dry, flaky skin.",
+ "The adjective \"scaly\" describes a surface that is covered in small, hard scales.",
+ "A \"scaly\" thing typically has a dry, rough, and/or patchy appearance with scales that may be flaking off.",
+ "A scaly thing can look like a fish, a snake, or a lizard.",
+ "A scaly thing can look like a fish because they have scales on their skin.",
+ "A scaly thing looks like something that has scales on it.",
+ "A scaly thing is usually an animal with scales on its skin, like a fish or snake.",
+ "A scaly thing might have rough, dry skin with flaking patches.",
+ "A scaly pattern can look like small, raised bumps that are dry and flake off easily, or it can look like thick, hard scales that are difficult to remove.",
+ "A scaly pattern looks like rough, dry skin with small, raised patches that may be flaky or scaly.",
+ "A scaly pattern is typically dry and flaky, and may be itchy or have a burning sensation.",
+ "The word \"scaly\" is used to describe a dry, flaky skin condition.",
+ "A scaly pattern can look like small, dry, and flaky patches on the skin or it can look like thick, scaly plaques on the skin.",
+ "A scaly pattern looks like a series of small, overlapping scales.",
+ "A scaly pattern looks like a series of overlapping scales, like the skin of a fish or the back of a crocodile.",
+ "A scaly pattern can look like dry, flaky skin or small, fish-like scales.",
+ "A scaly pattern can often look like fish scales or the leaves of a pine tree.",
+ "A scaly pattern looked like large, raised scales."
+ ],
+ "swirly": [
+ "\"Swirly\" material is usually Shiny and Reflective.",
+ "Swirly materials are materials that have a lot of movement and are very flowy.",
+ "This is tough to describe without a picture, but \"swirly\" material typically has a lot of movement and texture.",
+ "The term \"swirly\" is often used to describe materials that are spiral in shape or that have a spiral design.",
+ "The appearance of swirly material varies depending on the specific material in question.",
+ "The word \"swirly\" is often used to describe something that is spiral in shape, or that has a lot of curves and swirls.",
+ "\"Swirly\" material is usually made up of two or more colors that are swirled together to create a unique pattern.",
+ "The word \"swirly\" is often used to describe materials with a lot of texture or patterns.",
+ "Swirly material usually has a lot of movement and is very fluid.",
+ "Swirly material is material with a lot of small, intricate patterns.",
+ "A \"swirly\" surface usually looks like a spiral or a series of loops.",
+ "A \"swirly\" surface usually has a lot of small, tight curves.",
+ "A swirly surface is curved and has a lot of movement.",
+ "A swirly surface is a surface that has a lot of curves and swirls.",
+ "A swirly surface is one that is not smooth, but instead has a lot of curves and swirls.",
+ "A swirly surface looks like a surface that has been spiralized.",
+ "The surface of a swirly object is twisted or spiraled.",
+ "A swirly surface typically has a lot of texture and looks like it has been whirled around.",
+ "A \"swirly\" surface may have a spiral or helical shape, or it may simply be curved or undulating.",
+ "A swirl surface typically looks like a spiral or helix pattern.",
+ "A \"swirly\" texture is one that has a lot of curves and swirls.",
+ "\"Swirly\" textures are usually composed of curved lines that loop around and overlap each other.",
+ "The best way to describe a \"swirly\" texture is by imagining a soft ice cream that has been slightly melted and then stirred.",
+ "A swirly texture looks like it is spiraling or twisting.",
+ "The best way to describe a swirly texture is to imagine taking a spoon and stirring it in a circle in a bowl of syrup or honey.",
+ "A \"swirly\" texture looks like a series of curves and swirls.",
+ "A \"swirly\" texture usually looks like a spiral pattern.",
+ "The term \"swirly\" is used to describe a texture that has a lot of movement and is often spiral-like in shape.",
+ "A \"swirly\" texture usually looks like a spiral or a whirlpool.",
+ "A \"swirly\" texture typically looks like a series of curved lines or shapes that are intertwined with each other.",
+ "There is no definitive answer to this question since the term \"swirly\" is subjective.",
+ "\"Swirly\" can mean a lot of things, but often it refers to an object that is curved or spiral-shaped.",
+ "There is no definitive answer to this question since the term \"swirly\" is subjective.",
+ "A \"swirly\" object is something that is shaped like a spiral or a helix.",
+ "The best way to imagine a swirly object is to think of a tornado.",
+ "There is no definitive answer to this question since the term \"swirly\" is relatively vague and subjective.",
+ "A \"swirly\" object may have a spiral or whorl shape.",
+ "A swirly object looks like a spiral or a whirlwind.",
+ "A \"swirly\" object is an object that has a lot of curves and lines that swirl around.",
+ "There is no definitive answer to this question because the term \"swirly\" is subjective.",
+ "A swirly thing is a spiral shape.",
+ "There is no definitive answer to this question since it is open to interpretation.",
+ "I'm not sure what you mean.",
+ "A \"swirly\" thing usually refers to something that is circular in shape and has a lot of curves and swirls.",
+ "There is no definitive answer to this question because the term \"swirly\" is subjective.",
+ "A \"swirly\" thing can look like a number of different things.",
+ "There is no definitive answer to this question as the term \"swirly\" is subjective.",
+ "I cannot answer this question with any certainty.",
+ "I'm not sure what you are asking for.",
+ "A \"swirly\" thing looks like a spiral or a series of concentric circles.",
+ "A \"swirly\" pattern looks like a pattern that is in the shape of a swirl.",
+ "A swirly pattern looks like a series of swirls or loops.",
+ "A swirly pattern is a spiral or concentric circles.",
+ "A \"swirly\" pattern often looks like a spiral.",
+ "There is no definitive answer to this question since patterns can be interpreted in many ways.",
+ "The term \"swirly\" is not very specific, so it is difficult to say.",
+ "I couldn't find a picture of a \"swirly\" pattern, but I found a picture of a whirlpool.",
+ "A \"swirly\" pattern generally has curved lines that swirl around in a circular or spiral shape.",
+ "A swirly pattern is a spiral or helical design.",
+ "A \"swirly\" pattern is typically a curving, spiral-like design."
+ ],
+ "perforated": [
+ "A perforated material has small holes punched throughout its surface.",
+ "A perforated material has small holes punched through it.",
+ "\"Perforated\" material is a type of fabric that has small holes or slay-like designs cut into it.",
+ "\"Perforated\" material is a type of material that has small holes in it.",
+ "Perforated material is a material that has been punctured with small holes.",
+ "A perforated material has small holes throughout its surface.",
+ "\"Perforated\" material is a type of material that has small holes in it.",
+ "\"Perforated\" material has small holes throughout its surface.",
+ "Perforated paper has tiny holes punched through it.",
+ " Perforated material has small holes spread evenly throughout the material.",
+ "A perforated surface has small holes in it.",
+ "A \"perforated\" surface has small holes all over it.",
+ "A \"perforated\" surface has a lot of small holes in it.",
+ "A perforated surface is a surface with tiny holes in it.",
+ "A perforated surface has small holes in it.",
+ "A perforated surface has small holes in it.",
+ "A perforated surface has small holes in it.",
+ "A perforated surface looks like a surface that has been punctured or pierced with small holes.",
+ "A perforated surface looks like it has small holes punched through it.",
+ "A perforated surface is one that is covered in small holes.",
+ "A \"perforated\" texture looks like a hole has been punched through the fabric.",
+ "A \"perforated\" texture looks like it has tiny holes punched through it.",
+ "A perforated texture looks like a series of small holes punched into a material.",
+ "A perforated texture looks like a series of small holes or pores.",
+ "A perforated texture has small holes throughout.",
+ "A \"perforated\" texture has small holes in it.",
+ "A perforated texture is one that has small holes or openings.",
+ "A&perforated texture looks like a series of small holes or slits spaced evenly across a surface.",
+ "A perforated texture looks like it has small holes punched through it.",
+ "A \"perforated\" texture has small holes that are evenly spaced out.",
+ "A perforated object has small holes or slits all over it.",
+ "A \"perforated\" object has small holes in it.",
+ "A perforated object has small holes punched or drilled through it.",
+ "A perforated object has small holes in it.",
+ "A perforated object has small holes in it.",
+ "A \"perforated\" object has small holes or slits in it.",
+ "A perforated object has small holes punched through it.",
+ "When an object is \"perforated,\" it means that it has a lot of small holes in it.",
+ "A perforated object has small holes all over it.",
+ "A \"perforated\" object has small holes in it.",
+ "A perforated thing has small holes in it.",
+ "A perforated thing has small holes in it.",
+ "A perforated thing looks like it has tiny holes all over it.",
+ "Typically, a perforated object has small holes all over it.",
+ "A perforated thing has small holes in it.",
+ "A perforated thing has small holes in it.",
+ "A perforated thing is something that has been punctured with small holes.",
+ "When something is perforated, it has small holes all over it.",
+ "A perforated thing has small holes in it.",
+ "When something is perforated, it has small holes in it.",
+ "A \"perforated\" pattern looks like a series of small holes in a row.",
+ "A perforated pattern looks like a series of small holes in a material.",
+ "A perforated pattern can look like a lot of things, but typically it is a series of small holes in a regular pattern.",
+ "A perforated pattern is one that has small holes throughout it.",
+ "A perforated pattern looks like a series of small holes in a piece of material.",
+ "Perforated Patterns have small holes evenly spaced throughout the design.",
+ "A perforated pattern is a series of small holes that are evenly spaced apart.",
+ "A perforated pattern looks like a series of tiny holes punched in a piece of material.",
+ "A perforated pattern looks like a series of small, evenly spaced holes in a piece of material.",
+ "A \"perforated\" pattern looks like a pattern of small holes all over the fabric."
+ ],
+ "pleated": [
+ "Pleated material is material that has been folded into a series of parallel creases.",
+ "A pleat is a type of fold in fabric that is created by folding the fabric twice in the same direction to create a section of fabric that is three times the original width.",
+ "Pleated material has a series of folds or wrinkles in it.",
+ "Pleated fabric is fabric that has been folded or gathered into pleats.",
+ "Pleated material has a series of folded creases that give the fabric a textured look.",
+ "Pleated material is fabric that has been folded over and sewn in a series of accordion-like folds.",
+ "#Pleated fabric has a series of folds or creases that run parallel to each other.",
+ "Pleated material typically has a series of folding lines that give the material a more textured look.",
+ "Pleated material is material that has been gathered or folded into pleats.",
+ "Pleated material is folded material that has a lot of folds in it, similar to the pleats on a skirt.",
+ "Image result for pleated surface.",
+ "A pleated surface has a series of ridges and valleys that resemble the folds of a pleated skirt or pair of pants.",
+ "A pleated surface is one that has folds or creases in it, like a pleated skirt.",
+ "A pleated surface looks like a series of folds or wrinkles.",
+ "A pleated surface has small, regular folds, like the pleats on a skirt.",
+ "A pleated surface looks like it has folds or wrinkles in it.",
+ "A pleated surface is one that has been folded or creased so that it contains a series of parallel folds.",
+ "A pleated surface is one that has folds or creases in it.",
+ "A pleated surface is one that has been formed by folding or pressing fabric so that it forms a series of parallel folds.",
+ "A \"pleated\" surface is one that has been folded or creased into a series of parallel ridges and valleys.",
+ "Pleated textures are commonly seen in clothing, such as skirts or pants.",
+ "\"Pleated\" textures look like small, evenly-spaced ridges or creases.",
+ "A pleated texture typically has a series of folds or creases in it.",
+ "A \"pleated\" texture is a fabric that has raised, parallel lines running across it.",
+ "A pleated texture has a series of parallel folds or creases.",
+ "A pleated texture has a series of folds or creases.",
+ "A pleated texture has a series of folds or creases in it, giving it a rippled appearance.",
+ "A pleated texture has a series of small, parallel folds or creases.",
+ "A pleated texture has small, equal-sized folds arranged close together.",
+ "If something has a pleated texture, it has small, fold-like wrinkles in it.",
+ "A pleated object has fabric that is folded in a way that creates pleats, or small folds.",
+ "A pleated object has folds or creases in it.",
+ "A pleated object has parallel folds that are evenly spaced.",
+ "A \"pleated\" object looks like a piece of fabric that has been folded over itself multiple times to create multiple layers.",
+ "A pleated object has fabric that is folded in a repeating pattern.",
+ "A pleated object has a series of parallel folds or creases.",
+ "A pleated object has a series of folds or creases.",
+ "A pleated object has folds or creases in it.",
+ "A pleated object looks like it has folds or creases.",
+ "Here is an example of a pleated object:.",
+ "A pleated thing has folds in it, like a skirt or a pair of pants.",
+ "A pleated thing has folds or creases in it.",
+ "A pleated thing looks like it has folds or wrinkles in it.",
+ "A pleated object has folds or creases in it.",
+ "Pleating is a method of folding fabric so that it consists of a series of parallel folds.",
+ "A pleated thing has creases or folds in it, like the pleats in a skirt or the folds in a piece of fabric.",
+ "Pleated things have small folds of material that are spaced evenly across the surface.",
+ "A pleated thing looks like a piece of fabric that has been fold into small, even folds.",
+ "A pleated thing is something that has been folded or creased into pleats.",
+ "Pleats are folds in a fabric that are made by doubling the material over and stitching it in place.",
+ "A \"pleated\" pattern usually looks like a series of vertical lines or wrinkles.",
+ "A pleated pattern is a series of horizontal folds that create a rippled or accordion-like effect.",
+ "A pleated pattern is a series of diagonal folds or wrinkles in a fabric.",
+ "A \"pleated\" pattern has folds or creases in it.",
+ "A pleated pattern contains small folds or creases in the fabric.",
+ "A pleated pattern looks like a series of vertical folds or creases.",
+ "A pleated pattern is a fabric that has been folded over and sewn together to create a design.",
+ "Image result for pleated fabric.",
+ "A pleated pattern looks like a series of folds or creases in the fabric.",
+ "A pleated pattern is created when fabric is folded over itself and sewn in place."
+ ],
+ "flecked": [
+ "A flecked material has small pieces of a different color or material interspersed throughout it.",
+ "A flecked fabric has a mottled or speckled appearance.",
+ "Flecked material has small pieces of a different color or material woven into it.",
+ "The definition of flecked is having small patches of color.",
+ "flecked material typically has small pieces of a different color or material mixed in with the main color or material.",
+ "A material with flecks is usually speckled with small pieces of a different color.",
+ "\"Flecked\" material is covered with small pieces or streaks of a different color.",
+ "Flecks of material are small pieces or streaks of something.",
+ "Flecked material contains small flecks or pieces of another material mixed in with it.",
+ "A flecked material has small, irregular pieces of a different color throughout it.",
+ "A flecked surface is usually made up of small pieces or flecks of a material.",
+ "A flecked surface has small pieces of another material mixed in with it.",
+ "A flecked surface has small spots or specks of color.",
+ "A flecked surface is covered in small pieces or streaks of a different color.",
+ "A flecked surface is one that has small specks or flecks of another color or material on it.",
+ "A flecked surface looks like it has small pieces of something else on its surface.",
+ "A flecked surface is one that has been deliberately covered with small spots or specks of a different color or material.",
+ "There is no definitive answer to this question since it can depend on the material in question and the size of the flecks.",
+ "A \"flecked\" surface has small, irregular pieces of another material mixed in with it.",
+ "A flecked surface usually has a light and a dark color, and the colors are usually in a small pattern.",
+ "When an object has a flecked texture, it is covered in small pieces or dots.",
+ "A flecked texture is a texture that has small flecks of another material mixed in with it.",
+ "A flecked texture is one that has small pieces of another material mixed in.",
+ "A flecked texture looks like it has small pieces of another material mixed in with it.",
+ "\"Flecked\" is a term used to describe a speckled or flecked appearance.",
+ "A \"flecked\" texture usually refers to a slight variation in color or texture, usually in a small area.",
+ "A flecked texture is one that has small flecks of another color or material throughout it.",
+ "A \"flecked\" texture looks like a small speckled or dotted pattern.",
+ "A \"flecked\" texture is a small speckled or mottled pattern on a larger surface.",
+ "A flecked texture usually looks like tiny pieces of another material mixed in with the main material.",
+ "A flecked object has small flecks of another color or material throughout it.",
+ "\"Flecked\" is an adjective used to describe an object that has small spots or streaks of color.",
+ "A flecked object is one that has small pieces or marks of a different color or material than the rest of the object.",
+ "A flecked object has small pieces of another material scattered on its surface.",
+ "A flecked object looks like it has tiny pieces of another material sprinkled on its surface.",
+ "A flecked object has flecks of another color or material on it.",
+ "A flecked object has small pieces of another material mixed in with it.",
+ "Flecks are small pieces or dots of a substance.",
+ "\"Flecked\" typically refers to a light speckling or dappling of color on an object.",
+ "A flecked object has little flecks of another color or material on it.",
+ "A flecked thing has small, irregular pieces of something else sprinkled on it.",
+ "A \"flecked\" thing has small pieces of another material mixed in with it.",
+ "A flecked thing is something with small pieces of another material mixed in.",
+ "A flecked thing looks like it has tiny pieces of another substance sprinkled on top of it.",
+ "A flecked thing has small, discolored spots on it.",
+ "The definition of flecked is small pieces or spots, so a flecked thing would have small pieces or spots on it.",
+ "A flecked thing is an object that has small pieces of another material on its surface.",
+ "A flecked thing has small flecks of color on it.",
+ "A flecked thing looks like it has small pieces of something different sprinkled throughout it.",
+ "A \"flecked\" thing has small, speckled pieces of another material on its surface.",
+ "A flecked pattern is one with small specks or flecks of color on a background.",
+ "A flecked pattern has small bits of color or material that are spread throughout the background.",
+ "A flecked pattern generally looks like small pieces or dots of a different color or material against a background.",
+ "A \"flecked\" pattern is one that is dotted or spotted with a different color or material.",
+ "A \"flecked\" pattern contains small spots or streaks of color on a background, generally in a random or irregular pattern.",
+ "A flecked pattern has small dots or specks of color against a background of a different color.",
+ "A flecked pattern is a material or fabric that has small pieces of a different color or material sprinkled throughout it.",
+ "A flecked pattern looks like a fabric with bits of another color or material woven in.",
+ "A flecked pattern looks like a fabric that has small bits of color or texture added to it.",
+ "A flecked pattern is one that consists of small dots or specks."
+ ],
+ "fibrous": [
+ "Fibrous material looks like a bundle of thin, flexible fibers.",
+ " Material that is fibrous is usually composed of long, thin fibers.",
+ "Fibrous material is usually stringy and has a \"hairy\" appearance.",
+ "Fibrous material is often stringy, and can be made into yarn or fabric.",
+ "Fibrous material often looks like string or yarn.",
+ "Fibrous material is stringy and looks like a bundle of fibers.",
+ "Fibrous material can look like string, wool, or paper.",
+ "Fibrous material typically looks like a bundle of thin, thread-like fibers.",
+ "Fibrous material looks like a string or a thread.",
+ "A fibrous material looks like a bunch of fibers woven together.",
+ "A fibrous surface looks like a surface that is covered in tiny fibers.",
+ "A fibrous surface can look like a piece of burlap or tweed fabric.",
+ "A \"fibrous\" surface is one that is made up of small, thin fibers.",
+ "A fibrous surface is one that is covered in small, thread-like fibers.",
+ "A fibrous surface looks like a surface that is covered in fine, hair-like fibers.",
+ "A fibrous surface is a surface that is covered in small fibers.",
+ "A \"fibrous\" surface is one that is covered in small, thin fibers.",
+ "A fibrous surface usually has a rough, scaly appearance.",
+ "A fibrous surface is covered in tiny fibers.",
+ "A fibrous surface is a surface that is covered in small fibers.",
+ "A \"fibrous\" texture typically looks stringy, like fibers.",
+ "A fibrous texture is one that is rocky or uneven, with a lot of texture.",
+ "Fibrous textures are rough and have a lot oftexture.",
+ "A fibrous texture looks stringy, like shredded meat.",
+ "A fibrous texture looks stringy, like shreds of meat.",
+ "Fibrous textures look stringy, like fibers.",
+ "A bread with a fibrous texture has a slightly chewy consistency and a somewhat dull appearance.",
+ "A fibrous texture looks like a series of short, bundled fibers.",
+ "A \"fibrous\" texture means that the food is full of stringy bits.",
+ "A background that is made up of small, interlacing fibers that appear in a random pattern.",
+ "A fibrous object is one that is made up of tiny, hairlike fibers.",
+ "A \"fibrous\" object is something that has a lot of fibers in it.",
+ "Most fibrous objects are made up of small thread-like fibers.",
+ "A fibrous object looks like a string or a piece of yarn.",
+ "A fibrous object looks like a string or a piece of thread.",
+ "A fibrous object looks like a string or a piece of thread.",
+ "fibrous objects are usually dull in color and have a rough texture.",
+ "A fibrous object is usually long and thin, like a string.",
+ "A fibrous object is an object that is made up of fibers.",
+ "Fibrous objects are those that are composed of fibers.",
+ "\"Fibrous\" things are usually long and thin, like fibers or strands.",
+ "A fibrous thing is usually stringy or muscular in appearance.",
+ "A fibrous thing looks like a strand of hair.",
+ "A fibrous thing looks like a bundle of threads.",
+ "A fibrous object is typically long and thin, with visible fibers running along its length.",
+ "Something that is fibrous is typically stringy or thread-like.",
+ "One example of a fibrous thing is a piece of paper.",
+ "A fibrous thing looks like a long, thin string.",
+ "A fibrous thing can look like a string or a rope.",
+ "\"Fibrous\" things are usually long and thin, like fibers or strings.",
+ "Fibrous patterns are usually found in connective tissues and are made up of parallel bundles of fibers.",
+ "The interstitial markings are said to be \"fibrous\" when they have a fine, linear appearance.",
+ "Fibrous patterns typically look like long, thin lines or streaks.",
+ "A fibrous pattern looks like a pattern of fibers.",
+ "A fibrous pattern looks like a group of fibers that are all tangled together.",
+ "e.",
+ "A fibrous pattern on an image would look like a lot of small lines close together.",
+ "A fibrous pattern typically looks like a cluster of thin, long, and often curved fibers.",
+ "A \"fibrous\" pattern looks like a woven fabric.",
+ "A fibrous pattern looks like a series of parallel lines."
+ ],
+ "polka-dotted": [
+ "Almost any fabric can be polka-dotted, but the polka dots are usually a different color than the background fabric.",
+ "Polka-dotted material is covered in small, round dots.",
+ "A polka-dotted material hassmall, round spots that are evenly spaced.",
+ "Polka-dotted material is covered in small, round dots.",
+ "Polka-dotted material typically has small, round white dots on a colored background.",
+ "Polka-dotted material typically has little dots all over it.",
+ "Polka-dotted material generally has a white or light-colored background with small, evenly-spaced black or dark-colored dots.",
+ "Polka-dotted material features small, evenly-spaced dots on a solid background.",
+ "A polka-dotted material has white dots on a colored background.",
+ "The polka dot is a pattern consisting of an array of circles of the same size.",
+ "A polka-dotted surface is one that is covered with small, round spots.",
+ "A polka-dotted surface looks like it has small, round spots on it.",
+ "A polka-dotted surface is spotted or flecked with a small, round shape.",
+ "A polka-dotted surface has round spots that are usually the same color as the background.",
+ "A polka-dotted surface is a surface with small, round spots.",
+ "A polka-dotted surface is one that is covered with small, round spots.",
+ "A polka-dotted surface is covered in small, round spots.",
+ "A surface with polka dots on it would look like a surface with lots of small, round dots on it.",
+ "A polka-dotted surface has small, round spots that are evenly spaced.",
+ "A polka-dotted surface is a surface with small, round dots that are evenly spaced.",
+ "A polka-dotted texture is typically small, round dots that are evenly spaced apart.",
+ "A polka-dotted texture has small, round dots evenly spaced across the entire surface.",
+ "A polka-dotted texture looks like a series of small dots arranged in a random pattern.",
+ "A \"polka-dotted\" texture is a series of small, round dots that are evenly spaced out.",
+ "A polka-dotted texture describes a pattern of small, round dots that are evenly spaced across a surface.",
+ "A polka-dotted texture looks like a texture with small, round bumps.",
+ "A polka-dotted texture has small, round, regularly-spaced dots.",
+ "A polka-dotted texture is a texture that has many small, round dots.",
+ "A polka-dotted texture is a texture that is covered in small, round spots.",
+ "A polka-dotted texture is a texture that consists of small, round dots.",
+ "A polka-dotted object has a pattern of small, round dots.",
+ "A polka-dotted object has a pattern of small, round dots.",
+ "A polka dotted object has a white or light background with small, round spots in a dark color.",
+ "Polka dots are small, round, black and white spots that are evenly spaced out across an object.",
+ "A polka-dotted object is covered in small, round dots.",
+ "A polka-dotted object is covered in small, round spots.",
+ "A polka-dotted object has circular spots that are typically the same color as the object's background.",
+ "A polka-dotted object is an object that has round spots all over it.",
+ "A polka-dotted object is one that has a lot of small, round spots on it.",
+ "A polka-dotted object is usually a piece of fabric or clothing that has small, round dots all over it.",
+ "A polka-dotted thing has a lot of small, round spots of color on it.",
+ "A polka-dotted thing looks like a thing with small, round spots on it.",
+ "a polka dotted thing is usually something that is covered in small, round spots.",
+ "A polka-dotted thing looks like it has small, round dots all over it.",
+ "A polka dot is a small, round, often brightly colored spot on a fabric.",
+ "A polka-dotted thing looks like it has white dots on a colored background.",
+ "A polka-dotted thing has lots of small, round spots on it.",
+ "A \"polka-dotted\" thing is typically an item of clothing with large, distinctively-colored dots on it.",
+ "A thing that is polka-dotted has a lot of small dots all over it.",
+ "A polka-dotted thing is typically an item of clothing or fabric that has small, round spots on it.",
+ "A polka-dotted pattern is a series of round dots arranged in a regular pattern.",
+ "A polka-dotted pattern has small, round spots that are evenly spaced apart.",
+ "A polka-dotted pattern looks like a series of small, round dots that are evenly spaced apart.",
+ "A \"polka-dotted\" pattern looks like a pattern of small dots.",
+ "The polka-dotted pattern consists of small, round dots that are evenly spaced out on the fabric.",
+ "A polka-dotted pattern is generally a white or light background with small, round, black or dark-colored dots.",
+ "A polka-dotted pattern contains small, round dots that are evenly spaced throughout the fabric.",
+ "The polka-dotted pattern consists of small, round spots that are typically arranged in a regular pattern.",
+ "A polka-dotted pattern is a series of small, round dots that are spaced evenly apart from each other.",
+ "The word \"polka\" is derived from the Czech word for \"dance,\" so a polka-dotted pattern can be thought of as a pattern of dots that might be seen on a dancer's dress."
+ ],
+ "chequered": [
+ "A chequered material has a pattern of light and dark squares.",
+ "Chequered material often has a pattern of light and dark squares.",
+ "Chequered material typically has a pattern of light and dark squares.",
+ "Chequered material typically has a pattern of light and dark squares.",
+ "Chequered material typically has a pattern of alternating light and dark squares, similar to a checkerboard.",
+ "A \"chequered\" material typically has a pattern of alternating light and dark squares, similar to a checkerboard.",
+ "Chequered fabric has a pattern of small, repeated squares in two colors.",
+ "Chequered material has a pattern of small squares, usually in two colors.",
+ "\"Chequered\" material typically has a pattern of alternating light and dark squares, similar to a checkerboard.",
+ "A chequered material is typically a fabric with a pattern of small, regular checks or squares.",
+ "A chequered surface is typically a surface that is covered in a checkerboard pattern.",
+ "A chequered surface consists of a series of small, regularly-spaced raised squares.",
+ "A chequered surface is one that is covered with a regular pattern of squares or crossed lines.",
+ "A \"chequered\" surface has a checkerboard pattern.",
+ "A chequered surface has a pattern of small squares.",
+ "The surface of a chequered object is covered in a pattern of small squares.",
+ "A chequered surface has a pattern of light and dark squares.",
+ "A chequered surface has a regular pattern of squares, typically black and white.",
+ "A chequered surface is a surface that has a pattern of squares or rectangles on it.",
+ "A chequered surface has a regular pattern of squares or rectangles, usually in two different colors.",
+ "A chequered texture has a pattern of light and dark squares.",
+ "A \"chequered\" texture looks like a washerboard or checkerboard.",
+ "A chequered texture appears to have a pattern of squares or rectangles.",
+ "A chequered texture is one that has a pattern of small squares or rectangles.",
+ "A chequered texture typically has a pattern of light and dark squares.",
+ "A chequered texture has a pattern of light and dark squares.",
+ "A \"chequered\" texture has a pattern of squares or diamonds, like a chessboard.",
+ "A chequered texture has a regular pattern of light and dark squares.",
+ "\"Chequered\" textures alternate light and dark squares in a regular pattern.",
+ "The chequered texture has a pattern of small squares.",
+ "A chequered object has a pattern of alternating light and dark squares.",
+ "A chequered object has a pattern of light and dark squares.",
+ "A chequered object has a pattern of alternating light and dark squares.",
+ "A \"chequered\" object has a pattern of light and dark squares.",
+ "A chequered object is one that has a pattern of light and dark squares.",
+ "A chequered (or checkered) object is one that has a pattern of light and dark squares, usually in a diagonally-offset grid.",
+ "A \"chequered\" object has a pattern of alternating light and dark squares.",
+ "A chequered object may have a pattern of light and dark squares, or a pattern of two different colors.",
+ "A chequered object is covered in a pattern of squares or rectangles, usually in two colors.",
+ "A chequered object has a pattern of light and dark squares, typically used for decoration.",
+ "A chequered thing is covered with a pattern of small, usually regular shapes in different colors.",
+ "A chequered thing has a pattern of light and dark squares.",
+ "A \"chequered\" thing has a pattern of alternating light and dark squares.",
+ "A chequered thing has a pattern of squares or rectangles in different colors.",
+ "A \"chequered\" thing has a pattern of squares, typically in two colors.",
+ "A chequered thing looks like a chess board.",
+ "A chequered thing has a pattern of light and dark squares.",
+ "A chequered thing is usually black and white, or some other combination of two colors.",
+ " likes A chequered thing has a pattern of different colors, typically black and white.",
+ "A \"chequered\" thing has a pattern of alternating squares of two different colors.",
+ "A \"chequered\" pattern typically consists of a checked or plaid design.",
+ "A \"chequered\" pattern is a pattern that consists of a series of squares or rectangles of different colors, typically arranged in a checkerboard pattern.",
+ "A chequered pattern contains small, repeating squares or rectangles in two colors.",
+ "One popular checkered pattern is built up of squares, with alternating light and dark colors.",
+ "A chequered pattern is usually a black-and-white or red-and-white checkerboard pattern.",
+ "A chequered pattern is a series of small, usually square or rectangular shapes, that are alternate light and dark colors.",
+ "A chequered pattern typically consists of two colors which are arranged in a checkerboard pattern.",
+ "A chequered pattern is a series of light and dark squares.",
+ "A chequered pattern consists of small, even-sized squares that are arranged in a grid.",
+ "A chequered pattern is a black and white pattern that looks like a checkerboard."
+ ],
+ "blotchy": [
+ "A blotchy material has an uneven surface with patches of different colors or shades.",
+ "A blotchy material has patches of different colors or shades.",
+ " Blotchy material typically has an uneven pattern or dark and light areas.",
+ "A blotchy material is one that has dark and light areas, usually in an irregular pattern.",
+ "\"Blotchy\" material typically has an irregular or uneven pattern.",
+ "\"Blotchy\" material is usually characterized by an uneven color or texture.",
+ "\"Blotchy\" material is usually a light-colored fabric that has dark spots on it.",
+ "A blotchy material has an uneven distribution of color or shading.",
+ "Blotchy material can look like it has water spots, or like it has been stained with a substance that has not been evenly distributed.",
+ "The word \"blotchy\" is often used to describe skin that has an uneven color.",
+ "A \"blotchy\" surface looks like a surface with blotches of color on it.",
+ "A blotchy surface looks like it has small, dark spots all over it.",
+ "A blotchy surface is one that is not smooth, but instead has patches of color or texture.",
+ "A blotchy surface is one that has lots of different colors on it, usually without any pattern.",
+ "A \"blotchy\" surface looks like it has large, uneven spots of color.",
+ "A blotchy surface usually refers to a surface that is not even or smooth, but instead has patches of different colors or shades.",
+ "A \"blotchy\" surface is one that is not smooth, but has bumps or ridges.",
+ "A \"blotchy\" surface has an uneven texture, with visible marks or discoloration.",
+ "A blotchy surface can refer to a number of different things, but generally it is an uneven surface with patches of discoloration.",
+ "A blotchy surface looks like a surface with irregular patches of color.",
+ "A blotchy texture is one that is uneven and patchy.",
+ "A blotchy texture is usually irregular and can be bumpy or uneven.",
+ "A \"blotchy\" texture looks like an irregular surface with dark and light spots.",
+ "A \"blotchy\" texture is usually uneven, with some parts being more dense or darker than others.",
+ "A blotchy texture can look like a series of flat patches that are different colors.",
+ "A blotchy texture is a textural quality in which an area appears uneven or marked with patches of color.",
+ "The term \"blotchy\" is used to describe a skin texture that is uneven or patchy.",
+ "A blotchy texture is one with an uneven surface.",
+ "A blotchy texture is uneven and has patches of different colors or shades.",
+ "A blotchy texture looks like it has tiny spots or bumps all over it.",
+ "A blotchy object can look like it has stains or smears on it.",
+ "A blotchy object is one that has patches of color on it, rather than being a solid color.",
+ "A blotchy object looks like it has been marked with spots or stains.",
+ "Typically, a blotchy object has uneven patches of color or tone.",
+ "A \"blotchy object\" looks like it has spots or patches of color on it.",
+ "A blotchy w object is one that has dark and light areas, usually in an irregular or uneven pattern.",
+ "A blotchy object has uneven patches of color.",
+ "A blotchy object would have different colors or shades in patches.",
+ "A \"blotchy\" object has areas that are darker or lighter than other areas, often in an irregular pattern.",
+ "A blotchy object has patches of color or light and dark areas.",
+ "A \"blotchy\" thing has patches of color that are not evenly distributed.",
+ "A \"blotchy\" thing is usually an irregular shape with dark and light areas.",
+ "A blotchy thing looks like a thing that has Blotches on it.",
+ "There isn't a definitive answer to this question since the word \"blotchy\" can mean different things to different people.",
+ "A \"blotchy\" thing is usually an irregular shape with dark and light areas.",
+ "There is no one definitive answer to this question.",
+ "There is no definitive answer to this question since the word \"blotchy\" is subjective.",
+ "A blotchy thing usually looks like a rash or a bruise.",
+ "A blotchy thing is a thing that has blotches on it.",
+ "There is no definitive answer to this question as \"blotchy\" is a subjective term.",
+ "A blotchy pattern is one with large, dark patches that are separated by lighter-colored areas.",
+ "A \"blotchy\" pattern looks like an irregular pattern with dark and light areas.",
+ "A blotchy pattern is one where the colors are not evenly distributed, but instead are patchy and irregular.",
+ "A blotchy pattern looks like raised areas of skin that are discolored.",
+ "A blotchy pattern is an irregular pattern with dark and light areas.",
+ "There is no precise answer to this question since what is considered a \"blotchy\" pattern can vary depending on the person's interpretation.",
+ "A blotchy pattern looks like a series of stains or smears.",
+ "A blotchy pattern looks like a series of dark and light patches.",
+ "There is no definitive answer to this question since different people may have different interpretations of what \"blotchy\" means.",
+ "A blotchy pattern looks like a series of dark and light patches."
+ ],
+ "stained": [
+ "There is no definitive answer to this question since the term \"stained\" is relative.",
+ "The term \"stained\" is often used to describe items that are discolored or have marks on them.",
+ "Stained material is material that is discolored by a substance.",
+ "A material that is stained will have a discoloration on its surface.",
+ "A stained material is one that has been discolored by a substance.",
+ "Stained material is discolored or spotted.",
+ "Stained material is typically yellow, brown, or black in color.",
+ "\"Stained\" material is any fabric that has had a liquid spilled on it.",
+ "Stained materials are usually darker than the surrounding material, although the exact color can vary.",
+ "Stained materials are usually darker in color than the surrounding material, although the stain may be lighter or darker than the original color of the material.",
+ "A nailed or stapled surface that has been painted over without proper preparation will result in the paint failing prematurely.",
+ "A stained surface looks like it has been discolored by a substance.",
+ "A stained surface looks like it has been damaged by a substance.",
+ "A \"stained\" surface is a discolored or uneven surface.",
+ "A \"stained\" surface is a surface that has been discolored by a substance.",
+ "A \"stained\" surface is one that has been marked or discolored by a substance.",
+ "A stained surface is usually discolored or has a mark on it.",
+ "A \"stained\" surface is one that has been contaminated with a liquid or other substance.",
+ "A \"stained\" surface is one that has had a liquid spilled on it, which has then dried, leaving a mark.",
+ "A \"stained\" surface looks like it has been discolored by a substance.",
+ "Stained textures are usually darker than the surrounding area, and have irregular edges.",
+ "A \"stained\" texture usually looks like a dark or light colored spot on the texture.",
+ "A stained texture is usually a dark color, and it can be either smooth or rough.",
+ "\"Stained\" textures are characterized by their dark and dirty appearance.",
+ "A \"stained\" texture usually looks like a fabric that has had something spilled on it and has a dark discoloration.",
+ "A stained texture looks like a smooth texture with a slight bit of graininess.",
+ "There are many types of stains, but most are generally darker than the surrounding area and have irregular shapes.",
+ "A \"stained\" texture usually looks like a smeared or dirty version of the original texture.",
+ "A stained texture does not have a uniform color.",
+ "A \"stained\" texture is a texture that has been purposely discolored or faded in order to create a certain look.",
+ "A stained object is one that has been marked or discolored by something else.",
+ "It is an object with a colored design on it.",
+ "A stained object is any object that has been marked or discolored by a substance.",
+ "A stained object has a discoloration on its surface.",
+ "A stained object is an object that has a stain on it.",
+ "A stained object is one that is discolored by a substance.",
+ "A \"stained\" object typically has a dark discoloration that cannot be removed.",
+ "A stained object is one that has been marked or discolored by something else.",
+ "When an object is stained, there is a discoloration on the surface of the object.",
+ "A stained object typically has a discoloration from exposure to a substance.",
+ "A \"stained\" thing is something that has a discoloration on it, usually from a substance that has been spilled on it.",
+ "When something is stained, it has a discoloration on it that was not there before.",
+ "A stained thing looks like it has a mark on it that cannot be removed.",
+ "A \"stained\" thing is covered in a substance that is not supposed to be there.",
+ "A stained thing is usually a piece of cloth that has a discoloration from something else.",
+ "A \"stained\" thing looks like it has a lot of dirt on it.",
+ "A stained thing looks like it has a stain on it.",
+ "Stained things look like they have had something spilled on them and it has left a mark.",
+ "If something is \"stained,\" it is likely discolored or has a permanent mark.",
+ "When something is stained, it is usually discolored from something else that has gotten on it.",
+ "A stained pattern looks like a marks or smears on the surface of the material.",
+ "A stained pattern has small, random spots of color that are darker than the surrounding area.",
+ "A stained pattern is one that has been discolored or darkened by a substance.",
+ "A stained pattern can look like a smudge, a discoloration, or a small spot.",
+ "A stained pattern is a style of fabric that has had a design applied to it using a dye.",
+ "A \"stained\" pattern usually has a dark or dirty appearance.",
+ "A stained pattern looks like a piece of wood that has been stained with color.",
+ "A \"stained\" pattern is a design that is created by using a colored or darkened background to highlight a lighter piece of fabric.",
+ "A stained pattern is a term used to describe a piece of fabric that has been dyed or painted.",
+ "A stained pattern looks like a smudge or a mark on the surface of the paper."
+ ],
+ "crystalline": [
+ "A crystalline material looks like a geometric pattern of repeating shapes.",
+ "A crystalline material is typically transparent and has a highly regular, repeating internal structure.",
+ "A crystalline material has a repeating, symmetrical pattern.",
+ "Crystalline material is typically transparent or translucent, with a uniform structure.",
+ "Under a microscope, crystalline material looks like a series of interconnected, repeating geometric shapes.",
+ "Crystalline materials have a repeating, three-dimensional structure.",
+ "Crystalline material typically looks like a regular crystal.",
+ "A crystalline material is one that is made up of a repeating, three-dimensional pattern of atoms, molecules, or ions.",
+ "The term \"crystalline\" refers to the orderly arrangement of atoms in a material.",
+ "A crystalline material looks like a diamond or a crystal.",
+ "A crystalline surface is a smooth, flat surface that is atomically level and has a regular or repeating pattern.",
+ "A \"crystalline\" surface has a repeating, 3-dimensional structure.",
+ "A \"crystalline\" surface looks like a Shattered Glass surface.",
+ "A crystalline surface looks smooth and shiny, like a piece of glass.",
+ "A crystalline surface has a repeating, three-dimensional pattern.",
+ "A crystalline surface is smooth and free of pits or other imperfections.",
+ "A crystalline surface is smooth and shiny, like a mirror.",
+ "A crystalline surface is one that is made up of small, repeating units called crystals.",
+ "A crystalline surface is one that is smooth, hard, and polished.",
+ "A crystalline surface is one that is smooth and made up of small, regular crystals.",
+ "A crystalline texture looks like a mesa, with a flat top and steep sides.",
+ "A crystalline texture resembles a series of tiny crystals.",
+ "A crystalline texture looks like a shining, flawless surface.",
+ "A crystalline texture looks like a surface that has been coated with sugar.",
+ "A crystalline texture has a clean, sharp look.",
+ "A crystalline texture is typically shiny and smooth, with a geometric pattern.",
+ "A crystalline texture indicates that a mineral is made up of distinct crystals.",
+ "A crystalline texture typically looks shiny and smooth, like glass.",
+ "A crystalline texture looks clean and sharp, like crystals.",
+ "Crystalline textures are usually found in metamorphic rocks and are characterized by sharp, well-formed crystals.",
+ "A crystalline object is one that has a definite, three-dimensional shape and a regular, repeating pattern.",
+ "A \"crystalline\" object is a solid object that is made up of a regular, repeating pattern of atoms.",
+ "A \"crystalline\" object has a regular, geometric shape.",
+ "A crystalline object looks buttoned-up and orderly, like a perfect little gem.",
+ "A crystalline object is typicallyclear or transparent, and has a definite geometric shape.",
+ "A crystalline object is typically transparent or translucent.",
+ "A crystalline object typically has a very symmetrical, ordered appearance.",
+ "A crystalline object has a regularly repeating, three-dimensional structure.",
+ "A \"crystalline\" object is one that has a regular, repeating structure.",
+ "A crystalline irregularity appears as a flat surface with a geometric shape.",
+ "A crystalline thing is usually transparent and has a sharp, geometric shape.",
+ "A \"crystalline\" thing looks smooth, reflective, and gem-like.",
+ "A crystalline object is one that has a very symmetrical, ordered structure.",
+ "A \"crystalline\" thing looks like a thing made of crystals.",
+ "A \"crystalline\" thing is usually clear or translucent, and has a well-defined geometric shape.",
+ "A crystalline thing usually has a very symmetrical, geometric shape.",
+ "A crystalline object is usually transparent or translucent, with a geometric shape.",
+ "A crystalline thing looks like a bunch of little rocks put together.",
+ "A crystalline object is typically transparent and has a uniform structure.",
+ "A crystalline object looks like it is made up of a series of small,Regularly shaped crystals.",
+ "Crystalline patterns can take many different forms, but they all have one thing in common: they are composed of repeating geometric shapes.",
+ "A crystalline pattern is made up of many small, crystals that fit together.",
+ "A crystalline pattern looks like a series of geometric shapes connected together in a repeating pattern.",
+ "A \"crystalline\" pattern looks like a clear, geometric pattern.",
+ "A crystalline pattern looks like a geometric repeating pattern.",
+ "A \"crystalline\" pattern looks like a series of geometric shapes arranged in a symmetrical pattern.",
+ "A crystalline pattern looks like a geometric pattern that has been created out of crystals.",
+ "A \"crystalline\" pattern is a pattern that is made up of small, repeating units.",
+ "A crystalline pattern looks like a repeating pattern of geometric shapes.",
+ "A \"crystalline\" pattern looks like a pattern that is made up of small, delicate crystals."
+ ],
+ "porous": [
+ "Porous material is a material that has tiny holes in it.",
+ "A porous material has small holes or pores that allow liquid or gas to pass through.",
+ "Porous material is material that has small holes throughout it.",
+ "Porous materials have small holes throughout them.",
+ "Porous materials have small holes throughout them.",
+ "Porous material is typically full of tiny holes.",
+ "Porous materials are full of tiny holes.",
+ "\"Porous\" materials have tiny holes in them that allow fluids and gases to pass through them.",
+ "Porous material has tiny holes all over its surface.",
+ "A porous material has tiny holes throughout it.",
+ "A \"porous\" surface looks like a surface that has a lot of tiny holes in it.",
+ "A porous surface has tiny holes in it.",
+ "A porous surface is one that has tiny holes or pores.",
+ "A porous surface has tiny holes that allow liquids or gases to pass through.",
+ "a surface with small pores or holes.",
+ "A porous surface is covered in tiny holes.",
+ "A \"porous\" surface has tiny pores or holes that liquids or gases can pass through.",
+ "A porous surface is a surface that has tiny holes in it.",
+ "A porous surface is one that is full of tiny holes.",
+ "A porous surface is one that has small holes or pores.",
+ "A porous texture can have a lot of small holes or pores in it.",
+ "A porous texture has tiny pores or openings on the surface.",
+ "A porous texture looks like a surface that has small holes or pores.",
+ "A porous texture has a lot of small holes in it.",
+ "A porous texture has a lot of tiny holes in it.",
+ "A \"porous\" texture looks like a sponge or a honeycomb.",
+ "A porous texture is a texture that is full of small holes.",
+ "A porous texture is one that has many small pores or holes.",
+ "A porous texture means that the material has small holes or voids that allow liquid or gases to pass through.",
+ "A \"porous\" texture has small holes or pores that allow liquid or gas to pass through.",
+ "A porous object looks like it has tiny holes in it.",
+ "A porous object is one that has small holes throughout it.",
+ "A porous object looks like a sponge.",
+ "A \"porous\" object has tiny holes in it.",
+ "A porous object is one that has tiny holes or spaces in it.",
+ "A \"porous\" object has many small holes or gaps in it.",
+ "A porous object has tiny holes all over its surface.",
+ "A \"porous\" object has tiny holes or pores in it that allow liquid or air to pass through.",
+ "A porous object is an object with tiny holes in it.",
+ "A \"porous\" object is something that has many tiny holes in it.",
+ "A porous object has small holes or pores all over its surface.",
+ "A \"porous\" thing is something that has small holes in it.",
+ "An example of a porous object would be a sponge.",
+ "A \"porous\" thing is something that has tiny holes in it.",
+ "A porous object has tiny holes or pores all over its surface.",
+ "A \"porous\" thing has tiny holes in it.",
+ "A porous thing can have small holes or be permeable to fluids and gases.",
+ "A porous thing is usually full of small holes.",
+ "A \"porous\" thing is something that has tiny holes in it.",
+ "A \"porous\" thing has many small holes in it.",
+ "A \"porous\" pattern looks like a series of small holes or pores.",
+ "A porous pattern has small pores or holes.",
+ "A porous pattern looks like a lot of little holes.",
+ "A \"porous\" pattern has tiny holes or pores.",
+ "A porous pattern looks like a honeycomb.",
+ "A porous pattern looks like a series of small holes or pores.",
+ "A porous pattern looks like a piece of paper that has been crumpled up and then smoothed out again.",
+ "A porous pattern usually looks like a series of small holes or voids in a material.",
+ "A porous pattern looks like a bunch of small holes or pores.",
+ "In a porous pattern, there are small holes or pores throughout the material."
+ ],
+ "banded": [
+ "Banded material is material that has been wrapped around something else, typically in a strip or bands.",
+ "Banded material is two pieces of material that are joined together by a strip of material in the middle.",
+ "Banded material usually has stripes or other patterns running across it.",
+ "Banded material looks like it has stripes running through it.",
+ "Banded material has a series of stripes or other markings that run around it.",
+ "\"Banded\" material is material that has been wrapped in a band or similar object.",
+ "A banded material typically has stripes or bands of color.",
+ "\"Banded\" material typically has a stripe or series of stripes running perpendicular to the grain.",
+ "Banded material has a stripe or series of stripes running through it.",
+ "Banded material is a type of fabric that has been dyed or printed with stripes or other patterns that are of different colors.",
+ "A banded surface looks like it has stripes or bands running across it.",
+ "A banded surface has alternating light and dark stripes.",
+ "A banded surface is one that consists of a series of parallel lines or bands.",
+ "A banded surface is a surface that contain bands, or stripes, of color.",
+ "A banded surface has alternating light and dark stripes.",
+ "A banded surface is a surface that has visible bands or stripes.",
+ "Banding is a type of surface defect that appears as a series of dark and light stripes on the surface of the material.",
+ "A banded surface is made up of different layers of materials that are of different colors.",
+ "A banded surface is made up of bands or layers of different colors, materials, or textures.",
+ "A banded surface is a surface that is made up of a series of bands, or stripes.",
+ "A banded texture looks like a series of horizontal lines or bands.",
+ "Banded textures are made up of layers of sediment that are of different densities.",
+ "A banded texture has bands of color that are different from each other.",
+ "A banded texture is created when a material is made up of layers of different colors or textures.",
+ "Banded texture is a type of texture found in igneous rocks.",
+ "The best way to describe a \"banded\" texture is to imagine a piece of wood that has been cut into thin slices.",
+ "A banded texture is characterized by stripes or bands of color.",
+ "Banded textures are usually found in metamorphic rocks and are created when layers of sediment are subjected to high temperatures and pressures.",
+ "A banded texture has a series of parallel lines or bands running across it.",
+ "A banded texture usually refers to a repeating pattern of light and dark stripes.",
+ "A \"banded\" object has stripes or bands of color.",
+ "A banded object has stripes or bands of color.",
+ "A banded object looks like it has a strip or bands of color around it.",
+ "A banded object has a pattern of light and dark stripes.",
+ "A banded object has stripes of different colors or shades.",
+ "A banded object has stripes or bands of color.",
+ "A banded object can look like a stack of thin pancakes, or like a series of ridges or bands.",
+ "A banded object has a series of bands or lines of color running around it.",
+ "A \"banded\" object has horizontal or vertical bands of color.",
+ "A banded object has stripes running around it.",
+ "A \"banded\" thing has multiple bands or stripes of color.",
+ "A banded thing is something that has a band or stripe around it.",
+ "The word \"banded\" can refer to something that is striped or has a series of bands or markings around it.",
+ "\"Banded\" typically refers to something that has a stripe or series of stripes running around it.",
+ "A banded thing would have a band or a strip of material around it.",
+ "A \"banded\" thing has a band or strip of material around it.",
+ "Which thing are you referring to?.",
+ "A banded thing is usually a long, thin strip of material, such as cloth or paper, that is wrapped around something else.",
+ "There is no definitive answer to this question since the word \"banded\" can mean different things in different contexts.",
+ "A \"banded\" thing has stripes or markings that go around it.",
+ "A banded pattern looks like a series of bands or stripes.",
+ "In a banded pattern, items are arranged in horizontal or vertical rows.",
+ "A banded pattern can look like stripes or lines going around an object.",
+ "Banded patterns typically have stripes of different colors or shades going horizontally across the fabric.",
+ "Banded patterns are usually regular and evenly spaced, like the stripes on a zebra.",
+ "A banded pattern is a series of dark and light bands that run horizontally across an object.",
+ "A banded pattern looks like a repeating series of light and dark bands.",
+ "A banded pattern is a repeating pattern in which there are bands of color or light and dark.",
+ "A banded pattern is characterized by having stripes or bands of different colors or shades.",
+ "The term \"banded\" is used to describe a pattern that features stripes or bands of color."
+ ],
+ "lacelike": [
+ "\"Lacelike\" material is usually made of a very fine, delicate fabric.",
+ "Lacelike material is usually thin and delicate, with a lot of small holes or gaps.",
+ "Lace is a delicate fabric with an open, intricate weblike design.",
+ "Lacelike material typically has a hole pattern that resembles that of a doily.",
+ "Lacelike material is typically very delicate and has a lot of small holes in it.",
+ "Lace is a light, smooth fabric with a hole pattern.",
+ "The word \"lacelike\" is typically used to describe something that is delicate, intricate, and beautiful.",
+ "Lacelike material looks like a piece of lace.",
+ "Lacelike material is usually thin and delicate, with a lot of small holes or openings.",
+ "A lacelike material looks like a piece of lace.",
+ "A \"lacelike\" surface has a lot of small holes in it.",
+ "A lacelike surface is usually thin and delicate, with a lot of small holes or openings.",
+ "A lacelike surface is one that is covered in a pattern of small holes, like a piece of lace.",
+ "A lacelike surface is a surface with a lot of tiny holes in it, like a piece of lace.",
+ "Lacelike surfaces are covered in small holes or indentations, like a piece of lace.",
+ "A lacelike surface is one that is covered in a pattern of small holes, like a piece of lace.",
+ "Lace is a delicate fabric made of interwoven threads, typically of cotton, nylon, or polyester.",
+ "A lacelike surface is a surface that has a lot of small holes in it, like a piece of lace.",
+ "A lacelike surface has a lot of small holes in it that make it look like lace.",
+ "A lacelike surface has a delicate, intricate, and open structure.",
+ "A lacelike texture usually refers to a fabric that is made to look like lace.",
+ "A lacelike texture looks like a piece of lace.",
+ "A lacelike texture is a very delicate, intricately detailed texture.",
+ "A \"lacelike\" texture usually refers to a delicate and intricate pattern.",
+ "A lacelike texture is one that is delicate and has a lot of small holes or spaces.",
+ "It looks like a piece of lace.",
+ "Lacelike textures are delicate, light, and often see-through.",
+ "Lace is a delicate fabric made of interwoven threads.",
+ "Lacelike textures are usually delicate and intricate.",
+ "A lacelike texture looks like a piece of lace.",
+ "A lacelike object looks like a piece of lace.",
+ "A \"lacelike\" object generally has a lot of small holes or gaps.",
+ "A lacelike object is usually made of interwoven strands, and has a delicate, open appearance.",
+ "A lacelike object looks like a piece of lace.",
+ "A lacelike object is typically a delicate and ornate fabric.",
+ "A lacelike object typically has a delicate and intricate appearance.",
+ "Lacelike objects have a delicate, intricate, and often symmetrical design.",
+ "A lacelike object has a lot of small, intricate details.",
+ "A \"lacelike\" object has a lot of intricate details and looks like it would be fragile.",
+ "A lacelike object looks like a piece of lace.",
+ "Lacelike typically refers to something that is delicate, intricate, and beautiful - like a piece of lace.",
+ "A \"lacelike\" thing is usually thin and delicate, like a piece of lace.",
+ "Lace is a delicate fabric made of intertwining threads.",
+ "A lacelike thing is a small, delicate, intricately shaped object.",
+ "A lacelike thing is usually very small and delicate, with a lot of intricate details.",
+ "Lace is a delicate fabric with a hole pattern.",
+ "A lacelike thing looks like a piece of lace.",
+ "A lacelike thing can look like a piece of lace, or it can be any other object that has a similar delicate, intricate pattern.",
+ "A correctly-drawn \"lacelike\" thing looks like a network of string, wire, or other thin material, with interlocking loops and/or points.",
+ "A \"lacelike\" thing is typically a delicate, intricate object with a lot of small holes or openings.",
+ "A lacelike pattern usually refers to a pattern that is intricate and delicate, like a piece of lace.",
+ "Lace is a delicate fabric made of yarn or thread in an openwork pattern, made by machine or by hand.",
+ "A lacelike pattern is a pattern that is similar to the pattern on a piece of lace.",
+ "Lace is a delicate fabric made of yarn or thread in an openwork pattern, typically used for trimming.",
+ "A lacelike pattern consists of small, intricate holes that are arranged in a beautiful and delicate design.",
+ "A \"lacelike\" pattern often looks like a series of intricate loops or a net.",
+ "A lacelike pattern is a pattern that resembles a piece of lace.",
+ "A lacelike pattern looks like a woven or embroidered fabric with a lot of small holes in it.",
+ "A lacelike pattern is typically a delicate, intricate pattern that resembles lace.",
+ "A \"lacelike\" pattern looks like a pattern that would be found on a piece of lace."
+ ],
+ "sprinkled": [
+ "Sprinkled material is material that has been sprinkled on something.",
+ " Sprinkled materials are usually in the form of a powder.",
+ "Sprinkled material typically looks like small pieces or grains of something scattered around.",
+ "This depends on the material being sprinkled.",
+ "A sprinkling of materials looks like a light dusting or covering.",
+ "\"Sprinkled\" material is usually small pieces or flakes of a substance.",
+ "\"Sprinkled\" material is typically small pieces or granules of a substance.",
+ "A material that has been sprinkled looks like it has been covered with a light dusting of something.",
+ "Sprinkled material looks like small pieces or droplets of something that has been scattered or spread over an area.",
+ "The word \"sprinkled\" can mean to scatter something lightly over a surface, so the material would be scattered lightly and would not be in any one particular place.",
+ "A sprinkled surface is one that is covered with a light layer of a substance, such as water droplets, snow, or sugar.",
+ "A \"sprinkled\" surface is a surface that is covered in a light layer of something, typically a powder.",
+ "A surface that has been \"sprinkled\" will appear to have small droplets of water on it.",
+ "A \"sprinkled\" surface is covered in small droplets of water.",
+ "A \"sprinkled\" surface is covered in small droplets of water.",
+ "A sprinkled surface is evenly covered with small drops of liquid.",
+ "There is no definitive answer to this question, as the term \"sprinkled\" can mean different things to different people.",
+ "A sprinkled surface indicates an irregular distribution of small drops or particles.",
+ "A sprinkled surface is one that has been covered with a light layer of something, like sugar or salt.",
+ "A sprinkler is a device used to apply water to an area in a controlled manner.",
+ "A \"sprinkled\" texture looks like small pieces of something (usually food) sprinkled on top of a surface.",
+ "A \"sprinkled\" texture looks like a lot of small pieces of something scattered around.",
+ "A sprinkled texture looks like tiny dots or specks.",
+ "A sprinkled texture looks rough and has small pieces of something sprinkled throughout it.",
+ "A \"sprinkled\" texture looks like a series of small dots or spots.",
+ "A \"sprinkled\" texture looks like an object that has been covered in a light layer of something, such as powder or tiny pieces.",
+ "A \"sprinkled\" texture looks like a series of small dots or droplets.",
+ "A sprinkled texture looks like tiny droplets or dots on a surface.",
+ "A sprinkled texture has small, consistent bumps throughout.",
+ "A \"sprinkled\" texture looks like a piece of paper that has been sprinkled with glitter.",
+ "A \"sprinkled\" object has small drops of liquid on its surface.",
+ "A sprinkled object has a light coating of something on its surface.",
+ "A \"sprinkled\" object looks like it has been covered with a small amount of something, usually a powder.",
+ "A sprinkled object looks like it has been covered in a light layer of powder or tiny droplets of liquid.",
+ "A \"sprinkled\" object looks like it has been covered with a small amount of a substance, typically in a random or irregular pattern.",
+ "An object that has been sprinkled has had a light shower of something, usually water or powder.",
+ "A sprinkled object is one that has been covered with a small amount of something, usually powder or water.",
+ "A \"sprinkled\" object has small droplets of liquid on its surface.",
+ "A sprinkled object typically has a light dusting of something on it.",
+ "A sprinkled object is one that has been covered with a light layer of something, usually powder or water.",
+ "I imagine a sprinkled thing would look like it was covered in a light dusting of something, like confectioners' sugar.",
+ "A sprinkled thing looks like it has been sprinkled with something, like powder or salt.",
+ "A \"sprinkled\" thing typically looks like it has been covered in small pieces or dots.",
+ "A \"sprinkled\" thing looks like it has been covered in small dots.",
+ "A \"sprinkled\" thing looks like it has tiny pieces of something dry and light (like powder) on its surface.",
+ "A sprinkled thing looks like it has had something sprinkled on it.",
+ "A sprinkled thing is covered in small pieces or dots.",
+ "I imagine a \"sprinkled\" thing would look like it was covered in tiny pieces or droplets.",
+ "A \"sprinkled\" thing can look like many things.",
+ "This is difficult to answer without knowing what the thing is.",
+ "A sprinkled pattern has small dots or spots that are evenly distributed over the surface.",
+ "A \"sprinkled\" pattern typically includes small, random dots.",
+ "A sprinkled pattern is a patterns of small dots.",
+ "A \"sprinkled\" pattern generally looks like a light, uniform dusting of something over a surface.",
+ "A sprinkled pattern looks like a light dusting of something.",
+ "A sprinkled pattern looks like tiny droplets or dots.",
+ "A sprinkled pattern is a design that features small dots or other shapes evenly spaced throughout the fabric.",
+ "A \"sprinkled\" pattern generally refers to a patterns that is not uniform or predictable.",
+ "A sprinkled pattern has small dots or spots that are evenly spaced.",
+ "A \"sprinkled\" pattern looks like spots or dots that are randomly placed on a surface."
+ ],
+ "bubbly": [
+ "A \"bubbly\" material looks like a material that has a lot of small bubbles in it.",
+ "Bubbly material often looks like foamy bubbles.",
+ "\"Bubbly\" material looks like a liquid with a lot of small bubbles in it.",
+ "A material that is bubbly would have a lot of small air pockets or gaps throughout.",
+ "A bubbly material is one that has a lot of small holes orWh bubbles in it.",
+ "A \"bubbly\" material typically has a lot of small bubbles throughout it.",
+ "Bubbly material looks foamy and full of bubbles.",
+ "A bubbly material often looks like a foam.",
+ "When materials are bubbly they appear to have small bubbles caught within them.",
+ "Bubbly material is typically light and frothy in appearance.",
+ "A bubbly surface looks like a surface that is covered in bubbles.",
+ "A \"bubbly\" surface is one that is covered in a lot of small bubbles.",
+ "A bubbly surface looks like a surface with a lot of small bubbles on it.",
+ "A surface that is \"bubbly\" typically has a lot of small holes or bumps on it.",
+ "The surface of a liquid that is \"bubbly\" is covered in tiny bubbles.",
+ "A bubbly surface is a surface that has a lot of small bubbles on it.",
+ "A \"bubbly\" surface looks like a surface with a lot of bubbles on it.",
+ "A \"bubbly\" surface has small, round protrusions.",
+ "A \"bubbly\" surface is one that is covered with small, round bubbles.",
+ "A \"bubbly\" surface is covered in small, round bumps.",
+ "The best way to describe a bubbly texture is to think of the bubbles in a glass of soda.",
+ "A bubbly texture looks like a surface that has a lot of small bubbles on it.",
+ "The \"bubbly\" texture may look like small holes or pores in the surface of the material.",
+ "A \"bubbly\" texture is one that is full of small, round bubbles.",
+ "A bubbly texture looks like it is filled with tiny bubbles.",
+ "A bubbly texture looks like a series of small bubbles or a foam.",
+ "A \"bubbly\" texture looks like it has tiny bubbles in it, like soda or champagne.",
+ "\"Bubbly\" is often used to describe a foamy or frothy texture.",
+ "A \"bubbly\" texture can look like a lot of small bubbles or a few large bubbles.",
+ "A bubbly texture looks like tiny, shiny, round bubbles.",
+ "A \"bubbly\" object typically has a lot of small, round bubbles on its surface.",
+ "A bubbly object is generally refers to something that is filled with or surrounded by small bubbles.",
+ "A bubbly object can either be filled with bubbles or produce bubbles.",
+ "A \"bubbly\" object looks like something that has a lot of small bubbles on the surface.",
+ "A \"bubbly\" object is typically spherical in shape and has a smooth, glossy surface.",
+ "A bubbly object can have a lot of small bubbles or a few large bubbles.",
+ "A \"bubbly\" object generally has a lot of small, round protrusions.",
+ "A \"bubbly\" object typically has a lot of small holes or pores on its surface.",
+ "A \"bubbly\" object has a lot of small bubbles on its surface.",
+ "A \"bubbly\" object is one that has many small bubbles on its surface.",
+ "A bubbly thing is something that is full of bubbles.",
+ "A \"bubbly\" thing can look like a lot of things.",
+ "A bubbly thing looks like a balloon.",
+ "A bubbly thing can look like a lot of different things.",
+ "A \"bubbly\" thing is typically round and has a soft, spongy texture.",
+ "When something is \"bubbly,\" it is full of small, round bubbles.",
+ "\"Bubbly\" often describes things that are full of air and lightweight, like a bubble.",
+ "A bubbly thing is a small, round object that is covered in tiny bubbles.",
+ "A bubbly thing is usually a small, round, and soft object.",
+ "A \"bubbly\" thing looks like a balloon.",
+ "A bubbly pattern is a pattern that features a series of small, round shapes.",
+ "The answer may vary depending on who you ask, but a \"bubbly\" pattern might feature bubbles or other circular shapes in different colors and sizes.",
+ "A bubbly pattern might look like a series of small circles joined together to form a larger circle.",
+ "A bubbly pattern is a small cluster of bubbles that is surrounded by a larger cluster of bubbles.",
+ "A \"bubbly\" pattern looks like a series of small, round bumps.",
+ "A \"bubbly\" pattern has small, air-filled bubbles spread evenly throughout.",
+ "A bubbly pattern has small, round bubbles that are evenly spaced throughout the design.",
+ "A \"bubbly\" pattern looks like a series of small circles or blobs that are close together.",
+ "A \"bubbly\" pattern often looks like a series of small circles or ovals.",
+ "A bubbly pattern has small, round bumps that look like bubbles."
+ ],
+ "lined": [
+ "Lined material has a second layer of fabric sewn beneath the outer layer.",
+ "Linen is a textile made from the fibers of the flax plant.",
+ "Lined material is fabric that has been sewn to another fabric along the edges.",
+ "Lined materials have a second layer of fabric sewn on the inside of the garment.",
+ "Lined material is one that has a second layer of fabric sewn on the inside.",
+ "A lined material is a fabric that has a secondary fabric sewn to the back of it.",
+ "Lined material is fabric that has a second layer of fabric sewn on top of it.",
+ "\"Lined\" material has a second layer of fabric sewn inside the garment.",
+ "Lined material has a second layer of fabric sewn on top of the main fabric.",
+ "A lined material is a type of fabric that has a second layer of fabric underneath the outer layer.",
+ "A \"lined\" surface is a surface that has been divided into a series of parallel lines.",
+ "A lined surface is a surface with a line on it.",
+ "A lined surface is a flat surface with lines drawn on it.",
+ "A lined surface has a consistent texture throughout.",
+ "A lined surface has parallel lines running along it.",
+ "A lined surface has straight lines running across it.",
+ "A lined surface looks like a surface with parallel lines running across it.",
+ "A lined surface has a consistent texture throughout with no variation.",
+ "A lined surface is a surface with a consistent texture or pattern.",
+ "A lined surface has a definite boundary, beyond which there is nothing.",
+ "A lined texture looks like a repeating pattern of lines.",
+ "A lined texture has visible lines running across it.",
+ "A \"lined\" texture can look like many things, but it generally refers to a texture that has a lot of small lines or cracks running through it.",
+ "A lined texture is typically characterized by straight, evenly spaced lines.",
+ "Lined textures are straight, with horizontal lines running across the image.",
+ "The \"lined\" texture looks like it has faint lines running through it.",
+ "Lined textures are made up of a series of parallel lines.",
+ "A lined texture is generally made up of a series of parallel lines.",
+ "Lined textures are made up of a series of parallel lines.",
+ "Lined texture looks like a series of parallel lines.",
+ "A lined object generally has a smooth surface with visible lines running parallel to each other.",
+ "A lined object is one that has a line or lines running across its surface.",
+ "A lined object typically has a smooth surface.",
+ "A lined object looks like it has a line running down the middle of it.",
+ "A lined object has a defined edge or border.",
+ "A lined object is one that has a line or border around it.",
+ "A lined object is one that has a line or lines running through it.",
+ "A lined object has a smooth, even surface.",
+ "A lined object has a line running down its center.",
+ "A lined object is one that has a line or lines going through it.",
+ "A line is a mark that is used to create a path of travel or movement.",
+ "A lined thing looks like a thing with a line on it.",
+ "A lined thing has a line going down the center of it.",
+ "A lined thing has a line running through the middle of it.",
+ "A lined item has a seam running down the middle, with fabric on either side.",
+ "A lined thing looks like it has a line or lines on it.",
+ "A lined thing looks like it has a line or lines going through it.",
+ "A lined thing is something that has a line running through the middle of it.",
+ "A lined thing looks like it has a line down the middle of it.",
+ "A lined thing looks like it has a line or lines running through it.",
+ "Lined patterns are straight lines that go from one side of the fabric to the other.",
+ "A lined pattern usually consists of a solid line down the middle with a dotted line on either side.",
+ "A lined pattern is one in which there are lines on the fabric.",
+ "A lined pattern is usually a series of parallel lines.",
+ "Lined patterns are patterns with horizontal lines running through them.",
+ "Typically, a lined pattern is a design that includes a line or lines running through it.",
+ "A lined pattern has a row of stitches running down the center of the fabric.",
+ "A lined pattern is a repeating pattern that has lines in it.",
+ "A lined pattern contains multiple layers of lines that are placed on top of each other.",
+ "A lined pattern has a design printed on the fabric and a second design printed on the lining fabric that is used to sew the garment."
+ ],
+ "veined": [
+ "Usually, \"veined\" material has lines or streaks running through it.",
+ "Veined material has a network ofthin lines or streaks running through it.",
+ "A \"veined\" material has lines or streaks running through it.",
+ "Veined material is material that has visible lines or streaks running through it.",
+ "Veined materials have lines or streaks running through them.",
+ "This type of material has a pattern that looks like veins running through it.",
+ "The word \"veined\" can describe a material that has lines or streaks running through it, or a material that is marbled with different colors.",
+ "Typically, \"veined\" materials contain lines or streaks of a different color or material running through them.",
+ "Veined material is material that has veins or lines running through it.",
+ "Veined materials have lines or streaks running through them.",
+ "Veined surfaces contain lines or streaks that resemble veins in a leaf.",
+ "A veined surface is covered in thick, raised lines that resemble veins in a human body.",
+ "A veined surface has raised lines that look like veins in a leaf.",
+ "A surface with veins is one that has lines or markings that look like veins in a leaf.",
+ "A veined surface is a surface that has lines or streaks running through it.",
+ "A \"veined\" surface has thin lines or grooves running through it.",
+ "A \"veined\" surface is one that has lines or streaks running through it.",
+ "A veined surface has lines or streaks running through it.",
+ "A \"veined\" surface is one that is marked by a network of fine lines or cracks.",
+ "A veined surface is a surface with a pattern of lines or streaks that resemble veins.",
+ "A \"veined\" texture can look like a lot of things.",
+ "A \"veined\" texture has small lines running through it.",
+ " Veined textures are characterized by a network of fine lines or cracks that give the surface a wrinkled appearance.",
+ "A veined texture typically has lines or streaks running through it.",
+ "The term \"veined\" is used to describe a textured surface that has lines or grooves running through it.",
+ "A veined texture usually has visible lines running through it, kind of like veins in a leaf.",
+ "A veined texture is one with visible lines or streaks running through it.",
+ "A veined texture looks like it has veins running through it.",
+ "A veined texture looks like it has veins or line patterns running through it.",
+ "The veins in a leaf are an example of a veined texture.",
+ "A veined object has a network of lines or wrinkles on its surface.",
+ "Objects with veins typically have lines running through them.",
+ "A veined object typically has markings that look like veins running through it.",
+ "A veined object has lines or streaks running through it.",
+ "A \"veined\" object has lines or streaks that resemble veins.",
+ "A veined object has lines or streaks running through it.",
+ "Marl or other sedimentary rocks can have a \"veined\" appearance when they contain thin streaks or layers of a different color or type of rock.",
+ "If something is veined, it has a network of lines or streaks running through it.",
+ "A veined object differs from a non-veined object in that it has a network of raised lines running across its surface.",
+ "A veined object is one that contains visible lines or streaks that resemble veins.",
+ "A veined thing is typically something that has lines or streaks running through it.",
+ "When something is veined, it has lines running through it that look like veins in a human body.",
+ "A \"veined\" thing is something that has veins running through it.",
+ "The term \"veined\" is used to describe something that has lines running through it, often in a pattern.",
+ "A \"veined\" thing has lines or streaks running through it.",
+ "A veined thing has lines or markings that look like veins.",
+ "A veined thing has lines or streaks running through it.",
+ "A \"veined\" thing has a network of fine lines or cracks on its surface.",
+ "A veined object has lines or streaks running through it, like a leaf or a piece of marble.",
+ "A \"veined\" thing typically has lines or streaks running through it.",
+ "A veined pattern is a type of pattern that features lines or streaks that resemble veins.",
+ "A \"veined\" pattern has lines or streaks that look like veins.",
+ "The word \"veined\" typically refers to a pattern that includes lines or streaks that look like veins.",
+ "A veined pattern typically features darker lines or streaks against a lighter background.",
+ "A \"veined\" pattern typically has lines or other marks that resemble the veins in a leaf.",
+ "A \"veined\" pattern has lines that look like veins running through it.",
+ "A \"veined\" pattern typically looks like a stone or marble surface with faint lines running through it.",
+ "A veined pattern is a pattern in which veins or lines radiate out from a center point.",
+ "A veined pattern is a repeating pattern of lines that branch out from a center point, like the veins on a leaf.",
+ "A \"veined\" pattern typically contains small lines or streaks that give the appearance of veins in a leaf."
+ ],
+ "bumpy": [
+ "Reference material for \"bumpy\" material: https://www.",
+ "\"Bumpy\" material typically has a textured surface with small bumps or ridges.",
+ "Bumpy material has a lot of small raised bumps on the surface.",
+ "Bumpy material has an uneven surface, with raised and lowered areas.",
+ "Bumpy material generally looks like it has bumps on it.",
+ "Bumpy material has an uneven surface, with protrusions and indentations.",
+ "Bumpy material typically has an irregular surface with raised areas.",
+ "A \"bumpy\" material has a textured surface with many small protrusions.",
+ "The word \"bumpy\" is used to describe a texture that is not smooth.",
+ "\"Bumpy\" material is material that is not smooth.",
+ "A \"bumpy\" surface is not smooth.",
+ "A \"bumpy\" surface is a surface that has many small protrusions or indentations.",
+ "A \"bumpy\" surface looks like a surface with bumps on it.",
+ "A \"bumpy\" surface is one that has a lot of small hills and valleys.",
+ "A \"bumpy\" surface contains many small bumps.",
+ "A bumpy surface looks like it has a lot of bumps on it.",
+ "A \"bumpy\" surface usually has small raised bumps on it.",
+ "A bumpy surface has a lot of bumps on it.",
+ "A \"bumpy\" surface can have many different looks, but generally it is a surface with a lot of raised areas or protrusions.",
+ "A \"bumpy\" surface has protrusions or indentations that make it uneven.",
+ "A bumpy texture can look like a lot of things.",
+ "A bumpy texture can look like a lot of things.",
+ "A \"bumpy\" texture looks like a surface with a lot of small bumps on it.",
+ "A \"bumpy\" texture looks like it has small bumps or protrusions on its surface.",
+ "A \"bumpy\" texture looks like a surface with small bumps.",
+ "A bumpy texture looks like it has small bumps or raised areas.",
+ "There is no definitive answer to this question since it is subjective.",
+ "Bumpy textures can have many different shapes and forms, but are generally characterized by an irregular, raised surface.",
+ "A bumpy texture looks like a surface with a lot of small bumps on it.",
+ "A bumpy texture looks like it has bumps on it.",
+ "A \"bumpy\" object is an object that has a lot of bumps on it.",
+ "A \"bumpy\" object is an object with a lot of bumps on it.",
+ "A \"bumpy\" object is an object that has a lot of bumps on its surface.",
+ "A \"bumpy\" object usually has a lot of small protrusions on its surface.",
+ "A bumpy object is one that has a lot of bumps on it.",
+ "A \"bumpy\" object has a lot of small bumps on it.",
+ "A \"bumpy\" object looks like it has a lot of bumps on it.",
+ "A bumpy object has a lot of bumps on it.",
+ "A \"bumpy\" object can have many different shapes, but is generally characterized by having a lot of small bumps on its surface.",
+ "A \"bumpy\" object looks like it has a lot of small raised areas.",
+ "There is no one answer to this question because things that are bumpy can look different depending on their size, shape, and texture.",
+ "A bumpy thing can look like a lot of things.",
+ "A \"bumpy\" thing is something that is not smooth.",
+ "The word \"bumpy\" is often used to describe something that is not smooth.",
+ "A \"bumpy\" thing can look like a number of different things.",
+ "A \"bumpy\" thing is something that has a lot of bumps on it.",
+ "There is no definitive answer to this question as different people may perceive bumps differently.",
+ "A bumpy thing looks like something that has a lot of bumps on it.",
+ "A \"bumpy\" thing looks like it has a lot of bumps on it.",
+ "A bumpy thing usually has a lot of texture and is not smooth.",
+ "A \"bumpy\" pattern looks like a series of hills and valleys.",
+ "A bumps pattern typically looks like a series of raised bumps or lines.",
+ "A \"bumpy\" pattern looks like a series of peaks and valleys.",
+ "A \"bumpy\" pattern looks like a series of peaks and valleys.",
+ "A \"bumpy\" pattern can look like a series of small hills or mountains.",
+ "A \"bumpy\" pattern looks like a lot of small, raised bumps.",
+ "A \"bumpy\" pattern can look like a series of small hills or mountains.",
+ "A bumpy pattern looks like a series of bumps or hills.",
+ "A \"bumpy\" pattern looks like a series of small hills or bumps.",
+ "A bumpy pattern looks like a series of peaks and valleys."
+ ],
+ "paisley": [
+ "Paisley material is typically a printed cotton fabric with a patterns of curved shapes.",
+ "Paisley material consists of curved shapes with swirling lines, similar to the design on a paisley tie.",
+ "Paisley is a design that is created by a series of curved shapes that are arranged in a repetitive pattern.",
+ "Paisley is a design that is made up of curved shapes that resemble teardrops or comma shapes.",
+ "Paisley material typically features a repeating pattern of curved shapes.",
+ "Paisley material is a textile print with a patterns of curved shapes resembling teardrops.",
+ "Paisley is a printed fabric with a pattern of curved shapes that look like leaves.",
+ "Paisley is a droplet-shaped vegetal motif, similar to half of a tear, often used in fabrics, wallpaper, and other patterned designs.",
+ "Paisley fabric typically has a colorful, intricate design.",
+ "Paisley is a decorative fabric design made of intricate curved shapes.",
+ "A paisley surface is characterized by a repeating pattern of curved shapes that resemble teardrops or comma shapes.",
+ "Paisley surfaces have a swirly, organic pattern.",
+ "The paisley surface is characterized by a series of curved lines that intersect in a teardrop-shaped motif.",
+ "A paisley surface is a surface with a repeating pattern of abstract shapes.",
+ "Paisley surfaces are usually covered in a repeating pattern of curved shapes.",
+ "A paisley surface is typically characterized by a curved, teardrop-shaped motif.",
+ "A paisley surface is usually curved or wavy, with a pattern of repetitive shapes that resemble teardrops or leaves.",
+ "A paisley surface is usually decorated with a repeating pattern of curved, comma-shaped figures.",
+ "A paisley surface is typically composed of a series of curved shapes that resemble the teardrop-shaped vegetative motif of the same name.",
+ "A \"paisley\" surface looks like an intricate, curved design that is often used in fabrics and wallpapers.",
+ "The term \"paisley\" can refer to a number of different designs, but most often it is used to describe a fabric with a pattern of curved, protuberant shapes that resembleffee beans or teardrops.",
+ "A paisley texture often looks like a teardrop-shaped decorative element with a curved stem.",
+ "A \"paisley\" texture typically looks like a teardrop-shaped design that is repeated.",
+ "A \"paisley\" texture is characterized by a repetitive, curved motif with a teardrop-like shape.",
+ "A paisley texture is a small, intricate design that is often used in fabrics or as a pattern on wallpaper.",
+ "A paisley texture can look like many things, but typically it is a curved, teardrop-shaped figure that is repeated in a design.",
+ "Paisley textures are typically ornate and detailed, with intricate designs that resemble curved leaves or flower petals.",
+ "A \"paisley\" texture usually features a teardrop-shaped motif with curved, flowing lines.",
+ "A paisley texture is often described as looking like a teardrop or almond shape.",
+ "The paisley texture is characterized by a repetitive, curved, abstract pattern.",
+ "A paisley object is typically characterized by a curved, teardrop-shaped motif with a curved stem.",
+ "A paisley object is marked with a design that resembles the shape of a teardrop, or cucumber.",
+ "A paisley object is typically a fabric with a pattern of curved, decorative shapes.",
+ "A paisley object typically has a teardrop-shaped pattern.",
+ "A paisley object is typically ornate and colorful, with a distinctively recurring motif of a teardrop-shaped vegetable.",
+ "A paisley object looks like a teardrop-shaped pattern that is often used in fabrics.",
+ "A \"paisley\" object typically has a teardrop-shaped pattern.",
+ "A paisley object looks like a decorative fabric with a pattern of curved shapes.",
+ "A paisley is a decorative motif of an oblong shape with a curved end.",
+ "A \"paisley\" object is typically an ornate, teardrop-shaped decoration.",
+ "A paisley-patterned item contains a curving, teardrop-shaped motif with a sawtooth edge.",
+ "A paisley is a curved, teardrop-shaped motif with a pointed end.",
+ "A paisley is a droplet-shaped vegetable motif of Persian origin.",
+ "The paisley pattern is derived from an ancient Kashmiri design called BUTA that resembles a teardrop-shaped motif.",
+ "A paisley is a decoration with a curved, teardrop-shaped pattern.",
+ "Paisley is a design that is shaped like a teardrop.",
+ "A \"paisley\" thing is a teardrop-shaped, intricate design that is often used in fabrics.",
+ "A paisley is a multipetaled curved botanical motif, often with a teardrop-shaped center, found in Persian, Indian, and Central Asian fabrics.",
+ "A paisley thing looks like a swirly, teardrop-shaped design.",
+ "A paisley is a centuries-old curved, teardrop-shaped motif often found in fabrics and wallpaper.",
+ "A paisley pattern generally features a curved, teardrop-shaped motif with a curved stem.",
+ "Paisley is a droplet-shaped vegetal motif, of Iranian and Indian origin, similar to half of a mango.",
+ "A paisley pattern is an elaborate decorative design using the prints of a droplet-shaped vegetable, traditionally either the mango or the potato.",
+ "A paisley pattern is a decorative motif of a curved, feather-shaped figure with a teardrop-shaped center.",
+ "The paisley pattern is a curved, teardrop-shaped motif with a curved line at the bottom.",
+ "A paisley pattern is a curved teardrop-shaped figure that is repeated to form a design.",
+ "A paisley pattern is a print with a curved, teardrop-shaped motif.",
+ "A paisley pattern is a highly stylized representation of a feather, typically found in a teardrop shape.",
+ "Paisley patterns feature intricate, curved shapes that often resemble teardrops or comma-shaped symbols.",
+ "A paisley pattern typically features a teardrop-shaped motif with curved, angling outlines."
+ ],
+ "potholed": [
+ "Potholed material typically looks like a broken or crumbled up pavement.",
+ "Potholed material generally looks like abroken-up road.",
+ "The samples are from a light-colored potholed material.",
+ "Potholed material typically looks like gravel or dirt.",
+ "Potholed material is typically cracked and full of holes.",
+ "\"Potholed\" material is typically a type of pavement that has been damaged by weather or traffic.",
+ "Potholing is a method of underground mining in which narrow shafts are dug outward from an existing opening.",
+ "Potholed material is full of holes.",
+ "\"Potholed\" material typically looks like a dry, cracked, and/or crumbled road surface.",
+ "Potholed material is typically a gray or dark gray color.",
+ "A road that is \"potholed\" is full of holes, or potholes.",
+ "A potholed surface is full of holes.",
+ "A potholed surface is one that is full of small holes, usually caused by the wearing away of the material.",
+ "A \"potholed\" surface looks like a piece of pavement or asphalt that has been damage by a hole.",
+ "A \"potholed\" surface is cracked and bumpy.",
+ "A road that is potholed has large holes in it.",
+ "A potholed surface is one that is full of small holes, often causing it to be bumpy.",
+ "A potholed surface looks like a surface that has been filled with holes.",
+ " Well-used roads often develop potholes.",
+ "A potholed surface is usually full of small holes or pits.",
+ "A potholed texture usually looks like a bunch of small holes or dents in a surface.",
+ "A potholed texture looks like a series of depressions or holes in a surface.",
+ "A potholed texture looks like it has small holes or pits in it.",
+ "A \"potholed\" texture is rough, uneven, and full of holes.",
+ "The most common type of potholed texture is a series of small, round indentations in the surface.",
+ "A \"potholed\" texture is one that is full of small indentations, or \"potholes.",
+ "A potholed texture looks like a bunch of small holes in the surface.",
+ "A potholed texture looks like a texture with a lot of small holes in it.",
+ "A \"potholed\" texture is similar to a road that has been damaged by potholes.",
+ "A \"potholed\" texture has small indentations or depressions in it.",
+ "A \"potholed\" object may have small, deep indentations on its surface.",
+ "Image result for what does a potholed object look like.",
+ "A potholed object has small, deep holes in it.",
+ "A potholed object is an object that has a lot of small holes in it.",
+ "There is no definitive answer to this question, as the appearance of a \"potholed\" object will depend on the object's material composition and the nature of the potholes themselves.",
+ "A potholed object usually has a lot of small holes in it.",
+ "A potholed object is usually an object that has been damaged or destroyed by a pothole.",
+ "A \"potholed\" object may have small, round depressions on its surface that resemble the holes that form in a road when water seeps in and the pavement deteriorates.",
+ "A \"potholed\" object has numerous small holes or indentations in it.",
+ "A \"potholed\" object has many small holes in it.",
+ "A potholed thing looks like a small hole in the ground that is usually surrounded by dirt.",
+ "A \"potholed\" thing looks like a thing that has a lot of holes in it.",
+ "A \"potholed\" thing is a thing that has been damaged by potholes.",
+ "There is no definitive answer to this question as the appearance of a \"potholed\" thing can vary greatly depending on the context and/or specific circumstances.",
+ "A potholed thing is a thing that has a hole in it.",
+ "When a thing is \"potholed,\" it is full of holes.",
+ "There is no definitive answer to this question, as the appearance of a \"potholed\" thing will vary depending on the specific object in question.",
+ "A potholed thing can look like a small hole in the ground that is surrounded by dirt or grass.",
+ "A \"potholed\" thing can look like a piece of fruit with a lot of small indentations, or a road with a lot of small craters.",
+ "I'm not sure what you mean.",
+ "Image result for potholed pattern.",
+ "A potholed pattern looks like a series of small, round depressions in the surface of a material.",
+ "A potholed pattern is a series of dips or indentations in a surface.",
+ "Potholed patterns typically have a repeating motif of some sort, often geometric, and look like they have been \"pocked\" with holes.",
+ "A potholed pattern typically looks like a series of small holes or depressions in a surface.",
+ "A potholed pattern looks like a repeating series of circles or ovals.",
+ "A potholed pattern looks like a series of small craters.",
+ "A potholed pattern is one where the prices make a series of lower highs and lower lows, and the lows are getting progressively lower.",
+ "The \"potholed\" pattern looks like a bunch of small holes that have been clustered together.",
+ "A \"potholed\" pattern looks like a series of small craters or divots."
+ ],
+ "waffled": [
+ "Waffled material often looks like honeycomb or a grid.",
+ "A waffled material is a fabric that has a raised, honeycomb-like texture.",
+ "\"Waffled\" material may have a raised, grid-like texture.",
+ "Waffled material typically has a textured or honeycomb-like appearance.",
+ "Waffled material can have a textured or embossed look.",
+ "\"Waffled\" material looks like a series of small, raised squares.",
+ "\"Waffled\" material is material that is made up of a series of small, raised ridges.",
+ "Waffled material has a raised, grid-like pattern.",
+ "\"Waffled\" material looks like a series of raised squares.",
+ "Waffled fabric has a textured, honeycomb-like appearance.",
+ "A waffled surface looks like the surface of a waffle.",
+ "A \"waffled\" surface is a surface with a series of raised bumps.",
+ "A \"waffled\" surface is one that has been covered with a series of indentations, making it look like a waffle.",
+ "A \"waffled\" surface has a series of small, raised squares.",
+ "A waffled surface is a declined surface that is covered in small, raised squares.",
+ "A waffled surface is one that is covered in a grid or diamond pattern.",
+ "A \"waffled\" surface looks like a surface with a lot of ridges or peaks and valleys.",
+ "A waffled surface has a texture that is similar to that of a waffle.",
+ "A waffled surface is one that has a lot of small indentations, making it look like a waffle.",
+ "A \"waffled\" surface has a series of indentations that resemble a waffle.",
+ "A waffled texture usually appears as a series of tangled lines or ridges.",
+ "Waffled textures are usually bumpy or ridged.",
+ "A waffled texture is a repeating pattern of ridges and valleys.",
+ "A waffled texture looks like a series of small squares.",
+ "A \"waffled\" texture is usually created by using a waffle iron.",
+ "A waffled texture looks like the texture of a waffle.",
+ "When something is \"waffled,\" it means it has a texture that is similar to that of a waffle.",
+ "If a texture is waffled, it means it is textured with a waffle pattern.",
+ "A \"waffled\" texture is a term used to describe a woven or knit fabric that has a raised, textured appearance.",
+ "A \"waffled\" texture looks like a grid of squares.",
+ "A \"waffled\" object looks like a waffle iron has been pressed onto it, creating a waffle-like texture.",
+ "A waffled object is one that has been pressed into a waffle iron to create a waffle-like pattern.",
+ "A waffled object looks like a waffle.",
+ "A \"waffled\" object looks like it has a waffle-patterned texture on it.",
+ "A \"waffled\" object has a raised, grid-like pattern on its surface.",
+ "The definition of waffle is \"to make an indecisive or evasive statement.",
+ "A waffled object has a surface with a distinctive honeycomb-like pattern.",
+ "A waffled object has a texture that resembles a waffle.",
+ "Waffled objects have a waffle-like texture, with raised lines that form a grid.",
+ "A \"waffled\" object looks like a waffle.",
+ "If you waffle something, it means you're indecisive or you're changing your mind a lot.",
+ "When something is waffled, it is usually in the shape of a waffle.",
+ "A waffled thing looks like a waffle.",
+ "The term \"waffled\" can mean two different things.",
+ "A \"waffled\" thing can look like a waffle iron has made an imprint on it.",
+ "It looks like it has been made with a waffle iron.",
+ "The word \"waffled\" can mean two different things.",
+ "Waffled things often have a grid-like pattern, as if they were made in a waffle iron.",
+ "A waffled thing generally has a grid-like pattern on it from being pressed in a waffle iron.",
+ "A \"waffled\" thing has a surface that is full of small indentations, like the surface of a waffle.",
+ "A waffled pattern is a fabric or material design that consists of a series of raised ridges or lines that create a geometric pattern.",
+ "A waffled pattern looks like a honeycomb or waffle iron.",
+ "A \"waffled\" pattern is a series of small squares that are interconnected.",
+ "A waffled pattern looks like a waffle.",
+ "A waffled pattern looks like a grid or honeycomb.",
+ "A waffled pattern has a textured, three-dimensional surface that resembles a waffle.",
+ "A waffled pattern has a textured surface that resembles a waffle.",
+ "A \"waffled\" pattern generally refers to a fabric that has a distinct grid-like pattern, often in a diamond or square shape.",
+ "A waffled pattern has a grid-like appearance with raised lines running in both directions.",
+ "A \"waffled\" pattern is a checkered orGrid-like pattern."
+ ],
+ "pitted": [
+ "Pitted material has small indentations or holes on the surface.",
+ "A pitted material has small indentations on its surface.",
+ "Pitted material has small indentations or holes on the surface.",
+ "A pitted material has small indentations or holes on its surface.",
+ "A pitted surface has small craters or depressions.",
+ "Pitted material has small depressions or holes on its surface.",
+ "\"Pitted\" material is material that has been worn away, typically by being rubbed or scratched repeatedly.",
+ "A pitted material has small indentations or holes on its surface.",
+ "Pitted material has small holes or indentations on the surface.",
+ "Pitted material looks like small holes or indentations on a surface.",
+ "A pitted surface is one that has small depressions or holes in it.",
+ "When a surface is \"pitted,\" it means there are small depressions or holes in the surface.",
+ " imagenotavailable.",
+ "A pitted surface looks like it has small craters.",
+ "A pitted surface has small craters or indentations.",
+ "A pitted surface is a surface that has been damaged by small crater-like depressions.",
+ "A pitted surface has small craters or indentations.",
+ "A pitted surface has small holes or indentations.",
+ "A pitted surface looks like it has tiny craters or divots.",
+ "A pitted surface is one that has small craters or indentations.",
+ "Pitted textures can appear smooth overall, but have tiny pits or indentations spread throughout.",
+ "A pitted texture has small, shallow depressions in it.",
+ "\"Pitted\" can mean different things depending on the context, but generally it refers to a surface that is not smooth, but instead has a lot of small indentations.",
+ "A pitted texture looks like a lot of small holes or depressions on a surface.",
+ "A \"pitted\" texture has small, shallow depressions in the surface.",
+ "A \"pitted\" texture looks like it has small holes or depressions in the surface.",
+ "A \"pitted\" texture is defined by small depressions or holes in the surface.",
+ "A pitted texture refers to a small depression or indentation in the surface of an object.",
+ "The word \"pitted\" is most often used to describe a citrus fruit that has had small holes punched into its skin.",
+ "A \"pitted\" texture looks like a series of small craters.",
+ "A pitted object has small craters or depressions on its surface.",
+ "A pitted object is one that has small craters or pits on its surface.",
+ "\"Pitted\" objects have small indentations or holes in them.",
+ "A pitted object typically has small indentations or holes on its surface.",
+ "A pitted object has small depressions or holes in it.",
+ "Pitted objects have small craters or indentations on their surface.",
+ "A pitted object looks like it has small divots or indentations on its surface.",
+ "A pitted object is one that has small craters or holes on its surface.",
+ "A pitted object is one that has small depressions or holes in it.",
+ "If an object is pitted, it has small depressions or holes on its surface.",
+ "A pitted thing can have small holes or indentations.",
+ "A pitted thing looks like it has been eaten by insects or has small craters all over it.",
+ "A pitted thing has small, shallow indentations on its surface.",
+ "A pitted thing has small depressions or holes in it.",
+ "A pitted thing has small indentations or holes in it.",
+ "When something is pitted, it has small depressions or holes on its surface.",
+ "A pitted thing typically has small indentations or holes on its surface.",
+ "A pitted thing is something that has a small, depressed area on its surface.",
+ "A pitted thing looks like it has small holes or indentations on its surface.",
+ "A pitted thing is covered in small depressions or pits.",
+ "Pitted patterns have a series of small, round depressions that run parallel to each other.",
+ "A pitted pattern usually looks like small, shallow craters.",
+ "A \"pitted\" pattern is a type of fabric pattern that has small holes or depressions in it.",
+ "A pitted pattern is one with small depressions, or craters, on the surface.",
+ "A pitted pattern can look like small holes or indentations in a surface.",
+ "A pitted pattern is one where the fabric has small holes or spots that are not smooth.",
+ "A pitted pattern has resemble small depressions or holes in the surface.",
+ "A pitted pattern is a raised, rounded pattern that is found on the surface of a material.",
+ "Pitted patterns look like small holes or divots in the surface of the fabric.",
+ "A pitted pattern is a surface texture that contains small craters or holes."
+ ],
+ "frilly": [
+ "The definition of frilly is something that is fancily decorated or lacy.",
+ "The best way to describe frilly fabric is to say that it is fabric with a lot of ruffles.",
+ "Frilly material looks like ruffles or lace.",
+ "A frilly material is usually a light-weight fabric with a lot of texture.",
+ "\"Frilly\" material can be many different things, but usually it refers to material that is very delicate looking, and often has a lot of small details.",
+ "A frilly material is usually a type of fabric that is intricately designed with a lot of ruffles or lace.",
+ "Frilly material is usually lightweight and has a lot of texture.",
+ "A frilly material might have a lot of ruffles or a lacy pattern.",
+ "Frilly material is material that has a lot of small, delicate folds in it.",
+ "This is a difficult question because \"frilly\" can mean different things to different people.",
+ "A frilly surface can be described as having a lot of small, raised bumps or protrusions.",
+ "A frilly surface is one that has a lot of ruffles or other decorations.",
+ "A \"frilly\" surface is a surface with a lot of small, delicate details.",
+ "A \"frilly\" surface is one that is covered in a lot of small, decorative details.",
+ "A \"frilly\" surface looks like it is covered in small, loops or ruffles.",
+ "A frilly surface looks like it has a lot of small bumps or ridges.",
+ "A frilly surface is one with a lot of small, decorative details.",
+ "A frilly surface is one that has a lot of small, decorative details.",
+ "A \"frilly\" surface is one that is covered with a lot of small, decorative details.",
+ "A \"frilly\" surface is one that is decorated with a lot of small, decorative details.",
+ "A frilly texture looks like it has a lot of little bumps and ridges.",
+ "A frilly texture can look like a series of small ruffles or waves.",
+ "A \"frilly\" texture looks like it has a lot of small, thin strips coming off of it.",
+ "A \"frilly\" texture often looks like it has a lot of small wrinkles or creases in it.",
+ "A \u201cfrilly\u201d texture looks like a series of ruffles or small pleats.",
+ "Frilly textures are often associated with fabrics that have a lot of ruffles or a lace-like appearance.",
+ "A \"frilly\" texture looks like a lot of small, thin pieces of material that are all bunched together.",
+ "A frilly texture generally looks like it has a lot of small folds or ruffles.",
+ "When an object has a frilly texture, it means that it is covered in small, delicate curves.",
+ "A \"frilly\" texture is characterized by its small, delicate, ruffled details.",
+ "A frilly object is usually decorated with a lot of small, intricate details.",
+ "Something that is frilly has a lot of small, fancy details.",
+ "A frilly object is one that is decorated with a lot of ornate details.",
+ "A \"frilly\" object is usually an object that is very ornate or detailed.",
+ "A frilly object has a lot of small, decorative details.",
+ "A frilly object is usually decorated with a lot of small, intricate details.",
+ "A \"frilly\" object is an object that has a lot of small details or decorations.",
+ "A \"frilly\" object has a lot of small, decorative details.",
+ "A \"frilly\" object is an object that is decorated with a lot of small, intricate details.",
+ "A \"frilly\" object is usually decorated with a lot of small, delicate details.",
+ "A frilly thing looks like it has a lot of lace or ruffles.",
+ "A \"frilly\" thing has a lot of small, decorative details.",
+ "A \"frilly\" thing looks like it has a lot of small, delicate details.",
+ "A frilly thing looks like it has a lot of small, intricate details.",
+ "A frilly thing can look like a lot of things.",
+ "A \"frilly\" thing typically has a lot of small details, such as ruffles, lace, or bows.",
+ "A \"frilly\" json object looks like the following:{\n \"frilly\": {\n \"foo\": \"bar\",\n \"baz\": \"qux\"\n }\n}.",
+ "A \"frilly\" thing is usually a piece of clothing that is decorated with a lot of lace or other fancy detailing.",
+ "A \"frilly\" thing is usually small and decorated with a lot of curves and swirls.",
+ "A frilly thing is something that is decorated with a lot of small, intricate details.",
+ "A frilly pattern is usually a pattern with a lot of small details.",
+ "A frilly pattern features lots of small, intricate details.",
+ "A \"\u2026frilly pattern\" can contain many different features, including: ruffles, bows, excessive lace, and/or other intricate designs.",
+ "A frilly pattern can look like a lot of things, but generally it is a pattern with a lot of small decoration or details.",
+ "A frilly pattern may have a lot of small details, such as ruffles or lace.",
+ "The definition of \"frilly\" is something that is decorated with a lot of ornamental details.",
+ "A frilly pattern typically has a lot of small, intricate details.",
+ "A frilly pattern looks like a pattern with a lot of small details.",
+ "When a pattern is frilly, it has a lot of small details that make it look decorative.",
+ "A frilly pattern is a pattern that has a lot of small, decorative details."
+ ],
+ "spiralled": [
+ "\"Spiraled\" material looks like a spiral or a coil.",
+ " spiraled material looks like a corkscrew.",
+ "It looks like a helix or a spiral.",
+ "Spiralled material looks like it has been wound around something in a spiral shape.",
+ "A spiralled material is a material that has been cut or shredded into long, thin strips that resemble a spiral.",
+ "\"Spiralled\" material is material that is coiled or twisted in a spiral shape.",
+ "Spiraled material is generally cylindrical in shape, with a spiral pattern running along its length.",
+ "When looking at a \"spiralled\" material, it would appear to be winding its way around in a circular pattern.",
+ "\"Spiralled\" material is usually twisted or coiled.",
+ "Spiralled material is material that is coiled or twisted together in a spiral shape.",
+ "A spiralled surface looks like a surface that has been wrapped around a spiral.",
+ "A spiralled surface is a surface that winds around a central point in a spiral pattern.",
+ "A spiralled surface looks like a surface that has been wrapped around a cylinder or cone.",
+ "A \"spiralled\" surface looks like a series of concentric circles that get progressively smaller as they get closer to the center of the spiral.",
+ "A spiralled surface looks like a surface that has been wrapped around a spiral.",
+ "A spiralled surface looks like a surface with a lot of twists and turns.",
+ "A spiralled surface looks like a series of spirals or coils.",
+ "A spiralled surface looks like a surface that has been wrapped around a cylinder or cone.",
+ "A \"spiralled\" surface looks like a series of spirals or coils.",
+ "A spiraled surface is a surface that has been twisted or curled so that it forms a spiral shape.",
+ "A \"spiralled\" texture looks like a series of concentric circles or spiral shapes.",
+ "A \"spiralled\" texture looks like a spiral or a coil.",
+ "A spiralled texture looks like a spiral or swirl.",
+ "A spiralled texture looks like a spiral or a coil.",
+ "The word \"spiralled\" is not a texture.",
+ "A spiralled texture looks like something that has been twisted or wound around.",
+ "A spiralled texture looks like a series of spiral shapes.",
+ "A spiralled texture usually has a tight, coil-like appearance.",
+ "A spiralled texture typically looks like a spiral or a coil.",
+ "A \"spiralled\" texture is a texture that has a spiral pattern.",
+ "A spiralled object looks like it has been wound around something in a spiral shape.",
+ "A spiralled object would have a circular shape with a spiral pattern.",
+ "If you are talking about a physical object, it would likely look like a corkscrew or drill bit.",
+ "A \"spiralled\" object is any object that has a spiral shape.",
+ "A spiralled object looks like a corkscrew or a screw.",
+ "A spiralled object is an object that has been wound around in a spiral shape.",
+ "A spiralled object has a curved or winding path.",
+ "A spiralled object has a helix shape.",
+ "A spiralled object looks like a spiral.",
+ "A spiraled object looks like it has been wrapped around something in a circular motion.",
+ "A \"spiralled\" thing may look like a coil, a twist, or a spiral shape.",
+ "A spiraled thing can look like a coil, a twist, or a spiral staircase.",
+ "The best way to imagine a spiralled thing is to think of a spiral staircase.",
+ "There isn't a definitive answer to this question since the term \"spiralled\" is somewhat vague.",
+ "A spiralled thing looks like a giant spiral.",
+ "There is no one correct answer to this question, as the word \"spiralled\" can describe a wide range of shapes and forms.",
+ "The best way to describe a spiralled thing is to imagine a corkscrew.",
+ "A \"spiralled\" thing looks like a spiral.",
+ "A spiral is a certain type of curve.",
+ "A items that is spiralled has a curved or coiled shape.",
+ "A pattern that is \"spiralled\" would likely look like a spiral shape.",
+ "A spiralled pattern can look like a spiral staircase or a coil.",
+ "A spiralled pattern looks like a series of interconnected spirals.",
+ "A spiralled pattern looks like a spiral.",
+ "A spiralled pattern looks like a series of spirals.",
+ "A \"spiralled\" pattern looks like a spiral.",
+ "A spiralled pattern looks like a series of curves that wind around a central point.",
+ "There is no definitive answer to this question as the term \"spiralled\" is somewhat subjective.",
+ "A spiralled pattern looks like a spiral.",
+ "A spiraled pattern looks like a series of circles or tubes that are interconnected and winding around a common center."
+ ],
+ "knitted": [
+ "Knitted fabric is made up of interlocking loops of yarn or thread.",
+ "Knitted material is usually made of two types of thread: the warp and weft.",
+ "A knitted fabric is one that is produced by interlocking loops of yarn.",
+ "Knitted fabric has a series of loops that are interlocked together.",
+ "Knitted material has a textured surface with small V-shaped ridges.",
+ "Knitted material looks like a series of loops that have been created by interlocking yarn.",
+ "Knitted material is made up of interlocking loops of yarn or thread.",
+ "Knitted fabric is created by interlocking loops of yarn.",
+ "\"Knitted\" material is made up of small loops of thread that are interlocked together.",
+ "Knitted material typically has a grid-like appearance with raised ridges running vertically and horizontally.",
+ "A knitted surface has a textured, three-dimensional look.",
+ "If you imagine a fabric made of interlocking loops of yarn, that is what a knitted surface looks like.",
+ "A knitted surface can look like a fabric made up of interlocking loops of yarn.",
+ "A \"knitted\" surface is a surface that is made up of small loops of yarn.",
+ "A knitted surface is a surface that has been made by interlocking loops of yarn or thread.",
+ "A \"knitted\" surface looks like a series of small loops that have been connected together.",
+ "A knitted surface has a textured, bumpy surface.",
+ "A knitted surface has a series of raised ridges and indentations that resemble the stitches of a knit fabric.",
+ "A knitted surface has a series of small loops that are interconnected.",
+ "A knitted surface typically has a series of interlocking loops that have been created by using a knitting needle.",
+ "A \"knitted\" texture looks like a series of small loops that are interlocked together.",
+ "A \"knitted\" texture looks woven, like a fabric that has been made with a knitting needle.",
+ "A knitted texture looks like small loops of yarn that are interlocked together.",
+ "A knitted texture looks like a series of interlocking loops.",
+ "A knitted texture is typically made up of small, repeating loops.",
+ "A knitted texture looks like a series of small loops that are connected together.",
+ "A knitted texture looks like a series of small loops that have been joined together.",
+ "A knitted texture usually looks like small, tight loops.",
+ "You can see a knitted texture in the photo below.",
+ "It takes on the appearance of small loops or stitches.",
+ "A knitted object looks like a fabric object that has been made using a knitting needle and yarn.",
+ "A knitted object generally looks like a fabric made up of interlocking loops of yarn.",
+ "A knitted object is typically a garment, such as a sweater, scarf, or hat, that has been made from interlocking loops of yarn.",
+ "A knitted object looks like a fabric made up of interlocking loops of yarn.",
+ "Knitted objects are usually made up of a series of interlocking loops of yarn.",
+ "A knitted object usually looks like a piece of fabric that has been created by interlocking loops of yarn.",
+ "A knitted object is a piece of fabric that has been created by interlocking loops of yarn or thread.",
+ "Knitted objects are typically composed of straight, parallel lines of stitches that are interlocked together in a certain pattern.",
+ "A knitted object, such as a sweater, scarf, or hat, is an object that has been created by interlocking loops of yarn or other material with needles.",
+ "A knitted object is usually a piece of clothing, like a sweater or a scarf.",
+ "A knitted thing looks like a piece of fabric that has been created by interlocking loops of yarn.",
+ "A knitted thing can take on many different forms, as it is a method of fabric construction that involves looping yarn or thread together with needles.",
+ "A knitted thing can look like a lot of different things.",
+ "A \"knitted\" thing looks like it is made out of interlocking loops of yarn.",
+ "A knitted item looks like it has been made with a knitting needle and thread.",
+ "A knitted thing looks like a piece of cloth that has been made by interlocking loops of yarn.",
+ "A knitted thing looks like it is made of interlocking loops of yarn.",
+ "A knitted thing looks like a piece of fabric that has been created by interlocking loops of yarn.",
+ "A knitted thing looks like a piece of fabric that has been made by interlocking loops of yarn.",
+ "A \"knitted\" thing looks like a piece of fabric that has been created by interlocking loops of yarn.",
+ "A knitted pattern typically consists of a series of rows of different stitches.",
+ "A knitted pattern looks like a series of stitches that are looped together.",
+ "A knitted pattern typically consists of a series of rows of stitches that are repeated to create a design.",
+ "A knitted pattern looks like a row of interlocking loops.",
+ "A knitted pattern is a set of instructions that tells you how to knit a specific item.",
+ "A knitted pattern looks like an interlocking net of loops.",
+ "Knitted pattern typically refers to the overall appearance of a knit fabric, and can often times look like a series of interlocking loops.",
+ "A knitted pattern is typically a series of rows of different stitches that are repeated to create a design.",
+ "A knitted pattern looks like a series of interconnected loops.",
+ "A knitted pattern may look like a series of loops or like a series of connected lines."
+ ],
+ "grooved": [
+ "Here is an image of what \"grooved\" material looks like:.",
+ "A grooved surface has parallel lines cut into it.",
+ "Grooved materials have ridges or lines running along their surface.",
+ "A material that is \"grooved\" has indentations or furrows on its surface.",
+ "A grooved material has parallelly spaced furrows or channels on its surface.",
+ "Grooved material has parallel lines cut into it, usually for the purpose of decoration or to create a rougher surface.",
+ "The term \"grooved\" can refer to many different types of surfaces or textures.",
+ "Grooves are usually long and narrow, like a trench.",
+ "A grooved material has a series of parallel ridges running along its surface.",
+ "\"Grooved\" material is characterized by having one or more grooves running along its length.",
+ "A grooved surface is formed when a hard object is dragged across a soft material, leaving a channel behind it.",
+ "A grooved surface is a surface that has ridges or furrows cut into it.",
+ "A grooved surface usually has parallel, linear scratches running across it.",
+ "A grooved surface has a series of parallel lines cut into it.",
+ "A grooved surface has a line or furrow cut into it.",
+ "A grooved surface is a surface with a series of parallel lines running along it.",
+ "A grooved surface has a series of evenly spaced, parallel indentations in it.",
+ "A grooved surface is a surface that has been marked with fine lines.",
+ "A grooved surface usually has parallel lines cut into it.",
+ "A \"grooved\" surface looks like a surface with grooves in it.",
+ "A grooved texture looks like a series of small lines or furrows.",
+ "A grooved texture has parallel lines running across it.",
+ "A grooved texture is a bit like a wavy texture, but with more defined lines.",
+ "\"Grooved\" can mean different things depending on the context, but typically a grooved texture is one that has parallel lines running across it.",
+ "The word \"grooved\" can describe different textures, but a common one is a series of parallel lines or ridges.",
+ "\"Grooved\" textures can vary depending on the size and depth of the groove, but they generally have a linear, furrowed appearance.",
+ "A grooved texture usually has a series of parallel lines running across it.",
+ "A grooved texture looks like a series of lines or ridges.",
+ "A \"grooved\" texture usually refers to a surface that has noticeable lines or indents running along it.",
+ "A grooved texture looks like it has furrows or channels running through it.",
+ "A grooved object is one that has a wide, shallow cut or depression running along its length.",
+ "A \"grooved\" object is an object with a line or furrow cut into its surface.",
+ "A grooved object has a smooth, deep channel cut into its surface.",
+ "A grooved object looks like an object that has a line or a crease running down the middle of it.",
+ "A grooved object has a long, narrow cut or indentation in its surface.",
+ "A grooved object has a line or furrow cut into it.",
+ "A grooved object is one that has a series of ridges or indentations running along its length.",
+ "A grooved object looks like an object with a line or crease running down the middle of it.",
+ "A grooved object is one that has a line or furrow cut into its surface.",
+ "A \"grooved\" object has a line or furrow cut into its surface.",
+ "A grooved thing can look like a ridged or furrowed object.",
+ "A \"grooved\" thing has indentations or furrows running along its length.",
+ "A grooved thing has furrows or indentations running along its length.",
+ "A grooved thing usually has a long, narrow depression running along its length.",
+ "A grooved thing has lines or markings on its surface that create a pattern.",
+ "A grooved thing looks like it has lines or ridges cut into it.",
+ "A grooved thing has a line or depression in it, usually for the purpose of holding something in place.",
+ "A \"grooved\" thing has raised lines running parallel to each other.",
+ "A grooved thing has lines or furrows cut into it.",
+ "A grooved thing has ridges or furrows running along its length.",
+ "The most common type of grooved pattern is a series of parallel lines that are spaced apart from each other.",
+ "The grooves in a \"grooved\" pattern are usually straight and evenly spaced.",
+ "One example of a grooved pattern is a series of parallel lines.",
+ "A grooved pattern comprises a series of parallel, V-shaped grooves that are evenly spaced and run in the same direction.",
+ "A grooved pattern is a pattern that has lines or furrows cut into it.",
+ "A grooved pattern is a series of parallel indents or ridges in a surface.",
+ "A \"grooved\" pattern typically has a series of parallel lines running across it.",
+ "A grooved pattern is when there is a line or groove in the fabric.",
+ "The image below shows an example of a \"grooved\" pattern.",
+ "A grooved pattern is a series of parallel lines that are slightly curved or indented."
+ ],
+ "dotted": [
+ "Dotted material generally consists of small circles or dots that are printed or embroidered onto the fabric.",
+ "Dottedmaterial typically has a textured surface with small bumps or ridges.",
+ "Dotted material typically has small raised dots on the surface.",
+ "Dotted material has small, raised dots on the surface.",
+ "Dotted material typically has a series of small dots printed on it.",
+ "A dotted material has small dots all over it.",
+ "A dotted material has small dots all over it.",
+ "A dotted material has a pattern of small dots.",
+ "Dotted material is material that has small dots on it.",
+ "Dotted material has small, raised dots on the surface.",
+ "A dotted surface looks like a surface with dots on it.",
+ "A dotted surface looks like it has a lot of small dots on it.",
+ "A \"dotted\" surface looks like a surface that has been covered in dots.",
+ "A dotted surface is a surface that is covered in dots.",
+ "A dotted surface has a series of dots on it, rather than a solid color or pattern.",
+ "A surface that is dotted looks like it has a lot of small bumps or pits.",
+ "A dotted surface is a surface that has small, raised dots.",
+ "A dotted surface is a surface with a lot of small bumps on it.",
+ "A dotted surface has a texture that is bumpy and has small raised dots.",
+ "A dotted surface looks like a surface with small dots on it.",
+ "A dotted texture would have small, raised dots all over the surface.",
+ "A dotted texture looks like a texture that has dots on it.",
+ "A dotted texture features small dots that are arranged in a regular pattern.",
+ "A dotted texture means that there are small raised dots on the surface of the fabric.",
+ "A dotted texture is one that has a lot of small dots on it.",
+ "A dotted texture generally looks like a polka dot pattern.",
+ "A dotted texture is a texture that has numerous small dots on its surface.",
+ "A \"dotted\" texture looks like a series of small dots.",
+ "A \"dotted\" texture looks like a series of small dots.",
+ "A dotted texture looks like a lot of small dots close together.",
+ "A \"dotted\" object has small dots all over it.",
+ "A dotted object has many small dots across its surface.",
+ "A \"dotted\" object is an object with a series of small dots on it.",
+ "A dotted object looks like it has dots on it.",
+ "A dotted object has a pattern of small dots.",
+ "A dotted object has a lot of small dots on it.",
+ "A dotted object looks like it has tiny dots all over it.",
+ "A dotted object has a series of small dots on it.",
+ "A dotted object has a series of small dots arranged in a pattern.",
+ "\"Dotted\" objects have a series of small round dots on them.",
+ "AAPL's earnings release yesterday was \"dotted\" with strong quarterly results.",
+ "The term \"dotted\" can mean different things depending on the context.",
+ "When something is dotted, it means it is covered in small dots.",
+ "A dotted thing has a series of small dots in a line or pattern.",
+ "A dotted thing looks like it has dots on it.",
+ "A \"dotted\" thing looks like it has dots on it, like a polka dot.",
+ "A dotted thing looks like a series of dots or points.",
+ "A dotted thing looks like a polka-dot.",
+ "A dotted thing typically has a series of dots that are evenly spaced apart.",
+ "A \"dotted\" thing looks like it has dots on it.",
+ "A dotted pattern is a pattern that has dots instead of solid lines.",
+ "A dot-and-dash pattern consists of dots separated by dashes.",
+ "A dotted pattern usually consists of a repeating pattern of dots.",
+ "A dotted pattern has a series of dots that are evenly spaced apart.",
+ "A dotted pattern can look like a series of dots, or a polka dot pattern.",
+ "The dots in a dotted pattern are usually evenly spaced, and the spaces between the dots are usually the same size as the dots.",
+ "A dotted pattern looks like a series of dots.",
+ "A dotted pattern has dots spaced evenly over the surface.",
+ "A dotted pattern is usually a polka dot pattern.",
+ "A dotted pattern looks like a series of dots."
+ ],
+ "interlaced": [
+ "Interlaced material is made up of a series of parallel lines that are crossed by a series of perpendicular lines.",
+ "Interlaced images appear as a series of scan lines.",
+ "Interlaced material is a material that is made up of two or more different types of materials that are interwoven together.",
+ "Interlaced material looks like a series of horizontal lines that are slightly offset from each other.",
+ "\"Interlaced\" material is a video signal that is composed of two fields captured at slightly different times.",
+ "Interlaced material is a type of digital video that appears to have scan lines.",
+ "\"Interlaced\" material looks like a series of horizontal lines that are slightly offset from each other.",
+ "Interlaced materials have a visible striped pattern.",
+ "The alternate scanning of odd and even lines in an interlaced video signal.",
+ "Interlaced material appears to have a series of curved lines running through it.",
+ "A interlaced surface looks like a series of parallel lines.",
+ "A interlaced surface has a surface that is not smooth, but instead has a series of ridges and valleys.",
+ "A \"interlaced\" surface looks like two pieces of paper that have been glued together at the edges.",
+ "A surface that is interlaced looks like a series of parallel lines that are crossed by a series of other parallel lines at regular intervals.",
+ "A \"interlaced\" surface has a series of ridges and furrows that give it a textured look.",
+ "Interlaced surfaces have a wavy, disorderly appearance.",
+ "An interlaced surface is a surface that has been divided into a number of small strips, which are then woven together.",
+ "Interlaced surfaces have a wavy or zigzag appearance.",
+ "A surface that is interlaced has a criss-crossing pattern.",
+ "The surface of an object that has been interlaced looks like it has been woven together.",
+ "An interlaced texture is a texture that has been created by combining two or more separate images into a single image.",
+ "An interlaced texture is a texture in which the individual elements are not aligned directly next to each other, but are staggered or offset.",
+ "An interlaced texture is a texture that looks like it has been split into horizontal bands.",
+ "An interlaced texture looks like a series of lines that cross over each other.",
+ "A textures that is interlaced looks like it has horizontal lines running through it.",
+ "A \"interlaced\" texture looks like a wavy or zigzag pattern.",
+ "A \"interlaced\" texture looks like a series of wavy lines.",
+ "A \"interlaced\" texture looks like a set of parallel lines that cross each other.",
+ "Interlaced textures are created by taking scanned images and dividing them into even and odd scan lines.",
+ "A \"interlaced\" texture looks like a checkerboard pattern.",
+ "An interlaced object is a type of optical illusion where-in two separate images are merged into one image that appears to be moving.",
+ "Interlacing is a technique for displaying video that minimizes flickering by painting every other line of the image on the screen, then immediately painting the remaining lines.",
+ "Interlacing is a method of displaying a computer graphic image by scanning it line by line.",
+ "A \"interlaced\" object is an object that has a pattern of crossing lines.",
+ "An interlaced object has a pattern of over-and-under weaving.",
+ "An interlaced object looks like an object that has been woven together.",
+ "A \"interlaced\" object look like a series of vertical lines that are slightly offset from each other.",
+ "When an object is interlaced, it appears to be woven together with other objects.",
+ "A \"interlaced\" object appears to have two images layered on top of one another.",
+ "A \"interlaced\" object is a object that has been divided into two or more parts.",
+ "The term \"interlaced\" can refer to different things, but often refers to a video display where each video frame is divided into two fields that are displayed alternately.",
+ "If you are talking about an interlaced television signal, it looks like a fuzzy picture.",
+ "Interlaced typically refers to images displayed on a screen, where two fields of the image are displayed alternately.",
+ "A \"interlaced\" thing can look like a chain link fence.",
+ "A \"interlaced\" thing looks like two things that are intertwined with each other.",
+ "The term \"interlaced\" can refer to anything that has been intertwined or woven together.",
+ "The term \"interlaced\" refers to a method of displaying video in which each frame is divided into two fields.",
+ "When something is interlaced, it is criss-crossed or woven together.",
+ "An interlaced thing looks like a netted or woven pattern.",
+ "An interlaced object has a pattern of lines or other markings that cross each other.",
+ "The interlaced pattern is a design that consists of a series of parallel lines that cross each other.",
+ "A \"interlaced\" pattern looks like a woven basket.",
+ "An interlaced pattern is made up of two sets of lines that cross each other.",
+ "An interlaced pattern weaves two sets of threads together.",
+ "An interlaced pattern looks like a series of diagonal lines crossing over each other.",
+ "A \"interlaced\" pattern typically looks like a set of parallel lines that are crossed by a set of perpendicular lines.",
+ "A \"interlaced\" pattern looks like a repeating series of overlapping lines or shapes.",
+ "The interlaced pattern is a set of parallel lines that intersect each other at regular intervals.",
+ "A interlaced pattern looks like a series of lines that cross each other.",
+ "A \"interlaced\" pattern looks like a series of parallel lines that are crossed with a series of perpendicular lines."
+ ],
+ "crosshatched": [
+ "A crosshatched material has a pattern of criss-crossed lines.",
+ "Crosshatched fabric is a fabric that has a design made up of crossed lines.",
+ "Crosshatched material is made up of a series of intersecting lines, usually in a criss-cross pattern.",
+ "Crosshatched fabrics are materials which have two sets of perpendicular lines running over them.",
+ "Crosshatched material is typically a fabric that has two different sets of parallel lines running in different directions.",
+ "Crosshatched material has a series of parallel lines that intersect each other to form a diamond pattern.",
+ "\"Crosshatched\" material usually has a pattern of repeated, intersecting lines.",
+ "Crosshatched material has a texture that resembles a series of crossed lines.",
+ " Crosshatched material has a series of parallel lines that intersect to form a diamond-like pattern.",
+ "Crosshatched material typically has a pattern of parallel lines that intersect at right angles.",
+ "A crosshatched surface is one that has a series of intersecting lines, giving it a criss-crossed appearance.",
+ "A crosshatched surface looks like a surface with a series of parallel lines intersecting at right angles.",
+ "A crosshatched surface looks like it has a lot of lines intersecting each other at different angles.",
+ "Crosshatched surfaces are surfaces that have been covered with a series of intersecting lines.",
+ "A crosshatched surface has a series of crossed lines running over it.",
+ "A crosshatched surface is a surface that has been covered with a series of crossed lines.",
+ "A crosshatched surface has a series of parallel lines that intersect each other at right angles.",
+ "A crosshatched surface has a series of intersecting diagonal lines.",
+ "A crosshatched surface looks like it has a series of overlapping diagonal lines.",
+ "A crosshatched surface is a surface that has been covered with a series of parallel lines that cross each other.",
+ "If you were to imagine a piece of wood that had been burned by a very hot fire, that is what a crosshatched texture would look like.",
+ "A crosshatched texture is one that has a series of lines going in different directions.",
+ "A crosshatched texture looks like a series of crossing lines.",
+ "Crosshatched textures are created when two sets of parallel lines are crossed over each other, creating a diamond-shaped pattern.",
+ "A crosshatched texture looks like a series of criss-crossing lines.",
+ "A crosshatched texture looks like a series of criss-crossed lines.",
+ "A crossed or crosshatched texture has two sets of lines crossing each other at right angles.",
+ "Crosshatched textures have a crisscross pattern.",
+ "Crosshatched textures are typically made up of a series of parallel lines that intersect each other at right angles.",
+ "A crosshatched texture is a series of intersecting lines that create a pattern of squares or diamonds.",
+ "A crosshatched object looks like it has a bunch of lines going across it, making it look like a bunch of little squares put together.",
+ "A crosshatched object has a series of diagonal lines crossed over each other.",
+ "It looks like a crosshatch pattern.",
+ "The lines on a crosshatched object are drawn in opposite directions, usually at a 45 degree angle.",
+ "A \"crosshatched\" object is an object that has been divided into multiple sections by crossed lines.",
+ "A \"crosshatched\" object is an object that has a pattern of parallel lines intersecting each other.",
+ "A \"crosshatched\" object is one that has a series of parallel lines intersecting each other to form a series of small squares or diamonds.",
+ "A crosshatched object looks like it has been cut across with a series of diagonal lines.",
+ "An object with crosshatching has a series of parallel lines drawn across it, at an angle to one another.",
+ "A crosshatched object has a series of lines that intersect each other to form a series of small squares.",
+ "A crosshatched thing looks like it has a lot of lines going across it.",
+ "A crosshatched thing has a series of lines that intersect to form a crisscross pattern.",
+ "A crosshatched thing is a thing that has two sets of parallel lines crossing each other.",
+ "If something is crosshatched, it is marked with a series of lines that intersect each other.",
+ "A \"crosshatched\" thing is a drawing or pattern that has two sets of lines crossing each other.",
+ "Crosshatched lines are lines that intersect each other to form a network of small squares.",
+ "A \"crosshatched\" thing is a thing that has been divided into equal parts by two or more lines that intersect each other.",
+ "A crosshatched thing is made up of a series of intersecting lines, usually forming a crisscross pattern.",
+ "When something is crosshatched, it is covered in a series of parallel lines that intersect each other to form a network of small squares.",
+ "A crosshatched thing is a drawing or design that consists of two sets of parallel lines that intersect each other.",
+ "A crosshatched pattern is made up of a series of crossed lines.",
+ "A crosshatched pattern is a series of diagonal lines that intersect each other to form a grid.",
+ "A crosshatched pattern is a series of crossed lines that form a diamond shape.",
+ "A \"crosshatched\" pattern has a series of parallel lines intersecting at right angles.",
+ "A crosshatched pattern has a series of parallel lines that intersect each other at right angles.",
+ "A crosshatched pattern is a series of intersecting lines that form a grid-like pattern.",
+ "A crosshatched pattern has a series of parallel lines that intersect at right angles.",
+ "A crosshatched pattern looks like a regular grid, but with the lines intersecting at different angles.",
+ "A crosshatched pattern is a series of crossed lines that form a grid.",
+ "A crosshatched pattern is a series of parallel lines that intersect each other."
+ ],
+ "wrinkled": [
+ "A wrinkled material looks like it has been folded or creased.",
+ "Wrinkled material is material that is no longer smooth, but instead is creased or folded.",
+ "A wrinkled piece of material typically has creases or folds in it.",
+ "Wrinkled material looks like it has been crumpled up and then smoothed out again.",
+ "Another word for wrinkled could be crumpled.",
+ "Wrinkled material generally looks like it has been crumpled up.",
+ "Wrinkled material is material that has been creased, folded, or twisted so that it is no longer smooth.",
+ "Wrinkled material can look like a fabric that has been rumpled or crumpled.",
+ "Wrinkled material is generally creased or folded.",
+ " Wrinkled material looks like it has wrinkles.",
+ "A wrinkled surface looks like a series of small hills and valleys.",
+ "A \"wrinkled\" surface looks like it has small, raised bumps all over it.",
+ "A \"wrinkled\" surface looks like a piece of fabric that has been bunched up and then smoothed out again.",
+ "A wrinkled surface has a lot of small folds or ridges in it.",
+ "A wrinkled surface usually looks like a piece of fabric that has been crumpled up.",
+ "A wrinkled surface looks like a surface that has been folded or creased.",
+ "A \"wrinkled\" surface looks like a surface that has a lot of small wrinkles or creases on it.",
+ "A wrinkled surface looks like it has a lot of small bumps or ridges.",
+ "A \"wrinkled\" surface looks like a piece of paper that has been crumpled up into a ball.",
+ "A wrinkled surface is one that is not smooth, but has ridges or bumps.",
+ "A wrinkled texture usually looks like a series of small lines or wrinkles.",
+ "A \"wrinkled\" texture has small, raised lines or creases on the surface.",
+ "A \"wrinkled\" texture usually looks like a bunch of small lines or wrinkles.",
+ "A wrinkle is a ridge or crease in the surface of something.",
+ "A \"wrinkled\" texture looks like a surface that has been folded or wrinkled.",
+ "A wrinkled texture looks like a surface that has a lot of small wrinkles or indentations.",
+ "A \"wrinkled\" texture typically looks like textured fabric that has been wrinkled or folded.",
+ "Wrinkled textures are usually dry, rough, and irregular.",
+ "A \"wrinkled\" texture usually looks like a series of small lines or creases in the surface.",
+ "A \"wrinkled\" texture usually looks like it has a lot of small lines in it.",
+ "If an object is wrinkled, it has many lines or creases on its surface.",
+ "A wrinkled object is an object that has lines or creases on its surface.",
+ "A wrinkled object can look like it has folds or creases in it.",
+ "A wrinkled object has many small folds or creases in it.",
+ "When an object is wrinkled, it has many lines or creases in it.",
+ "A wrinkled object is an object that has folds or creases in it.",
+ "A wrinkled object looks like it has wrinkles.",
+ "When an object is wrinkled, it has lines or creases on its surface.",
+ "A \"wrinkled\" object is an object that has been formed or shaped into ridges or wrinkles.",
+ "A wrinkled object is an object that has lines or folds on its surface.",
+ "If you are referring to wrinkles in fabric, they are normally caused by improper storage of the fabric or by repeated washings.",
+ "A wrinkled thing appears to have lines or creases on its surface.",
+ "A \"wrinkled\" thing looks like it has a lot of wrinkles, or lines, on its surface.",
+ "A wrinkled thing looks like something that has a lot of wrinkles in it.",
+ "\"Wrinkled\" can mean different things depending on what you're talking about.",
+ "A \"wrinkled\" thing looks like it has lines or creases on its surface.",
+ "A wrinkled thing looks like it has had all of the air squished out of it and has folded in on itself.",
+ "A \"wrinkled\" thing looks like it has wrinkles, or like it has been squished so that its shape is not very regular.",
+ "A wrinkled thing can look like a piece of fabric that has been bunched up and then smoothed out again.",
+ "A wrinkled thing typically looks like it has been folded or scrunched up for a long period of time.",
+ "A wrinkled pattern is one that is not smooth or even, but rather has a lot of small bumps or ridges.",
+ "A wrinkled pattern appears as a series of raised or lowered lines on a surface.",
+ "A wrinkled pattern is one that is not smooth, but instead has small lines or ridges running across it.",
+ "A wrinkled pattern is a series of lines or creases that are close together.",
+ "A wrinkled pattern has small, regular wrinkles running across the surface.",
+ "A wrinkled pattern looks like a series of creases or wrinkles.",
+ "A \"wrinkled\" pattern is one that has a lot of small lines or wrinkles in it.",
+ "A wrinkled pattern can look like a series of small lines or wrinkles that are close together.",
+ "A wrinkled pattern is one that has a lot of small lines or wrinkles in it.",
+ "Wrinkled patterns are characterized by small, raised bumps that give the appearance of wrinkles."
+ ],
+ "smeared": [
+ "\"Smeared\" material looks like a blur or a smear.",
+ "\"Smeared\" material looks like it has been smeared with a substance.",
+ "Smeared material is material that has been spread or smudged, often in a wet or messy way.",
+ "A smeared material is usually a liquid or a very fine powder.",
+ "A: Smeared material is usually liquid or gel-like in appearance.",
+ "A smeared material would have a streaky or blurry appearance.",
+ "\"Smeared\" material looks like it has been smeared or wiped across a surface.",
+ "\"Smeared\" material usually looks like a blur or a streak.",
+ "There is no definitive answer to this question since the appearance of smeared material will depend on the specific material that is being smeared as well as the conditions under which the smearing is taking place.",
+ "\"Smeared\" material can look like streaks or smudges on a surface.",
+ "A smeared surface is usually rough and uneven.",
+ "A \"smeared\" surface looks like it has been covered with a thin layer of something.",
+ "A smeared surface is one that is not smooth.",
+ "A \"smeared\" surface is a surface that has had a solid material applied to it in a very thin layer.",
+ "A smeared surface looks unusable and unappealing.",
+ "A smeared surface has a thin, even coating of something.",
+ "A \"smeared\" surface looks like a surface with a lot of smears on it.",
+ "A smeared surface looks like a surface that has been blurred or unclear.",
+ "A smeared surface looks like a surface that has been covered in a thin layer of something.",
+ "A smeared surfaces looks like it has been rubbed with a dirty cloth.",
+ "A \"smeared\" texture usually looks like a streak or a line.",
+ "A smeared texture looks like a streak or line.",
+ "The term \"smeared\" is often used to describe a textures that looks blurry or streaky.",
+ "A smeared texture looks like a surface that has been smeared with a substance, usually a thick liquid.",
+ "A smeared texture is one that has been blended or smudged so that the original image is no longer visible.",
+ "A smeared texture Looks Like a streak or line of color that has been dragged across the surface.",
+ "A smeared texture looks like a blur.",
+ "A smeared texture looks like a streaky or blotchy texture.",
+ "A \"smeared\" texture may appear as if the paint has been applied carelessly or with too much water, resulting in a runny or streaky appearance.",
+ "A smeared texture is usually caused by applying too much pressure when blending or by using a brush that is too large.",
+ "A smeared object looks like a streak or a line.",
+ "A smeared object looks like a blob.",
+ "A smeared object looks like a blur.",
+ "A smeared object is one that has lost its shape or form.",
+ "A smeared object may appear to have a blurry or fuzzy edge.",
+ "A smeared object looks like a blurred object.",
+ "A \"smeared\" object looks like a blurred object.",
+ "A smeared object appears to be streaky or blurry.",
+ "A smeared object looks blurry.",
+ "A \"smeared\" object does not have a well-defined shape.",
+ "There is no definitive answer to this question since the term \"smeared\" can be used to describe a wide range of visual textures and patterns.",
+ "A smeared thing looks like a mess.",
+ "When something is smeared, it looks like it has been smudged or rubbed together.",
+ "When something is smeared, it is usually spread out over a surface in a thin layer.",
+ "If something is smeared, it looks like a mess.",
+ "A \"smeared\" thing looks like a blur.",
+ "A \"smeared\" thing looks blurred, like it has been smeared with a finger.",
+ "If you smear something, it will become Spread out and unclear.",
+ "A smeared thing looks like a blurry mess.",
+ "When something is smeared, it is usually streaked or smudged.",
+ "A smeared pattern typically looks like a blur or a streak.",
+ "A smeared pattern looks like a series of lines or bars that are close together.",
+ "The term \"smeared\" is most often used to describe an unfocused or poorly defined image.",
+ "In a smeared pattern, the edges of the objects are not well defined and appear to be blurred.",
+ "A smeared pattern has blobs or smudges of color instead of clear lines or shapes.",
+ "A smeared pattern is one where the lines are blurred and not well defined.",
+ "A smeared pattern looks like a series of lines or blobs that have been smeared or streaked in a particular direction.",
+ "A smeared pattern is a repeating pattern that has been blurred or distorted.",
+ "A smeared pattern typically appears as a wash of color instead of a distinct pattern.",
+ "A \"smeared\" or \"fuzzy\" pattern is one in which the lines are not well defined and appear to be blurred."
+ ],
+ "striped": [
+ "Striped material usually has alternating bands of color running horizontally or vertically.",
+ "Striped material is usually a cotton fabric with vertical or horizontal stripes.",
+ "Striped material is a type of fabric that has stripes of different colors or shades.",
+ "A striped fabric has horizontal or vertical lines running through it.",
+ "A striped fabric has parallel lines of different colors running the length of the fabric.",
+ "A striped material typically has a repeating pattern of light and dark stripes.",
+ "A striped pattern typically consists of repeated, regular lines that run perpendicular to each other.",
+ "A striped fabric has lines running vertically or horizontally across it.",
+ "A striped fabric has parallel lines of different colors going across it.",
+ "A striped material has lines going horizontally or vertically across it.",
+ "A striped surface has alternating light and dark stripes.",
+ "A \"striped\" surface has parallel lines running across it.",
+ "A striped surface looks like a surface that has stripes on it.",
+ "A striped surface looks like a surface that has stripes on it.",
+ "A \"striped\" surface has alternating bands of light and dark colors.",
+ "A striped surface looks like a surface that has been divided into a series of vertical stripes.",
+ "A striped surface has evenly spaced lines running across it.",
+ "A striped surface is a surface that has stripes of different colors on it.",
+ "A \"striped\" surface looks like a surface that has stripes on it.",
+ "A \"striped\" surface has rows of alternating light and dark colors.",
+ "A \"striped\" texture looks like a surface that has been divided into a series of horizontal bands.",
+ "A \"striped\" texture usually looks like a series of perpendicular lines that run across the surface.",
+ "A \"striped\" texture look like horizontal or vertical lines going through it.",
+ "While there isn't a definitive answer, a striped texture is generally characterized by light and dark bands that are parallel to each other.",
+ "A \"striped\" texture looks like a repeated pattern of thin lines.",
+ "A striped texture looks like a series of evenly spaced stripes going in one direction.",
+ "A striped texture is a texture that is made up of stripes.",
+ "A striped texture has vertical lines running through it.",
+ "A striped texture usually looks like horizontal or vertical lines running across the texture.",
+ "A striped texture can look like a series of parallel lines that are close together, or it can look like a series of parallel lines that are farther apart.",
+ "A \"striped\" object is one that has alternating bands of two different colors.",
+ "A striped object has evenly-spaced lines running across it.",
+ ".",
+ "A \"striped\" object can have many different appearances, but a common theme is that the object has lines or stripes running along its surface.",
+ "A \"striped\" object has lines running across it, usually of a different color than the object's base color.",
+ "A striped object is an object that has lines or stripes on it.",
+ "A striped object has areas of color that alternate light and dark, giving the object the appearance of stripes.",
+ "A striped object has lines going across it.",
+ "A \"striped\" object is an object that has stripes on it.",
+ "A \"striped\" object is an object that has two colors that are evenly distributed along its length.",
+ "A striped thing has stripes on it.",
+ "A striped thing has lines going across it.",
+ "A \"striped\" thing has stripes running along its length.",
+ "A striped thing has lines or bands going across it.",
+ "A striped thing has horizontal or vertical lines of different colors running across it.",
+ "A \"striped\" thing has stripes on it.",
+ "A \"striped\" thing has horizontal or vertical lines of different colors.",
+ "A striped thing can look like a line or a series of lines that are evenly spaced and parallel to each other.",
+ "The definition of striped is having lines or markings of different colors.",
+ "A striped thing has vertical lines of different colors going down its length.",
+ "A striped pattern consists of lines or bands of different colors or shades.",
+ "A striped pattern features parallel lines that run the length of the fabric.",
+ "A \"striped\" pattern is a pattern that contains stripes.",
+ "A \"striped\" pattern typically consists of repeating vertical or horizontal lines of varying widths.",
+ "A striped pattern has parallel lines going in one direction.",
+ "A \"striped\" pattern typically consists of parallel lines that run the length of the fabric.",
+ "A \"striped\" pattern looks like a series of parallel lines.",
+ "A strip pattern consists of parallel lines that run the length of the fabric.",
+ "A stripes pattern typically consists of a series of horizontal or vertical lines that are of different colors.",
+ "A striped pattern looks like a series of stripes that are horizontal, vertical, or diagonal."
+ ],
+ "braided": [
+ " Braided material is made up of three or more strands of fabric that have been braided together.",
+ "A braided material has multiple strands of material that are interwoven together.",
+ "A braid is a complex weaving pattern created by interlacing three or more strands of flexible material such as textile yarns, wire, or hair.",
+ "Braided material is made up of three or more strands of fabric that have been interlaced together.",
+ "A braided material is a type of fabric that has been woven together in a narrowd, interlacing pattern.",
+ "Braided material is a type of fabric that is made by interlacing three or more strands of yarn or thread together.",
+ "A \"braided\" material looks like a rope or cord that is made up of three or more strands of material that have been twisted together.",
+ "Braided material looks like a series of interconnected loops.",
+ " Braided materials look like interwoven strands of material.",
+ "\"Braided\" material often looks like a series of intertwined ropes or strips of fabric.",
+ "A braided surface has a series of ridges and valleys that look like braids.",
+ "A braided surface can look like a series of interlocking loops, or it can look like a series of intersecting lines.",
+ "A braided surface looks like a series of interlocking loops.",
+ "A braided surface can look like a series of interlocking loops or like a series of twists and turns.",
+ "A braided surface looks like a series of interlocking loops.",
+ "A \"braided\" surface looks like a surface that has been torn apart and then put back together again in a way that is not smooth.",
+ "A \"braided\" surface is a surface formed by intersecting lines that cross over each other.",
+ "A braided surface has a series of ridges and valleys that look like a braid.",
+ "A braided surface is made up of two or more surface that intersect each other.",
+ "A braided surface looks like a surface that has been intersected by a series of curves.",
+ "A \"braided\" texture is defined by small, thin strands of material that are intertwined with each other.",
+ "A braided texture has the appearance of small, interwoven strands.",
+ "A \"braided\" texture has small, thin strands that are woven together in a criss-cross pattern.",
+ "A \"braided\" texture looks like a series of intertwined ropes or strands.",
+ "A braided texture has a series of small, raised lines that criss-cross each other, creating a textured surface.",
+ "A braided texture is a series of interlocking loops.",
+ "A \"braided\" texture would look like a series of interlocking loops.",
+ "A braided texture has the appearance of small strands of hair being interwoven together.",
+ "A \"braided\" texture looks like it has been plaited or interwoven.",
+ "The word \"braided\" can have many different connotations, so it is hard to say without knowing more about what you are trying to describe.",
+ "A braided object has multiple strands or plaits that are intertwined with each other.",
+ "I'm not sure what you mean.",
+ "A braided object has intertwining strands or threads.",
+ "A braided object has two or more strands that are woven together in a pattern.",
+ "A braided object is typically made up of three or more strands of material that are intertwined.",
+ "A braid is a complex structure made of three or more strands of hair, fabric, or other material interwoven together.",
+ "A braided object is one where multiple strands are interwoven together.",
+ "A braided object has strands that are interwoven in a pattern, similar to a braid in hair.",
+ "A \"braided\" object has three or more strands that are interlaced together.",
+ "A braided object looks like it has been braided, or woven together.",
+ "A braided object has three or more strands that have been woven together.",
+ "A braided object has three or more strands woven together in a diagonal pattern.",
+ "The most common type of braid is a three-strand braid, which is composed of three sections of hair that are intertwined together.",
+ "It looks like a braid.",
+ "A \"braided\" thing usually has three strands or cords that are intertwined.",
+ "A \"braided\" thing looks like a rope or a string that has been woven together.",
+ "One example of a braided thing is a rope.",
+ "A \"braided\" thing looks like a rope or string that has been woven together from smaller pieces.",
+ "A \"braided\" thing looks like a rope or a braid of hair.",
+ "I'm not sure exactly what you are asking for, but a braided thing can look like a plait or braid in hair, for example.",
+ "There is not a definitive answer to this question because braided patterns can vary considerably.",
+ "A braided pattern looks like a series of interwoven strands.",
+ "A braided pattern often looks like a series of interconnected loops.",
+ "A \"braided\" pattern usually consists of three or more strands of fabric that are interwoven together in a braid-like manner.",
+ "A \"braided\" pattern typically features two or more strands of material that are intertwined with each other in a decorative way.",
+ "A \"braided\" pattern usually consists of 3 or more strands of fabric that are intertwined together.",
+ "A \"braided\" pattern generally looks like three or more strands of rope that have been braided together.",
+ "In a braided pattern, three or more strands of yarn are interlaced to create a textured fabric.",
+ "A braided pattern is a series of interlocking loops.",
+ "A \"braided\" pattern simply looks like a series of intertwined strands or cords."
+ ],
+ "freckled": [
+ "Freckled material typically has small, dark spots on a light background.",
+ "Freckled material looks like it has small brown spots all over it.",
+ "Freckled material typically has small, dark spots on a light background.",
+ "There is no definitive answer to this question as \"freckled\" can mean different things to different people.",
+ "Freckled material can look like a material that has small brown spots on it.",
+ "Freckled material looks like small spots or dots on the surface.",
+ "Freckled material can look like any other type of material with small spots or discolorations.",
+ "Freckled material is material that contains small, dark spots.",
+ "\"Freckled\" material is usually a material with small brown or black spots on it.",
+ "Materials that are freckled usually have small spots of color on them.",
+ "A freckled surface looks like a surface that has small, dark spots on it.",
+ "A \"freckled\" surface is one that has many small, dark spots.",
+ "A \"freckled\" surface is one that is covered in small spots or patches.",
+ "A freckled surface looks like a small, flat, brown spot.",
+ "A freckled surface is covered in tiny spots.",
+ "A \"freckled\" surface usually has a small, brownish spot on it.",
+ "A freckled surface is one that is covered in small, brown spots.",
+ "A freckled surface will appear to have small dots or spots on it.",
+ "A freckled surface is one that is covered with small, brownish spots.",
+ "A freckled surface is one that is covered in small spots.",
+ "A freckled texture looks like a small, dark spot on the surface of something.",
+ "Freckles are small, brown or black spots on the skin that are caused by exposure to the sun.",
+ "A freckled texture looks like a lot of small, dark spots close together.",
+ "A freckled texture looks like a small, dark spot on the surface of the skin.",
+ "The word \"freckled\" is often used to describe a spotted or speckled appearance.",
+ "A freckled texture means that there are small spots of color on the surface.",
+ "A freckled texture is a small, round, raised spot on the surface of something.",
+ "A freckled texture generally looks like a small, dark spot on the surface of something.",
+ "The word \"freckled\" is often used to describe a rough, uneven surface.",
+ "A freckled texture has small, light-colored spots on a dark background.",
+ "A freckled object has small spots on its surface.",
+ "A freckled object has small spots of color on it.",
+ "A freckled object has small, dark spots on its surface.",
+ "A freckled object has small, dark spots on its surface.",
+ "A freckled object is one that is covered in small spots.",
+ "A freckled object has small spots of color on it.",
+ "A freckled object is one that is covered in small, darker spots.",
+ "A freckled object has small spots of color on it.",
+ "A freckled object has spots or patches of color that are spread over its surface.",
+ "A freckled object will have small spots or flecks of color on it.",
+ "A freckled thing looks like it has small dots or spots on its surface.",
+ "A freckled thing has small, brown spots on its skin.",
+ "A freckled thing is generally a small, round spot on the skin that is darker than the surrounding skin.",
+ "Typically, a freckled thing has small, dot-like spots that are darker than the surrounding area.",
+ "A thing that is freckled has small, flat, brown spots on its surface.",
+ "A freckled thing typically has small, brown spots on its skin.",
+ "There is no one definitive answer to this question.",
+ "A \"freckled\" thing is something that has small, brown spots on it.",
+ "A \"freckled\" thing is typically small and has a lot of tiny spots.",
+ "A \"freckled\" thing is something with small dark spots on it.",
+ "A freckled pattern looks like spots or marks that are clustered together.",
+ "A \"freckled\" pattern looks like a series of small, dark spots on a light background.",
+ "A \"freckled\" pattern looks like a series of small, dark spots on a lighter background.",
+ "A \"freckled\" pattern looks like small spots or freckles that are randomly located on the surface.",
+ "A \"freckled\" pattern usually looks like a series of small, dark spots on a lighter background.",
+ "A freckled pattern looks like small dots or spots on the surface of something.",
+ "A freckled pattern is characterized by small, dark spots on a lighter background.",
+ "A freckled pattern typically looks like small, dark spots on the skin.",
+ "A \"freckled\" pattern looks like small dots or spots.",
+ "A freckled pattern looks like a series of small, dark spots on a light background."
+ ],
+ "cobwebbed": [
+ "\"Cobwebbed\" material is usually covered in a layer of dust or spider webs.",
+ "Cobwebbed material is usually old and dusty.",
+ "Cobwebbed material is usually covered in dust.",
+ "Cobwebbed material is material that is covered in cobwebs.",
+ "The word \"cobwebbed\" is often used to describe a material that is covered in dust or small particles.",
+ "Cobwebbed material is usually old and dusty.",
+ "Cobwebbed material is covered with a thin layer of dust or debris.",
+ "Cobwebbed material is usually covered in dust and often has a web-like pattern.",
+ "Cobwebbed material is material that is covered in cobwebs.",
+ "Cobwebbed material has a lot of small, spidery threads coming from it.",
+ "A cobwebbed surface is usually covered in fine dust or lint.",
+ "Cobwebbed surfaces are often dusty and have a lot of spiders webs on them.",
+ "A surface that is \"cobwebbed\" is covered with a thin, delicate webbing, usually found in the corners of rooms or other places where spiders commonly build their webs.",
+ "When a surface is covered in cobwebs, it looks like there are thin, delicate webs stretched across it.",
+ "A \"cobwebbed\" surface is one that is covered in fine, spider-web like strands.",
+ "A cobwebbed surface has a lot of small, thin pieces of dirt or dust on it that look like a spider's web.",
+ "A cobwebbed surface is a surface that is covered in cobwebs.",
+ "A \"cobwebbed\" surface is usually covered in dust and looks like a spider's web.",
+ "A surface that is covered in cobwebs looks like it is covered in a thin, sticky spider web.",
+ "A cobwebbed surface looks like it has very fine, delicate, spider webs on it.",
+ "The term \"cobwebbed\" is often used to describe the appearance of a spider's web.",
+ "A cobwebbed texture is like a spider web; it is thin and delicate.",
+ " Cobwebbed textures are often described as looking like a spider's web.",
+ "A \"cobwebbed\" texture looks like a spider's web.",
+ "A cobwebbed texture looks like a spiders web.",
+ "A cobwebbed texture is one that is covered in thin, delicate strands of webbing.",
+ "A \"cobwebbed\" texture looks like a spider web.",
+ "The texture of a cobweb is usually thin, delicate, and lacy.",
+ "A cobwebbed texture is usually defined as a small, delicate web or network.",
+ "A \"cobwebbed\" texture is one that is covered in thin, delicate strands that resemble a spider's web.",
+ "Cob webs are a common sign of neglect.",
+ "A cobwebbed object looks like it is covered in cobwebs.",
+ "A cobwebbed object has a thin layer of spider webs over it.",
+ "A cobwebbed object looks like it has been covered in spider webs.",
+ "A \"cobwebbed\" object is coated with a thin layer of spider webs.",
+ "A \"cobwebbed\" object is covered in a thin layer of spider webs.",
+ "Cobwebbed objects have a lot of dust and dirt on them, and look like they have spider webs on them.",
+ "When an object is \"cobwebbed,\" it is covered in a thin layer of spider webs.",
+ "A cobwebbed object looks like it has cobwebs on it.",
+ "A \"cobwebbed\" object has a lot of dust and cobwebs on it.",
+ "A \"cobwebbed\" thing is usually covered in dust and spider webs.",
+ "Dusty and old.",
+ "A cobwebbed thing is usually covered in a thin layer of dust or dirt.",
+ "A \"cobwebbed\" thing is covered in thin, delicate webs.",
+ "A cobwebbed thing has a lot of spider webs on it.",
+ "A cobwebbed thing looks like it is covered in cobwebs.",
+ "A \"cobwebbed\" thing is covered in thin, sticky spider webs.",
+ "A cobwebbed thing is covered in cobwebs.",
+ "A cobwebbed thing is covered in cobwebs.",
+ "A \"cobwebbed\" thing is covered in cobwebs.",
+ "A \"cobwebbed\" pattern looks like a spider web.",
+ "A cobwebbed pattern resembles a spider's web.",
+ "A cobwebbed pattern has a center point with lines radiating outwards like the spokes of a wheel.",
+ "A cobwebbed pattern generally looks like a spider web.",
+ "Spider webs are characteristically composed of radial threads of proteinaceous spider silk extruded from the spinnerets of spiders.",
+ "A cobwebbed pattern typically looks like a spider's web, with a series of concentric circles radiating out from a central point.",
+ "There is no definitive answer to this question because it can vary depending on the textile, the size of the weave, and the amount of cobwebs present.",
+ "A cobwebbed notice board is one that is covered in a layer of fine dust or dirt.",
+ "Cobwebbed patterns are generally found in fabric that has been stored for a long time and has not been used.",
+ "A cobwebbed pattern looks like a web or a series of interconnected lines."
+ ],
+ "honeycombed": [
+ "Honeycombed material looks like a series of hexagonal cells that are all interconnected.",
+ "Honeycombed material is material that is full of small holes, like a beehive.",
+ "Honeycombed material is a material that has been formed into a series of small hexagonal cells.",
+ "A honeycomb material is typically a lightweight paper or plastic that has a hexagonal cell shape.",
+ "Honeycomb material is made up of a series of hexagonal cells that are stacked together.",
+ "a.",
+ "A honeycombed material looks like a series of hexagons or honeycombs.",
+ "Honeycombed material looks like a series of hexagonal shapes laid out in a honeycomb pattern.",
+ "A honeycombed material is one that has a lot of small, hexagonal holes in it, like a beehive.",
+ "Honeycombed material is material that has been cut or drilled into thin sheets with a honeycomb-like pattern.",
+ "A honeycombed surface looks like a series of hexagonal cells.",
+ "A honeycombed surface looks like a beehive, with a series of hexagonal cells.",
+ "A honeycombed surface is a surface that has been divided into a series of small, hexagonal cells.",
+ "A honeycombed surface is a series of hexagonal shapes that are all interconnected.",
+ "A honeycombed surface is one that has a lot of small holes in it, making it look like a piece of honeycomb.",
+ "A \"honeycombed\" surface is defined as a surface with a series of small, hexagonal indentations.",
+ "A honeycombed surface looks like a series of small hexagonal cells, similar in appearance to a honeycomb.",
+ "A honeycombed surface typically contains small, hexagonal holes stacked close together.",
+ "A honeycombed surface looks like a series of hexagonal cells or sectors.",
+ "A surface with a honeycomb pattern has a series of hexagonal cells that are empty in the center.",
+ "A honeycomb texture is defined by a series of hexagonal shapes.",
+ "A honeycombed texture is a textured surface that is bumpy and has a pattern that resembles a beehive.",
+ "A honeycomb is a network of hexagonal cells, which are often found in nature in the form of a beehive.",
+ "A \"honeycombed\" texture looks like a series of small, hexagonal cells.",
+ "A honeycomb texture looks like a series of hexagons.",
+ "A honeycombed texture is one that is made up of small, hexagonal cells.",
+ "A honeycombed texture has a raised, geometric pattern that resembles the cells of a beehive.",
+ "The honeycomb texture looks like a series of hexagonal cells.",
+ "The word \"honeycombed\" is often used to describe a textured surface that has a lot of small, evenly-spaced indentations.",
+ "The \"honeycombed\" texture looks like a series of hexagonal cells.",
+ "A \"honeycombed\" object may have a hexagonal or octagonal shape, and is filled with small, empty spaces.",
+ "A honeycombed object looks like it has a lot of small hexagonal-shaped indentations.",
+ "A honeycombed object is one that has a series of small, hexagonal cells or cavities.",
+ "A honeycombed object is one that has a series of hexagonal cells that are all interconnected.",
+ "A \"honeycombed\" object has a lot of small, repeating spaces inside it, like the cells of a honeycomb.",
+ "A honeycombed object has a series of hexagonal or round cavities.",
+ "A honeycombed object is one that has a series of hexagonal cells that are all interconnected.",
+ "A \"honeycombed\" object has a series of hexagonal cells that are all connected to each other.",
+ "A honeycombed object has a lot of small, hexagonal spaces.",
+ "A honeycombed object has a lot of small, hexagonal holes in it, like a bees' honeycomb.",
+ "A honeycomb is a mass of hexagonal wax cells built by bees in their nests to contain their larvae and stores of honey.",
+ "A honeycomb is a configuration of hexagonal cells that are used by bees to store honey and pollen.",
+ "A honeycomb is a structure made up of hexagonal cells.",
+ "A honeycomb is a series of hexagonal cells that are used by bees to store honey.",
+ "Take a piece of wax and divide it into little hexagonal cells.",
+ "A honeycomb is a mass of hexagonal wax cells built by bees in their nests to store honey and pollen.",
+ "A \"honeycomb\" is a structure made of hexagonal cells, often found in nature (in bee hives) or manufactured (as in a honeycomb panel).",
+ "A honeycomb typically has a hexagonal shape, although the specific shape depends on the type of bee.",
+ "A honeycomb is a repeating hexagonal pattern.",
+ "A honeycombed thing has a lot of small, hollow spaces in it, like the cells in a beehive.",
+ "A honeycombed pattern looks like a series of hexagons in a repeating pattern.",
+ "A honeycombed pattern looks like a series of small, hexagonal cells.",
+ "A \"honeycombed\" pattern typically consists of a series of small hexagonal cells that are joined together in a repeating pattern.",
+ "A honeycombed pattern typically features a series of hexagonal shapes.",
+ "A honeycombed pattern is a series of hexagons that are connected to each other.",
+ "A honeycombed pattern looks like a bunch of hexagons put together.",
+ "The definition of \"honeycombed\" is having a pattern of hexagonal cells or cavities, like those of a honeycomb.",
+ "A honeycombed pattern is a series of hexagons that are connected to each other.",
+ "A honeycomb is a series of hexagonal cells that are all connected to one another.",
+ "A \"honeycombed\" pattern is a repeating pattern that looks like a hexagonal shape."
+ ],
+ "woven": [
+ "Woven material looks like a piece of fabric with a weave pattern.",
+ "Woven material is made of threads that are woven together.",
+ "Woven material is material that has been interlaced to form a fabric.",
+ "Woven material is a type of fabric that is created by interlacing two sets of yarn or thread at right angles to each other.",
+ "Woven fabric has a flat surface with no piles.",
+ "The word \"woven\" typically refers to a fabric that is created by interlacing two sets of yarn or other material at right angles to each other.",
+ "The definition of woven is \"to construct (a fabric, etc.",
+ "The word \"woven\" is used to describe a type of fabric that is created by interlacing two sets of threads at right angles.",
+ "A woven fabric has a smooth surface with no loops on the right side, and the wrong side has a series of small loops.",
+ "A woven fabric has a \"right\" side and a \" wrong\" side.",
+ "A woven surface has a series of crossing lines that form a mesh-like pattern.",
+ "A woven surface is a textured surface that simulates the appearance of fabric.",
+ "A woven surface is composed of intersecting perpendicular threads or wires.",
+ "A woven surface has a pattern of interlocking loops, similar to a fabric.",
+ "A woven surface is a surface that is made of a series of interlocking loops of thread.",
+ "A woven surface is made up of a series of interlocking loops that form a close-knit surface.",
+ "A woven surface looks like a mesh or netting.",
+ "A \"woven\" surface is a flat surface that has been interlaced with a pattern of perpendicular threads.",
+ "A woven surface has a series of interwoven threads or strips of material.",
+ "A woven surface is a three-dimensional surface that is made up of a series of interconnected loops.",
+ "Typically, a woven texture has a \"tight\" and \"smooth\" appearance.",
+ "A woven texture is like a fabric.",
+ "Woven textiles have a flat surface with no pile, and are made by interlacing two sets of yarns at right angles.",
+ "A woven texture has a crisscrossed pattern, like the weave of a basket.",
+ "A woven texture looks like a fabric that has been interlaced with thread.",
+ "A \"woven\" texture looks like a grid, with each \"square\" in the grid being a different color or shade.",
+ "A woven texture has a criss-crossing pattern, like the threads in a piece of fabric.",
+ "A woven texture is a type of fabric that has a textured surface.",
+ "A woven texture is made up of tiny overlapping threads that form a grid-like pattern.",
+ "A woven texture has a similar appearance to a fabric that has been woven together.",
+ "A woven object looks like a piece of fabric that has been created by interlocking pieces of thread or yarn.",
+ "A woven object is made from a series of interlocking loops of thread or other material.",
+ "A woven object is made up of many small threads that are interwoven with each other.",
+ "Woven objects are made of interlacing threads or strips of material.",
+ "When an object is woven, it is interlaced with two or more sets of threads at right angles to form a fabric or material.",
+ "A woven object has a tight, interlocking weave.",
+ "A woven object looks like two threads or strands of material that have been interlaced with each other.",
+ "A woven object is made up of yarn or thread that has been interlaced at right angles to form a fabric.",
+ "A woven object looks like a fabric that has been created by interlacing two sets of threads at right angles to each other.",
+ "A woven object has a fabric-like appearance and is made up of interlocking threads or other material.",
+ "A woven thing would look like something that is made out of a lot of small pieces of material that are all interconnected with each other.",
+ "A woven thing look like a fabric that is made by interlacing two sets of yarn or thread at right angles to each other.",
+ "A woven thing looks like it has been made by interlacing two sets of yarn or other material at right angles to each other.",
+ "A woven thing looks like a basket or a fabric.",
+ "A woven thing is made of interlocking threads.",
+ "A woven thing looks like a piece of fabric with a lot of small holes in it.",
+ "A woven thing is made of interlacing threads.",
+ "A woven thing looks like a thing that has been made by interlacing two sets of threads at right angles, usually by hand.",
+ "A \"woven\" thing looks like it is made of many small pieces of material interwoven together.",
+ "A woven thing can look like a basket, or a piece of cloth.",
+ "A woven pattern looks like a series of interconnected loops or strands.",
+ "A woven pattern looks like a fabric that has been woven together.",
+ "A \"woven\" pattern looks like a series of overlapping horizontal and vertical lines.",
+ "A woven pattern looks like a mesh or net.",
+ "A woven pattern looks like a series of interlocking threads or strips of material.",
+ "The woven pattern consists of a series of interlocking loops that are created by the intersection of warp and weft threads.",
+ "A woven pattern looks like a series of interlocking loops.",
+ "A woven pattern has a repeated design that looks like it has been interlaced.",
+ "Generally, a woven pattern is created by interlacing two sets of yarn - the warp and the weft.",
+ "A woven pattern is a fabric pattern created by interlacing two sets of perpendicular threads."
+ ],
+ "matted": [
+ "The term \"matted\" typically refers to a material that is tangled, knotted, or otherwise stuck together in a clump.",
+ "Matted material has a tangled, matted appearance.",
+ "Something that is matted looks like it has been tangled or knotted together.",
+ "A mat is a piece of material that is used to cover or protect a surface.",
+ "Matted material is material that is tangled and stuck together.",
+ "The word \"matted\" is often used to describe hair that is tangled and unkempt.",
+ "Generally, matted material is clumped together, tangled, or otherwise stuck together in a way that makes it difficult to smooth out or separate.",
+ "Matted material is usually tangled or tangled up.",
+ "A material that is matted has a surface that is covered with a tangled mass of fibers, hair, or other debris.",
+ "Matted material may appear to be tangled or entwined.",
+ "A matted surface is one that is covered in a tangled mass of something, such as hair or fibers.",
+ "A matted surface is one that has had its fibers tangled together, making it appear dull, flat, and fuzzy.",
+ "A matted surface is a surface with a lot of small tangles in it.",
+ "A matted surface is usually bumpy or uneven.",
+ "A matted surface has a rough, Ken surface.",
+ "A matted surface looks like it has been covered in a thick layer of something.",
+ "A matted surface has a lot of small tangles.",
+ "A matted surface is a surface that has a lot of texture.",
+ "When a surface is matted, it has a rough, mat-like texture.",
+ "A matted surface has a rougher texture than a smooth one.",
+ "A matted texture is a texture that is rough and tangled.",
+ "A matted texture looks like it has been ironed flat.",
+ "A matted texture is a surface that is not smooth, but instead is rough and has a lot of texture.",
+ "A \"matted\" texture looks like it has been squashed down and is no longer smooth.",
+ "A matted surface has a rough, hairy texture.",
+ "A matted texture is one that has been tangled or matted together, often due to knots or tangles.",
+ "A matted texture has a lot of tiny, individual fibers that are all matted together.",
+ "A matted texture is one that is characterized by a web-like or tangled appearance.",
+ "A matted texture is one that is rough and tangled.",
+ "A \"matted\" texture looks like it has been squished together and is no longer smooth.",
+ "A \"matted\" object is typically covered in a thick layer of dirt, grime, and/or debris.",
+ "A matted object is usually covered in dirt, grime, and/or dried liquids, and has a rough surface.",
+ "A \"matted\" object may have knots or tangles, and may appear dirty or unkempt.",
+ "A matted object is one that has been covered in a mat or padding, usually for protection.",
+ "A matted object is covered in a tangled mass of fibers, usually hair.",
+ "A matted object is covered in a dense, tangled mass of something.",
+ "A matted object can have a tangled, knotted, or clumped appearance.",
+ "A matted object looks like it is covered in a tangled mass of something.",
+ "A matted object is one that is tangled, for example a matted piece of hair.",
+ "A matted object has a rough surface with clumps of material sticking together.",
+ "A \"matted\" thing looks like it has a lot of tangled hair.",
+ "A matted object is covered in tangles, like a matted piece of hair.",
+ "A matted thing can look like it is tangled, or like it has a lot of small knots.",
+ "When something is matted, it is tangled and stuck together.",
+ "A matted object is one that is tangled or covered in a thick layer of something.",
+ "A \"matted\" object is one that is tangled or stuck together.",
+ "A \"matted\" thing is usually covered in a lot of dirt and grime, and may be difficult to clean.",
+ "A \"matted\" thing has a lot of tangles in it.",
+ "A matted thing looks tangled and messed up.",
+ "A \"matted\" thing looks like it is covered in a thick layer of something.",
+ "A matted pattern is a series of patterns within patterns.",
+ "A matted pattern is a design that has a lot of small details that are all close together.",
+ "When a pattern is matted, it means that the individual pieces of the pattern are stuck together.",
+ "A \"matted\" pattern typically has a rough, textured surface.",
+ "A matted pattern is one in which the background and foreground colors are not clearly defined, and the overall effect is murky or muddy.",
+ "A matted pattern looks like a piece of fabric that has been cut into a shape and then glued or stitched to a backing.",
+ "A matted pattern typically has a textured or raised surface.",
+ "A matted pattern is one in which the individual strands of yarn are matted together, rather than being separate from one another.",
+ "A matted pattern can look like a tangle of different colors and textures that are all knotted together.",
+ "A matted pattern is a textured50 design in which the pile is lying flat in all directions, rather than standing up."
+ ],
+ "zigzagged": [
+ "Zigzagged material is material that has been bent or folded into a zigzag pattern.",
+ "Zigzag patterns are usually found on fabrics with a tight weave, such as twill or poplin.",
+ "Zigzag stitches are usually used to finish a raw edge and to prevent fabric from unraveling.",
+ "Zigzag patterns are created when parallel lines are connected by diagonal lines.",
+ "A \"zigzagged\" material would look like a material that has been cut into thin strips and then sewn together at an angle.",
+ "Zigzagged materials are materials that have been cut or torn into a zigzag shape.",
+ "Zigzagged material is material that has been folded or cut into a series of parallel lines that alternate between going in one direction and then going in the opposite direction.",
+ "\"Zigzagged\" material is characterized by its sharp, angular corners.",
+ "Zigzag patterns are created when two diagonal lines are intersected by a horizontal or vertical line.",
+ "Zigzag patterns are created when lines are drawn that connect at sharp angles, rather than curves.",
+ "A zigzagged surface is one that is not smooth, but instead has a series of peaks and valleys.",
+ "A zigzagged surface looks like it has a lot of angular shapes sticking out from it.",
+ "A \"zigzagged\" surface is one that is not flat, but has a series of peaks and valleys.",
+ "A zigzagged surface is a surface that has a lot of angular corners or edges.",
+ "A zigzagged surface looks like a surface that has been cut or ripped into smaller pieces that are then put back together in a zigzag pattern.",
+ "A zigzag surface has a series of peaks and valleys that resemble a zigzag pattern.",
+ "A zigzagged surface looks like a surface with a lot of small peaks and valleys.",
+ "A \"zigzagged\" surface has a series of sharp curves that alternate between going up and down.",
+ "A zigzagged surface looks like a surface that has been cut into a series of angles.",
+ "A zigzagged surface is one that has been cut or torn so that it is no longer smooth, but instead has a jagged edge.",
+ "A zigzag texture looks like a series of diagonal lines.",
+ "A zigzagged texture looks like a series of peaks and valleys.",
+ "When you look at a surface with a zigzagged texture, it looks like a series of sharp points or angles.",
+ "A zigzagged texture has a repeating pattern of sharp angles that creates a jagged look.",
+ "A zigzagged texture has a series of sharp turns or angles.",
+ "The word \"zigzagged\" is usually used to describe a line that goes back and forth in a sharp, angular pattern.",
+ "A \"zigzagged\" texture looks like a series of small, sharp peaks and valleys.",
+ "A zigzagged texture looks like a series of sharp angles or peaks and valleys.",
+ "If you imagine a piece of fabric with closely spaced parallel lines running horizontally, and then imagine a second set of lines running diagonally and intersecting the first set at a zig-zag pattern, that would be a good approximation of.",
+ "A zigzagged texture has a lot of sharp, pointed edges.",
+ "A zigzag is a sharp change in direction.",
+ "A zigzagged object looks like an object that has been bent or twisted so that it has a series of sharp turns or angles.",
+ "A zigzagged object has a Pointed, zigzag shape.",
+ "A zigzag object has a series of sharp turns or bends.",
+ "A \"zigzagged\" object looks like a series of sharp lines or angles that alternate direction.",
+ "A \"zigzagged\" object has a series of sharp angles, like the letter \"Z\".",
+ "A \"zigzagged\" object looks like it has a lot of sharp angles and turns.",
+ "A zigzag is a sharp change in direction.",
+ "A zigzagged object looks like it has a series of sharp turns or angles.",
+ "A \"zigzagged\" object looks like it has a series of sharp angles or points.",
+ "A zigzag is a series of sharp turns in alternating directions.",
+ "The best way to describe a zigzag pattern is by using an example.",
+ "A zigzag is a series of sharp turns in alternating directions.",
+ "A \"zigzagged\" thing looks like it has a lot of angular corners, like a jagged line.",
+ "A zigzag is a shape made up of a series of connected zig-zag lines.",
+ "A zigzagged object looks like it has a series of sharp turns or angles.",
+ "When something is zigzagged, it is angled or curved in a sharp, irregular way.",
+ "A \"zigzagged\" thing has a lot of sharp turns.",
+ "A \"zigzagged\" thing looks like a line that goes back and forth, rather than going in a straight line.",
+ "Zigzagging can mean to move in a sharp, angles line or it can mean to move back-and-forth in a regular pattern.",
+ "A zigzagged pattern is a pattern that has a lot of small, sharp turns.",
+ "A \"zigzagged\" pattern alternates between a peak and a trough, like the letter \"Z\".",
+ "A zigzagged pattern looks like a series of zigzags, or a line that curves and angles sharply.",
+ "A zigzag pattern has a series of sharp turns or angles.",
+ "A zigzagged pattern can look like a series of mountains and valleys when graphed on a line, or like a series of V shapes.",
+ "A \"zigzag\" pattern is a series of sharp angles in alternating directions.",
+ "The best way to describe a zigzag pattern is with an image:.",
+ "A zigzag pattern looks like a series of sharp turns or angles, going back and forth in a steady, continuous pattern.",
+ "A \"zigzagged\" pattern looks like a pattern that is made up of a series of angled lines.",
+ "A \"zigzagged\" pattern look like a line going up and down in a jagged pattern."
+ ],
+ "marbled": [
+ "Marbled material typically has a swirled or mottled appearance, as if different colors or types of material have been combined together.",
+ "\"Marbled\" material is usually stained or discolored in a blotchy or streaked pattern.",
+ "Marbled material usually has a streaked or clouded appearance, like marble.",
+ "Marbled material is marked with patterns that look like veins or streaks in marble.",
+ "Material that is marbled looks like it has been swirled together, creating a pattern that is similar to marble.",
+ "In general, \"marbled\" material has a streaked or mottled appearance, like that of marble.",
+ "Marbled material is material that has a smooth, shiny surface with a pattern that looks like it was created by swirling different colors of paint together.",
+ "A material that is \"marbled\" is usually streaky or mottled in appearance.",
+ "What does \"marbled\" material look like?Marbled materials have a streaked or mottled appearance, like that of a marble.",
+ "Marbled material often looks like swirls of two colors.",
+ "A marbled surface is one that has been marked with swirls or veins of color to resemble marble.",
+ "A marbled surface is a surface with a pattern that looks like it was made by swirling different colors of paint or ink together.",
+ "Marbled surfaces are usually found in nature and are created when two different colors of rock are layered on top of each other and then carved or cut into.",
+ "A marbled surface looks like it has been covered in paint and then swirls have been added to create a marble effect.",
+ "A marbled surface has a smooth, even surface with a slight swirl pattern.",
+ "Amarbling is a spatter painting technique.",
+ "A marbled surface has a smooth, flat surface with a design that appears to be swirled or mottled.",
+ "Marbling is a pattern with a swirled or mottled appearance.",
+ "A marbled surface has a swirled or streaked appearance, like that of marble.",
+ "Marbling is a pattern of swirls and streaks in a material, usually caused by the mixed colors of a fluid.",
+ "A \"marbled\" texture looks like it has swirls or waves in it.",
+ "A \"marbled\" texture has a swirl or wave-like pattern.",
+ "A marbled texture is one that contains swirls or veins of another color running through it.",
+ "A \"marbled\" texture usually looks like swirls of light and dark colors.",
+ "A marbled texture looks like a surface that has been marked or veined with lines that resemble those in a marble.",
+ "A marbled texture looks like it has swirls or waves in it, like marble.",
+ "A \"marbled\" texture has swirls of different colors or shades.",
+ "A marbled texture usually has swirls or streaks of different colors.",
+ "A marbled texture usually looks like swirls of colors.",
+ "A \"marbled\" texture is a surface that looks like it has been swirls of different colors or shades.",
+ "A marbled object is one that has a streaked or swirled pattern, like that of marble.",
+ "A marbled object is one that has been covered or streaked with another color or substance so that it resembles marble.",
+ "A \"marbled\" object has a smooth surface with swirling patterns of different colors.",
+ "Marbled objects have a lot of different colors mixed together in a way that resembles marble.",
+ "A marbled object appears to have swirls of different colors or shades.",
+ "A marbled object has a streaked or mottled appearance, like that of marble.",
+ "A marbled object generally has a dark base color with lighter streaks or patterns throughout.",
+ "A marbled object has a surface that is marked with streaks or swirls of different colors.",
+ "A marbled object looks like it has streaks of different colors running through it, like a block of marble.",
+ "A marbled object has a surface that is marked with streaks or veins of different colors.",
+ "When something is marbled, it has a swirl of colors throughout it, kind of like how marble looks.",
+ "A \"marbled\" thing looks like it has streaks of different colors or shades running through it, like marble.",
+ "A \"marbled\" thing is covered in swirls or streaks of color.",
+ "A \"marbled\" thing has a streaked or mottled appearance, as if it were made of different colors or shades that have been swirled together.",
+ "A \"marbled\" thing appears to have swirls of color running through it, similar to the pattern found in marble.",
+ "A marbled thing looks like it has been created by combining two different colors or materials together to produce a mottled effect.",
+ "The word \"marbled\" can describe something that has a streaked or mottled appearance, like marble stone.",
+ "Marbled things usually have a streaked or mottled appearance, as if they are made of several different colors or materials that have been swirled together.",
+ "A marbled thing has a lot of different colors mixed together.",
+ "A \"marbled\" thing looks like it has been through a process called \"marbling\" where different colors are swirled together to create a unique design.",
+ "Marbled patterns are usually irregular patterns that resemble the veins in a marble.",
+ "Marbling is a pattern with swirls or streaks of color.",
+ "A marbled pattern looks like streaks or blotches of color that have been swirled together.",
+ "A \"marbled\" pattern looks like veins of color running through a solid background.",
+ "A \"marbled\" pattern is a design that is made by swirling different colors of paint or other materials together to create a smooth, mottled effect.",
+ "A \"marbled\" pattern usually looks like a light color mixed with a dark color, making it look like marble.",
+ "A marbled pattern is a pattern that has a lot of small swirls or programs and usually has two colors.",
+ "A marbled pattern is usually created by combining two different colors of clay together to create a swirled effect.",
+ "A marbled pattern is one in which different colors are swirled together, giving the appearance of a marble.",
+ "Marbled patterns can vary greatly, but often resemble stone or marble that has been swirled or veined."
+ ],
+ "studded": [
+ "A studded material is one that has had small, metal studs affixed to it.",
+ "Studded material is a material that has studs on it.",
+ " leather that has metal spikes sticking out of it.",
+ "Studded material typically has small metal ornaments embedded in it.",
+ "\"Studded\" material normally refers to fabric that has had metal studs affixed to it in a decorative pattern.",
+ "Studded material is typically a leather or fabric material that has metal studs affixed to it in a decorative manner.",
+ "Studded material typically has small metal or plastic studs affixed to the surface.",
+ "Studded material often looks like it has metal spikes sticking out of it.",
+ "Studded material is material that has small, metal studs on it.",
+ "A studded material typically has small metal studs or spikes adorning the surface.",
+ "A studded surface should have a uniform grid of evenly-spaced raised bumps.",
+ "A \"studded\" surface is one that has been covered with small projecting objects.",
+ "A studded surface is covered in small, sharp protrusions.",
+ "A studded surface is a surface that has small, raised bumps.",
+ "A studded surface has small, raised bumps.",
+ "Sadie has no studs.",
+ "Studded surfaces have metal studs that provide traction in winter weather.",
+ "A studded surface is covered in small, pointed objects.",
+ "A studded surface is a surface that has a lot of small raised bumps on it.",
+ "Image result for STUDDED SURFACE.",
+ "A studded texture looks like it has tiny bumps all over it.",
+ "A studded texture usually refers to a leather or fabric that has small metal or plastic studs embedded in it.",
+ "If an item is studded, it has small, metal decorations affixed to it.",
+ "A studded texture looks like a series of small, raised bumps.",
+ "A studded texture is when there are small, raised bumps all over the surface.",
+ "A studded texture has small, raised bumps.",
+ "Studded textures are usually characterized by small, raised bumps.",
+ "A \"studded\" texture looks like a series of small, raised bumps.",
+ "A studded texture is one that has a lot of small bumps or \"studs\" on it.",
+ "The studded texture is a bit more complex than a regular texture.",
+ "A \"studded\" object has small metal or plastic studs on the surface.",
+ "A studded object is one that has been decorated with small, metal studs.",
+ "A studded object has small, metal spikes sticking out of it.",
+ "A \"studded\" object is one that has protruding spikes or studs.",
+ "Studded objects have small metal or plastic protrusions sticking out of them.",
+ "A studded object has small, metal studs on it.",
+ "Studded objects tend to have small, pointed protrusions sticking out from them.",
+ "\"Studded\" typically refers to an object that has ornamental metal studs affixed to its surface.",
+ "A studded object has small, raised decorations on its surface.",
+ "A studded object is one that has a lot of small, metal studs embedded in it.",
+ "A studded thing has small metal ornaments sticking out of it.",
+ "There is no definitive answer to this question since the term \"studded\" can be used to describe a lot of different things.",
+ "A \"studded\" thing is covered in small, decorative metal studs.",
+ "A studded thing has small, metal protrusions sticking out of it.",
+ "In general, a studded item is covered in small decorative protrusions.",
+ "A studded thing has small, metal protrusions sticking out of it.",
+ "A studded thing is covered in small, metal spikes.",
+ "As far as I know, when something is \"studded\" it is covered in small decorations.",
+ "A studded thing has small metal or jeweled decorations on it.",
+ "A studded thing has a lot of small, decorative spikes sticking out of it.",
+ "A studded pattern has small, raised dots on the surface.",
+ "A studded pattern is defined as a raised or embossed design achieved by pressing small metal studs or nails into the surface of the fabric.",
+ "In a studded pattern, small, round beads are sewn or glued onto the fabric to create a design.",
+ "Studded patterns are created by adding small metal studs to a fabric.",
+ "A studded pattern has small raised dots on the surface.",
+ "In a studded pattern, small metal or plastic studs are affixed to the surface of the fabric in a symmetrical or random design.",
+ "A \"studded\" pattern can look like a series of dots, or it can look like a series of small, raised bumps.",
+ "A studded pattern can be achieved by dotting beads or rhinestones around an item in a irregular or random pattern.",
+ "A studded pattern can resemble a small polka dot or a large sequin.",
+ "A studded pattern typically consists of small metal studs that are sewn or otherwise attached to a piece of fabric."
+ ],
+ "grid": [
+ "\"Grid\" material is typically a black, plastic material that has a honeycomb-type structure.",
+ "A material with a grid pattern has a series of parallel lines that cross each other to form a regular pattern.",
+ "Grid material is a type of fabric that has a grid-like pattern.",
+ "Grid material is a type of material that is often used in construction.",
+ "\"Grid\" material can vary in appearance, but is typically a series of intersecting lines or a honeycomb-like pattern.",
+ "In general, grid material is a network of uniformly spaced horizontal and vertical bars that are used to support or reinforce other materials.",
+ "A grid pattern is a repeating, evenly spaced set of lines that intersect each other to form a series of squares or rectangles.",
+ "Grid material looks like a network of squares.",
+ "Most grid materials are made from some sort of plastic, and they have a bunch of small square or rectangular openings running through them.",
+ "The grid material is placed over the opening in the window.",
+ "A grid surface is like a checkered board.",
+ "A grid surface is a surface that contains a series of evenly spaced horizontal and vertical lines.",
+ "A grid surface looks like a checkerboard.",
+ "A grid surface looks like a series of evenly spaced, parallel lines that intersect at right angles.",
+ "A grid surface is usually a perpendicular array of lines, typically on a graph paper.",
+ "A grid surface can look like a series of squares or a series of intersecting lines.",
+ "A \"grid\" surface can look like a checkerboard, with squares of different colors or shades.",
+ "Image result for grid surface.",
+ "A grid surface has evenly spaced lines running horizontally and vertically.",
+ "A \"grid\" surface looks like a set of evenly spaced horizontal and vertical lines that intersect to form squares.",
+ "A \"grid\" texture is a texture with a regular pattern of squares.",
+ "A grid texture usually looks like a series of straight lines that intersect to form a series of squares.",
+ "A grid texture is a repeating pattern of square or rectangular shapes.",
+ "A grid texture looks like a geometric pattern made up of horizontal and vertical lines.",
+ "A grid texture is a texture that looks like a grid or a series of lines.",
+ "A grid texture is a repeating pattern of squares that are aligned in a grid.",
+ "A grid texture looks like a repeating pattern of squares.",
+ "A grid texture looks like a repeating pattern of squares.",
+ "Grid textures are composed of parallel lines that intersect to form a regular pattern.",
+ "A grid texture typically looks like a series of evenly spaced horizontal and vertical lines.",
+ "There is no single answer to this question because grid objects can take on many different forms.",
+ "A \"grid\" object is a network of lines that are spaced evenly apart from each other.",
+ "A \"grid\" object is a two-dimensional array of numbers, usually used to represent a map or board.",
+ "There is no grid object in Javascript.",
+ "There is no precise answer to this question since it can vary depending on the particular application or software program.",
+ "A grid is an array of objects that are arranged in a rectangular fashion.",
+ "A grid object is a2-dimensional array of cells.",
+ "A grid object is a rectangular array of cells.",
+ "A grid object is a two-dimensional array of cells.",
+ "A grid is a two-dimensional array that is used to map data in a graph or network.",
+ "Grid systems are used for creating page layouts through a series of rows and columns that house your content.",
+ "There is no one answer to this question since grids can take on many different forms.",
+ "A grid is a network of evenly spaced horizontal and vertical lines that are used to divide a page into columns and rows.",
+ "There is no one answer to this question as the appearance of a grid can vary depending on its function and the specific industry or application.",
+ "A grid is a system of rectangles that are parallel to each other and perpendicular to each other.",
+ "A grid is typically a series of evenly spaced horizontal and vertical lines.",
+ "There is no definitive answer to this question as the term \"grid\" can be used to describe a wide variety of objects or structures.",
+ "A \"grid\" is a network of horizontal and vertical lines that intersect to form squares or rectangles.",
+ "A \"grid\" thing can look like a lot of different things.",
+ "There is no one answer to this question as the appearance of a grid will depend on its purpose and the objects with which it is made.",
+ "A grid pattern is a regularly spaced series of horizontal and vertical lines.",
+ "The grid pattern is a consistent, repeating pattern of squares (or other shapes) that are evenly spaced apart.",
+ "A grid pattern has straight, parallel lines that cross each other to form squares or rectangles.",
+ "A grid pattern is a series of vertical and horizontal lines that intersect to form a series of squares or rectangles.",
+ "A grid pattern has parallel lines going in both directions, creating a series of squares.",
+ "a grid pattern looks like a checkerboard.",
+ "A grid pattern looks like a series of squares or rectangles that are arranged in a regular pattern.",
+ "A grid pattern is a series of horizontal and vertical lines that intersect to form a series of squares.",
+ "A grid pattern is a series of parallel lines that cross each other at right angles.",
+ "A grid pattern is a repeating pattern of squares."
+ ]
+}
\ No newline at end of file
diff --git a/cupl/descriptors_eurosat.json b/cupl/descriptors_eurosat.json
new file mode 100644
index 0000000..74b522f
--- /dev/null
+++ b/cupl/descriptors_eurosat.json
@@ -0,0 +1,522 @@
+{
+ "annual crop land": [
+ "Although the specific appearance of a annual crop land may vary depending on the climate and geographical location, in general, an annual crop land is a large, open piece of land where crops are grown.",
+ "Unlike a permanent crop, which is planted and remains until it is harvested, an annual crop is planted at the beginning of each growing season and then harvested at the end of that season.",
+ "A annual crop land looks like a field with crops.",
+ "A annual crop land looks like a piece of farmland that is used to grow crops.",
+ "A crop that is planted and harvested once a year is typically a field of green grass with crops planted in rows.",
+ "A area of land that is used to grow annual crops.",
+ "An annual crop land generally looks like a large field that has been cleared of trees and other vegetation.",
+ "A annual crop land looks like a large field that is divided into small sections.",
+ "A annual crop land looks like a field of corn or wheat.",
+ "A annual crop land looks like a field with crops growing in it.",
+ "Some clues that a land might be used for annual crops are if the land is flat, has good drainage, and is close to a water source.",
+ "By looking at a map.",
+ "The best way to identify a annual crop land is to look for fields that have been recently plowed or are being actively worked.",
+ "The best way to identify an annual crop land is to look for land that is being used to grow crops.",
+ "You can identify annual crop land by looking for land that is used to grow crops that are harvested once a year.",
+ "The best way to identify annual crop land is to look for planted fields with crops that are harvested each year.",
+ "A annual crop land is a field that is planted with crops once a year.",
+ "If a land is used to grow crops once a year, it is annual crop land.",
+ "A good way to identify annual crop land is to look for large, rectangular fields that are planted with crops.",
+ "The best way to identify an annual crop land is to look for fields that have been recently planted.",
+ "A annual crop land usually looks like a big field with crops planted in it.",
+ "A annual crop land looks like a field of crops.",
+ "Perennial crops are planted once and then harvested year after year, while annual crops are planted and harvested each year.",
+ "A annual crop land looks like a field with crops planted in it.",
+ "A annual crop land looks like a flat piece of land with crops planted in it.",
+ "A crop that is harvested once a year generally has a single growth cycle and produces one harvest.",
+ "A annual crop land looks like a field that has been cleared of trees and other vegetation, and is now being used to grow crops.",
+ "A annual crop land looks like a field of crops that have been harvested.",
+ "A annual crop land looks like a field with crops planted in it.",
+ "A annual crop land looks like a farmer's field that has been plowed and is ready to plant.",
+ "I found an image on the internet of a annual crop land.",
+ "The image is of a field with crops planted in neat rows.",
+ "I found an image of a annual crop land on Pinterest.",
+ "I found an image of a vast annual crop land with endless rows of perfectly aligned plants.",
+ "The image shows a vast expanse of land with rows of crops growing in it.",
+ " with a lot of farm housesThe image shows a vast field of crops with several farmhouses in the distance.",
+ "The image depicts a field with annual crops planted in it.",
+ "A vast amount of land with crops planted in neat rows as far as the eye can see.",
+ "The image is of a large field with rows of crops growing in it.",
+ "I found an image of a farm with annual crops on Google Images.",
+ "An image of annual crop land.",
+ "A field of wheat waiting to be harvested.",
+ "A farmer surveys his annual crop of corn.",
+ "A field of annual crops in the Midwest.",
+ "This is a field of annual crops.",
+ " An expansive field of green farmland with a slight breeze blowing through it.",
+ "Annual crop land in the United States.",
+ " Wheat field in HDRThis image shows a wheat field in HDR, or high dynamic range.",
+ "This is a picture of annual crop land.",
+ "Fertile farmland in the Midwest that yields bountiful harvests year after year."
+ ],
+ "forest": [
+ "A forest is a large area of land covered in trees and underbrush.",
+ "A forest is a large area of land covered with trees.",
+ "The forest is a dark and scary place.",
+ "A forest is a large area of land covered in trees and other vegetation.",
+ "The forest is a place where the trees grow very close together and their leaves form a thick canopy that blocks out most of the sunlight.",
+ "A forest is a large area of land covered in trees and plants.",
+ "A forest looks like an area of land that is covered in trees and other vegetation.",
+ "A forest typically has trees that are close together and have leaves that block out most of the sunlight.",
+ "A forest is a large area of land covered with trees and other vegetation.",
+ "A forest is usually a large area of land covered in trees and other plants.",
+ "To identify a forest, look for an area that is densely populated with trees.",
+ "The easiest way to identify a forest is by the presence of trees.",
+ "A forest is a large area of land that is covered in trees.",
+ "A forest is a large area of land covered in trees.",
+ "A forest is a large area of land covered with trees.",
+ "A forest is a large area of land covered with trees.",
+ "The easiest way to identify a forest is by the presence of trees.",
+ "The easiest way to identify a forest is by its trees.",
+ "A forest is a large area of land covered in trees.",
+ "A forest is an area of land with many trees.",
+ "A forest is a large area of land covered in trees and other vegetation.",
+ "A forest is a large, natural area of land that is covered in trees.",
+ "Colorful, with lots of trees and animals.",
+ "A forest can look like many different things depending on where it is located.",
+ " Our forests are a great example of what a forest looks like.",
+ "A forest looks like a large area of land with a lot of trees.",
+ "A forest is a large area of land covered in trees.",
+ "A forest is a large area of land covered with trees.",
+ "A forest typically has trees, bushes, and other plants.",
+ "Most forests are lush and green, with trees of various heights.",
+ "This image from the internet shows a lush, green forest with tall trees towering overhead.",
+ "A dense forest with tall trees and a green canopy.",
+ "An image of a forest from the internet shows trees with lush green leaves, moss covering the ground, and a stream running through the middle.",
+ "This image is of a forest with tall, green trees and a dense canopy.",
+ "In this image, a forest is seen through the trees.",
+ "In this image, a dense forest is shown with trees that are tall and close together.",
+ "This image is of a forest in the autumn.",
+ "The image is of a dense forest with tall trees.",
+ "In the image, there is a forest with tall trees, a winding path, and a lake in the distance.",
+ "In this image, a forest is shown with its tall trees, green leaves, and brown soil.",
+ " The light shines through the trees, casting a natural cathedral of shadows and light.",
+ "The forest floor is blanketed in a layer of fallen leaves.",
+ "In the middle of the forest, there is a small clearing with a tree in the center.",
+ "A dense forest with various shades of green and brown.",
+ "Dense forest in OregonThis is a picture of a dense forest in Oregon.",
+ "A majestic forest, with tall trees and a thick canopy of leaves.",
+ "The forest is a beautiful and peaceful place, full of life and wonder.",
+ " It is a Dense and Dark forest.",
+ " The serene forest floor, blanketed in a fresh layer of snow.",
+ "A peaceful forest with a small stream running through it."
+ ],
+ "herbaceous vegetation land": [
+ "A herbaceous vegetation land looks like a land with a lot of grass and other plants.",
+ "Herbaceous vegetation land typically contains a variety of plants, including grasses, herbs, and shrubs.",
+ "Herbaceous vegetation is land that is covered in plants that die back each year.",
+ "A herbaceous vegetation land typically has low shrubs and no trees.",
+ "A herbaceous vegetation land looks like a field with grass and other plants growing in it.",
+ "A herbaceous vegetation land is a land covered with plants that die back to the ground each year.",
+ "A herbaceous vegetation land typically looks like a grassland.",
+ "A herbaceous land typically has a thick layer of grasses, sedges, and forbs.",
+ "A herbaceous vegetation land typically looks like a field of grass or other low-lying plants.",
+ "A land with herbaceous vegetation looks like a field with many grasses and other plants growing close to the ground.",
+ "There are many ways to identify a herbaceous vegetation land.",
+ "Herbaceous land is land that is covered in grasses and other herbaceous plants.",
+ "A herbaceous vegetation is land with soft-stemmed plants that die back to the ground each year.",
+ "The herbaceous layer of a vegetation refers to the layer of plants that are not woody.",
+ "Herbaceous vegetation land refers to a land that is mostly covered in herbs or grasses.",
+ "Herbaceous vegetation means that the dominant plant life in an area is made up of herbs, or plants with soft, green stems that die back to the ground each year.",
+ "The main way to identify a herbaceous land is by the type of plants that are found there.",
+ "Herbaceousacio vegetation is composed mostly of herbaceous plants rather than woody shrubs or trees.",
+ "A herbaceous vegetation land is usually identified by its green, leafy appearance.",
+ "Herbaceous vegetation is a land that is dominated by herbs, grasses, and other non-woody plants.",
+ "Herbaceous vegetation consists of plants that have soft, green stems and leaves.",
+ "Herbaceous vegetation land typically looks like a grassland or a forest.",
+ "A herbaceous vegetation land has an abundance of grasses, plants, and flowers.",
+ "Herbaceous vegetation land typically looks like a field or grassland, with grasses, sedges, and other herbaceous plants (plants without woody stems) making up the majority of the vegetation.",
+ "A herbaceous vegetation land typically looks like a grassland.",
+ "Herbaceous vegetation lands are typically made up of grasses, sedges, and other plants that do not have woody stems.",
+ "A herbaceous vegetation land looks like a grassland.",
+ "A herbaceous vegetation land looks like a land with grasses and other herbaceous (non-woody) plants.",
+ "A herbaceous vegetation land typically looks like a grassland or a meadow.",
+ "A herbaceous vegetation is characterized by having mostly non-woody plants.",
+ "coverOne image that comes to mind is of a field with tall grass and wildflowers.",
+ " coverThis image is of a grassy field with small yellow flowers dotting the green landscape.",
+ " coverThe image shows a field of tall grasses and other plants.",
+ " coverImage shows a field of green plants with narrow leaves and small white flowers.",
+ " and its edgesI found an image on the internet of a field of tall grass with wildflowers sprinkled throughout.",
+ " coverThe image is of a field with different types of herbs and grasses growing.",
+ " coverThis image depicts a field of tall grasses and other herbaceous plants.",
+ " coverThe image is of a field of green vegetation with some yellow flowers.",
+ "formThe image shows a field of tall grasses and wildflowers.",
+ " cover typeThe image is of a field with tall grasses and other plants.",
+ "A typical herbaceous vegetation land.",
+ "A field of tall grasses and wildflowers.",
+ "A dense growth of herbaceous vegetation, including many tall grasses, in a natural setting.",
+ "A field of herbs and wildflowers in full bloom.",
+ " Proserpine Air Quality Monitoring Station, Esther Islet, Proserpine River, Whitsunday Islands, Queensland, Australia.",
+ "A field of herbs and wildflowers.",
+ "This image shows a land covered in herbaceous vegetation.",
+ "Herbaceous vegetation land refers to an area where the dominant plant life is composed of herbaceous plants, rather than woody shrubs or trees.",
+ " Mother Earth's Green gown made of Thousands of herbs and plants.",
+ "A view of a lush, green field of herbs and wildflowers."
+ ],
+ "highway or road": [
+ "In the United States, a highway is normally an paved road designed for travel by car or other motorized vehicles.",
+ " during a rainstormA highway or road during a rainstorm looks wet and shiny.",
+ "A highway or road typically has two lanes going in each direction, with a yellow line down the middle to indicate division.",
+ "A highway or road typically consists of two lanes of travel, with a divider in the middle, and a shoulder on each side.",
+ "A highway or road typically consists of two lanes or more, with each lane being wide enough to accommodate a vehicle.",
+ "A highway or road is a long, paved surface with room for multiple lanes of traffic.",
+ "A highway or road is typically a cleared, paved path with markings that is used by vehicles to travel from one location to another.",
+ "A highway or road typically looks like a long, straight path that is paved with asphalt.",
+ "A highway or road typically looks like a long, paved path that is meant for vehicles to travel on.",
+ "Highways or roads typically have two lanes going in opposite directions with a turning lane in the middle.",
+ "The term highway or road can be used to describe many different types of thoroughfares.",
+ "There are a few ways to identify a highway or road.",
+ "You can identify a highway or road by looking at the markings on the road.",
+ "The easiest way to identify a highway or road is by looking for a road sign.",
+ "The easiest way to identify a highway or road is by looking at a map.",
+ "Highways and roads can be identified by their pavement.",
+ "By the number of lanes, the width of the lanes, the type of surface, and the type of markings.",
+ "There are a few ways to identify a highway or road.",
+ "The easiest way to identify a highway or road is by looking for road signs.",
+ "Highways and roads can be identified by their unique number.",
+ "A road typically has two lanes going in opposite directions and is separated by a yellow line.",
+ "A highway or road typically has two lanes going in each direction, with a yellow line down the middle to divide the lanes.",
+ "A highway or road typically looks like a long, straight path that is paved and has two yellow lines down the middle.",
+ "Most highways and roads have two lanes going in each direction, with a line down the middle to divide the lanes.",
+ "A highway or road typically contains one or more lanes going in each direction, with lines or markings to indicate traffic flow, and a shoulder on each side.",
+ "A highway or road typically has two lanes going in each direction, with a line down the middle to divide the lanes.",
+ "A highway or road often looks like a long, straight path through a landscape.",
+ "A highway or road can look like a long strip of pavement with lines painted on it.",
+ "A highway or road looks like a long, flat path that is wide enough for vehicles to drive on.",
+ "A highway or road typically looks like a paved pathway that is meant for cars and other vehicles to travel on.",
+ "I found an image of a highway on the internet.",
+ "the image is of a long, straight highway with yellow lines down the middle.",
+ "I found an image of a highway with cars driving on it.",
+ "The image is of a busy highway at night.",
+ "In the image, there is a long, straight highway that goes off into the distance.",
+ "I found an image of a highway on the internet that looks like it is in the middle of a desert.",
+ "This image shows a roadsign along a highway.",
+ "Image shows a long, winding highway through a mountainous region.",
+ "This image is of a freeway in Los Angeles, California.",
+ "An image of a highway or road might show a long stretch of pavement with cars or trucks driving on it.",
+ "Traffic on I-5 in Seattle, Washington.",
+ "The endless road ahead.",
+ "A road through the desert.",
+ " A busy highway in Los Angeles, California.",
+ "Stretching out before me is an endless ribbon of asphalt, leading to who knows where.",
+ " Traffic moves along I-5 in Los Angeles.",
+ " Straight as an arrow.",
+ " Route 66.",
+ "A stretch of highway in Kansas.",
+ "The concrete jungle."
+ ],
+ "industrial buildings or commercial buildings": [
+ "Commercial buildings are usually larger than industrial buildings and have more windows.",
+ "Industrial buildings and commercial buildings can vary greatly in their appearance, depending on their function.",
+ "Industrial buildings are usually large, single-story buildings with a lot of open space inside.",
+ "Industrial buildings are usually large warehouses with high ceilings and no windows.",
+ "Industrial buildings and commercial buildings are usually large rectangular buildings with smooth walls and roofs.",
+ "There is no one answer to this question as industrial and commercial buildings can come in all shapes and sizes.",
+ "A typical commercial or industrial building looks like a large rectangular structure with a flat roof.",
+ "A commercial building is typically a rectangular structure with a large, open floor plan.",
+ "A commercial building is typically a structure built for the purpose of business, such as office buildings, warehouses, or retail stores.",
+ "\ufeffA commercial building is typically a rectilinear building with a storefront on the ground floor and office space or apartments above.",
+ "A commercial building is typically any building that is used for commercial purposes, such as a office, retail store, or warehouse.",
+ "Industrial buildings or commercial buildings can be identified by their large size, multiple stories, and lack of windows.",
+ "Industrial buildings or commercial buildings can typically be identified by their large size, multiple stories, and lack of landscaping.",
+ "Industrial buildings are typically large buildings that are used for storing or manufacturing products.",
+ "If you see a building with a lot of trucks or other vehicles parked outside, it is probably a commercial or industrial building.",
+ "The following are some characteristics that can help you identify industrial buildings or commercial buildings:-They are usually large in size.",
+ "One way to identify a industrial buildings or commercial buildings is by looking for a loading dock.",
+ "Industrial buildings are usually made of concrete or metal, and are often very large with high ceilings.",
+ "The most common way to identify a industrial buildings or commercial buildings is by looking for the presence of large, unobstructed spaces that are typically found in these types of buildings.",
+ "Industrial buildings or commercial buildings can usually be identified by their large size, multiple stories, and the presence of windows.",
+ "A industrial buildings or commercial buildings typically has a large open floor plan, high ceilings, and large windows.",
+ "A commercial or industrial building can vary greatly in appearance, depending on the type of business that it is housing.",
+ "Most industrial buildings are large, single-story structures with a high ceiling and few windows.",
+ "There is no definitive answer to this question, as the appearance of industrial buildings or commercial buildings can vary widely depending on their purpose and location.",
+ "A industrial building or commercial building can look like a large warehouse or a small office building.",
+ "A industrial buildings or commercial buildings typically has a large, open floor plan with high ceilings.",
+ "A large, rectangular building with a flat roof.",
+ "A industrial buildings or commercial buildings typically has a large open floor plan, high ceilings, and is designed to accommodate a variety of businesses.",
+ "Industrial buildings and commercial buildings can come in many different shapes and sizes, but typically they are large structures that are designed for business or industrial use.",
+ "Industrial buildings and commercial buildings can come in many different shapes and sizes.",
+ "This image is of a large commercial building with numerous windows.",
+ "The image is of a large factory with several smokestacks.",
+ "This image is of a commercial building in New York City.",
+ "The image shows a large commercial building with many windows.",
+ "The image is of a large commercial building with many windows and a glass front.",
+ "The image is of a large, industrial building with several smokestacks.",
+ "This image is of an industrial building in China.",
+ "This image is of a commercial building in New York City.",
+ "This image is of a group of commercial buildings in a cityscape.",
+ "The image is of a large, industrial building with a series of large windows running along the top.",
+ "Factories churning out smoke into the sky, contributing to air pollution.",
+ "Industrial buildings or commercial buildings can be found in many different parts of the world.",
+ "The proliferation of industrial and commercial buildings in the late 19th and early 20th centuries was a symptom of the Industrial Revolution.",
+ " Industrial buildings or commercial buildings can provide a variety of services, including office space, storage space, manufacturing space, and more.",
+ "Industrial buildings or commercial buildings can be seen in this image.",
+ "Industrial and commercial buildings in an urban area.",
+ "Commercial buildings in the city.",
+ "This is a plastery in Xizhou.",
+ " hired hands brewing co.",
+ "This is a photo of an industrial area in an unidentified city."
+ ],
+ "pasture land": [
+ "A pasture land is a piece of land that is used to graze animals.",
+ "A pasture is an area of grassland where livestock can graze.",
+ "A pasture land looks like a green field with some trees.",
+ "A pasture is an area of land where animals such as cows, sheep, and horses graze.",
+ "A pasture land is a large area of land where animals, usually cows, can roam and graze.",
+ "A pasture land typically looks like a large, open field with grass or other vegetation.",
+ "A pasture land is a piece of land that is used for grazing animals.",
+ "A pasture land typically contains grass and other plants that are eaten by animals.",
+ "A pasture land looks like a flat field with grass.",
+ "Typically, pasture land is composed of grasses, legumes, and forbs.",
+ "There are several ways to identify pasture land.",
+ " Pasture is defined as grassland that is used for grazing livestock.",
+ "Pasture land is generally flat and has grasses or other plants that are suitable for grazing.",
+ "Typically, pasture land is Flat with good drainage and is used for grazing animals such as cows, sheep, and horses.",
+ "One way to identify a pasture land is by looking for areas with grasses or other plants that are suitable for grazing animals.",
+ "Pasture land is typically identified by its use; it is land that is used to graze livestock.",
+ "Pasture land is typically flat or rolling land with grasses or other forage growing on it.",
+ "The best way to identify pasture land is by its vegetation.",
+ "A pasture land is typically an area of land that is used for grazing animals.",
+ "Pasture land can be identified by its natural grasses and plants.",
+ "A pasture land is a flat or rolling land covered with grass.",
+ "A pasture is a field where grass is grown to be eaten by livestock.",
+ "A pasture land looks like a field with grass and sometimes other plants.",
+ "A pasture land typically looks like a large, open field with grass and other plants growing.",
+ "A pasture land typically looks like a large, open field with grass.",
+ "A pasture land typically looks like a field with grass and other plants growing in it.",
+ "Pasture land is typically grassland that is used for grazing animals.",
+ "A pasture land typically looks like a large, open area of land with grasses or other vegetation growing.",
+ "Organically managed pasture land looks like a diverse grassland with a variety of grasses and forbs (flowering plants).",
+ "Pasture land is a piece of land that is used for grazing animals.",
+ "The image shows a pasture land with green grass and some trees.",
+ "The image is of a vast green field with rolling hills.",
+ "The image is of a green pasture with rolling hills.",
+ "This image from the internet is of a pastoral scene with a rolling green hills, a gravel path leading up to a weathered wooden fence.",
+ "The image is of a large, green field with tall trees along the perimeter.",
+ "The image shows a pasture land with grass and trees.",
+ "The image from the internet shows a pasture land with grass and trees.",
+ "The image is of a large, grassy field with a few trees dotting the landscape.",
+ "I see rolling hills of green grass with a few trees dotting the landscape.",
+ "I found an image on Google of a pasture land with beautiful, rolling hills and a blue sky.",
+ "Grazing land in New Zealand.",
+ "\",This pasture land appears to be well-grazed and healthy.",
+ "Grazing Land in the Southern Plains.",
+ "A vast and empty pastureland extends to the horizon in every direction.",
+ "Lush green pasture land dotted with trees, perfect for grazing cattle.",
+ "A beautiful pasture land with plenty of room to roam.",
+ "Interior of a sheep pasture on the LEGO\u00ae SERIOUS PLAY\u00ae ranch.",
+ "A vast and empty pastureland, stretching out to the horizon in all directions.",
+ " \"This pasture land in Chile's central valley has been in the same family for six generations.",
+ "A beautiful pastureland with plenty of room to roam."
+ ],
+ "permanent crop land": [
+ "A field with trees or other plants that are not harvested each year.",
+ "A permanent crop land looks like a piece of property that has been developed for the purpose of growing crops.",
+ "Land that is used to grow crops that are not harvested and replanted each year is permanent cropland.",
+ "Permanent crop land usually has trees or plants that are regularly harvested for food or other products.",
+ "Permanent crop land typically contains crops that are not rotated and remain in the same location year after year.",
+ "Fertile, well-drained soil with a constant supply of water.",
+ "A permanent crop land usually has the same crops planted in it year after year.",
+ "A field that is planted with a crop that does not need to be replanted each year, such as a citrus orchard.",
+ "A permanent crop land looks like a farmland that is dedicated to cultivating crops that do not need to be replanted each year, such as trees or vines.",
+ "A permanent crop land looks like a field with crops that are planted and grown permanently.",
+ "Permanent crops can be identified by looking for areas in a field that remain unplowed and un-irrigated for long periods of time.",
+ "A permanent crop land is a land that is used to cultivate crops on a long-term basis.",
+ "A permanent crop land is a land that is used to grow crops that do not need to be replanted after each harvest.",
+ "A crop that is grown and harvested on the same land for an extended period of time is referred to as a permanent crop.",
+ "A permanent crop land is a land that has been converted for the express purpose of cultivation of crops.",
+ "A permanent crop land is a land that is dedicated to the growth of crops that are not intended for human consumption.",
+ "A permanent crop land is a piece of land that is used to grow crops that are not intended to be harvested and replanted.",
+ "A permanent crop land is a land that is maintained and vegetated for the purpose of cropping activities.",
+ "If a crop is planted and expected to last indefinitely, it is a permanent crop.",
+ "Permanent crop land is defined as cropland that has been planted for five or more years in crops like orchards, groves, vineyards, and nurseries.",
+ "Permanent crop land is land that is used for growing crops that are not intended to be harvested and replanted, such as trees and vines.",
+ "A permanent crop land usually looks like a farm with crops planted in rows.",
+ "There is no definitive answer to this question as the appearance of permanent crop land can vary greatly depending on the type of crop being grown, the climate, and the geographical location.",
+ "A permanent crop land is typically planted with trees or other plants that are not harvested on a yearly basis.",
+ "A farm with permanent crops is likely to have crops that are planted and grown in the same location year after year.",
+ "A permanent crop land looks like a field with crops that have been planted and are growing.",
+ "A permanent crop land looks like a field that has crops planted in it.",
+ "A permanent crop is a agricultural land that is used to cultivate trees, fruits, vegetables, and other plants that are not intended to be harvested and replanted.",
+ "A permanent crop land usually has a crop that is planted and harvested every year, such as wheat or corn.",
+ "A permanent crop land may look like any other farmland, depending on the crop that is grown.",
+ "This image is of a farm in New Zealand.",
+ "This image is of a farm in the winter.",
+ "This image is of a farm in Ohio that grows corn and soybeans.",
+ "A photograph of permanent crop land might show crops planted in neat rows, with irrigation pipes or hoses running alongside them.",
+ "https://o.",
+ ".",
+ "The image is of a large field with crops growing in it.",
+ "An image of a permanent crop land would show a field that is planted with crops that are not intended to be harvested and replanted, such as trees or shrubs.",
+ "The image is of a field with crops planted in it.",
+ "A photo of permanent crop land might show acres of farmland with crops like wheat or corn growing in neat rows.",
+ " Agricultural land in Java, Indonesia.",
+ "Permanent crop land in the United States.",
+ "Aerial view of a farm in the Central Valley of CaliforniaThis image shows a farm in the Central Valley of California.",
+ "Fields of Gold: A permanent crop land in California.",
+ "This is a permanent crop land that has been well-maintained.",
+ "Permanent crop land is land that is used to grow crops that are not intended to be replanted.",
+ "This is a photo of a farm that grows crops that are harvested and replanted every year.",
+ "Permanent crop land is land that is used to cultivate crops that are not intended for commercial sale.",
+ "Permanent crops are those planted with the intention of continuous or repeated yield, rather than being harvested and replanted after each crop cycle.",
+ "A farm in the Midwest United States."
+ ],
+ "residential buildings or homes or apartments": [
+ "Residential buildings come in all shapes and sizes, but usually have several floors and many apartments or homes.",
+ "Residential buildings, homes, or apartments generally have a few floors with many rooms, including bedrooms, bathrooms, a kitchen, and a living room.",
+ "The exterior of a residential building can vary considerably, but they typically have several stories and are made of bricks or wood.",
+ "Residential buildings, including homes and apartments, typically have several floors with living quarters on each floor.",
+ "A typical residential building or home comprises several bedrooms, a kitchen, a living room and a bathroom.",
+ "Residential buildings can come in all shapes and sizes, but typically they are standalone structures that are used as homes or apartments.",
+ "A residential building is a building that contains apartments or homes.",
+ "Residential buildings, homes, or apartments can vary significantly in their appearance, but they typically have some common features.",
+ "Some residential buildings are high-rise apartments while others are townhouses or single family homes.",
+ "Residential buildings or homes typically have brick or stone exteriors, and may have multiple stories.",
+ "There is no definitive answer to this question, but some common distinguishing features of residential buildings or homes or apartments include a lack of commercial businesses on the premises, and a predominance of dwellings units (as opposed to office space or other non-.",
+ "Look for evidence of people living in the building, such as driveways, yards, and windows.",
+ "The simplest way to identify a residential building is by its size.",
+ "A residential building is typically a building that is used for people to live in.",
+ "Residential buildings, homes, or apartments can be identified by their smaller size, lack of commercial activity, and close proximity to other similar buildings.",
+ "One way to identify residential buildings is by their height.",
+ "A residential building is a building that is used for people to live in.",
+ "The easiest way to identify a residential building is by its height.",
+ "A residential building is a building that is used as a residence, such as an apartment building or a house.",
+ "Residential buildings generally have a few floors and are close together.",
+ "A residential building or home typically has a front door that opens into a living room, with a kitchen and bathroom off of the living room.",
+ "There is no one answer to this question as homes and apartments can come in all shapes and sizes.",
+ "There is no one answer to this question since there is such a wide variety of residential buildings, homes, and apartments.",
+ "A residential building can vary greatly in appearance, but usually, they are multiple stories tall with many small individual units inside.",
+ "A residential building can come in many shapes and sizes, but usually they are multi-story buildings with many individual units, such as apartments or homes.",
+ "There is no definitive answer to this question as the appearance of residential buildings can vary greatly depending on their location, age, and style.",
+ "There is no one answer to this question since there is such a wide variety of types of residential buildings, homes, and apartments.",
+ "A residential building can take on many different appearances, depending on its location and the materials it is made from.",
+ "A possible answer:Residential buildings or homes or apartments can vary greatly in appearance, depending on their location, size, and age.",
+ "There is no one answer to this question as different people have different ideas of what makes a building or home look \"nice.",
+ "The image is of a large, multi-story residential building.",
+ "The image is of several large, rectangular buildings that are uniform in shape and size.",
+ "The image is of a cluster of beige residential buildings set against a backdrop of mountains.",
+ "I found an image on the internet of a modern residential building.",
+ "The image shows a line of buildings that are all different colors.",
+ "This image shows a three-story residential building with a light-colored fa\u00e7ade and dark-colored windows.",
+ "This image is of a four-story apartment building with a red tile roof.",
+ "The image is of a large, modern home with a three-car garage.",
+ "The image is of a large, modern looking building with several balconies on each floor.",
+ "In the image, there are several high rise residential buildings in a cityscape.",
+ "An exterior view of a group of English-style row houses.",
+ " pool, tennis court, and clubhouseAl Fresco Apartments offer residents exclusive access to luxurious amenities like a sparkling pool, a tennis court, and a clubhouse.",
+ "Residential buildings in Manhattan, New York City.",
+ "Beautiful residential buildings in the heart of the city.",
+ "A view of the skyline of New York City, with its many residential buildings and homes.",
+ "The stance of the buildings shows that they were designed with people's living comfort in mind.",
+ "A view of the skyline of a city with many high-rise residential buildings.",
+ "Residential buildings in the Financial District of New York City.",
+ "The buildings in the distance are part of the skyline of downtown Los Angeles.",
+ "The Tierra del Fuego Apartments are some of the most luxurious in all of Buenos Aires."
+ ],
+ "river": [
+ "The river is flowing downstream, the water is murky and there is debris floating in it.",
+ "The sun was setting and the cool breeze was blowing.",
+ "A river typically looks like a long, narrow body of water that flows from high in the mountains, across the plains, and into the sea.",
+ "A river looks like a long, thin line of water winding its way through the landscape.",
+ "A river is a flowing body of water that is usually fresh water and is found on Earth.",
+ "A river is a long, flowing body of water that typically flows from high in the mountains to lower ground, where it meets another body of water, such as a lake or the ocean.",
+ "A river is a body of moving water that generally flows towards an ocean, lake, or another river.",
+ "A river is a waterway that flows from a high point, such as a mountain, to a lower point, such as a lake or the ocean.",
+ "A river is a body of water that flows downhill from its source to its mouth.",
+ "A river looks like a flowing body of water that is typically found in a natural setting.",
+ "A river can be identified by its flowing water.",
+ "There are many ways to identify a river.",
+ "Rivers can be identified by their position on a map, by their size, and by their shape.",
+ "The best way to identify a river is by looking at a map.",
+ "There are many ways to identify a river.",
+ "There are many ways to identify a river.",
+ "The easiest way to identify a river is by its tributaries.",
+ "A river is a natural flowing watercourse, usually freshwater, flowing towards an ocean, sea, lake or another river.",
+ "A river is generally identified by its watershed, the land area that drains into the river.",
+ "A river is a natural flowing watercourse, usually freshwater, flowing towards an ocean, sea, lake or another river.",
+ "A river typically looks like a long, winding body of water with a smooth surface.",
+ "A river is a natural flowing watercourse, usually freshwater, flowing towards an ocean, sea, lake or another river.",
+ "A river is a long, narrow body of water that flows from a mountainside spring or lake toward a lowland sea.",
+ "A river has two main parts: the stream bed and the riverbanks.",
+ "A river has a flowing surface of water, typically winding through land.",
+ "A river can look like many things.",
+ "A river looks like a long, winding body of water.",
+ "A river typically looks like a long, winding body of water.",
+ "There is no one answer to this question as rivers can take on many different forms.",
+ "A river can look like a long, winding body of water that flows through a landscape.",
+ "This image shows a river flowing through a rocky landscape.",
+ "This image is of a river in New Zealand.",
+ "The image is of a river running through a green and hilly landscape.",
+ "This is an image of a river in Utah.",
+ "The image is of a river with clear water and a few rocks visible near the surface.",
+ "This image is of a river in Mongolia.",
+ "The image is of a river flowing through a canyon.",
+ "This image is of a river in South America.",
+ "The image is of a river flowing through a canyon.",
+ "The image is of a river winding through a green valley.",
+ "A river flows through a green, forested landscape.",
+ " A raging river carrying debris and sediment downstream.",
+ "A meeting of two rivers.",
+ "A river in the Amazon rainforest.",
+ " A river in Olympic National Park, Washington State, USA.",
+ "The river bends as it flows through the valley.",
+ " A river flowing through a canyon.",
+ "A river in Alaska.",
+ " A view of the river from the bridge.",
+ "The river is flowing swiftly downstream."
+ ],
+ "sea or lake": [
+ "A sea or lake looks like a large body of water.",
+ "A sea or lake looks like a large body of water surrounded by land.",
+ "A sea is a large body of salt water that is surrounded by land.",
+ "A sea or lake typically looks like a large body of water that is surrounded by land.",
+ "A sea or lake can look like a big body of water with different types of animals living in it.",
+ " from aboveThe surface of a sea or lake looks like a calm mirror from above, reflecting the sky and the surrounding land.",
+ " when you view it from spaceFrom space, oceans look like blue marble with swirls of white.",
+ "A sea or lake is a large body of water surrounded by land.",
+ " in term of colorA sea or lake is typically a blue color.",
+ "The surface of a sea or lake is usually covered with ripples from the wind.",
+ "Most seas and lakes are distinguished by their color.",
+ "If you see water that goes on as far as you can see, then it is probably a sea.",
+ "The easiest way to identify a sea or lake is by its size.",
+ "A sea or lake can be identified by looking at a map.",
+ "The bottom of a sea or lake is usually sandy, muddy, or rocky.",
+ "Fresh water vs salt water.",
+ "You can identify a sea or lake by looking at a map.",
+ "The best way to identify a sea or lake is by looking at a map.",
+ "A sea or lake can be identified by its large size and abundance of water.",
+ "The easiest way to identify a sea or lake is by its size.",
+ "A sea or lake can look like a large body of water with waves on the surface.",
+ "A sea or lake typically looks like a large body of water that is surrounded by land.",
+ "A sea or lake looks like a large body of water surrounded by land.",
+ "A sea or lake is a large body of water that is surrounded by land.",
+ "A sea or lake looks like a large body of water.",
+ "A sea or lake typically looks like a large body of water that is surrounded by land.",
+ "A sea or lake looks like a body of water that is surrounded by land.",
+ "The color of a sea or lake depends on its depth, how clear the water is, and the angle of the sun.",
+ "A sea or lake typically looks like a large body of water with shorelines on all sides.",
+ "A sea or lake looks like a large body of water.",
+ "I found an image of the sun shining on a lake with mountains in the background.",
+ "The image is of a beautiful, serene lake.",
+ "In the image, the sea is a deep blue color and the waves are crashing against the shore.",
+ "This image is of a beautiful sea with blue waters and a few white clouds in the sky.",
+ "The image is of a calm lake at night.",
+ "The image is of a calm blue sea with a few ripples.",
+ "The image is of a calm, turquoise sea.",
+ "The image shows a large body of water with waves crashing onto the shore.",
+ "The image is of a calm, blue sea with a few ripples.",
+ "The image is of a crystal clear lake with mountains in the background.",
+ " The vastness of the ocean is unmatched.",
+ "The beautiful blue waters of the Caribbean Sea.",
+ "The deep blue waters of the Caribbean Sea are perfect for a summer vacation.",
+ "The calm water is like a mirror, reflecting the beauty of the surrounding mountains.",
+ "The vastness of the open water is breathtaking.",
+ "The vast and beautiful ocean.",
+ "The vast and gorgeous view of the sea and sky.",
+ "The vast expanse of water is so calming.",
+ " A beautiful landscape of a sea or lake.",
+ "The vast blue expanse of the open ocean is a sight to behold."
+ ]
+}
\ No newline at end of file
diff --git a/cupl/descriptors_fgvc_aircraft.json b/cupl/descriptors_fgvc_aircraft.json
new file mode 100644
index 0000000..7ae876b
--- /dev/null
+++ b/cupl/descriptors_fgvc_aircraft.json
@@ -0,0 +1 @@
+{"DC-3": ["The Douglas DC-3 is a twin-engine propeller-driven airliner which was produced by Douglas Aircraft Company from 1936 to 1947.", "The DC-3 aircraft is a twin-engine, propeller-driven plane that was first flown in 1935.", "The DC-3 was a propeller-driven passenger and cargo aircraft that was first flown in 1935.", "The Douglas DC-3 is an American fixed-wing, propeller-driven aircraft that was manufactured by the Douglas Aircraft Company from 1936 to 1945.", "The DC-3 is a twin-engined, fixed-wing propeller-driven aircraft.", "ifly DC-3 is a popular and well-known propeller-driven aircraft that was used extensively by airlines and military organizations around the world during the 1930s and 1940s.", "The Douglas DC-3 is a fixed-wing propeller-driven airliner.", "The DC-3 was a twin-engine, propeller-driven passenger and cargo aircraft Cardoworking introduced in 1936.", "The DC-3 aircraft was a twin-engine, propeller-driven plane that was first built in the 1930s.", "The Douglas DC-3 is a fixed-wing, propeller-driven aircraft.", "The DC-3 aircraft was a twin-engine, propeller-driven plane that was first flown in 1935.", "The DC-3 is a propeller-driven passenger and cargo aircraft that was introduced in the 1930s.", "The DC-3 was a twin-engine propeller-driven aircraft that was introduced in 1936.", "The Douglas DC-3 is an American fixed-wing, propeller-driven aircraft.", "The DC-3 is a fixed-wing, propeller-driven aircraft with a tailwheel landing gear configuration.", "The Douglas DC-3 is a fixed-wing, propeller-driven aircraft.", "The DC-3 aircraft is a propeller-driven airplane with a tricycle landing gear.", "The Douglas DC-3 aircraft is a twin-engine, propeller-driven plane that was first flown in 1935.", "The Douglas DC-3 is a fixed-wing propeller-driven airliner.", "The DC-3 is a twin-engine, propeller-driven passenger aircraft that was first flown in 1935."], "ERJ 135": ["The ERJ 135 is a twin-engine regional jet manufactured by Embraer.", "The ERJ 135 is a twin-engine jet aircraft capable of carrying up to 37 passengers.", "The ERJ 135 is a twin-engine regional jet that was introduced in 1999.", "The ERJ 135 is a small commercial jet aircraft manufactured by Embraer, a Brazilian aerospace company.", "The ERJ 135 is a small, single-engine jet plane used for short flights.", "The ERJ 135 is a 30-passenger regional jet produced by Embraer.", "The ERJ 135 is a twin-engine, regional jet aircraft that was designed and manufactured by Embraer, a Brazilian aerospace company.", "The ERJ 135 is a twin-engine regional jet aircraft manufactured by Embraer.", "The ERJ 135 is a twin-engine regional jet that was designed and manufactured by Embraer, a Brazilian aerospace company.", "The ERJ 135 is a regional jet that was manufactured by Embraer, a Brazilian aerospace company.", "The ERJ 135 is a twin-engine regional jet that seats up to 37 passengers.", "The ERJ 135 is a twin-engine regional jet that seats up to 37 passengers.", "The ERJ 135 is a twin-engine, regional jet aircraft manufactured by Embraer, a Brazilian aerospace company.", "The ERJ 135 is a 37-seat regional jet produced by Embraer.", "An ERJ 135 is a twin-engine, regional jet aircraft designed and built by Embraer, a Brazilian aerospace company.", "The ERJ 135 is a regional jet that seats up to 37 passengers.", "The ERJ 135 is a small jet aircraft that typically seats between 30 and 40 passengers.", "The ERJ 135 is a twin engine aircraft that can hold up to 37 passengers.", "The ERJ 135 is a twin-engine regional jet that was manufactured by Embraer, a Brazilian aerospace company.", "The ERJ 135 is a regional jet that was designed and manufactured by Embraer, a Brazilian aerospace company."], "DC-10": ["The McDonnell Douglas DC-10 is a three-engine long-range wide-body jet airliner manufactured by McDonnell Douglas.", "The DC-10 aircraft is a wide-body, three-engine jet airliner that was manufactured by the McDonnell Douglas Corporation.", "The McDonnell Douglas DC-10 is a three-engine wide-body jet airliner manufactured by McDonnell Douglas.", "The DC-10 is a three-engine jet airplane manufactured by McDonnell Douglas.", "The DC-10 aircraft is a three-engine wide-body jet airliner that was manufactured by McDonnell Douglas.", "The DC-10 is a wide-body jet airliner manufactured by McDonnell Douglas.", "The DC-10 is a wide-body McDonnell Douglas airliner.", "The DC-10 is a three-engine jet airliner that was manufactured by McDonnell Douglas.", "The DC-10 aircraft is a three-engine wide-body jet airliner that was manufactured by the McDonnell Douglas Corporation.", "The McDonnell Douglas DC-10 is a three-engine wide-body jet airliner manufactured by McDonnell Douglas.", "A DC-10 aircraft is a three-engine, long-range plane that was first introduced in 1971.", "The Douglas DC-10 is a wide-body airliner manufactured by McDonnell Douglas.", "The DC-10 is a three-engine wide-body jet airliner manufactured by McDonnell Douglas.", "The Douglas DC-10 is a three-engine wide-body jet airliner with a two-deck configuration produced by the American manufacturer McDonnell Douglas.", "The McDonnell Douglas DC-10 is an American commercial wide-body jet airliner manufactured by McDonnell Douglas.", "The McDonnell Douglas DC-10 is a three-engine wide-body jet airliner manufactured by McDonnell Douglas.", "A DC-10 is a wide-body jet airliner that was manufactured by McDonnell Douglas.", "The McDonnell Douglas DC-10 is an American three-engine wide-body jet airliner manufactured by McDonnell Douglas.", "The McDonnell Douglas DC-10 is an American trijet wide-body airliner manufactured from 1971 to 1989.", "The Douglas DC-10 is a three-engine long-range wide-body jet airliner manufactured by McDonnell Douglas."], "Gulfstream V": ["The Gulfstream V is a business jet aircraft produced by Gulfstream Aerospace.", " in as much detail as possibleThe Gulfstream V is a twinjet aircraft produced by Gulfstream Aerospace.", "The Gulfstream V is a business jet aircraft produced by Gulfstream Aerospace, the US high-end business jet manufacturer.", "The Gulfstream V is a business jet aircraft produced by Gulfstream Aerospace, derived from the earlier Gulfstream IV.", "The Gulfstream V is a twin-engine jet aircraft produced by Gulfstream Aerospace, capable of flying intercontinental distances at a speed of Mach 0.", "The Gulfstream V is a twin-engine business jet aircraft produced by Gulfstream Aerospace, derived from the earlier Gulfstream IV.", "The Gulfstream V is a long-range, large-cabin, twin-engine business jet aircraft produced by Gulfstream Aerospace, derived from the previous Gulfstream IV.", "The Gulfstream V is a twin-engine business jet aircraft produced by Gulfstream Aerospace.", "The Gulfstream V is a long-range, large-cabin, twin-engine business jet aircraft produced by Gulfstream Aerospace.", "The Gulfstream V is a business jet aircraft produced by Gulfstream Aerospace.", "The Gulfstream V aircraft is a large, long-range jet that can seat up to 19 passengers.", "The Gulfstream V is a long-range, large-cabin, intercontinental business jet aircraft produced by Gulfstream Aerospace, derived from the earlier Gulfstream IV.", "A Gulfstream V aircraft is a long-range, large-cabin business jet designed and built by Gulfstream Aerospace.", "The Gulfstream V is a business jet aircraft produced by Gulfstream Aerospace, derived from the earlier Gulfstream IV.", "The Gulfstream V is a long-range, large-cabin, jet aircraft produced by Gulfstream Aerospace.", "The Gulfstream V (GV) is an American long-range, large-cabin, twin-engine jet aircraft produced by Gulfstream Aerospace.", "The Gulfstream V is a twin-engine business jet aircraft produced by Gulfstream Aerospace.", "The Gulfstream V (G5) is a long-range, large-cabin, twin-engine business jet aircraft produced by Gulfstream Aerospace, a General Dynamics company.", "A Gulfstream V is a twin-engine business jet airplane produced by Gulfstream Aerospace,derived from the earlier Gulfstream IV.", "The Gulfstream V is a large-cabin, long-range jet airplane produced by Gulfstream Aerospace, derived from the earlier Gulfstream IV."], "A340-500": ["The A340-500 aircraft is a long-range, four-engine jet airliner that was produced by Airbus.", "The A340-500 is an aircraft from the A340 family manufactured by Airbus.", "The A340-500 is a long-range, four-engine wide-body commercial airliner developed and produced by Airbus Industrie, the European consortium.", "The A340-500 is a long-range, wide-body airliner produced by Airbus.", "The A340-500 is a long-range, four-engine jet airliner manufactured by Airbus.", "The A340-500 is a long-range, wide-body commercial passenger airliner manufactured by Airbus.", "The Airbus A340-500 is a long-range, wide-body commercial passenger jet aircraft capable of seating up to 375 passengers in a two-class layout.", "The A340-500 is a long-range, wide-body aircraft produced by Airbus.", "The A340-500 is a long-range, four-engine jet airliner developed and produced by Airbus.", "The A340-500 is a long-range, wide-body jet airliner that was manufactured by Airbus.", "The A340-500 is an intercontinental commercial passenger jetliner that was produced by the European manufacturer Airbus.", "The A340-500 is a long range four engine wide-body airliner produced by Airbus.", "The Airbus A340-500 is a long-range, four-engine jet airliner made by Airbus.", "The A340-500 is a long-range commercial passenger jet aircraft developed by Airbus.", "The Airbus A340-500 is a long-range, four-engine commercial airliner.", "The A340-500 is a four-engined long-range wide-body airliner with a capacity of up to 375 passengers in a three-class configuration.", "The A340-500 is a four-engine long-range wide-body airliner produced by Airbus.", "The A340-500 is a long-range, four-engine jet airliner from Airbus.", "The Airbus A340-500 is a four-engined long-range wide-body airliner with a capacity of 220 passengers produced by the European manufacturer Airbus.", "The A340-500 is a four engine long range wide-body commercial passenger airliner."], "DHC-8-300": ["The DHC-8-300 is a twin-engine, turboprop regional airliner with a capacity of up to 39 passengers.", "The DHC-8-300 aircraft is a short-haul, regional turboprop aircraft.", "The DHC-8-300 is a twin-engined turboprop aircraft operated by Air Canada and Jazz Air.", " takeoffThe DHC-8-300 is a powerful aircraft that is capable of taking off in a very short distance.", "The DHC-8-300 aircraft is a two-engine, turboprop-powered aircraft that can seat up to 37 passengers.", "The DHC-8-300 aircraft is a twin-engine turboprop airplane that can seat up to 37 passengers.", "The DHC-8-300 Dash 8 is a twin-engine, 19-seat turboprop aircraft.", "The DHC-8-300 is a Twin-Engine Turbo-Prop Airplane manufactured by de Havilland Canada.", "The DHC-8-300 is a twin-engine turboprop aircraft used for short-haul flights.", "The DHC-8-300 is a twin-engine turboprop regional airliner with a capacity of up to 70 passengers.", "The DHC-8-300 aircraft is a Short Take-Off and Landing (STOL) aircraft that is used for short-haul flights.", "A DHC-8-300 aircraft is a twin-engined turboprop regional airliner with 30 seats.", "The DHC-8-300 is a turboprop aircraft with 30 seats and a cruising speed of 500 kilometers per hour.", "The DHC-8-300 is a twin-engine, turboprop airplane that can seat up to 37 passengers.", "Aircraft: DHC-8-300 Type: Turboprop Seating Capacity: 30 \u2013 39 Number of Engines: 2 Manufacturer: De Havilland Canada.", "The DHC-8-300 is a twin-engine, short-range, regional commuter airliner manufactured by de Havilland Canada.", "The DHC-8-300 is a twin-engine, short-haul regional airliner produced by de Havilland Canada.", "The DHC-8-300 is a twin-engine short-haul regional airliner with a capacity of up to 39 passengers.", "The de Havilland Canada DHC-8-300 Dash 8 is a twin-engined, short-range, regional airliner with a capacity of up to 37 passengers, designed and produced by de Havilland Canada.", "The DHC-8-300 is a twin-engine, turboprop aircraft with a pressurized cabin."], "Eurofighter Typhoon": ["The Eurofighter Typhoon is a twin-engine, canard-delta wing, multirole fighter.", "The Eurofighter Typhoon is a multi-role fighter aircraft designed and built by a consortium of Airbus, BAE Systems and Leonardo that presently comprises the bulk of the United Kingdom Royal Air Force's (RAF) fast jet fleet.", "The Eurofighter Typhoon is a twin-engine, canard-delta wing, multirole fighter.", "The Eurofighter Typhoon is a twin-engine, canard-delta wing, multirole fighter.", "The Eurofighter Typhoon is a twin-engine, canard-delta wing, multirole fighter designed and built by a consortium of Airbus, BAE Systems and Leonardo that performs air-to-air and air-to-surface missions.", "The Eurofighter Typhoon is a twin-engine, canard-delta wing, multirole fighter.", "The Eurofighter Typhoon is a twin-engine, canard-delta wing, multirole fighter aircraft.", "The Eurofighter Typhoon is a multi-role combat aircraft, capable of being configured for air-to-air and air-to-ground missions.", "The Eurofighter Typhoon is a twin-engine, canard-delta wing, multirole fighter.", "The Eurofighter Typhoon is a European twin-engine, canard-delta wing, multirole fighter.", "The Eurofighter Typhoon is a multi-role combat aircraft, designed and built by a consortium of three companies: Airbus, BAE Systems and Leonardo.", "An Eurofighter Typhoon aircraft is a twin-engine, canard-delta wing, multirole fighter.", "The Eurofighter Typhoon is a multi-role combat aircraft, designed and built by a consortium of European aerospace companies.", "The Eurofighter Typhoon is a twin-engine, canard-delta wing, multirole fighter.", "The Eurofighter Typhoon is a twin-engine, canard\u2013delta wing, multirole fighter.", "The Eurofighter Typhoon is a twin-engine, canard-delta wing, multirole fighter.", "The Eurofighter Typhoon is a twin-engine, canard-delta wing, multirole fighter.", "The Eurofighter Typhoon is a twin-engine, canard-delta wing, multirole fighter.", "The Eurofighter Typhoon is a twin-engine, canard-delta wing, multirole fighter designed and built by a consortium of Airbus, BAE Systems and Leonardo that conducts its flight test and evaluation program with the Royal Air Force and.", "The Eurofighter Typhoon is a twin-engine, canard-delta wing, multirole fighter."], "747-400": ["The 747-400 is a four-engine long-range wide-body airliner built by Boeing Commercial Airplanes.", "The 747-400 is a wide-body, long-haul airliner produced by Boeing Commercial Airplanes.", "The 747-400 is a wide-body, long-range, passenger airliner that was first introduced in 1989.", "The 747-400 is a wide-body jet airliner that was introduced in 1988.", "The 747-400 is an improved version of the 747-300, with a strengthened fuselage and wing structure, an increased wingspan, new and more efficient engines, new avionics, and a redesigned interior.", "The 747-400 is a family of long-range, wide-body jets produced by Boeing.", "The 747-400 is a four-engined wide-body jet airliner produced by Boeing Commercial Airplanes.", "The Boeing 747-400 is a wide-body jet airliner produced by Boeing Commercial Airplanes.", "The 747-400 is a wide-body aircraft produced by Boeing Commercial Airplanes.", "The 747-400 is a wide-body commercial jet airliner typically configured with a two-story high-density main deck and a lower-density long-range deck.", "The 747-400 is a wide-body jet airliner produced by Boeing Commercial Airplanes.", "The 747-400 is a wide-body jet airliner produced by Boeing Commercial Airplanes.", "The 747-400 is a passenger jet that can seat up to 416 passengers.", "The 747-400 is a wide-body airliner produced by Boeing Commercial Airplanes.", "The 747-400 is a four-engine commercial jetliner that was introduced in 1988 and was produced until 2009.", "The 747-400 is a widebodied passenger airliner produced by Boeing Commercial Airplanes.", "The 747-400 is a wide-body jet airliner produced by Boeing Commercial Airplanes.", "The 747-400 is a wide-body, long-haul aircraft with a capacity of 400 passengers and a range of 7,670 nautical miles.", "The 747-400 is an improved version of the 747-300, with a longer range and increased efficiency.", "A 747-400 is a wide-body aircraft with a capacity of 400 passengers and a range of 8,000 to 9,000 miles."], "Beechcraft 1900": ["The Beechcraft 1900 is a twin-engine turboprop fixed-wing aircraft with a pressurized cabin.", "The Beechcraft 1900 is a light transport aircraft manufactured by Beechcraft.", "The Beechcraft 1900 is a twin-engined turboprop airplane that was designed specifically for regional airline service.", "The Beechcraft 1900 is a 19-passenger, pressurized twin-engine turboprop fixed-wing aircraft that was introduced in 1982.", "The Beechcraft 1900 is a twin-engine turboprop airplane designed for commercial use.", "The Beechcraft 1900 is a twin-engined, fixed-wing aircraft manufactured by Beechcraft.", "The Beechcraft 1900 is a 19-passenger, pressurized twin-engine turboprop fixed-wing aircraft that was designed and manufactured by Beechcraft.", "The Beechcraft 1900 is a twin-engine turboprop passenger plane.", "The Beechcraft 1900 is a twin-engined turboprop commuter airliner.", "The Beechcraft 1900 is a twin-engine, turboprop corporate shuttle and regional airliner.", "The Beechcraft 1900 is a twin-engine, pressurized, turboprop airplane manufactured by Beechcraft.", "The Beechcraft 1900 is a twin-engine, pressurized turboprop passenger airplane.", "The Beechcraft 1900 is a twin-engined, pressurized, turboprop commuter liner aircraft.", "A Beechcraft 1900 is a twin-engine, turboprop, pressurized airplane that can seat up to 19 people.", "The Beechcraft 1900 is a turboprop-powered provincial airliner, designed and built by Beechcraft.", "The Beechcraft 1900 is a twin-engine turboprop passenger plane.", "The Beechcraft 1900 is a 19-passenger, twin-engine turboprop aircraft.", "-A twin-engine turboprop airplane that seats up to 19 passengers\n-Has a cruising speed ofine 300 mph (483 km/h)\n-A typical range is 1,350 miles (2,174 km)\n.", "The Beechcraft 1900 is a twin-engine, turboprop aircraft that can seat up to 19 passengers.", "The Beechcraft 1900 is a twin-engined turboprop passenger airliner used for short-haul flights."], "An-12": ["The Antonov An-12 is a four-engined turboprop military transport aircraft designed in the Soviet Union.", "The Antonov An-12 (NATO reporting name: Cub) is a four-engined turboprop transport aircraft designed in the Soviet Union.", "The Antonov An-12 is a four-engined turboprop transport aircraft designed in the Soviet Union.", "The An-12 is a four-engined turboprop transport aircraft designed in the Soviet Union.", "The An-12 aircraft is a four-engined turboprop transport aircraft designed in the Soviet Union.", "The An-12 is a quad-engined turboprop transport aircraft designed in the Soviet Union.", "The Antonov An-12 is a four-engined turboprop transport aircraft designed in the Soviet Union.", "The Antonov An-12 is a four-engined turboprop military transport aircraft designed in the Soviet Union.", "The An-12 is a four-engined turboprop transport aircraft designed in the Soviet Union.", "The Antonov An-12 is a four-engined turboprop transport aircraft designed in the Soviet Union.", "An-12 aircraft is a military transport aircraft that was developed in the Soviet Union.", "The Antonov An-12 is a four-engined turboprop transport aircraft designed in the Soviet Union.", "The Antonov An-12 is a four-engined turboprop transport aircraft designed in the Soviet Union.", "An-12 aircraft is a Soviet military transport aircraft.", "The Antonov An-12 is a four-engined turboprop transport aircraft designed in the Soviet Union.", "The Antonov An-12 is a four-engined turboprop transport aircraft designed in the Soviet Union.", "The Antonov An-12 is a four-engined turboprop transport aircraft designed in the Soviet Union.", "The An-12 is a four-engined turboprop transport aircraft designed in the Soviet Union.", "The An-12 is a Soviet military transport aircraft that was designed in the 1950s.", "The An-12 is a four-engined turboprop transport aircraft designed in the Soviet Union."], "Il-76": ["The Il-76 is a four-engine turbofan strategic airlifter designed by the Soviet Union's Ilyushin design bureau.", "The Il-76 is a multi-purpose four-engine turbofan strategic airlifter designed by the Soviet Union's Ilyushin Design Bureau.", "The Il-76 is a four-engine turbofan strategic airlifter designed by the Soviet Union's Ilyushin design bureau.", "The Ilyushin Il-76 (Russian: \u0418\u043b\u044c\u044e\u0301\u0448\u0438\u043d \u0418\u043b-76; NATO reporting name: Candid) is a multi-purpose four-engined turbofan strategic.", "The Ilyushin Il-76 (NATO reporting name: Candid) is a Soviet four-engine turbofan strategic airlifter designed by the Ilyushin design bureau.", "The Il-76 is a Soviet-built four-engined transport aircraft designed for landing troops and materials onto unimproved runways.", "The Il-76 is a multi-purpose four-engine turbofan strategic airlift cargo aircraft, designed by the Soviet Union's Ilyushin Aviation Complex.", "The Il-76 is a Soviet multi-purpose four-engine turbofan strategic airlifter designed by the Ilyushin Design Bureau.", "The Ilyushin Il-76 (NATO reporting name: Candid) is a multi-purpose four-engined turbofan strategic airlifter designed by the Soviet Union's Ilyushin design bureau.", "The Ilyushin Il-76 (Russian: \u0418\u043b\u044c\u044e\u0301\u0448\u0438\u043d \u0418\u043b-76; NATO reporting name: Candid) is a Soviet four-engined transport aircraft designed by the Ily.", "The Ilyushin Il-76 is a multi-purpose four-engined turbofan strategic airlifter designed by the Soviet Union's Ilyushin design bureau.", "The Il-76 is a four-engined multi-role transport aircraft designed by the Soviet Union.", "The Ilyushin Il-76 is a multi-purpose four-engine turbofan strategic airlifter designed by the Soviet Union's Ilyushin design bureau.", "The Il-76 is a multipurpose four-engine turbofan strategic airlifter designed by the Soviet Union's Ilyushin design bureau.", "The Il-76 is a cargo aircraft designed by the Soviet Union's Ilyushin Aviation.", "The Ilyushin Il-76 (NATO reporting name: Candid) is a Soviet/Russian four-engined transport aircraft designed by the Ilyushin design bureau.", "An IL-76 is a Soviet/Russian four-engine turbocharged jet transport aircraft.", "The Il-76 is a multi-purpose four-engine turbofan strategic airlifter designed by the Soviet Union's Ilyushin design bureau.", "The Il-76 is a multi-purpose four-engined turbofan strategic airlifter designed by the Soviet Union's Ilyushin design bureau.", "Il-76 is a multi-purpose four-engine turbojet aircraft designed by the Soviet Union's Ilyushin design bureau."], "MD-11": ["The MD-11 is a three-engine wide-body jet airliner that was manufactured by McDonnell Douglas.", "MD-11 is a long-range, wide-body trijet aircraft manufactured by McDonnell Douglas.", "The McDonnell Douglas MD-11 is a wide-body airliner produced by McDonnell Douglas.", "The McDonnell Douglas MD-11 is an American wide-body airliner, designed and manufactured by McDonnell Douglas.", "The MD-11 is a wide-body jet airliner that was manufactured by McDonnell Douglas.", "The McDonnell Douglas MD-11 is a wide-body twin-engine jet airliner designed and manufactured by McDonnell Douglas.", "The McDonnell Douglas MD-11 is a wide-body airliner that was manufactured by McDonnell Douglas.", "The MD-11 aircraft is a wide-body, twin-engine jetliner that was originally designed and built by McDonnell Douglas.", "The McDonnell Douglas MD-11 is a wide-body airliner with a capacity of up toSeats.", "The McDonnell Douglas MD-11 is a wide-body passenger jet airliner.", "The McDonnell Douglas MD-11 is a wide-body airliner that was manufactured by McDonnell Douglas.", "The MD-11 is a wide-body aircraft manufactured by McDonnell Douglas.", "A MD-11 is a long-range, wide-body trijet aircraft manufactured by McDonnell Douglas.", "The McDonnell Douglas MD-11 is a three-engine wide-body jet airliner that was manufactured by McDonnell Douglas.", "The McDonnell Douglas MD-11 is a wide-body McDonnell Douglas airliner, often referred to as the \"triple- Eleven\".", "The McDonnell Douglas MD-11 is a wide-body airliner developed and manufactured by McDonnell Douglas.", "The McDonnell Douglas MD-11 is an American wide-body trijet cargo aircraft manufactured by McDonnell Douglas.", "The McDonnell Douglas MD-11 is a wide-body airliner that was produced by McDonnell Douglas.", "The McDonnell Douglas MD-11 is a wide-body airliner with three engines, manufactured by McDonnell Douglas and, later, by Boeing Commercial Airplanes.", "The McDonnell Douglas MD-11 is a three-engine long-range wide-body airliner."], "Metroliner": ["The Metropolitan Liner, or Metroliner, is a 30-seat, twin-engined turboprop regional airliner that was produced by Fairchild Aircraft from 1965 to 1982, and later by British Aerospace from 1983 to 1998.", "The Metroliner aircraft is a light, twin-engined turboprop plane.", "TheMetrolineris a 19-seat, twin-turboprop business class airliner manufactured by Fairchild Aircraft.", "The Metroliner aircraft was a twin-engined aircraft that was manufactured by the Fairchild Aircraft Corporation.", "The Metroliner is a twin-engine turboprop airplane that was used for short-haul flights.", "The Metroliner is a twin-engine turboprop passenger airplane.", "The Metroliner is a 19-seat, twin-engined turboprop commuter airliner.", "The Metroliner is a small twin-engine turboprop airliner.", "The Metroliner aircraft is a small, twin-engine turboprop airliner.", "The Metroliner aircraft was a twin-engined turboprop airliner that was introduced in 1968.", "A Metroliner is a small, turboprop airliner that seats between 19 and 36 passengers.", "A Metroliner is a twin-engined turboprop airliner.", "A Metroliner is an aircraft that is used for Metrolinar flights.", "The Metroliner is a 19-seat, twin-turboprop business class aircraft.", "A Metroliner aircraft is a propeller-driven airplane that was designed and manufactured by the Fairchild Aircraft Corporation.", "The Metroliner is a 19-seat, twin-engined turboprop airliner designed and built by the British aircraft manufacturerHandley Page.", "The Metroliner is a twin-engined, high-speed turboprop passenger airliner originally designed and built by the Grumman Aircraft Company.", "TheMetroliner is a turboprop-powered regional airliner that was introducted in 1967.", "The Metroliner is a small, twin-engine turboprop airliner.", "The Metroliner is a twin-engine turboprop aircraft designed for short-haul flights."], "BAE 146-200": ["The BAE 146-200 is a twin-engined regional airliner with a capacity of up to 146 passengers, designed and manufactured by British Aerospace (now BAE Systems).", "The BAE 146-200 is a twin-engined short-haul airliner with a capacity of up to 146 passengers, designed and built by British Aerospace (now BAE Systems).", "The BAE 146-200 is a short-haul passenger jet manufactured by British Aerospace between 1983 and 1992.", "The BAE 146-200 is a twin-engined commercial aircraft that was manufactured by British Aerospace.", "The BAE 146-200 is a short-haul airliner that was manufactured by British Aerospace (now BAE Systems).", "The BAE 146-200 is a British twin-engine, short-haul aircraft that was formerly manufactured by British Aerospace (now BAE Systems).", "The BAE 146-200 is a short-haul aircraft with a capacity of up to 100 passengers.", "The BAE 146-200 is a twin-engine passenger plane designed by British Aerospace (now BAE Systems).", "The BAE 146-200 aircraft is a short-haul, four-engined jetliner that was manufactured by British Aerospace (now BAE Systems).", "The BAE 146-200 is a British twin-engine, Medium-range aircraft that was manufactured by British Aerospace (now BAE Systems).", "The BAE 146-200 is a British regional airliner that was manufactured by British Aerospace (now BAE Systems).", "The BAE 146-200 aircraft is a four-engined regional jet that was manufactured by British Aerospace.", "The BAE 146-200 is a British short-haul airliner that was manufactured by British Aerospace (now BAE Systems).", "The BAE 146-200 is a short-haul passenger plane manufactured by British Aerospace.", "The BAE 146 is a short-haul airliner that was manufactured by British Aerospace.", "The BAE 146-200 is a twin-engined short-haul aircraft with a capacity of up to 120 passengers.", "The BAE 146-200 aircraft is a four-engined short-haul airliner that was manufactured by British Aerospace.", "The BAE 146-200 is a twin-engine short-haul commercial aircraft that was manufactured by British Aerospace (now BAE Systems).", "The BAE 146-200 is a twin-engine jetliner that was manufactured by British Aerospace (now BAE Systems).", "The BAE 146-200 is a British four-engined turboprop regional airliner with a capacity of up to 102 passengers."], "MD-80": ["The MD-80 aircraft is a twin-engine, single-aisle jetliner that was designed and manufactured by McDonnell Douglas.", "The McDonnell Douglas MD-80 is a twin-engine, short- to medium-range commercial jet airliner.", ".", "The MD-80 is a short- to medium-range, twin-engine, single-aisle commercial jet airliner.", "The MD-80 is a twin-engine short-to-medium-range commercial jet airliner that was introduced in 1980.", "The McDonnell Douglas MD-80 is a twin-engine, short- to medium-range commercial jet airliner.", "The MD-80 is a twin-engine commercial jet airliner that was introduced in 1980.", "The MD-80 is a twin-engine, single-aisle aircraft produced by the McDonnell Douglas Corporation.", "The McDonnell Douglas MD-80 is a twin-engined short- to medium-range commercial jet airliner.", "The McDonnell Douglas MD-80 is a twin-engine, short- to medium-range commercial jet airliner.", "A MD-80 aircraft is a twin-engine, single-aisle jetliner that was first delivered in October 1980.", "A McDonnell Douglas MD-80 is a twin-engine short- to medium-range commercial jet airliner.", "A MD-80 aircraft is a twin-engine, low-wing, narrow-body McDonnell Douglas airliner.", "The McDonnell Douglas MD-80 is a twin-engine, short- to medium-range commercial jet airliner.", "A McDonnell Douglas MD-80 is a twin-engine, short- to medium-range commercial airliner.", "The McDonnell Douglas MD-80 is a twin-engined short- to medium-range commercial jet airliner.", "The McDonnell Douglas MD-80 is a twin-engine, short- to medium-range commercial jet airliner.", "The McDonnell Douglas MD-80 is a series of twin-engine, short- to medium-range, single-aisle commercial jet airliners.", "A McDonnell Douglas MD-80 is a twin-engine, short- to medium-range commercial jet airliner.", "A McDonnell Douglas MD-80 is a twin-engine, single-aisle passenger jetliner that was introduced in 1980."], "737-300": ["The 737-300 is a twin-engined short-to-medium-range narrowbody aircraft with a capacity of maximum 149 passengers produced by American manufacturer Boeing Commercial Airplanes.", "The 737-300 is a twin-engined short-to-medium-range narrow-body airliner with a capacity of maximum 149 passengers produced by Boeing Commercial Airplanes.", "The 737-300 is a twin-engined short-to-medium-range narrow-body aircraft with a capacity of maximum 149 passengers produced by American manufacturer Boeing Commercial Airplanes.", "The 737-300 is part of the 737 Classic series, which also includes the 737-400 and 737-500.", "The 737-300 is a narrow-body aircraft produced by Boeing as part of their 737 series.", "The 737-300 is a twin-engine short- to medium-range narrowbody airliner with a capacity of maximum 149 passengers produced by Boeing Commercial Airplanes.", "The 737-300 is a short-to-medium-range narrow-body airliner, with a capacity of maximum 149 passengers in a two-class configuration.", "The 737-300 is a twin-engine jetliner that was manufactured by Boeing.", "The 737-300 is a twin-engined short-to-medium-range narrow-body aircraft with a capacity of maximum 149 passengers produced by Boeing Commercial Airplanes.", "The 737-300 is a short-range narrow-body aircraft produced by Boeing as part of the 737 Classic series.", "The 737-300 is a twin-engined short-to-medium-range Boeing 737 commercial airliner.", "The 737-300 is a twin-engine jet airliner typically configured with 158 seats.", "A 737-300 is a twin-engined short-to-medium-range narrow-body aircraft with a capacity of maximum 149 passengers produced by Boeing Commercial Airplanes.", "The 737-300 is a short- to medium-range, twin-engine jet airliner that was manufactured by Boeing Commercial Airplanes from 1984 to 2000.", "A737-300 is an aircraft with 129 seat configuration.", "The 737-300 is a twin-engined narrow-body aircraft with a capacity of maximum 149 passengers produced by Boeing Commercial Airplanes.", "A 737-300 is a narrow-body aircraft manufactured by Boeing Commercial Airplanes.", "The Boeing 737-300 is a twin-engined short-to-medium-range narrow-body aircraft with a capacity of maximum 149 passengers produced by the American manufacturer Boeing Commercial Airplanes.", "The 737-300 is a twin-engine jet airplane that was manufactured by Boeing as a short-to-medium-range commercial airliner.", "The 737-300 is a twin-engined short-to-medium-range narrow-body aircraft with a capacity of maximum 149 passengers produced by American manufacturer Boeing Commercial Airplanes."], "MD-87": ["The McDonnell Douglas MD-87 is a short to medium-range, twin-engine commercial jet airliner.", "The McDonnell Douglas MD-87 is a twin-engine, short- to medium-range commercial jet airliner.", "The McDonnell Douglas MD-87 is a twin-engined short- to medium-range commercial transport aircraft.", "The McDonnell Douglas MD-87 is a twin-engined stretched version of the MD-80 series airliner.", "The McDonnell Douglas MD-87 is a twin-engine, short- to medium-range commercial airliner.", "The McDonnell Douglas MD-87 is a twin-engine, short- to medium-range commercial transport aircraft.", "The McDonnell Douglas MD-87 is a twin-engine, short-to-medium-range commercial airliner.", "The McDonnell Douglas MD-87 is a twin-engine, short- to medium-range commercial jet airliner.", "The McDonnell Douglas MD-87 is an American twin-engine, short- to medium-range commercial jet airliner.", "The McDonnell Douglas MD-87 is a twin-engined commercial jetliner with a tricycle landing gear.", "An MD-87 is a twin-engine, long-range commercial airliner.", "A McDonnell Douglas MD-87 is a twin-engine, large-cabin jet airliner.", "The McDonnell Douglas MD-80 is a series of twin-engine, short- to medium-range, single-aisle commercial jet airliners.", "The McDonnell Douglas MD-87 is a twin-engined short- to medium-range airliner.", "The McDonnell Douglas MD-87 is a twin-engine short- to medium-range commercial airliner.", "A McDonnell Douglas MD-87 is a twin-engine, short- to medium-range commercial airliner.", "A McDonnell Douglas MD-87 is a twin-engined, short- to medium-range commercial jet airliner.", "The McDonnell Douglas MD-87 is a twin-engine, short- to medium-range commercial airliner.", "The McDonnell Douglas MD-87 is a twin-engine, short- to medium-range commercial airliner.", "The McDonnell Douglas MD-87 is a short- to medium-range, twin-engine jet airliner."], "Tu-154": ["The Tupolev Tu-154 is a Soviet-built three-engine medium-range airliner designed in the mid-1960s.", "The Tupolev Tu-154 is a Soviet-era narrow-body jet airliner which was produced by Tupolev from 1968 to 2013.", "The Tu-154 is a Soviet-era three-engine jet airliner.", "The Tupolev Tu-154 is a twin-engine jet airliner designed in the 1960s.", "The Tupolev Tu-154 is a Soviet three-engine medium-range narrow-body airliner designed in the late 1960s.", "The Tu-154 is a three-engine, long-range passenger jet airplane designed in the Soviet Union.", "The Tu-154 is a three-engine, long-range passenger aircraft produced by the Soviet Union.", "The Tupolev Tu-154 is a Soviet-built three-engine airliner.", "The Tu-154 is a Soviet-built three-engined airliner.", "The Tupolev Tu-154 is a Soviet-era three-engine medium-range narrow-body airliner designed in the 1960s.", "The Tupolev Tu-154 is a Soviet-era three-engine airliner designed in the 1960s.", "The Tupolev Tu-154 is a three-engine medium-range narrow-body airliner designed in the 1960s.", "A Tu-154 aircraft is a Soviet-era jet airliner.", "The Tupolev Tu-154 is a three-engine medium-range narrow-body airliner designed in the mid 1960s and manufactured by Tupolev.", "The Tupolev Tu-154 is a three-engine medium-range narrow-body airliner designed in the 1960s.", "The Tu-154 is a three-engine medium-range narrow-body airliner produced by the Soviet Union.", "The Tupolev Tu-154 is a three-engine medium-range narrow-body aircraft designed in the 1960s.", "The Tupolev Tu-154 is a Soviet-built three-engine airliner designed to operate on long-haul routes.", "The Tu-154 is a twin-engine, mid-range aircraft that was first introduced in the early 1970s.", "A Tu-154 is a Soviet-built three-engine jet airliner designed in the 1960s."], "737-900": ["The 737-900 is a twin-engine short-to-medium-range narrow-body airliner.", "The 737-900 is a twin-engine short- to medium-range narrowbody airliner.", "The 737-900 is an American narrow-body airliner manufactured by Boeing.", "The 737-900 is a twin-engine short- to medium-range narrowbody airliner.", "The 737-900 is a twin-engine short-to-medium-range narrow-body jet airliner.", "The 737-900 is a twin-engine, single-aisle plane that seats 162 passengers.", "The 737-900 is a twin-engine, single-aisle jetliner that was launched by Boeing in 1997.", "The 737-900 is a twin-engine, short- to medium-range commercial jet airliner.", "The Boeing 737-900 is a short-to-medium-range twin-engine jetliner.", "The 737-900 is a twin-engine short-to-medium range Boeing 737 commercial airliner.", "The 737-900 is a twin-engine short- to medium-range narrow-body jet airliner.", "A 737-900 is a twin-engine, single-aisle jetliner that can seat up to 215 passengers.", "The 737-900 is a twin-engined short- to medium-range narrowbody airliner with a capacity of 162 passengers, produced by Boeing Commercial Airplanes.", "A Boeing 737-900 is a twin-engine short- to medium-range narrow-body airliner.", "A Boeing 737-900 is a twin-engined short-to-medium-range narrowbody airliner with a capacity of up to 215 passengers.", "The 737-900 is a twin-engine short- to medium-range narrow-body jet airliner.", "The 737-900 is a twin-engined short-to-medium-range narrow-body airliner with a capacity of 162 passengers produced by Boeing Commercial Airplanes.", "A 737-900 is a twin-engine, single-aisle jetliner that is typically configured with 162 seats in a two-class layout, or 189 seats in a single-class layout.", "The 737-900 is a twin-engined short-to-medium-range narrowbody airliner with a capacity of 215 passengers in a two-class layout or 189 passengers in a single-class layout.", "A 737-900 is an airplane produced by Boeing Commercial Airplanes."], "Cessna 172": ["The Cessna 172 is a four-seat, single-engine, fixed-wing airplane produced by Cessna Aircraft Company.", "The Cessna 172 is a four-seat, single-engine, fixed-wing aircraft produced by Cessna Aircraft Company.", "The Cessna 172 aircraft is a high-wing monoplane with a tricycle landing gear.", "The Cessna 172 is a four-seat, single-engine, light airplane.", "The Cessna 172 is a four-seat, single-engine light airplane produced by Cessna Aircraft Company.", "The Cessna 172 is a four-seat, single-engine, fixed-wing aircraft produced by Cessna Aircraft Company.", "The Cessna 172 Skyhawk is a four-seat, single-engine, fixed-wing aircraft produced by Cessna Aircraft Company.", "The Cessna 172 is a four-seat, single-engine, fixed-wing aircraft produced by Cessna Aircraft Company.", "The Cessna 172 is a four-seat, single-engine, fixed-wing aircraft.", "The Cessna 172 is a four-seat, single-engine, light airplane.", "The Cessna 172 is a four-seat, single-engine, fixed-wing aircraft.", "The Cessna 172 is a four-seat, single-engine, fixed-wing aircraft made by the Cessna Aircraft Company.", "The Cessna 172 is a four-seat, single-engine, fixed-wing aircraft.", "The Cessna 172 is a four-seat, single-engine, fixed-wing aircraft.", "Cessna 172s are four-seat, single-engine, high-wing planes.", "A Cessna 172 aircraft is a four-seat, single-engine airplane.", "The Cessna 172 is a four-seat, single-engine, fixed-wing aircraft.", "The Cessna 172 is a four-seat, single-engine, high-wing airplane.", "The Cessna 172 is a four-seat, single-engine, fixed-wing aircraft.", "A Cessna 172 is a single-engine, fixed-wing aircraft with four seats and three wheels."], "737-700": ["The 737-700 is a twin-engine, narrow-body jet airliner manufactured by Boeing Commercial Airplanes.", "The 737-700 is a twin-engine, narrow-body jet airliner manufactured by Boeing Commercial Airplanes.", "The 737-700 is a twin-engine, single-aisle airplane that seats between 110 and 149 passengers.", "The 737-700 is a twin-engined short-to-medium-range narrow-body airliner with a capacity of 132 passengers.", "-Boeing 737-700\n-Wingspan: 112 ft\n-Length: 112 ft\n-Height: 41 ft\n-Weight: 171,000 lb\n-Fuel Capacity: 6,300 gallons\n-Maximum Speed.", "The 737-700 is a twin-engine, single-aisle commercial jetliner.", "The 737-700 is a twin-engined short-to-medium-range narrowbody airliner with a capacity of up to 140 passengers produced by Boeing Commercial Airplanes.", "The 737-700 is a mid-size, single-aisle commercial jetliner.", "The 737-700 is a twin-engine aircraft that can seat up to 150 passengers.", "The 737-700 is a twin-engine jet aircraft with a capacity of up to 145 passengers.", "The 737-700 is a twin-engine, short- to medium-range Boeing commercial jetliner.", "The 737-700 is a twin-engined, single-aisle commercial jet airliner developed by Boeing Commercial Airplanes, the stretched variant of the 737-600.", "Boeing 737-700 aircraft are twin-engined, short-to-medium range jet airliners.", "A 737-700 is a twin-engine commercial jetliner typically used for short-haul flights.", "Aircraft description from AirFleets.", "The 737-700 is a narrow-body aircraft produced by Boeing Commercial Airplanes.", "The Boeing 737-700 is a twin-engine aircraft typically used for short to medium-haul flights.", "The Boeing 737-700 is a twin-engine short- to medium-range narrow-body airliner.", "737-700 aircrafts seat 126 passengers and have a range of 2,975 miles.", "The 737-700 is a twin-engine, narrow-body jetliner that can seat up to 140 passengers."], "A330-200": ["The A330-200 is a twin-engined ais airliner with a widebody cabin produced by Airbus.", "The A330-200 is a twin-engine, wide-body airplane that can carry up to 293 passengers.", "The A330-200 is a twin-engine, wide-body aircraft manufactured by Airbus.", "The A330-200 aircraft has a length of 210 feet, a wingspan of 197 feet, and a height of 64 feet.", "The A330-200 is a twin-engine, wide-body aircraft manufactured by Airbus.", "The A330-200 aircraft is a medium-range, twin-engine, wide-body airliner manufactured by Airbus.", "The A330-200 is a long-range, wide-body aircraft produced by Airbus.", "The A330-200 is a twin-engine, wide-body aircraft manufactured by Airbus.", "The A330-200 aircraft is a twin-engine, wide-body aircraft that can seat up to 240 passengers.", "The A330-200 is a twin-engine, wide-body commercial aircraft.", "The A330-200 is a long-range, wide-body twin-engine jet airliner made by Airbus.", "An A330-200 is a twin-engine, wide-body airliner that can seat up to 293 passengers.", "The Airbus A330-200 is a twin-engine wide-body aircraft with two aisles and a capacity of 253 passengers in a three-class configuration or 296 passengers in a two-class configuration.", "The Airbus A330-200 is a twin-engine, long-range wide-body aircraft produced by Airbus, a division of Airbus Group.", "The A330-200 is a twin-engine, wide-body aircraft produced by Airbus.", "The A330-200 is a twin-engine, wide-body aircraft produced by Airbus.", "The A330-200 is a twin-engine wide-body Airbus Airbus A330 aircraft.", "The A330-200 is a twin-engine, wide-body aircraft with a capacity of up to 300 passengers.", "The A330-200 is a twin-engined wide-body aircraft with a capacity of up to 293 passengers.", "The A330-200 is a twin-engine, wide-body aircraft manufactured by Airbus."], "Global Express": ["The Global Express aircraft is a long-range, large-cabin business jet that can fly up to 12 hours without stopping.", "The Global Express aircraft is a long-range, high-speed business jet that can seat up to 19 passengers.", "The Global Express is a long-range business jet aircraft produced by Bombardier Aerospace.", "Global Express aircraft are long-range business jets manufactured by Bombardier Aerospace.", " interiorThe interior of the Global Express aircraft is designed to be comfortable and functional.", "The Global Express aircraft is a long-range business jet that can seat up to 19 passengers.", "The Global Express aircraft is a long-range, large-cabin business jet that can seat up to 19 passengers.", "The Global Express is a twin-engine business jet aircraft produced by Bombardier Aerospace.", ".", "The Bombardier Global Express is a large cabin, long-range business jet manufactured by Bombardier Aerospace.", "A Global Express aircraft is a large, long-range business jet that can seat up to 19 passengers.", "A Global Express aircraft is a large, long-range business jet that can fly non-stop for over 12 hours.", "The Global Express aircraft is a long range, large capacity business jet that can seat up to 19 passengers.", "A Global Express aircraft is a long-range jetliner that can seat up to 19 passengers.", "The Global Express is a long-range business jet aircraft produced by Bombardier Aerospace.", "Global Express aircraft are long-range business jets manufactured by Bombardier Aerospace.", "A Global Express aircraft is a long-range, high-speed business jet that can seat up to 19 passengers.", "A Global Express aircraft is a long-range, high-end business jet that can seat up to 18 passengers.", "A Global Express aircraft is a long-range business jet produced by Bombardier Aerospace.", "The Global Express aircraft is a long-range, large-cabin business jet that can travel at high speeds and altitudes."], "707-320": ["The 707-320 is a narrow-body aircraft that was manufactured by Boeing from 1958 to 1959.", "The 707-320 is a short- to medium-range, wide-body jet airliner.", "The 707-320 is a mid-sized, long-range jet airliner.", "The 707-320 is a short- to medium-range, narrow-body, twin-engine jetliner that was produced by Boeing Commercial Airplanes from 1958 to 1979.", "The 707-320 is a wide-body jet airliner that was produced by Boeing from 1958 to 1959.", "Aircraft descriptionThe 707-320 is a twin-engine, medium-range jetliner that was produced by Boeing from 1958 to 1960.", "The 707-320 is a medium-range, four-engined jet airliner produced by Boeing Commercial Airplanes from 1958 to 1979.", "The 707-320 is a wide-body aircraft that can seat up to189 passengers.", "The 707-320 is a mid-size, wide-body jetliner that was produced by Boeing from 1958 to 1979.", "The 707-320 is a mid-size, long-range airliner.", "A 707-320 aircraft is a medium-sized commercial jet airliner that was produced by Boeing in the 1960s.", "A 707-320 is a narrow-body, four-engine commercial jet airliner originally developed by Boeing in the late 1950s.", "The 707-320 is a commercial airliner that was introduced in 1959.", "The Boeing 707 is a four-engine commercial jet airliner developed by Boeing in the early 1950s.", "The 707-320 is a twin-engine, wide-body jetliner that was produced by Boeing between 1958 and 1960.", "The 707-320 is a mid-size, long-range airliner produced by Boeing Commercial Airplanes from 1958 to 1979.", "The 707-320 is a commercial airliner that was produced by Boeing from 1959 to 1967.", "A 707-320 is a mid-sized, twin-engine jet airliner that was manufactured by Boeing.", "The 707-320 is a medium-range, twin-engine, narrow-body jet airliner.", "A 707-320 is a mid-sized, long-range commercial jetliner that was first introduced in the early 1960s."], "Fokker 70": ["The Fokker 70 is a narrow-body, twin-engine jet airliner built by the Dutch aerospace manufacturer Fokker.", "The Fokker 70 is a twin-engined short-range regional airliner with a capacity of up to 80 passengers.", "The Fokker 70 is a narrow-body twin-engine turbofan regional airliner.", "The Fokker 70 is a narrow-body, twin-engined airliner produced by the Dutch aircraft manufacturer Fokker.", "The Fokker 70 is an airliner that was designed and produced by the Dutch aircraft manufacturer Fokker.", "The Fokker 70 is a narrow-body short-range airliner produced by the Dutch aircraft manufacturer Fokker.", "The Fokker 70 is a twin-engined short-range regional airliner with 70 seats, produced by the Dutch aircraft manufacturer Fokker.", "The Fokker 70 is a twin-engine, short-range regional jet aircraft produced by the Dutch aerospace manufacturer Fokker.", "The Fokker 70 is a twin-engined short-range regional airliner with a capacity of up to 80 passengers.", "The Fokker 70 is a twin-engine, short-range regional airliner produced by the Dutch aviation manufacturer Fokker.", "The Fokker 70 is a twin-engine short-range regional jetliner produced by the Dutch aerospace manufacturer Fokker.", "The Fokker 70 is a twin-engine, short-haul passenger jet aircraft.", "The Fokker 70 is a twin-engined short-range regional airliner with a capacity of up to 80 passengers.", "A Fokker 70 is a twin-engine, short-haul airliner produced by the Dutch aerospace manufacturer Fokker.", "The Fokker 70 aircraft is a twin-engined, short-range regional jet.", "The Fokker 70 is a twin-engine short-range regional airliner produced by the Dutch aircraft manufacturer Fokker.", "The Fokker 70 is a twin-engined short-range regional airliner with a capacity of up to 80 passengers.", "The Fokker 70 is a twin-engine short-range regional jetliner, introduced in 1993.", "The Fokker 70 is a twin-engine short-range regional jetliner produced by the Dutch manufacturer Fokker.", "A Fokker 70 is a twin-engined short-range regional airliner with a capacity of up to 85 passengers, designed by the Dutch aircraft manufacturer Fokker."], "C-47": ["The C-47 is a military transport aircraft developed from the civilian Douglas DC-3 airliner.", "The Douglas C-47 Skytrain or Dakota is a military transport aircraft developed from the civilian Douglas DC-3 airliner.", "The C-47 aircraft is a transport plane that was used extensively during World War II.", "The C-47 aircraft is a twin-engine transport aircraft that was used extensively during World War II.", "The C-47 airplane was a military transport aircraft used by the United States during World War II.", "The C-47 aircraft is a military transport plane that was used during World War II.", "The C-47 is a military transport aircraft that was developed from the civilian Douglas DC-3 airliner.", "TheDouglas C-47Skytrain or Dakota is a military transport aircraft developed from the civilianDouglas DC-3airliner.", "The C-47 is a twin-engine aircraft used for transport purposes.", "The C-47 is a twin-engine, cargo aircraft that was used extensively by the Allies during World War II.", "The aircraft has a low-mounted cantilever wing and a tricycle landing gear.", "The C-47 is a military transport aircraft that was used extensively by the Allies during World War II.", "A C-47 aircraft is a twin-engine, military transport aircraft used for carrying troops, equipment, and supplies.", "A C-47 aircraft is a twin-engine, military transport plane that was used extensively in World War II.", "The C-47 is a twin-engine, military transport aircraft used for airlift operations.", "The C-47 is a twin-engine, military transport aircraft that was developed from the civilian Douglas DC-3 airliner.", "A C-47 aircraft is a twin-engine, military transport plane that was used extensively in World War II.", "The C-47 is a twin-engine, low-wing military transport aircraft designed and built by the Douglas Aircraft Company during World War II.", "A C-47 is a military transport aircraft that was used extensively during World War II.", "The C-47 is a transport aircraft that was used extensively by the Allies during World War II."], "Saab 340": ["The Saab 340 is a twin-engine turboprop aircraft designed and manufactured by the Swedish aerospace company Saab AB.", "The Saab 340 is a Swedish twin-engine turboprop aircraft designed and initially produced by a partnership between Saab AB and Fairchild aircraft in a 65:35 ratio.", "The Saab 340 is a Swedish twin-engine turboprop aircraft designed and initially produced by a partnership between Saab AB and Fairchild Aircraft in a 65/35 ratio.", "The Saab 340 aircraft is a Swedish twin-engine turboprop passenger plane.", "The Saab 340 is a Swedish twin-engine turboprop aircraft designed and initially produced by a partnership between Saab AB and Fairchild Aircraft in a 65:35 ratio.", "The Saab 340 is a Swedish twin-engine turboprop aircraft designed and initially produced by a partnership between Saab AB and Fairchild Aircraft in 1983.", "The Saab 340 is a Swedish twin-engine turboprop aircraft designed and initially produced by a partnership between Saab AB and Fairchild Aircraft in a 65/35 ratio.", "The Saab 340 is a Swedish twin-engine turboprop aircraft designed and initially produced by Saab AB and later by Saab Aerotechnik AB.", "The Saab 340 is a Swedish twin-engine turboprop aircraft designed and initially produced by a partnership between Saab AB and Fairchild Aircraft in a 65/35 relation.", "The Saab 340 is a Swedish twin-engine turboprop aircraft designed and initially produced by a partnership between Saab AB and Fairchild Aircraft in a 65/35 ratio.", "The Saab 340 is a twin-engine turboprop aircraft designed and manufactured by the Swedish aerospace company Saab AB.", "The Saab 340 is a Swedish twin-engine turboprop aircraft designed and initially produced by a partnership between Saab AB and Fairchild Aircraft in a 65:35 ratio.", "The Saab 340 is a Swedish twin-engine turboprop aircraft designed and initially produced by a partnership between Saab AB and Fairchild Aircraft in a 65:35 ratio.", "The Saab 340 is a Swedish twin-engine turboprop aircraft designed and initially produced by a partnership between Saab AB and Fairchild aircraft in a 65:35 ratio.", "The Saab 340 is a Swedish twin-engine turboprop aircraft designed and initially produced by a partnership between Saab AB and Fairchild Aircraft in a 65/35 ratio.", "The Saab 340 is a twin-engine turboprop regional airliner with 34 seats.", "A Saab 340 is a small, twin-engine turboprop aircraft.", "The Saab 340 is a Swedish twin-engine turboprop aircraft designed and initially produced by a partnership between Saab AB and Fairchild Aircraft in a 65/35 ratio.", "The Saab 340 is a Swedish twin-engine turboprop aircraft designed and initially produced by a consortium of Saab AB and Fairchild Aircraft in a 65:35 ratio.", "The Saab 340 is a Swedish twin-engine turboprop aircraft designed and initially produced by a partnership between Saab AB and Fairchild Aircraft in a 65/35 ratio."], "Cessna 560": ["The Cessna 560 is a twin-engine corporate jet that seats up to 10 passengers.", "The Cessna 560 is a twin-engine business jet aircraft produced by Cessna.", "The Cessna 560 is a light jet aircraft that can seat up to 8 passengers.", "The Cessna 560 is a light jet aircraft with a maximum range of 2,500 miles and a maximum speed of 528 miles per hour.", "The Cessna 560 is a twin-engine, corporate jet aircraft produced by Cessna.", "The Cessna 560 is a large, twin-engine corporate jet that seats up to 12 passengers in a pressurized cabin.", "The Cessna 560 is a mid-size corporate jet with a stand-up cabin.", "The Cessna 560 is a twin-engine corporate jet aircraft produced by Cessna.", "The Cessna 560 is a twin-engine corporate jet with a range of 2,700 miles.", "The Cessna 560 is a twin-engined business jet aircraft produced by Cessna.", "A Cessna 560 is a twin-engine corporate jet aircraft produced by Cessna.", "The Cessna 560 is a twin-engine, corporate travel aircraft.", "The Cessna 560 Citation Ultra is a twin-engined corporate jet aircraft produced by Cessna.", "A Cessna 560 is a twin-engine, corporate jet aircraft produced by Cessna.", "The Cessna 560 aircraft is a twin-engine, five-seat business jet designed for high-speed, long-range travel.", "The Cessna 560XL is a state-of-the-art, large-cabin, twin-engine business jet.", "The Cessna 560 is a large aircraft with room for up to 8 passengers and 2 crew members.", "The Cessna 560 is a twin-engine corporate jet aircraft produced by Cessna.", "The Cessna 560 is a twin-engine business jet aircraft produced by Cessna.", "The Cessna 560 Citation Ultra is a twin-engine corporate jet aircraft produced by Cessna."], "747-300": ["The 747-300 is an American long-haul, wide-body jet airliner, produced by Boeing Commercial Airplanes from 1981 to 1991.", "The 747-300 is a wide-body aircraft produced by Boeing.", "The 747-300 is a wide-body airliner produced by Boeing Commercial Airplanes from 1981 to 1991.", "The 747-300 is a wide-body airplane produced by Boeing Commercial Airplanes.", "The 747-300 was a stretched version of the 747-200, with a longer upper deck.", "The 747-300 is an extended-range, wide-body aircraft that was introduced in 1983.", "The 747-300 is a jumbo jet aircraft that was manufactured by Boeing from 1983 to 1992.", "The 747-300 is a wide-body passenger airliner produced by Boeing Commercial Airplanes.", "The 747-300 is a wide-body jet airliner manufactured by Boeing Commercial Airplanes.", "The 747-300 is a wide-body airliner produced by Boeing Commercial Airplanes.", "The 747-300 is a wide-body aircraft that can seat up to 416 passengers.", "The 747-300 is a long-range, wide-body airliner that was first introduced in 1980.", "The 747-300 is a wide-body aircraft produced by Boeing Commercial Airplanes.", "The 747-300 is a wide-body airliner that was produced by Boeing Commercial Airplanes from 1983 to 1992.", "A 747-300 is a wide-body airliner, typically configured with 350 seats in a three-class cabin and a maximum range of 5,650 miles.", "The 747-300 is a wide-body, long-range jet airliner that was manufactured by Boeing.", "The 747-300 is a stretched version of the 747-200, and was introduced in 1983.", "A 747-300 is a wide-body Boeing 747 jetliner that was manufactured between 1980 and 1991.", "A 747-300 is a jumbo jet aircraft with a stretched upper deck.", "A 747-300 is a wide-body jet airliner produced by Boeing Commercial Airplanes."], "A340-600": ["The A340-600 is a long-range, wide-body commercial airliner produced by Airbus.", "The A340-600 is a long-range, wide-body airliner produced by Airbus.", "The A340-600 is a wide-body aircraft produced by Airbus.", "The Airbus A340-600 is a long-range, wide-body airliner made by Airbus.", "The Airbus A340-600 is a wide-body airliner produced by Airbus.", "The A340-600 is a long-range, four-engine jet airliner manufactured by Airbus.", "The A340-600 is a long-range passenger jet aircraft developed by the European aerospace manufacturer Airbus.", "The Airbus A340-600 is a four-engined long-range wide-body airliner with a capacity of up to 375 passengers produced by the European manufacturer Airbus.", "The A340-600 is a long-range, wide-body four-engine jet airliner manufactured by Airbus.", "The A340-600 is a wide-body aircraft produced by Airbus.", "The A340-600 is a long-range, wide-body jetliner that was developed by Airbus.", "The A340-600 is a long-range, wide-body passenger airliner manufactured by Airbus.", "An A340-600 is a twin-aisle, wide-body commercial airliner with a design range of 14,800 km (8,000 nmi; 9,200 mi).", "The A340-600 is a long-range, wide-body commercial airliner manufactured by Airbus.", "The A340-600 is a long-range, wide-body commercial passenger airliner produced by Airbus.", "An A340-600 is a four-engine wide-body commercial airliner produced by Airbus.", "The A340-600 is an aircraft from the A340 family.", "The Airbus A340-600 is a long-range, wide-body commercial passenger airliner manufactured by Airbus Industrie, a consortium of European aerospace companies.", "The A340-600 is a long-range, wide-body jet airliner manufactured by Airbus.", "The A340-600 is an extended range, wide-body four-engine jet airliner manufactured by Airbus."], "767-200": ["The 767-200 is a twin-engined medium-range wide-body airliner produced by Boeing Commercial Airplanes.", "The 767-200 is a twin-engine, wide-body airliner produced by Boeing Commercial Airplanes.", "The 767-200 aircraft is a twin-engine, wide-body plane that can seat up to 375 passengers.", "The 767-200 is a twin-engined narrow-body aircraft with a capacity of 162 passengers and a range of 5,235 miles.", "The 767-200 aircraft model is a twin-engine, mid-size widebody jet airliner that was first introduced in 1982 by Boeing.", "The 767-200 is a twin-engined, wide-body airliner produced by Boeing Commercial Airplanes.", "The 767-200 is a twin-engine, wide-body jetliner that was introduced in 1982.", "The 767-200 is a mid-size, long-range twin-engine jet airliner that was introduced in 1982.", "The 767-200 is a wide-body twin-engine jet airliner that was manufactured by Boeing Commercial Airplanes.", "The 767-200 is a twin-engined airliner with a capacity of 162 passengers in a two-class layout, or 181 passengers in a one-class layout.", "The Boeing 767 is a mid-size, wide-body twin-engine jet airliner built by Boeing Commercial Airplanes.", "The 767-200 is a narrow-body twin-engine jet airliner that was produced by Boeing Commercial Airplanes from 1982 to 2004.", "The 767-200 is a twin-engined aircraft with a capacity of between 181 and 218 passengers.", "The 767-200 is a twin-engined, wide-body jetliner that was introduced in 1982 by Boeing Commercial Airplanes.", "The 767-200 is a mid-size, twin-engine jetliner that was first introduced in 1982.", "The 767-200 is a twin-engined, short- to medium-range commercial airliner.", "The 767-200 is a twin-engined short- to medium-range airplane that was introduced in 1982.", "The 767-200 is a twin-engine, wide-body airliner produced by Boeing Commercial Airplanes.", "The 767-200 is a twin-engined, wide-body airliner produced by Boeing Commercial Airplanes.", "The 767-200 is a twin-engined medium-range airliner produced by Boeing Commercial Airplanes."], "CRJ-200": ["The CRJ-200 aircraft is a regional jet that can seat up to 50 passengers.", "The CRJ-200 is a regional jet that seats up to 50 passengers.", "The CRJ-200 aircraft is a small, single-aisle jetliner that can seat up to 50 passengers.", "The CRJ-200 is a regional jet designed and manufactured by Bombardier Aerospace.", "The Bombardier CRJ-200 is a twin-engined, short-range regional jetliner with 50 seats, produced by Canadian manufacturer Bombardier Aerospace.", "The CRJ-200 aircraft is a regional jet that was manufactured by Bombardier.", "The CRJ-200 is a 76-seat aircraft that was designed to replace the older, smaller 50-seat Bombardier Challenger 600 series aircraft.", "The CRJ-200 is a twin-engine regional jet that was introduced in 1991 by Canadian company Bombardier.", "The CRJ-200 is a medium-range jet airliner manufactured by Bombardier Aerospace.", "The CRJ-200 is a twin-engine, regional jet aircraft manufactured by Bombardier Aerospace.", "The CRJ-200 aircraft is a twin-engine, regional jet that seats up to 50 passengers.", "The CRJ-200 is a regional airliner manufactured by Bombardier.", "The CRJ-200 aircraft is a small, twin-engine jet.", "A CRJ-200 aircraft is a Canadair Regional Jet 200 plane.", "The CRJ-200 aircraft is a aircraft that can seat 50-70 people.", "A CRJ-200 is a commercial jetliner manufactured by Bombardier Aerospace.", "The CRJ-200 is a twin-engine, regional jet aircraft that can seat up to 50 passengers.", "The CRJ-200 is a regional jet that is designed to seat 50 passengers.", "The CRJ-200 is a small jet aircraft typically used for short-haul flights.", "A CRJ-200 aircraft is a regional jet that seats 50 passengers."], "Dornier 328": ["The Dornier 328 is a twin-engine turboprop-powered commuter airliner.", "The Dornier 328 is a twin-engine turboprop aircraft designed and built by the German company Dornier Luftfahrt GmbH.", "The Dornier 328 aircraft is a twin-engined turboprop-powered commuter airliner.", "The Dornier 328 is a twin-engine turboprop-powered regional airliner.", "The Dornier 328 is a twin-engined turboprop aircraft designed and built by the German manufacturer Dornier Flugzeugwerke.", "The Dornier 328 is a twin-engined turboprop aircraft, designed and built by the German company Dornier Flugzeugwerke.", "The Dornier 328 is a twin-engine turboprop aircraft that was manufactured by Dornier Flugzeugwerke.", "The Dornier 328 aircraft is a light, twin-engine turboprop aircraft.", "The Dornier 328 aircraft is a twin-engine turboprop aircraft.", "The Dornier 328 is a twin-engined turboprop passenger plane.", "The Dornier 328 is a 19-seat, twin-engine turboprop-powered regional airliner.", "The 328 is a twin-engine turboprop-powered commuter airliner.", "The Dornier 328 is a twin-engine turboprop regional airliner.", "The DO328 aircraft is a high-wing, twin-engine, turboprop-powered plane.", "The Dornier 328 is a twin-engined turboprop aircraft, capable of carrying up to 32 passengers or 9,000lbs of cargo.", "The Dornier 328 is a twin-engine turboprop aircraft, designed and produced by the German company Dornier Flugzeugwerke.", "The Dornier 328 aircraft is a twin-engine turboprop-powered regional airliner.", "The Dornier 328 is a turboprop-powered commuter aircraft.", "A Dornier 328 is a twin-engine turboprop regional airliner.", "The Dornier 328 aircraft is a twin-engine turboprop-powered regional airliner."], "Fokker 100": ["The Fokker 100 is a short-range, twin-engined jet airliner from the Dutch manufacturer Fokker.", "The Fokker 100 is a regional jet that seats up to 100 passengers.", "The Fokker 100 aircraft is a short-ranged, twin-enginedjet airliner.", "The Fokker 100 is a twin-engined short-haul passenger aircraft.", "The Fokker 100 is a twin-turbofan jet airliner, designed and built by the Dutch aircraft manufacturer Fokker.", "The Fokker 100 is a twin-engined regional jetliner produced by the Dutch aerospace manufacturer Fokker, now part of the United Aircraft Corporation.", "Fokker 100 aircraft are twin-engined, short-haul airliners.", "The Fokker 100 is a twin-engined short-haul jet airliner from the Dutch manufacturer Fokker, now part of Airbus.", "The Fokker 100 is a twin-engined short-haul jetliner, introduced in 1986 as an upscale 100-seat version of the earlier Fokker F28 Fellowship.", "The Fokker 100 is a twin-engined, short-range regional jetliner introduced in 1986 by the now-defunct Fokker Aircraft Company.", "The Fokker 100 is a twin-engine jet airliner with a capacity of 100 passengers and a range of 2,500 miles.", "The Fokker 100 is a Dutch twin-turbofan regional airliner.", "The Fokker 100 is a twin-engine, short-range regional jetliner, introduced in 1987.", "The Fokker 100 is a twin-engined short-range regional jetliner, introduced in the late 1980s.", "The Fokker 100 is a twin-turboproppowered airliner, designed by Fokker, formerly of the Netherlands.", "The Fokker 100 is a twin-engined short-range regional jetliner, introduced in 1986.", "The Fokker 100 is a regional airliner that was designed and manufactured by Fokker, now part of Airbus.", "The Fokker 100 is a twin-engined short-haul jet airliner from the Dutch manufacturer Fokker, now part of Airbus.", "The Fokker 100 is a twin-engine, short-range jet air liner.", "The Fokker 100 is a medium-sized, twin-turbofan jet airliner from the Dutch manufacturer Fokker."], "A340-200": ["The A340-200 aircraft is designed for long-haul flights and offers a variety of features to suit the needs of passengers and crew.", "The A340-200 is a wide-body four-engine commercial passenger aircraft produced by Airbus.", "The A340-200 aircraft is a long-range, twin-engine plane that was developed by Airbus.", "The A340-200 is a four-engined long-range wide-body airliner with a capacity of up to passengers in a two-class configuration.", "The A340-200 aircraft was produced by Airbus between 1993 and 1997.", "The A340-200 is a long-range, wide-body commercial passenger jet airliner that was developed by Airbus.", "The A340-200 is a long-range, wide-body commercial passenger jet airliner that was developed and produced by Airbus.", "The A340-200 is a four-engined commercial passenger jet with a cruising speed of 890km/h.", "The A340-200 aircraft is a wide-body aircraft that can seat up to 270 passengers.", "The A340-200 is a long-range, wide-body commercial airliner that was produced by Airbus.", "An A340-200 is a long-range, four-engine jet airliner manufactured by Airbus Industries.", "The A340-200 is a twin-engine, long-range commercial passenger jet airliner that was developed and produced by the European aerospace company Airbus.", "The A340-200 is a long-range, wide-body commercial passenger jet airliner that was developed by Airbus.", "The A340-200 is a long-range, wide-body commercial airliner produced by Airbus.", "The A340-200 is a wide-body Airbus aircraft with four engines.", "The A340-200 is a twin-engine, long-range commercial airliner produced by the European aerospace company Airbus.", "The A340-200 was a passenger aircraft that was in service with several airlines between 1993 and 2014.", "The A340-200 is a long-range, four-engine wide-body commercial passenger jet airliner with a capacity of up to 293 passengers.", "The A340-200 was an aircraft produced by Airbus.", "An A340-200 is a long-range, wide-body jet airliner that was produced by Airbus."], "EMB-120": ["The EMB-120 is a twin-engine, 30-seat turboprop regional airliner.", "The EMB-120 is a small, twin-engine turboprop passenger plane.", "The EMB-120 aircraft is a twin-engine turboprop passenger plane typically used for short-haul flights.", "The EMB-120 is a twin-engine turboprop aircraft manufactured by Embraer.", "The EMB-120 is a twin-engine, 30-seat turboprop regional airliner.", "The Embraer EMB-120 Brasilia is a twin-turboprop commuter aircraft with a Pressurized cabin designed to seat 30 passengers.", "The EMB-120 is a 30-passenger turboprop aircraft manufactured by Embraer of Brazil.", "The EMB-120 is a twin-engine commuter turboprop aircraft designed and manufactured by Embraer of Brazil.", "The EMB-120 is a twin-engine turboprop regional airliner produced by Embraer of Brazil.", "The EMB-120 aircraft is a Brazilian-made twin-engine turboprop commuter airliner.", "An EMB-120 is a twin-engine regional turboprop airliner produced by Embraer, a Brazilian aerospace company.", "The Embraer ERJ-120 is a regional jet manufactured by Brazilian aerospace manufacturer Embraer.", "The Embraer EMB 120 Brasilia is a twin-turboprop commuter aircraft produced by the Brazilian manufacturer Embraer.", "The EMB-120 aircraft is a twin-engine, 30-passenger turboprop aircraft manufactured by Embraer of Brazil.", "The EMB-120 aircraft is a 30-seat twin-engine turboprop commuter airliner.", "The EMB-120 is a twin-engine Brazilian turboprop passenger aircraft.", "The EMB-120 Brasilia is a twin-engine turboprop passenger aircraft designed and manufactured in Brazil by Embraer.", "The EMB-120 is a twin-engine turboprop regional airliner manufactured by Embraer.", "The EMB-120 is a 30-seat twin-turboprop airliner produced by Embraer, a Brazilian aerospace company.", "The EMB-120 is a twin-engined, 30-seat corporate aircraft manufactured by Embraer of Brazil."], "A300B4": ["The A300B4 is a twin-engine, wide-body aircraft that was first introduced in 1972.", "The A300B4 is a twin-engine, wide-body jet airliner that was first introduced in 1974.", "The A300B4 is a wide-body airliner produced by Airbus.", "The A300B4 is a wide-body twin-engine jet airliner.", "The A300B4 is a commercial aircraft produced by Airbus.", "The A300B4 is a twin-engine, wide-body aircraft that was first introduced in 1974.", "The A300B4 is a twin-engine, wide-body aircraft produced by Airbus.", "It is a twin-engine, wide-body aircraft that can carry up to 250 passengers.", "The A300B4 is a twin-engine, wide-body airliner produced by Airbus Industrie, then a consortium of European aerospace manufacturers.", "The A300B4 is a twin-engine wide-body aircraft that was manufactured by Airbus.", "The A300B4 was a twin-engined, wide-body aircraft produced by Airbus Industries.", "The A300B4 is a wide-body aircraft produced by Airbus Industries.", "The A300B4 is a wide-body twin-engine jet airliner that was developed and manufactured by Airbus.", "The A300B4 is a twin-engine, wide-body Airbus airliner.", "The A300B4 is a twin-engined, wide-body aircraft produced by Airbus.", "The Airbus A300B4 is a full-length double-deck wide-body twin-engine jet airliner which was produced by Airbus Industrie, then a consortium of European aerospace manufacturers.", "The A300B4 is a twin-engine jetliner that was originally manufactured by Airbus.", "The A300B4 is a long-range, wide-body airliner manufactured by Airbus Industrie.", "The A300B4 is a French-made twin-engine, wide-body airliner.", "The A300B4 is a flight simulator that is used to train pilots how to fly an Airbus A300 aircraft."], "Yak-42": ["The Yakovlev Yak-42 is a large Soviet/Russian three-engined jet airliner designed in the 1970s.", "The Yak-42 is a Soviet three-engined commercial aircraft designed in the 1970s.", "The Yak-42 is a Soviet-built jetliner that can seat up to 132 passengers.", "The Yak-42 is a Soviet-built jetliner that can seat up to 120 passengers.", "The Yak-42 is a Soviet-built jetliner that first flew in 1975.", "The Yak-42 is a Soviet-designed and -built jetliner and transport aircraft.", "The Yak-42 is a twin-engined short-range passenger jet aircraft.", "The Yak-42 is a twin-engine jet airliner that was designed and produced in the Soviet Union.", "The Yak-42 is a trijet aircraft designed in the Soviet Union.", "The Yakovlev Yak-42 is a Soviet three-engined regional jet powered by General Electric CF6 engines.", "The Yak-42 is a Soviet/Russian twin-engined regional jet aircraft designed by the Yakovlev design bureau.", "The Yak-42 is a Soviet transport aircraft designed in the 1970s.", "The Yak-42 is a Soviet/Russian three-engined regional jet aircraft.", "A Yak-42 is a twin-engine turboprop passenger airplane with a capacity of 100 to 140 passengers.", "A Yak-42 aircraft is a twin-engined turboprop passenger plane.", "The Yak-42 is a Soviet-designed and built twin-engined jet airliner.", "The Yak-42 is a Soviet three-engined regional transport aircraft designed by the Yakovlev design bureau.", "The Yak-42 is a Soviet/Russian trijet regional airliner.", "The Yakovlev Yak-42 is a Russian trijet regional airliner, first flown in 1975.", "A Yak-42 is a Soviet three-engined regional jet aircraft designed by the Yakovlev Design Bureau."], "F-16A/B": ["The F-16A/B is a single-engine, supersonic, highly maneuverable, tactical fighter aircraft.", "The F-16A/B is a single-engine, supersonic multi-role fighter aircraft.", "The F-16A/B is a single-engine, supersonic, multi-role fighter aircraft.", "The F-16A/B is a single-engine, multi-role fighter aircraft.", "The F-16A/B is a single-seat, twin-engine fighter aircraft.", "The General Dynamics F-16 Fighting Falcon is a single-engine supersonic multirole fighter aircraft originally developed by General Dynamics for the United States Air Force (USAF).", "The F-16A/B is a single-engine, multirole fighter aircraft.", "The F-16A/B is a single-engine, supersonic, highly maneuverable, tactical fighter aircraft.", "The F-16A/B aircraft is a twin-engine, single-seat fighter that was first introduced in 1976.", "The F-16A/B is a single-engine, supersonic, highly maneuverable, multi-role fighter aircraft.", "The General Dynamics (now Lockheed Martin) F-16A/B was an American single-engine, supersonic multirole fighter aircraft, designed as an air superiority day fighter in the late 1970s.", "The F-16A/B is a single-engine, supersonic, fighter aircraft.", "The F-16A/B is a single-engine, supersonic multirole fighter aircraft.", "The F-16A/B is a twin-engine, supersonic fighter aircraft.", "The F-16A/B is a twin-engine, single-seat fighter aircraft.", "The F-16A/B is a single-engine, supersonic fighter aircraft that was first introduced in 1978.", "The F-16A/B aircraft is a fighter plane that was first introduced in the early 1980s.", "F-16A/B aircraft are single-engine, supersonic multirole fighters.", "The F-16A/B aircraft is a single-engine, supersonic fighter aircraft.", "F-16A/B aircraft are designed to provide air dominance, multi-role, and all-weather capabilities."], "ERJ 145": ["The ERJ 145 is a short-range, single-aisle jet airliner produced by Embraer, a Brazilian aerospace company.", "The ERJ 145 is an American-built twin-engine regional jet aircraft.", "The ERJ 145 is a regional jet that was designed and manufactured by Embraer, a Brazilian aircraft company.", "The Embraer ERJ 145 is a twin-engine regional jet manufactured by Brazilian company Embraer.", "The ERJ 145 is a twin-engine regional jet that was designed and manufactured by Embraer, a Brazilian aerospace company.", "The ERJ 145 aircraft is a regional jet that seats up to 50 passengers.", "The ERJ 145 is a twin-engined regional jet manufactured by Embraer.", "The ERJ 145 aircraft is a twin-engine regional jet that seats up to 50 passengers.", "The ERJ 145 aircraft is a twin-engine regional jet that can seat up to 50 passengers.", "The ERJ 145 is a twin-engine regional jet that was designed and built by Embraer, a Brazilian aerospace conglomerate.", "An ERJ 145 is a small, twin-engine regional jet that typically seats 44 passengers in a two-class configuration.", "The ERJ 145 is a regional jet that was manufactured by Embraer, a Brazilian aerospace company.", "The ERJ 145 is a twin-engine regional jet aircraft that can seat up to 50 passengers.", "The ERJ 145 is a twin-engine regional jet that was designed and manufactured by Embraer, a Brazilian aerospace company.", "An ERJ 145 aircraft is a twin-engine regional jet that seats up to 50 passengers.", "An ERJ 145 aircraft is a regional jet that can seat up to 50 passengers.", "An ERJ 145 aircraft is a twin-engine regional jet that can seat up to 50 passengers.", "The ERJ 145 aircraft is a twin-engine regional jet that can seat up to 50 passengers.", "The ERJ 145 is a twin-engine regional jet that was designed and manufactured by Embraer, a Brazilian aerospace company.", "The ERJ 145 is a twin-engine jet aircraft manufactured by Embraer, a Brazilian aerospace company."], "ATR-42": ["The ATR 42 is a twin-turboprop, short-haul regional airliner developed and produced in France and Italy by ATR, a consortium formed by A\u00e9rospatiale of France and Aeritalia of Italy.", "The ATR-42 is a twin-turboprop, short-haul regional airliner designed and manufactured in France and Italy by ATR.", "The ATR-42 is a twin-turboprop, short-haul regional airliner built in France and Italy by ATR (Aerei da Trasporto Regionale or Avions de transport r\u00e9gional), a.", "The ATR-42 is a twin-turboprop, short-haul regional airliner developed and produced in France and Italy by ATR.", "The ATR-42 is a twin-turboprop regional airliner built in France and Italy by ATR.", "The ATR-42 is a twin-turboprop, short-haul regional airliner built in France and Italy by ATR (Aerei da Trasporto Regionale or Avions de transport r\u00e9gional), a.", "The ATR-42 is a twin-turboprop, short-haul regional airliner built in France and Italy by ATR.", "The ATR 42 is a twin-turboprop, short-haul regional airliner developed and manufactured in Franco-Italian partnership by aircraft manufacturers ATR and A\u00e9rospatiale.", "The ATR 42 is a twin-turboprop, short-haul regional airliner built in France and Italy by ATR (Aerei da Trasporto Regionale or Avions de transport r\u00e9gional), a joint.", "The ATR 42 aircraft is a twin-engine turboprop regional passenger plane.", "The ATR-42 is a twin-turboprop, short-haul regional airliner developed and produced in France and Italy by aircraft manufacturer ATR.", "ATR-42 is a twin-turboprop aircraft.", "The ATR-42 is a twin-turboprop, short-haul regional airliner built in France and Italy by ATR (Aerei da Trasporto Regionale or Avions de transport r\u00e9gional), a.", "The ATR-42 is a twin-turbo prop aircraft that seats up to 40 passengers and is commonly used for short-haul flights.", "An Aerospatiale/Alenia ATR 42 is a twin-turboprop, short-haul regional airliner developed and produced in France and Italy.", "The ATR-42 is a twin-turboprop, short-haul regional airliner built in France and Italy by ATR.", "The ATR-42 is a twin-turboprop, short-haul regional airliner developed and produced in Western Europe jointly by French aircraft manufacturer ATR and Italian aircraft manufacturer Alenia Aeronautica (today Leonardo S.", "An ATR-42 is a twin-turboprop regional airliner produced by the French-Italian aircraft manufacturer ATR.", "The ATR-42 is a twin-turboprop, short-haul regional airliner developed and manufactured in France and Italy by ATR.", "The ATR-42 is a twin-turboprop, short-haul regional airliner built in France and Italy."], "Falcon 2000": ["The Falcon 2000 is a twin-engine business jet aircraft produced by the French manufacturer Dassault Aviation.", "The Falcon 2000 is a twin-engine business jet developed and manufactured by Dassault Aviation in France.", "The Falcon 2000 is a twin-engine business jet airplane produced by Falcon Jet, a subsidiary of Dassault Aviation.", "The Falcon 2000 is a twin-engine business jet designed and built by Dassault Aviation.", "The Dassault Falcon 2000 is a twinjet corporate jet aircraft produced by Dassault Aviation.", "The Falcon 2000 is a twin-engine corporate jet aircraft produced by the French manufacturer Dassault Aviation.", "The Falcon 2000 is a twin-engine business jet aircraft produced by the French manufacturer Dassault Aviation.", "The Falcon 2000 is a twin-engine corporate jet aircraft developed by Dassault Aviation of France.", "The Falcon 2000 is a twin-engine, long-range business jet manufactured by Dassault Aviation, a French aerospace company.", "The Falcon 2000 is a twin-engine corporate jet aircraft produced by Gulfstream Aerospace.", "The Falcon 2000 is a business jet developed and manufactured by Dassault Aviation.", "The Falcon 2000 is a twin-engine business jet aircraft produced by the French-American manufacturer Dassault Aviation.", "The Falcon 2000 is a twin-engine business jet aircraft produced by Dassault Aviation.", "The Falcon 2000 is a twin-engine corporate jet aircraft produced by Dassault Aviation.", "A Falcon 2000 is a mid-size jet that can seat up to ten passengers.", "The Falcon 2000 is a twin-engine business jet produced by Dassault Aviation.", "The Falcon 2000 is a twin-engine business jet that seats up to nine passengers.", "The Falcon 2000 aircraft is a twin-engine business jet that can seat up to 12 people.", "The Falcon 2000 is a business jet aircraft produced by Dassault Aviation.", "The Falcon 2000 is a business jet aircraft produced by the French manufacturer Dassault Aviation."], "Model B200": ["The Model B200 is a light, twin-engine turboprop airplane that seats up to nine passengers and two crew members.", "The Model B200 is a light, single-engine turboprop aircraft.", "The Model B200 is a twin-engine, turbo-prop aircraft that can seat up to nine passengers.", "The Model B200 is a twin-engine, turboprop airplane that can seat up to ten passengers.", "The Model B200 is a single-engine turboprop aircraft designed and manufactured by Beechcraft, a subsidiary of Textron Aviation.", "The Model B200 is a twin-engine airplane that seats up to 10 passengers and has a range of over 2,500 miles.", "The Beechcraft Model 200 Super King Air is a twin-turboprop utility and business aircraft produced by Beechcraft.", "The Model B200 is a twin-engine turboprop aircraft manufactured by Beechcraft.", "?The Model B200 is a light single-engined turboprop aircraft designed and manufactured by Beechcraft.", "The B200 is a twin-engine turboprop aircraft manufactured by Beechcraft.", "The Model B200 is a twin-engine, turboprop aircraft manufactured by Beechcraft.", "The B200 is a turboprop-powered light utility aircraft produced by Beechcraft.", "The B200 is a light, twin-engine turboprop aircraft.", "The Model B200 is a single-engine turboprop aircraft manufactured by Beechcraft.", "The Model B200 is a twin-engine turboprop aircraft manufactured by Beechcraft.", "The Model B200 is a single-engine, six-seat, light business jet aircraft produced by Beechcraft.", "The Beechcraft Model 200 Super King Air is a twin-engined turboprop corporate aircraft with a pressurized cabin produced by Beechcraft.", "The Model B200 is a twin-engine turboprop aircraft manufactured by Beechcraft.", "The Model B200 is a twin-engine turboprop aircraft manufactured by Beechcraft.", "The Model B200 is a single-engine, high-performance turboprop aircraft."], "777-200": ["The 777-200 is a wide-body twin-engine jet airliner developed and manufactured by Boeing Commercial Airplanes.", "The Boeing 777-200 is a twin-engine long-range commercial airliner.", "The 777-200 is a twin-engine commercial jet airliner that was introduced in 1995.", "The Boeing 777-200 is a long-range, wide-body twin-engine airliner developed and manufactured by Boeing Commercial Airplanes.", "The 777-200 is a twin-engine jet airliner developed by Boeing Commercial Airplanes.", "The 777-200 is a twin-engine aircraft that seats up to 284 passengers and has a range of 7,370 kilometers.", "The 777-200 is a long-range, wide-body twin-engine jet airliner developed and manufactured by Boeing Commercial Airplanes.", "The 777-200 is a two-engine, wide-body commercial airliner that was introduced in 1995 by Boeing.", "The 777-200 is a long-range, wide-body twin-engine jet airliner developed and manufactured by Boeing Commercial Airplanes.", "The 777-200 is a long-range, wide-body twin-engine airliner developed and manufactured by Boeing Commercial Airplanes.", "The 777-200 is a mid-size, long-range twin-engine jet airliner developed and manufactured by Boeing Commercial Airplanes.", "A 777-200 is a large twin-engine jet airliner with a capacity of 300-350 passengers.", "A 777-200 is a twin-engine, wide-body commercial airliner.", "The 777-200 is a twin-engine, wide-body airliner produced by Boeing Commercial Airplanes.", "The Boeing 777-200 is a twin-engine widebody aircraft with a capacity of 300 passengers.", "The Boeing 777-200 is a wide-body airliner produced by Boeing Commercial Airplanes.", "A 777-200 aircraft is a large twin-engine commercial plane used for long-distance flights.", "The 777-200 is a wide-body airliner produced by Boeing Commercial Airplanes.", "The Boeing 777-200 is a twin-engine wide-body airliner with a capacity of up to 300 passengers, depending on the cabin configuration.", "The Boeing 777-200 is a long-range, wide-body twin-engine jet airliner developed and manufactured by Boeing Commercial Airplanes."], "ATR-72": [".", "The ATR-72 aircraft is a twin-engine, short-haul regional airliner.", "The ATR-72 is a twin-engined turboprop short-haul regional airliner.", "The ATR-72 is a twin-engine turboprop short-haul regional airliner manufactured by the French-Italian aircraft manufacturer ATR.", "The ATR-72 aircraft is a twin-engine, short-haul regional turboprop airplane.", "The ATR-72 is a twin-engine turboprop short-haul regional airliner manufactured by the French-Italian aircraft manufacturer ATR.", "The ATR-72 is a twin-engine turboprop, short-haul regional airliner manufactured by the French-Italian aircraft manufacturer ATR.", "The ATR 72 is a twin-engine turboprop short-haul regional airliner manufactured by the French-Italian aircraft manufacturer ATR.", "The ATR-72 is a twin-engine turboprop, short-haul regional airliner manufactured by the French-Italian aircraft manufacturer ATR.", "The ATR 72 is a twin-engine turboprop short-haul regional airliner manufactured by the French-Italian aircraft manufacturer ATR.", "An ATR 72 is a twin-engine turboprop aircraft manufactured by the French-Italian aircraft manufacturer ATR.", "The ATR-72 aircraft is a twin-engine turboprop commuter plane.", "The ATR-72 is a twin-engine turboprop short-haul regional airliner manufactured by the French-Italian aircraft manufacturer ATR.", "The ATR-72 is a twin-engine turboprop, short-haul regional airliner developed and produced in France and Italy by ATR, a joint venture formed by French aerospace company A\u00e9rospatiale and Italian aviation conglomerate.", "The ATR-72 is a twin-engine turboprop regional airliner manufactured by the French-Italian aircraft manufacturer ATR.", "An ATR-72 is a twin-engine turboprop aircraft.", "An ATR-72 aircraft is a twin-engine, short-haul regional airliner developed and manufactured in France and Italy.", "The ATR-72 is a twin-engine turboprop, short-haul regional airliner manufactured by the French-Italian aircraft manufacturer ATR.", "An ATR-72 aircraft is a twin-engine turboprop short-haul regional airliner manufactured by the French-Italian aircraft manufacturer ATR.", "ATR-72 aircraft are twin-engine, turboprop aircrafts that seat up to 74 people."], "DC-9-30": ["The DC-9-30 is a twin-engine jetliner that was introduced in 1965.", "The DC-9-30 is a twin-engine, Short Take-Off and Landing (STOL), commercial jet airliner developed by McDonnell Douglas.", "The DC-9-30 is a twin-engine short-range narrow-body airliner produced by the American aircraft manufacturer McDonnell Douglas.", "The DC-9-30 is a twin-engine, single-aisle jetliner that was first delivered in 1965.", "The DC-9-30 is a mid-range, twin-engine jet airliner that was first manufactured by the McDonnell Douglas corporation in 1965.", "The McDonnell Douglas DC-9-30 is a twin-engined, single-aisle jet airliner.", "The DC-9-30 is a twin-engine jet airliner with a capacity of up to 145 passengers.", "The McDonnell Douglas DC-9-30 is a twin-engine, single-aisle jet airliner.", "The DC-9-30 is a narrow body, twin-engine jet airliner that was first introduced in 1965.", " cabinThe cabin of the DC-9-30 is designed to seat up to 132 passengers in a two-class layout, or up to 149 passengers in a single-class layout.", "A DC-9-30 aircraft is a twin-engine, narrow-body jet airliner that was manufactured by the McDonnell Douglas Corporation.", "A DC-9-30 is a twin-engine, single-aisle jet airliner.", "A DC-9-30 is a twin-engine, single-aisle jet airliner that was first manufactured by the McDonnell Douglas Corporation in 1965.", "A DC-9-30 is a twin-engine, single-aisle jet airliner manufactured by McDonnell Douglas.", "The McDonnell Douglas DC-9-30 is a twin-engined short-range narrowbody airliner produced from 1965 to 1982.", "The McDonnell Douglas DC-9 is a twin-engine, single-aisle jet airliner.", "The McDonnell Douglas DC-9 is a narrow-body twin-engine jet airliner.", "The McDonnell Douglas DC-9-30 is a short-range, twin-engine jet airliner that was first introduced in 1965.", "The DC-9-30 is a short-range, twin-engine jet airliner that was manufactured by the McDonnell Douglas company.", "The DC-9-30 is a twin-engine narrow-body jet airliner with a capacity of up to 120 passengers."], "DR-400": ["The DR-400 is a light aircraft manufactured by Soci\u00e9t\u00e9 Fran\u00e7aise de l'Aviation et de Construction A\u00e9ronautique (later known as Robin Aviation).", "The DR-400 is a light aircraft produced by the French manufacturer Robin Aircraft.", "The DR-400 is a French light aircraft designed and built by Robin Aircraft.", "The DR-400 is a light aircraft produced by Robin Aircraft.", "The DR-400 is a light, single-engine airplane produced by the French aircraft manufacturer Robin Aircraft.", "The DR-400 is a single-engine airplane that typically seats four people.", "The DR-400 aircraft is a light, single-engine, four-seat airplane.", "The DR-400 is a single-engine, four-seat light aircraft.", "The DR-400 is a four-seat light aircraft marketed as both a touring aircraft and a flight training aircraft.", " cabinThere is room for four people in the DR-400 aircraft cabin.", "A DR-400 is a light aircraft typically used for training and personal flying.", "The DR-400 is a kit plane that can be built at home.", "The DR-400 is a light aircraft produced by the French manufacturer Gibault-Aviation.", "The DR-400 is a light aircraft produced by the French aircraft manufacturer Robin Aircraft.", " The DR-400 is a light, four-seat single-engine utility aircraft produced by Robin Aircraft.", "A DR-400 is a four-seat light aircraft designed and built in France.", "The DR-400 is a single-engine, light aircraft designed and built by Robin Aircraft.", "The DR-400 is a four-seat, single-engine light aircraft produced by the French aircraft manufacturer Robin Aircraft.", "The DR-400 is a light, single-engine, four-seat aircraft designed for general aviation.", "The Dornier Do\u00a0400\u00a0was a\u00a0twin-engined\u00a0light\u00a0bomber\u00a0and reconnaissance aircraft produced by the\u00a0German\u00a0company\u00a0Dornier Flugzeugwerke."], "757-300": ["The 757-300 is a narrow-body aircraft with a length of 183 feet 9 inches (56.", "The 757-300 is a two-engine commercial passenger jet airplane.", "The 757-300 is a twin-engine, long-range commercial airliner.", "The 757-300 is a twin-engine, long-range airliner that was introduced in 1983.", "The 757-300 is a twin-engined short-to-medium-range aircraft.", "The 757-300 is a narrow-body aircraft equipped with winglets and is powered by two engines.", "The 757-300 is a twin-engine, long-range narrow-body aircraft produced by Boeing Commercial Airplanes.", "The 757-300 is a wide-body aircraft that was produced by Boeing as a higher-capacity version of the 757-200.", "The 757-300 is a twin-engine, long-range Boeing 757 airliner, stretched 6.", "The 757-300 is a twin-engined medium-range wide-body airliner with a capacity of up to 280 passengers.", "A 757-300 is a twin-engine, wide-body airliner produced by Boeing Commercial Airplanes.", "The 757-300 is a twin-engine commercial passenger jet that was produced by Boeing from 1983 to 2004.", "The 757-300 is a twin-engine aircraft that seat a maximum of 289 passengers.", "The 757-300 is a narrow-body airliner produced by Boeing Commercial Airplanes.", "The 757-300 is a twin-engine, long-range airliner that was first introduced in 1983.", "The 757-300 is a twin-engine, long-range airliner used for medium to long-haul flights.", "The 757-300 is a twin-engine, long-range commercial airliner that was introduced in 1983 by Boeing.", "The 757-300 is a single-aisle commercial jet airliner that was produced by Boeing from 1983 to 2004.", "A 757-300 is a twin-engine, midsize airliner that can carry up to 280 passengers."], "F/A-18": ["The F/A-18 is a twin-engine, supersonic, all-weather, carrier-capable, multirole fighter jet, designed to dogfight and perform ground attack, reconnaissance, and air defense missions.", "The F/A-18 is a twin-engine, supersonic, all-weather, carrier-capable, multirole combat jet, designed as both a fighter and attack aircraft.", "The McDonnell Douglas F/A-18 Hornet is a twin-engine, supersonic, all-weather, carrier-capable, multirole combat jet, designed as both a fighter and attack aircraft (hence the F/.", "F/A-18 aircraft are twin-engine, all-weather, day night, fighter-bomber aircraft.", "The F/A-18 is a fly-by-wire supersonic multi-role fighter aircraft.", "The F/A-18 is a twin-engine, multi-mission fighter/attack aircraft that can operate in both conventional and short takeoff and landing (STOL) modes.", "The F/A-18 aircraft is a twin-engine supersonic fighter jet.", "The McDonnell Douglas F/A-18 Hornet is a twin-engine, supersonic, all-weather, carrier-capable, multi-role combat jet, designed as both a fighter and attack aircraft.", "The McDonnell Douglas F/A-18 Hornet is a twin-engine supersonic all-weather carrier-capable multirole combat jet, designed as both a fighter and attack aircraft (hence the F/A designation).", "?The McDonnell Douglas F/A-18 Hornet is a twin-engine, supersonic, all-weather, carrier-capable, multirole combat jet, designed as both a fighter and attack aircraft (hence the F.", "The F/A-18 is a twin-engine fighter aircraft that was designed by McDonnell Douglas and Northrop.", "F/A-18s are twin-engine, supersonic, all-weather fighter-bombers.", "The McDonnell Douglas F/A-18 Hornet is a twin-engine, supersonic, all-weather, carrier-capable, multirole combat jet, designed as both a fighter and attack aircraft (hence the F/.", "The McDonnell Douglas F/A-18 Hornet is a twin-engine, supersonic, all-weather, carrier-capable, multirole combat jet, designed as both a fighter and attack aircraft (hence the F/.", "The McDonnell Douglas F/A-18 Hornet is a twin-engine, supersonic, all-weather, carrier-capable, multirole combat jet, designed as both a fighter and attack aircraft (hence the F/.", "The F/A-18 is a twin-engine, supersonic, all-weather, carrier-capable, multirole fighter jet, designed as both a fighter and attack aircraft (hence the F/A designation).", "The F/A-18 is a twin-engine, supersonic fighter jet designed for both air-to-air and air-to-ground missions.", "The McDonnell Douglas F/A-18 Hornet is a twin-engine, supersonic, all-weather, carrier-capable, multirole combat jet, designed as both a fighter and attack aircraft (hence the F/.", "The McDonnell Douglas F/A-18 Hornet is a twin-engine, supersonic, all-weather, carrier-capable, multirole combat jet, designed as both a fighter and attack aircraft (hence the F/.", "The McDonnell Douglas F/A-18 Hornet is a twin-engine, supersonic, all-weather, carrier-capable, multirole combat jet, designed as both a fighter and attack aircraft (hence the F/."], "737-400": ["The 737-400 is a twin-engined short-to-medium-range narrow-body airliner with a capacity of 162 passengers.", "The 737-400 is a twin-engine short-to-medium-range narrowbody airliner.", ".", ".", "The 737-400 is a twin-engine short-to-medium-range narrow-body jet airliner.", "The 737-400 is a twin-engined short-to-medium-range narrow-body airliner with a capacity of up to 188 passengers.", "The 737-400 is a commercial airliner that was introduced in 1985.", "The 737-400 is a twin-engine short-to-medium-range narrowbody airliner.", "The 737-400 is a twin-engined short-to-medium-range narrow-body airliner with a capacity of 162 passengers.", "The 737-400 is a twin-engined short-haul Boeing 737 airliner.", "The 737-400 is a twin-engine short-to-medium-range narrow-body jet airliner.", "The 737-400 is a twin-engined short-to-medium-range narrow-body airliner with a capacity of 149 to 188 passengers.", "The 737-400 is a twin-engined short-to-medium-range narrow-body airlinerwith a capacity of 140 to 188 passengers.", "Aircraft dimensions:Overall length: 39.", "The 737-400 is a twin-engined short-haul aircraft with a capacity of 150 passengers.", "The 737-400 is a short-to-medium range narrow-body jetliner.", "A 737-400 is a twin-engine, short- to medium-range commercial jet airliner, often used as a regional airliner.", "The 737-400 is a twin-engined short-to-medium-range narrow-body aircraft with a capacity of 162 passengers produced by Boeing Commercial Airplanes.", "A 737-400 is a short-to-medium range, single-aisle airliner."], "E-195": ["The Embraer E-195 is a twin-engine medium-range jet airliner manufactured by Embraer, a Brazilian aerospace company.", "'s main featuresThe E-195 aircraft is a twin-engine, single-aisle plane that can seat up to 120 passengers.", "The E-195 is a twin-engine, single aisle aircraft designed for short to medium range flights.", "The Embraer E-195 is a twin-engine, single-deck jet airliner manufactured by Embraer, a Brazilian aerospace company.", "The Embraer E-195 is a narrow-body, twin-engine jet airliner manufactured by Embraer, a Brazilian aerospace company.", "The Embraer E-195 is a narrow-body, twin-engine, medium-range commercial jetliner manufactured by Embraer, a Brazilian aerospace conglomerate.", "The Embraer 195 is a narrow-body airliner produced by Brazilian aerospace manufacturer Embraer.", "The Embraer E-195 is a narrow-body, twin-engine, commercial airliner manufactured by Embraer, a Brazilian aerospace company.", "The E-195 is a twin-engine, single aisle turbofan jet airliner manufactured by Embraer.", "The E-195 is a twin-engine, single-aisle commercial jet airliner manufactured by Embraer.", "The E-195 is a twin-engine, single-aisle commercial jet.", "The E-195 aircraft is a twin-engine, single-aisle jetliner that can seat up to 118 passengers.", "The Embraer E-195 is a twin-engine narrow-body jet airliner manufactured by Embraer, a Brazilian aerospace company.", "The Embraer E-195 is a regional jet manufactured by Embraer.", "Embraer's E-195 is a single-aisle commercial jet capable of carrying up to 124 passengers.", "An E-195 aircraft is a twin-engine, single-aisle commercial jet.", "\"The E-195 is a narrow-body, twin-engine, jet aircraft produced by Brazilian aerospace manufacturer Embraer.", "The Embraer E-195 is a narrow-body twin-engine jet airliner produced by Brazilian aerospace manufacturer Embraer.", "The Embraer E-195 is a regional jet manufactured by Embraer.", "The E-195 is a twin-engine aircraft with a capacity of up to 130 passengers."], "747-200": ["The 747-200 is a wide-body aircraft with four engines and a capacity of 366 passengers in a two-class configuration.", "The 747-200 is an airplane that can seat up to 366 passengers and has a maximum range of 7,620 miles.", "The 747-200 aircraft is a wide-body jet airliner with a capacity of up to 380 passengers.", "The 747-200 is a jumbo jet produced by Boeing.", "The 747-200 is a wide-body jet airliner that was produced by Boeing Commercial Airplanes from 1971 to 1987.", "The 747-200 is a wide-body jet airliner that was produced by Boeing Commercial Airplanes from 1971 to 1987.", "The 747-200 was the second iteration of the 747 aircraft.", "The 747-200 is a jumbo jet airliner that was produced by Boeing Commercial Airplanes from 1971 to 1987.", "The 747-200 was an early version of the 747 jumbo jet, with a longer range and greater fuel capacity than the 747-100.", "The 747-200 is a wide-body jet airliner that was produced by Boeing Commercial Airplanes from 1971 to 1987.", "The 747-200 is a wide-body, four-engine jet airliner that was produced by Boeing Commercial Airplanes from 1971 to 1991.", "A 747-200 is a four-engine commercial jetliner that was manufactured by Boeing.", "A747-200 is a wide-body, long-range airliner that was first introduced in 1971 by Boeing.", "The Boeing 747-200 is wide-body jet airliner.", "The 747-200 is a wide-body jet airliner that was produced by Boeing Commercial Airplanes from 1971 to 1987.", "The Boeing 747-200 is a jumbo jet that was introduced in 1971.", "The 747-200 is a large, long-range airliner that was first introduced in 1971.", "The 747-200 is a four-engine, long-range widebody aircraft manufactured by Boeing Commercial Airplanes.", "The Boeing 747-200 is a wide-body aircraft produced by Boeing Commercial Airplanes from 1971 to 1987.", "The 747-200 is a four-engine, long-range wide-body airliner produced by Boeing Commercial Airplanes, the second model of the 747 family."], "Spitfire": ["The Supermarine Spitfire was a British single-seat fighter aircraft that was used by the Royal Air Force and other Allied countries before, during, and after World War II.", "The Spitfire is a British single-seat fighter aircraft that was used by the Royal Air Force and other Allied countries before, during and after World War II.", "The Supermarine Spitfire was a British single-seat fighter aircraft that was used by the Royal Air Force and other Allied countries before, during, and after World War II.", "The Supermarine Spitfire is a British single-seat fighter aircraft that was used by the Royal Air Force and other Allied countries before, during, and after World War II.", "The Spitfire was a British single-seat fighter aircraft used by the Royal Air Force throughout the Second World War.", "A fighter aircraft that was used by Britain during World War II.", "The Supermarine Spitfire is a British single-seat fighter aircraft that was used by the Royal Air Force and other Allied countries before, during, and after World War II.", "The Supermarine Spitfire was a British single-seat fighter aircraft that was used by the Royal Air Force and other Allied countries before, during, and after World War II.", "The Spitfire was a British single-seat fighter aircraft that was used by the Royal Air Force and other Allied countries before, during, and after World War II.", "The Supermarine Spitfire is a British single-seat fighter aircraft that was used by the Royal Air Force and other Allied countries before, during, and after World War II.", "A Spitfire is a British single-seat fighter aircraft that was used by the Royal Air Force and other Allied countries before, during and after World War II.", "A Spitfire aircraft is a British single-seat fighter aircraft that was used by the Royal Air Force and other Allied countries before, during, and after World War II.", "The Supermarine Spitfire was a single-seat fighter aircraft that was used by the Royal Air Force and other Allied countries before, during, and after World War II.", "A Spitfire aircraft is a British single-seat fighter aircraft used by the Royal Air Force during World War II.", "A Spitfire aircraft is a British single-seat fighter aircraft that was used by the Royal Air Force and other Allied countries before, during, and after World War II.", "The Spitfire was a British single-seat fighter aircraft that was used by the Royal Air Force and other Allied countries before, during, and after World War II.", "A Spitfire aircraft is a British single-seat fighter aircraft that was used by the Royal Air Force and other Allied countries before, during, and after World War II.", "The Supermarine Spitfire is a British single-seat fighter aircraft that was used by the Royal Air Force and other Allied countries before, during, and after World War II.", "The Spitfire aircraft is a British single-seat fighter airplane that was used by the Royal Air Force and other Allied countries before, during, and after World War II.", "A Spitfire is a British single-seat fighter aircraft that was used by the Royal Air Force and other Allied countries before, during and after World War II."], "767-300": ["The 767-300 is a two-engine, wide-body commercial airplane.", "A 767-300 is a twin-aisle, wide-body jetliner that first flew in 1986.", "The 767-300 is a wide-body twin-engine jetliner produced by Boeing Commercial Airplanes.", "The 767-300 aircraft is a twin-engine, wide-body jetliner that was introduced in 1986.", "The 767-300 aircraft is a twin-engined wide-body jetliner.", "The 767-300 is a mid-size, wide-body twin-engine jetliner developed by Boeing Commercial Airplanes.", "The 767-300 is a mid-size, long-range twin-engine jetliner.", "The 767-300 is a mid-size, long-range twin-engine jet airliner that was developed by Boeing Commercial Airplanes.", "The 767-300 is a twin-engine aircraft that seats up to 375 passengers.", "The 767-300 aircraft is a twin-engine, long-range airplane that was first delivered in 1986.", "The 767-300 is a mid-size, wide-body twin-engine jet airliner.", "The 767-300 is a wide-body aircraft produced by Boeing Commercial Airplanes.", "The 767-300 is a plane that can seat up to 375 passengers.", "The Boeing 767-300 is a twin-engined mid-size wide-body airliner with a standard capacity of 251 passengers in a two-class configuration, and a maximum capacity of 375 passengers in a one-class configuration.", "The 767-300 is a twin-engine, medium-range airliner that was first introduced in 1986 by Boeing.", "The 767-300 is a twin-engined wide-body airliner with a capacity of 250-300 passengers, produced by Boeing Commercial Airplanes.", "The 767-300 is a twin-engine, wide-body commercial airliner produced by Boeing Commercial Airplanes.", "The 767-300 is a wide-body aircraft produced by Boeing Commercial Airplanes.", "The 767-300 is a wide-body aircraft produced by Boeing Commercial Airplanes.", "A 767-300 is a twin-engine, long-range commercial airliner."], "BAE-125": ["The BAE-125 is a business jet aircraft produced by BAE Systems.", "The North American B-25 Mitchell was an American twin-engine medium bomber manufactured by North American Aviation (NAA).", "The BAE-125 is a small aircraft designed for general aviation.", "The Northrop Grumman B-2 Spirit, also known as the Stealth Bomber, is an American heavy strategic bomber, designed for penetrating dense anti-aircraft defenses; it is a flying wing design with a crew of two.", "The BAE-125 is a twin-engine, business jet aircraft manufactured by Bombardier Aerospace.", "The BAE-125 aircraft is a small twin-engine business jet.", "The BAE-125 is a fixed-wing aircraft that was designed by British manufacturer BAE Systems.", "The BAE-125 aircraft is a twin-engine business jet designed and manufactured by British Aerospace (now BAE Systems).", "The BAE-125 is a small, two-engine business jet aircraft.", "The BAE-125 aircraft is a single-engine, turboprop plane that can seat up to nine passengers.", "The BAE-125 is a small, single-engine jet aircraft.", "The BAE-125 aircraft is a small, twin-engine business jet that can seat up to seven passengers.", "The BAE-125 is a twin-engine, light-aircraft manufactured by British Aerospace.", "The Beechcraft Baron is a twin-engined piston-powered aircraft, introduced in 1961.", "The BAE Systems Hawk is a British single-engine, jet-powered advanced trainer aircraft.", "The BAE-125 aircraft is a twin-engine business jet produced by BAE Systems.", "The North American Rockwell OV-10 Bronco is an American twin-turboprop light attack aircraft designed in 1964.", "The Northrop Grumman B-2 Spirit, also known as the Stealth Bomber, is an American long-range, strategic bomber, designed for penetrating dense anti-aircraft defenses; it is a flying wing design with a crew of.", "BAE-125 aircraft are small, twin-engine jet aircrafts.", "The BAE-125 aircraft is a twin-engine business jet that can seat up to 12 passengers."], "Tornado": ["The Tornado is a twin-engine, multi-role combat aircraft developed by the UK, West Germany and Italy.", "The Tornado is a supersonic twin-engine strike aircraft developed jointly by West Germany and the United Kingdom in the 1960s.", "The Tornado aircraft is a twin-engine, multi-role fighter aircraft.", "The North American Aviation P-51 Mustang is an American long-range, single-seat fighter and fighter-bomber used during World War II, the Korean War and other conflicts.", "The Tornado is a twin-engine, supersonic fighter-bomber that was jointly developed by the UK, West Germany and Italy.", "The Tornado is a twin-engine combat aircraft designed to perform air-to-air and ground attack missions.", "The Tornado aircraft is a twin-engine, multirole combat aircraft developed by the United Kingdom, West Germany, and Italy.", "The Tornado is a twin-engine, multirole combat aircraft that was developed by a consortium of European aerospace companies.", "The Tornado is a two-seat, twin-engine Panavia aircraft designed for many missions, including ground attack, reconnaissance and interceptor duties.", "The North American Aviation P-51 Mustang is an American long-range, single-seat fighter and fighter-bomber used during World War II, the Korean War and other conflicts.", "The Tornado is a twin-engine, three- or four-seat multi-role fighter aircraft, capable of all- weather operation from bases in the United Kingdom, Germany, Italy, and Saudi Arabia.", "The Tornado is a military aircraft designed for ground attack, close air support, and weather reconnaissance missions.", "The Tornado is a two-seat, twin-engine jet fighter equipped with a wide range of electronics and weaponry.", "The Tornado aircraft is a twin-engine, multi-role combat aircraft designed and built by the Panavia Aircraft Company.", "A Tornado is a twin-engine, multi-role combat aircraft operated by the Royal Air Force and other European air forces.", "The Tornado is a two-seat multi-role aircraft designed to perform ground attack and airborne reconnaissance missions.", "A Tornado aircraft is a combat aircraft designed to fly at low altitudes and speeds, and to fire missiles at ground targets.", "A Tornado aircraft is a single-engine, twin-seat fighter aircraft that was developed by the UK in the 1970s.", "Delta-wing multirole combat aircraft, designed and built by the British aircraft manufacturer BAE Systems, who are the prime contractors.", "The Tornado is a supersonic, twin-engine, multirole fighter aircraft, jointly developed and manufactured by Britain, West Germany, and Italy."], "CRJ-700": ["The CRJ-700 is a regional airliner that seats up to 70 passengers.", "The CRJ-700 is a small, twin-engine jetliner.", "The CRJ-700 is a regional jet manufactured by Bombardier.", "The CRJ-700 is a commercial jet aircraft manufactured by Bombardier Aerospace.", "The Bombardier CRJ-700 is a regional jet designed and manufactured by Bombardier Aerospace.", "The CRJ-700 is a small-sized, twin-engine jetliner that seats up to 70 passengers.", "The CRJ-700 is a regional airliner with a capacity of up to 70 passengers.", "The CRJ-700 aircraft is a regional jet that can seat up to 70 passengers.", "The CRJ-700 is a short-range, single-aisle commuter jet, with a capacity of 70-78 passengers.", "The CRJ-700 is a regional jet aircraft manufactured by Canadian company Bombardier.", "A CRJ-700 is a short-range, twin-engine jetliner produced by Canadian manufacturer Bombardier Aerospace.", "The CRJ-700 is a Canadian regional jet originally designed and manufactured by Bombardier.", "The CRJ-700 is a long-range, twin-engine jetliner designed to carry up to 78 passengers.", "The CRJ-700 aircraft is a regional jet that can seat up to 70 passengers.", "A CRJ-700 is a regional jet aircraft that can seat up to 70 passengers.", "A CRJ-700 aircraft is a small-sized commercial jet plane.", "The CRJ-700 is a mid-size jetliner designed to carry up to 78 passengers.", "The CRJ-700 is a regional jet manufactured by Bombardier.", "The CRJ-700 is a twin-engine regional jet aircraft manufactured by Bombardier Aerospace.", "The CRJ-700 is a regional airliner produced by Bombardier Aerospace."], "Cessna 208": ["The Cessna 208 Caravan is a single engine, turboprop airplane.", "The Cessna 208 Caravan is a single engine, turboprop aircraft.", "The Cessna 208 Caravan is a single turboprop engine, fixed-gear short-haul regional airliner and utility aircraft.", "The Cessna 208 Caravan is a single-engine turboprop fixed-wing aircraft that is used for short-haul flights.", "The Cessna 208 Caravan is a single-engine, turboprop aircraft used for short-haul cargo and passenger operations.", "The Cessna 208 Caravan is a single engine, turboprop aircraft designed for short takeoff and landing (STOL).", "The Cessna 208 Caravan is a single engine, high wing, fixed-gear turboprop aircraft.", "The Cessna 208 Caravan is a single-engine turboprop aircraft produced by Cessna.", "The Cessna 208 aircraft is a high-wing, single-engined turboprop airplane.", "The Cessna 208 Caravan is a single-engined turboprop fixed-gear short-haul regional airliner and utility aircraft.", "A Cessna 208 aircraft is a single-engine, fixed-gear turboprop aircraft.", "The Cessna 208 Caravan is a single-engined turboprop aircraft built in the United States by Cessna.", "The Cessna 208 is a single turboprop engine, fixed-gear short-haul aircraft.", "The Cessna 208 Caravan is a single-engine, fixed-gear turboprop aircraft.", "The Cessna 208 Caravan is a single engine, turboprop aircraft.", "A Cesna 208 Caravan is a single-engined turboprop aircraft produced by the American manufacturer Cesna Aircraft Company.", "The Cessna 208 Caravan is a singleengine turboprop aircraft designed for cargo or passenger operations.", "The Cessna 208 Caravan is a single turboprop engine, fixed-gear short-haul passenger plane.", "The Cessna 208 Caravan is a turboprop-powered STOL light transport aircraft.", "The Cessna 208 Caravan is a single-turboprop engine, fixed-gear short-haul regional airliner and utility aircraft."], "CRJ-900": ["The CRJ-900 is a Canadian regional jet produced by Bombardier Aerospace.", "The CRJ-900 is a regional jet that was introduced in 2001.", "The CRJ-900 is a Canadian regional jetliner manufactured by Bombardier Aerospace.", "The CRJ-900 is a twin-engine, regional jet that was introduced in 2001 by Bombardier Aerospace.", "The CRJ-900 is a comfortable, quiet and fuel-efficient airliner.", "The CRJ-900 is a short-range, single-aisle, twin-engine jetliner.", "The CRJ-900 is a 90- seat regional jet that was developed by Bombardier Aerospace.", "The Bombardier CRJ-900 is a short-range, twin-engine, regional jet aircraft developed by Canadian manufacturer Bombardier Aerospace.", "The CRJ-900 is a 90-seat regional jet plane produced by Bombardier Aerospace.", "The CRJ-900 aircraft is a short-haul, twin-engine jetliner that can accommodate up to 90 passengers.", "The CRJ-900 is a twin-engine regional jet produced by Bombardier Aerospace.", "The CRJ-900 aircraft is a high-performance, long-range jet that can seat up to 90 passengers.", "The CRJ-900 is a regional jet that was designed and built by Canadian company Bombardier.", "The CRJ-900 is a regional jet that was designed and manufactured by Bombardier Aerospace.", "The CRJ-900 is a next-generation aircraft that was introduced in 2003.", "The CRJ-900 is a twin-engined regional airliner with a capacity of up to 90 passengers, produced by Bombardier Aerospace.", "The CRJ-900 is a Canadian regional jet aircraft manufactured by Bombardier Aerospace.", "The CRJ-900 is a state-of-the-art, twin-engine aircraft that offers best-in-class performance, fuel efficiency and passenger comfort in the 60- to 90-seat market.", "The Bombardier CRJ-900 is a regional jet designed and manufactured by Bombardier Aerospace.", "The CRJ-900 aircraft is a 90-seat regional jet that was introduced in 2001 by Canadian manufacturer Bombardier."], "E-170": ["The Embraer E-170 is a narrow-body, twin-engine aircraft manufactured by Embraer, a Brazilian aerospace company.", "The E-170 is a commercial aircraft made by Brazilian aerospace manufacturer Embraer.", "The Embraer 170 is a twin-engine commercial jet aircraft manufactured by Embraer, a Brazilian aerospace conglomerate.", "The E-170 aircraft is a mid-sized, twin-engine jetliner.", "The E-170 is a twin-engine, single-aisle commercial jet aircraft.", "The E-170 is a twin-engine regional jet airliner manufactured by Embraer.", "The Airbus E-170 is a twin-engine, single-aisle commercial jet.", "The E-170 aircraft is a twin-engine plane that can seat up to 85 passengers.", "The Embraer E-170 is a mid-size, single-aisle commercial jet airliner.", "The E-170 aircraft is a mid-range, twin-engine commercial jet.", "The E-170 is a twin-engine, single-aisle commercial jet.", "The Embraer 170 is a narrow-body aircraft manufactured by Embraer.", "The E-170 is a narrow-body regional jet aircraft produced by Embraer.", "An E-170 aircraft is a twin-engine regional jet that seats up to 70 passengers.", "The E-170 is a twin-engine, single-aisle jetliner.", "The Embraer E-170 is a regional jet aircraft produced by Brazilian manufacturer Embraer.", "An E-170 aircraft is a commercial jetliner that seats up to 86 passengers.", "The Embraer E-170 is a narrow-body, twin-engine jet airliner produced by Brazilian manufacturer Embraer.", "The Embraer E-170 is a narrow-body commercial jet airliner produced by the Brazilian company Embraer.", "The E-170 aircraft is a twin-engine, regional airliner that can seat up to 81 passengers."], "DC-8": [" as much as you canThe Douglas DC-8 is a four-engine long-range narrow-body jet airliner built from 1958 to 1972 by the Douglas Aircraft Company.", "The DC-8 is a four-engine long-range narrow-body jet airliner built from 1958 to 1972 by the Douglas Aircraft Company.", "The DC-8 is a four-engine long-range narrow-body airliner built from 1958 to 1972 by the Douglas Aircraft Company.", "The DC-8 was a four-engine long-range narrow-body airliner produced from 1958 to 1972 by the Douglas Aircraft Company.", "The Douglas DC-8 is a four-engine long-range narrow-body jet airliner built from 1958 to 1972 by the Douglas Aircraft Company.", "The DC-8 is a four-engine, long-range jet airliner that was first introduced in 1958.", "The DC-8 is a long-range, narrow-body, twin-engine jet aircraft produced by the American aircraft manufacturer McDonnell Douglas.", "The DC-8 aircraft is a four-engined long-range jetliner that was built by the Douglas Aircraft Company from 1958 to 1972.", " and how it became the leading commercial jetThe DC-8 was a four-engine narrow-body jet airliner produced from 1958 to 1972.", "The DC-8 is a narrow-body jet airliner.", "A DC-8 is a four-engined long-range narrow-body jet airliner with a length of 153 ft (46.", "The Douglas DC-8 is a four-engined long-range jet airliner built from 1958 to 1972 by the Douglas Aircraft Company.", "The DC-8 is a four-engine, long-range jet airliner that was first introduced in the late 1950s.", "The DC-8 is a four-engine long-range narrow-body jet airliner produced by the Douglas Aircraft Company.", "The DC-8 is a four-engine, long-range jet airliner that was manufactured by the Douglas Aircraft Company from 1958 to 1972.", "A DC-8 is a mid-sized, long-range jet airliner that was designed and built by the Douglas Aircraft Company.", "A DC-8 is a long-range, narrow-body jet airliner that was manufactured by the Douglas Aircraft Company from 1958 to 1972.", "A DC-8 aircraft is a jet airplane that was manufactured by the Douglas Aircraft Company from 1958 to 1972.", "A DC-8 is a four-engine long-range wide-body jet airliner build by McDonnell Douglas.", "The DC-8 is a long-range, narrow-body, four-engine jet airliner built from 1958 to 1972 by the Douglas Aircraft Company."], "Challenger 600": ["The Challenger 600 is a twin-engine business jet designed and built by Bombardier Aerospace.", "The primary passenger liner aircraft, the Challenger 600 has set the new standard in the industry, seating up to 19 passengers in unparalleled comfort.", "The Challenger 600 is a business jet aircraft produced by Bombardier Aerospace.", "The Challenger 600 is a Canadian-built business jet with a capacity of up to 12 passengers.", "The Challenger 600 is a business jet introduced in 1978 by Canadian company Bombardier Aerospace.", "The Challenger 600 is a Canadian-built business jet, introduced in 1978 by Canadian aircraft manufacturer Bombardier.", "The Challenger 600 is a twin-engine business jet designed and manufactured by Bombardier Aerospace.", "The Challenger 600 is a twin-engine business jet manufactured by Bombardier Aerospace in Montreal, Quebec, Canada.", "The Challenger 600 aircraft is a business jet that can seat up to 12 people.", "The Challenger 600 is a business jet manufactured by Bombardier Aerospace.", "The Challenger 600 aircraft is a medium-sized, twin-engine business jet.", "The Challenger 600 is a Canadian business jet.", "The Challenger 600 is a twin-engined business jet designed by Canadian manufacturer Bombardier Aerospace.", "The Challenger 600 aircraft is a Canadian-built business jet.", "A Challenger 600 is a twin-engine business jet produced by Bombardier Aerospace.", "The Challenger 600 aircraft is a private jet that can seat up to 12 passengers.", "The Challenger 600 is a private jet that seats up to 10 passengers.", "The Challenger 600 aircraft is a twin-engine jet that can seat up to twelve passengers.", "The Challenger 600 is a twin-engined corporate jet produced by Bombardier Aerospace.", "The Challenger 600 aircraft is a business jet that was first introduced in 1978."], "DHC-8-100": ["The DHC-8-100 is a short-range, twin-engine, turboprop airliner.", "The DHC-8-100 is a small, twin-engined turboprop aircraft manufactured by de Havilland Canada.", "The DHC-8-100 aircraft is a twin-engine turboprop regional airliner with a capacity of up to 90 passengers.", "The DHC-8-100 aircraft is a Twin-engine turboprop regional airliner with a capacity of up to 90 passengers.", "The de Havilland Canada DHC-8-100 Dash 8 is a twin-engine, short-range, regional turboprop airliner.", "The Bombardier DHC-8-100 is a twin-turboprop regional airliner typically configured with between 37 and 39 seats.", "The DHC-8-100 is a Canadian regional airliner manufactured by de Havilland Canada.", "The DHC-8-100 is a twin-engine turboprop regional airliner with 50-70 seats.", "The de Havilland Canada DHC-8-100 Dash 8 is a twin-engine, short-range, regional airliner.", "The DHC-8-100 is a twin-engine regional turboprop airplane with a pressurized cabin that can seat up to 37 passengers.", "The DHC-8-100 is a short-range, twin-engine turboprop aircraft designed and built by de Havilland Canada.", "The DHC-8-100 aircraft is a small, twin-engine passenger plane.", "The DHC-8-100 is a short-range, single-engine turboprop aircraft that can seat up to 37 passengers.", "The DHC-8-100 is a twin-engined turboprop aircraft produced by de Havilland Canada.", "The DHC-8-100 is a twin engine turboprop airliner with a capacity of up to 90 passengers.", "The DHC-8-100 is a twin-engine, short-range commuter airliner.", "The De Havilland Canada DHC-8-100 is a twin-engined short-haul regional airliner with a seating capacity of up to 90 passengers, derived from the earlier Dash 8.", "The DHC-8-100 is a twin-engine turboprop regional airliner with a capacity of up to 37 passengers.", "The Bombardier Dash 8 or Q-Series, previously known as the De Havilland Canada Dash 8 or DHC-8, is a series of twin-engine, medium range, turboprop airliners.", "The de Havilland Canada DHC-8,known as the Dash 8,is a twin-engine,short-range,horizontalpod,airliner developed and manufactured by de Havilland Canada."], "DC-6": ["The Douglas DC-6 is a piston-powered airliner and transport aircraft manufactured by the Douglas Aircraft Company from 1946 to 1958.", "The DC-6 aircraft is a four-engine commercial airliner that was produced by the Douglas Aircraft Company from 1946 to 1958.", "The Douglas DC-6 is a piston-powered airliner and cargo aircraft produced by the Douglas Aircraft Company from 1946 to 1958.", "The DC-6 aircraft was manufactured by the Douglas Aircraft Company from 1946 to 1958.", "The Douglas DC-6 is a piston-powered airliner and cargo aircraft produced by the Douglas Aircraft Company from 1946 to 1958.", "The DC-6 is a four-engine commercial propeller-driven airliner produced by the Douglas Aircraft Corporation.", "The Douglas DC-6 is a piston-powered airliner and cargo aircraft produced by the Douglas Aircraft Company from 1946 to 1958.", "The DC-6 is a piston-powered airliner produced by the Douglas Aircraft Company from 1946 to 1958.", "The Douglas DC-6 is a piston-powered airliner and transport aircraft manufactured by the Douglas Aircraft Company from 1946 to 1958.", "The Douglas DC-6 is a piston-powered airliner and transport aircraft produced by the Douglas Aircraft Company from 1946 to 1958.", "A Douglas DC-6 is a twin-engine, piston-powered commercial airliner produced by the Douglas Aircraft Company from 1946 to 1958.", "The DC-6 is a piston-powered airliner produced by the Douglas Aircraft Company from 1946 to 1958.", "TheDC-6 aircraft is a piston-powered airliner produced by the Douglas Aircraft Corporation from 1946 to 1958.", "The Douglas DC-6 is a commercial airliner that was produced by the Douglas Aircraft Company from 1946 to 1958.", "The Douglas DC-6 is a piston-engined airliner and cargo aircraft produced by the Douglas Aircraft Company from 1946 to 1958.", "A Douglas DC-6 aircraft is a four-engine propeller plane that was manufactured by the Douglas Aircraft Company from 1946 to 1958.", "The Douglas DC-6 is a piston-engined airliner produced by the Douglas Aircraft Company.", "A Douglas DC-6 is a four-engined long-range propeller-driven airliner developed by the Douglas Aircraft Company in the early 1940s.", "The DC-6 aircraft was a twin-engine, piston-powered airliner manufactured by the Douglas Aircraft Company from 1946 to 1958.", "The DC-6 is a piston-powered airliner produced by the Douglas Aircraft Company from 1946 to 1958."], "A340-300": ["The A340-300 is a long-range, four-engine jet airliner produced by Airbus Industrie, the European consortium.", "The A340-300 is a long-range wide-body aircraft produced by Airbus.", "The A340-300 is a long-range, four-engined wide-body commercial passenger airliner produced by Airbus.", "The A340-300 is a long-range, four-engine wide-body commercial passenger airliner produced by Airbus.", "The A340-300 is a long-range, wide-body commercial passenger jet airliner that was developed by Airbus.", "The A340 is a long-range, four-engine, wide-body commercial passenger jet airliner developed and produced by Airbus.", "The A340-300 aircraft is a long-range, four-engine wide-body commercial airliner produced by Airbus Industries.", "The A340-300 is a wide-body aircraft manufactured by Airbus.", "A340-300 is a long-range wide-body twin-engine jet airliner developed and produced by Airbus.", "The A340-300 is a long-range, wide-body aircraft with a cruising speed of Mach 0.", "The A340-300 is a long-range, wide-body airliner produced by Airbus Industrie.", "The A340-300 is a long-range, wide-body passenger aircraft produced by Airbus.", "The A340-300 is a four-engine long-range wide-body airliner produced by Airbus.", "The A340-300 is a wide-body aircraft with a fuel-efficient four-engine design.", "The A340-300 is a twin-engine, wide-body aircraft that can carry up to 280 passengers.", "The A340-300 is a long-range, four-engine civil airliner produced by Airbus.", "An A340-300 is a long-range, wide-body commercial passenger jet airliner that was developed and produced by Airbus.", "An A340-300 aircraft is a wide-body, long-haul commercial airliner.", "The A340-300 is a four-engine long-range wide-body airliner with a capacity of 300 passengers produced by the French manufacturer Airbus.", "The A340-300 is a long-range four-engine wide-body airliner produced by Airbus."], "DHC-6": ["The DHC-6 Twin Otter is a 20-passenger STOL (Short Take-Off and Landing) utility aircraft developed by de Havilland Canada and currently produced by Viking Air.", "The DHC-6 is a twin-engine utility aircraft produced by de Havilland Canada.", "The DHC-6 Twin Otter is a Canadian 19-passenger STOL (Short Take-Off and Landing) utility aircraft developed by de Havilland Canada and currently produced by Viking Air.", "The DHC-6 is a high-wing commuter turboprop aircraft, produced by the Canadian aircraft manufacturer de Havilland Canada.", "The DHC-6 is a twin-engine turboprop aircraft used for short-haul flights.", "The DHC-6 is a twin-engine turboprop transport aircraft designed and manufactured by de Havilland Canada.", "The de Havilland Canada DHC-6 Twin Otter is a Canadian 19-passenger STOL (Short Take-Off and Landing) utility aircraft developed by de Havilland Canada and currently produced by Viking Air.", "The DHC-6 is a Canadian twin-engined short-takeoff-and-landing aircraft manufactured by de Havilland Canada.", "The DHC-6 Twin Otter is a Canadian 19-passenger STOL (Short Takeoff and Landing) utility aircraft developed by de Havilland Canada and currently produced by Viking Air.", "The DHC-6 is a twin-engined aircraft that is used for short takeoff and landing (STOL).", "The DHC-6 Twin Otter is a Canadian 19-passenger STOL utility aircraft developed by de Havilland Canada and currently produced by Viking Air.", "The DHC-6 is a twin-engined STOL utility aircraft developed and manufactured by de Havilland Canada.", "The DHC-6 aircraft is a twin-engined, short-takeoff-and-landing (STOL) utility airplane.", "The DHC-6 Twin Otter is a Canadian 20-passenger STOL (Short Take-Off and Landing) utility aircraft, manufactured by de Havilland Canada.", "The DHC-6 is a twin-engine, short-takeoff-and-landing (STOL) aircraft that was manufactured by de Havilland Canada.", "The DHC-6 Twin Otter is a Canadian 19-passenger STOL (Short Take-Off and Landing) utility aircraft, employing high-lift wing and STOL kits for various runway lengths.", "The DHC-6 is a short takeoff and landing aircraft manufactured by de Havilland Canada.", "empty weight - 4890 kg\nMax.", "The DHC-6 is a single-engine, short take-off and landing (STOL) utility aircraft produced by de Havilland Canada.", "The DHC-6 is a twin-engine, single-rotor utility helicopter produced by de Havilland Canada."], "DHC-1": ["The DHC-1, later the de Havilland Canada Chipmunk, is a Canadian primary training aircraft that was designed and produced by de Havilland Canada.", "The DHC-1, otherwise known as the de Havilland Chipmunk, is a small, single-engine biplane that was used primarily for training purposes by the Royal Canadian Air Force (RCAF) and numerous other air.", "The DHC-1 is a light, single-engine aircraft that was manufactured by de Havilland Canada.", "The DHC-1 aircraft is a small, single-engined, propeller-driven airplane that was originally designed for use as a personal aircraft or light utility plane.", "The DHC-1, also known as the de Havilland Chipmunk, is a British single-engine, tandem-seat primary trainer aircraft.", "The DHC-1 aircraft is a Canadian-built single-engined light utility helicopter.", "The DHC-1, also known as the de Havilland Chipmunk, is a general aviation aircraft designed in the 1940s by de Havilland Canada.", "The DHC-1, known as the Chipmunk in the UK, Canada and New Zealand, is a tandem, two-seat, single-engined primary trainer aircraft.", "The DHC-1, or De Havilland DHC-1 Chipmunk, is a British single-engine, tandem-seated primary trainer aircraft designed and manufactured by De Havilland Canada.", "The DHC-1 De Havilland Chipmunk is a British single-engined primary trainer aircraft designed and manufactured by De Havilland Canada.", "The de Havilland Canada DHC-1 Chipmunk is a tandem, two-seat, primary trainer aircraft designed and manufactured by de Havilland Canada.", "The DHC-1 is a single-engine light utility helicopter that was manufactured by de Havilland Canada.", "The de Havilland Canada DHC-1 Chipmunk is a tandem, two-seat, single-engined primary trainer aircraft.", "The DHC-1, or de Havilland Canada Chipmunk, is a small, single-engine, two-seat primary trainer aircraft that was designed and manufactured by de Havilland Canada.", "The DHC-1 Chipmunk is a tandem, two-seat, primary trainer designed and manufactured by de Havilland Canada.", "The DHC-1, otherwise known as the Chipmunk, is a small, single-engine, single-rotor aircraft.", "The DHC-1 is a light single-engine turboprop aircraft produced by de Havilland Canada.", "The DHC-1, more commonly known as the de Havilland Chipmunk, is a British single-engined primary trainer aircraft.", "The DHC-1 aircraft is a small, single-engine plane used for short-range flights.", "The DHC-1 Chipmunk is a small, two-seat, single-engined primary trainer aircraft."], "Boeing 717": ["The Boeing 717 is a narrow-body twin-engine jet airliner.", "The Boeing 717 is a twin-engine, single-aisle jetliner.", "The Boeing 717 is a twin-engine, single-aisle commercial jetliner that was formerly manufactured by McDonnell Douglas.", "The Boeing 717 is a twin-engine, single-aisle commercial jetliner.", "The Boeing 717 is a twin-engine, single-aisle commercial jetliner.", "The Boeing 717 aircraft is a twin-engine, single-aisle commercial jetliner.", "The Boeing 717 is a twin-engine, single-aisle commercial jet airliner.", "The Boeing 717 is a twin-engined, single aisle commercial jet airliner.", "The Boeing 717 is a narrow-body aircraft with two engines mounted on the rear of the fuselage.", "The Boeing 717 aircraft is a McDonnell Douglas MD-95.", "The Boeing 717 is a twin-engine, single-aisle commercial jet airliner.", "The Boeing 717 is a small twin-engined commercial jet aircraft.", "The Boeing 717 is a twin-engine, single-aisle jetliner.", "The Boeing 717 is a twin-engined aircraft with a capacity of up to 133 passengers.", "The Boeing 717 aircraft is a twin-engine, single-aisle commercial jetliner.", "The Boeing 717 is a mid-size twin-engine commercial airliner.", "A Boeing 717 aircraft is a twin-engine, single-aisle commercial jetliner.", "The Boeing 717 is a twin-engine, single-aisle commercial jetliner with seating for up to 135 passengers.", "A Boeing 717 aircraft is a narrow-body jet airliner with two engines.", "The Boeing 717 is a twin-engined narrow-body jet airliner, produced by the American manufacturer Boeing."], "Cessna 525": ["The Cessna 525 is a twin-engine, light jet aircraft manufactured by Cessna.", "The Cessna 525 is a light jet aircraft that seats up to 8 passengers.", "The Cessna525 is a twin-engine, six-seat business jet.", "A cessna 525 is a small, twin-engine jetliner.", "The Cessna 525 is a twin-engine, light jet aircraft.", "The Cessna 525 is a twin-engine aircraft that can seat up to seven people.", "The Cessna 525 is a six-seat, twin-engine business jet with a pressurized cabin.", "The Cessna 525 is a twin-engine, six-seat business jet aircraft produced by Cessna.", "The Cessna 525 is a twin engine corporate jet that seats up to eight passengers.", "The Cessna 525 is a light jet aircraft that seats up to eight passengers.", "The Cessna 525 is a light jet aircraft that seats up to eight passengers.", "The Cessna 525, also known as the CitationJet, is a small business jet aircraft produced by Cessna.", "The Cessna 525 is a twin-engine light jet aircraft.", "The Cessna 525 is a private jet that seats up to eight passengers.", "The Cessna 525 is a twin-engine corporate jet aircraft built by Cessna.", "The Cessna 525 is a light jet aircraft that can seat up to eight passengers.", "The Cessna 525 is a single-engine light jet aircraft that seats up to eight passengers.", "The Cessna 525 is a private jet that can seat up to 8 people.", "The Cessna 525 is a Jet-Powered corporate aircraft that seats up to 8 people.", "The Cessna 525 is a light jet aircraft."], "Gulfstream IV": ["The Gulfstream IV is a twin-engine business jet aircraft produced by Gulfstream Aerospace.", "The Gulfstream IV is a twin-engined jet aircraft produced by Gulfstream Aerospace.", "The Gulfstream IV is a twin-engine business jet aircraft produced by Gulfstream Aerospace, derived from the earlier Gulfstream III.", "The Gulfstream IV is a twin-engine business jet aircraft produced by Gulfstream Aerospace.", "The Gulfstream IV is a twin-engine business jet aircraft produced by Gulfstream Aerospace.", "The Gulfstream IV is a long-range, large-cabin, twin-engine business jet aircraft produced by Gulfstream Aerospace, a General Dynamic subsidiary.", "The Gulfstream IV is a twin-engine business jet plane produced by Gulfstream Aerospace, a General Dynamics company.", "The Gulfstream IV is a long-range, large-cabin, twin-engine business jet aircraft produced by Gulfstream Aerospace, a General Dynamics company.", "The Gulfstream IV is a twinjet aircraft produced by Gulfstream Aerospace.", "The Gulfstream IV is a twin-engine business jet aircraft produced by Gulfstream Aerospace.", "The Gulfstream IV is a long-range, large-cabin, intercontinental business jet aircraft produced by Gulfstream Aerospace, a General Dynamics company.", "The Gulfstream IV is a twin-engine business jet aircraft produced by Gulfstream Aerospace.", "The Gulfstream IV is a wide-body corporate jet aircraft produced by Gulfstream Aerospace.", "The Gulfstream IV is a twin-engine business jet aircraft produced by Gulfstream Aerospace.", "A Gulfstream IV is a large, long-range, twin-engine business jet aircraft produced by Gulfstream Aerospace, a General Dynamics company.", "The Gulfstream IV is a business jet aircraft produced by Gulfstream Aerospace, a General Dynamics company.", "A Gulfstream IV aircraft is a large, long-range business jet that can seat up to 19 passengers.", "The Gulfstream IV is a twin-engine business jet aircraft produced by Gulfstream Aerospace.", "A Gulfstream IV is a twin-engine business jet aircraft produced by Gulfstream Aerospace.", "The Gulfstream IV is a twin-engine business jet aircraft produced by Gulfstream Aerospace."], "777-300": ["The 777-300 is a long-range, wide-body twin-engine jetliner developed by Boeing Commercial Airplanes.", "The Boeing 777-300 is a wide-body airliner produced by Boeing Commercial Airplanes.", "The 777-300 is a large aircraft with a wide body.", "The 777-300 is a twin-engine jetliner that offers a seating capacity of 350 passengers and a range of 5,235 to 9,380 nautical miles.", "The 777-300 is a wide-body aircraft produced by Boeing Commercial Airplanes.", "The 777-300 is a long-range, twin-engine wide-body jet airliner.", "The 777-300 is a long-range, wide-body twin-engine jet airliner developed by Boeing Commercial Airplanes.", "The 777-300 is a long-range, twin-engine jetliner manufactured by Boeing Commercial Airplanes.", "The 777-300 is a wide-body aircraft produced by Boeing Commercial Airplanes.", "The Boeing 777-300 is a twin-engine long-range wide-body airliner developed and manufactured by Boeing Commercial Airplanes.", "A 777-300 aircraft is a long-range, wide-body jet airliner.", "A 777-300 aircraft is a long-range, wide-body jet airliner developed by Boeing.", "The Boeing 777-300 is a twin-engine wide-body airliner developed and manufactured by Boeing Commercial Airplanes.", "The 777-300 is a long-range, wide-body jet airliner developed by Boeing Commercial Airplanes.", "A 777-300 is a twin-engine jetliner with a capacity of up to 550 passengers.", "The Boeing 777-300 is a twin-engine wide-body airplane produced by Boeing Commercial Airplanes.", "The 777-300 is a wide-body aircraft produced by Boeing Commercial Airplanes.", "A 777-300 is a twin-engine, long-range wide-body airliner that can carry up to 384 passengers.", "The 777-300 is a twin-engine, wide-body aircraft that can carry up to 350 passengers.", "The 777-300 is a long-range, wide-body jet airliner manufactured by Boeing Commercial Airplanes."], "737-500": ["The 737-500 is a twin-engine, single-aisle jet aircraft that was first introduced in the early 1990s.", "The 737-500 is a narrow-body airliner produced by Boeing Commercial Airplanes.", "The 737-500 is a twin-engined short-haul aircraft with a capacity of up to 140 passengers.", "The 737-500 is a twin-engined short-haul passenger jet aircraft.", "The 737-500 is a twin-engine, short-to-medium-range Boeing 737 commercial jetliner.", "The 737-500 is a twin-engine, single-aisle aircraft that was first delivered in 1993.", ".", "The 737-500 is a twin-engined short-haul aircraft with a capacity of 132 passengers and a range of 2,980 kilometers.", "The 737-500 is a short- to medium-range narrow-body jetliner.", "737-500 aircraft are single-aisle planes with a capacity of 132 to 189 seats.", "The 737-500 is a twin-engine, single-aisle jetliner that was introduced in the late 1980s.", "The 737-500 is a twin-engine, short-to-medium-range airplane.", "A 737-500 is a twin-engine, single-aisle jetliner that can carry up to 140 passengers.", "The 737-500 is a twin-engine, single-aisle jetliner that was introduced in the early 1990s.", "The Boeing 737-500 is a twin-engined short-to-medium-range narrowbody airliner with a capacity of up to 140 passengers produced by Boeing Commercial Airplanes.", "The 737-500 is a twin-engined short-haul aircraft with a capacity of up to 140 passengers.", "The 737-500 is a twin-engined short-haul aircraft with a capacity of 132 passengers and a range of 2,060 miles.", "A 737-500 is a twin-engined short-to-medium-range narrowbody airliner with a capacity of maximum 145 passengers produced by Boeing Commercial Airplanes.", "The 737-500 is a twin-engined short-to-medium-range narrowbody airliner with a capacity of maximum 148 passengers produced by Boeing Commercial Airplanes.", "A Boeing 737-500 is a twin-engined short-to-medium-range narrowbody airliner with a capacity of maximum 138 passengers produced by Boeing Commercial Airplanes."], "Tu-134": ["The Tupolev Tu-134 (NATO reporting name: Crusty) is a twin-engined short-range narrow-body passenger airliner built in the Soviet Union.", "Type: Twin-engined short-range narrow-body jet airliner\n Origin: Soviet Union\n Produced: 1963-1989\n Number built: 1,658\n Variants: Tu-134A, Tu-134B, Tu.", "The Tu-134 is a Soviet twin-engined short-range narrow-body airliner with a capacity of up to 80 passengers.", "The Tupolev Tu-134 (NATO reporting name: Crab) is a twin-engined narrow-body jet airliner with a capacity of max.", "The Tupolev Tu-134 (NATO reporting name: Crusty) is a twin-engined short-range narrow-body jet airliner developed in the Soviet Union.", "The Tupolev Tu-134 (NATO reporting name: Crusty) is a twin-engined short-range jet airliner with a capacity of up to fifty-eight passengers produced by the Soviet Tupolev company from 1966.", "The Tu-134 is a twin-engine, narrow-body turboprop aircraft designed in the Soviet Union.", "The TU-134 is a twin-engined short-range narrow-body passenger airliner designed in the Soviet Union.", "The Tupolev Tu-134 (NATO reporting name: Crusty) is a twin-engined short-range narrow-body domestic passenger airliner with retractable tricycle landing gear, manufactured in the Soviet Union from 1966 to.", "The Tupolev Tu-134 (NATO reporting name: Crusty) is a twin-engined short-range narrow-body jet airliner built in the Soviet Union from 1966 to 1985.", "The Tupolev Tu-134 (NATO reporting name: Crusty) is a Soviet narrow-body twin-engined airliner with about 50 variations.", "The Tupolev Tu-134 (NATO reporting name: Crusty) is a twin-engined short-range narrow-body jet airliner with a capacity of between 68 and 83 passengers produced by the Soviet Union's Tupole.", "The Tupolev Tu-134 (NATO reporting name: Crusty) is a twin-engined short-range jet airliner with a capacity of up to 80 passengers produced by the Soviet Union.", "A Tu-134 aircraft is a Soviet-built twin-engined turboprop airliner.", "The Tu-134 is a twin-engined jet airliner used by the Soviet Union.", "A Tu-134 aircraft is a Soviet-built twin-engined airliner.", "The Tu-134 is a twin-engined airliner used for medium-range flights.", "A Tu-134 aircraft is a Soviet-built twin-engined airliner.", "The Tu-134 is a twin-engined short-range narrow-body domestic passenger airliner produced in the Soviet Union from 1963 to 1985.", "The Tupolev Tu-134 (NATO reporting name: Crusty) is a twin-engined short-range narrow-body jet airliner constructed in the Soviet Union."], "SR-20": ["The SR-20 is a single-engine, low-wing general aviation aircraft marketed by Cirrus Aircraft.", "The SR-20 is a single-engine, low-wing airplane with a cantilever wing.", "The SR-20 is a single-engine, low-wing aircraft with a fixed-pitch propeller.", "The SR-20 is a aircraft produced by Cirrus Aircraft.", "The SR-20 is a single engine, low-wing general aviation aircraft.", "The Cirrus SR20 is a single-engine general aviation aircraft designed and built by Cirrus Aircraft of Duluth, Minnesota, United States.", "The SR20 is a four-seat, single-engine, low-wing airplane with a fixed-pitch propeller.", "The SR-20 is a high-performance, four-seat, single-engine, low-wing general aviation airplane.", "The SR-20 is a single-engine, low-wing airplane with retractable landing gear.", "The SR-20 is a single-engine, low-wing general aviation aircraft developed by Cirrus Design.", "The SR-20 is a single-engine, low-wing aircraft with tricycle landing gear.", "The SR-20 is a single-engine, low-wing monoplane with retractable landing gear.", "The D-model introduced Rolls-Royce turbofan engines, winglets, and other improvements to increase performance and fuel efficiency.", "An aircraft powered by a single turbocharged engine driving a propeller.", "The SR-20 is a single-engine, low-wing general aviation aircraft marketed by Cirrus Aircraft of Duluth, Minnesota.", "The SR-20 is a single-engine, low-wing general aviation aircraft produced by Cirrus Aircraft.", "A SR-20 aircraft is a single-engine, low-wing monoplane that seats up to four people.", "The SR-20 is a single-engine, low-wing airplane with a cantilever wing.", "The SR-20 is a high-performance four-seat aircraft produced by Cirrus Aircraft.", "The SR-20 is a high performance, low wing, single engine airplane."], "757-200": ["The 757-200 is a twin-engine aircraft that can seat up to 201 passengers.", "The 757-200 is a short-to-medium range, twin-engine jetliner that was designed and built by Boeing Commercial Airplanes.", "The 757-200 is a mid-size, single-aisle commercial jet airliner with a typical range of 2,960 miles.", "The 757-200 is a twin-engine, narrow-body aircraft with a capacity of 200 passengers.", "The 757-200 is a commercial plane that was manufactured by Boeing.", "The 757-200 aircraft is a medium-sized, twin-engined jetliner that was designed and built by Boeing Commercial Airplanes.", "The 757-200 airplane is a twin-engine, narrow-body aircraft that can seat up to 219 passengers.", "The 757-200 is a narrow-body aircraft with two engines, manufactured by Boeing.", "The 757-200 is a twin-engine, medium-range airplane that can carry up to 239 passengers.", "The 757-200 is a twin-engine, medium-range airplane that was designed and built by Boeing Commercial Airplanes.", "A 757-200 aircraft is a twin-engine jetliner that was first introduced in 1983.", "The 757-200 is a twin-engine commercial airliner that was designed and built by Boeing.", "The 757-200 is a twin-engine aircraft that can seat up to 234 passengers.", "The 757-200 is a twin-engine, narrow-body jet airliner with a capacity of 200 passengers.", "Boeing 757-200 aircraft are twin-engine, mid-size jets that can seat up to 279 passengers.", "The Boeing 757 is a twin-engine, narrow-body airliner that was designed and built by Boeing Commercial Airplanes.", "The 757-200 is a narrow-body airliner that was produced by Boeing Commercial Airplanes from 1981 to 2004.", "A 757-200 is a midsize, narrow-body jetliner.", "The 757-200 is a twin-engine, narrow-body commercial airliner that was produced by Boeing from 1981 to 2004."], "Hawk T1": ["The Hawk T1 is a fast jet trainer used by the Royal Air Force and other air forces around the world.", "The Hawk T1 aircraft is a twin-engine, single-seat fighter aircraft built by British Aerospace (later BAE Systems).", "The Hawk T1 aircraft is a light attack and training aircraft used by the British Armed Forces.", "The Hawk T1 is a British trainer aircraft used by the Royal Air Force and other air forces around the world.", "The Hawk T1 is a single-engine, two-seat jet trainer aircraft used by the Royal Air Force (RAF) and other air forces around the world.", "The Hawk T1 is a single-engine, single-seat multi-role fighter aircraft designed for ground attack, interceptor, and advanced training roles.", "The Hawk T1 is a British single engine, advanced jet trainer.", "The Hawk T1 is a British single-engine, jet-powered advanced trainer aircraft.", "The Hawk T1 is a single-engine, jet-powered, advanced trainer aircraft.", "The Hawk T1 is a British single-engine, jet trainer aircraft.", "The Hawk T1 is a single-engine, jet-powered trainer aircraft.", "The Hawker T1 was a British single-seat jet trainer aircraft produced by the Hawker Aircraft Company.", "The Hawk T1 is a British single-engine, jet-powered advanced trainer aircraft.", "The Hawk T1 is a single-engine, single-seat jet trainer aircraft.", "A Hawk T1 aircraft is a single-engine, jet-powered advanced trainer that was designed and built by British Aerospace.", "The Hawk T1 is a British jet trainer aircraft.", "The Hawk T1 is a two-seat jet trainer aircraft used by the Royal Air Force and other air forces around the world.", "The Hawk T1 is a single-engine, single-seat military trainer aircraft designed and built by British company Hawker Siddeley Aviation (later BAE Systems).", "A Hawk T1 is a military trainer aircraft designed and built by BAE Systems.", "The Hawk T1 is a British single-engine, jet-powered advanced trainer aircraft."], "A318": ["The A318 is a narrow-body aircraft produced by Airbus Industries.", "The Airbus A318 is a narrow-body jet airliner produced by Airbus.", "The A318 is a twin-engine, narrow-body airliner manufactured by Airbus.", "The A318 is a narrow-body aircraft produced by Airbus.", "The A318 is a twin-engine, single-aisle commercial jet.", " systemsThe A318 aircraft is a twin-engine, narrow-body jet airliner.", "The A318 is a narrow-body aircraft produced by Airbus.", "The A318 is a twin-engine, single-aisle commercial jet airliner manufactured by Airbus.", "The A318 has a cruising speed of 828km/h and a range of 12,064km.", "The A318 is a twin-engined narrow-body aircraft produced by Airbus.", "The Airbus A318 is a twin-engine, single-aisle commercial jet.", "The A318 is a twin-engine, single-aisle commercial jet airliner manufactured by Airbus.", "An A318, is a short-to-medium range narrow-body jet airliner.", "An A318 aircraft is a narrow-body, twin-engine jetliner manufactured by Airbus.", "An Airbus A318 is a narrow-body, twin-engine jet airliner manufactured by Airbus.", "The Airbus A318 is a narrow-body aircraft produced by Airbus.", "The Airbus A318 is a narrow-body aircraft produced by Airbus.", "An A318 is a commercial jet airliner typically used for short-haul flights.", "The Airbus A318 is a twin-engine, single-aisle commercial jet.", "The Airbus A318 is a twin-engine, single-aisle commercial jet airliner launched by Airbus in 1997."], "Falcon 900": ["The Falcon 900 is a twin-engine, long-range business jet aircraft produced by Dassault Aviation, the French aircraft manufacturer.", "The Falcon 900 is a twin-engine private jet manufactured by Dassault Aviation.", "The Falcon 900 is a private jet produced by Dassault Aviation.", "The Falcon 900 is a three-engine business jet produced by Dassault Aviation.", "The Falcon 900 is a long-range trijet corporate jet aircraft produced by Dassault Aviation.", "The Falcon 900 is a French-built private jet aircraft manufactured by Dassault Aviation.", "The Falcon 900 is a three-engine business jet produced by the French aircraft manufacturer Dassault Aviation.", "The Falcon 900 is a jet aircraft that seats up to 12 passengers and has a range of over 6,000 miles.", "The Falcon 900 is a three-engine business jet aircraft produced by Dassault Aviation.", "The Falcon 900 is a twin-engine business jet aircraft produced by the French manufacturer Dassault Aviation.", "The Falcon 900 is a French-built private jet aircraft made by Dassault Aviation.", "The Falcon 900 is a French-built business jet aircraft made by Dassault Aviation.", "The Falcon 900 is a French-built private jet aircraft made by Dassault Aviation.", "The Falcon 900 is a three-engine business jet produced by the French-American aircraft manufacturer Dassault Aviation.", "The Falcon 900 is a French-built business jet aircraft made by Dassault Aviation.", "The Falcon 900 is a French-built private jet aircraft with three engines, a low-wing monoplane with a T-tail.", "The Falcon 900 is a jet aircraft produced by the French manufacturer Dassault Aviation.", "The Falcon 900 is a private jet manufactured by Dassault Aviation.", "A Falcon 900 is a private jet that can seat up to 14 passengers.", "The Falcon 900 is a three-engine business jet produced by Dassault Aviation."], "A320": ["The A320 aircraft is a twin-engine, narrow-body aircraft that can seat up to 186 passengers.", "The A320 is a short- to medium-range, twin-engine jet airliner manufactured by Airbus.", "The A320 is a twin-engine short-haul aircraft that can carry up to 180 passengers.", "The A320 is a narrow-body aircraft produced by Airbus.", "The A320 aircraft is a twin-engine jet airliner developed and produced by Airbus.", "The A320 aircraft is a narrow-bodied jet airliner that typically seats between 150-180 passengers.", "The A320 aircraft is a twin-engine, single-aisle airplane that seats up to 180 passengers.", "The A320 aircraft is a twin-engine, single-aisle airplane that can seat up to 186 passengers.", "The A320 is a twin-engine short- to medium-range narrow-body aircraft.", "The A320 is a narrow-body aircraft manufactured by Airbus.", "The A320 is a narrow-body aircraft manufactured by Airbus.", "The A320 is a narrow-body aircraft produced by Airbus.", "An A320 is a commercial airliner that typically seats around 150 passengers.", "The A320 is a popular Airbus aircraft that can seat up to 180 passengers.", "An A320 aircraft is a narrow-bodied commercial passenger jet.", "An A320 is a single-aisle, twin-engine jetliner typically configured with 150-180 seats.", "An A320 aircraft is a twin-engine, single-aisle commercial jet.", "An A320 is a narrow-body aircraft manufactured by Airbus.", "An A320 aircraft is a narrow-body, twin-engine jet airliner manufactured by Airbus.", "An A320 aircraft is a twin-engine, single-aisle airplane that can seat up to 180 passengers."], "PA-28": ["The Piper PA-28 is a family of light aircraft built by Piper Aircraft.", "The Piper PA-28 Cherokee is a family of light aircraft built by Piper Aircraft.", "The Piper PA-28 aircraft is a four-seat, single-engine airplane.", "The Piper PA-28 Cherokee is a light aircraft manufactured by Piper Aircraft.", "The Piper PA-28 Cherokee is a family of light aircraft built by Piper Aircraft.", "The people's aircraft, or PA-28, is a family of light aircraft manufactured by Piper Aircraft.", "The Piper PA-28 Cherokee is a four-seat general aviation aircraft produced by Piper Aircraft since the 1960s.", "The Piper PA-28 Cherokee is a family of light aircraft built by Piper Aircraft.", "The PA-28 is a small, single-engine piston airplane.", "The Piper PA-28 is a family of small aircraft designed for flight training and general aviation.", "The PA-28 is a fixed-wing, four-seat, single-engine airplane.", "A PA-28 aircraft is a small, four-seat, single-engine airplane.", "A Piper PA-28 is a single-engine, propeller-driven airplane.", "Single-engine, low-wing monoplane.", "The Piper PA-28 Cherokee is a four-seat light aircraft produced by Piper Aircraft.", "A Piper PA-28 Cherokee is a light aircraft made by Piper Aircraft.", "The Piper PA-28 Cherokee is a family of light aircraft built by Piper Aircraft.", "The Piper PA-28 Cherokee is a four-seat, single-engine light aircraft manufactured by Piper Aircraft.", "The Piper PA-28 Cherokee is a light aircraft designed for flight training, air taxi and personal use.", "A PA-28 aircraft is a single-engine, four-seat light airplane manufactured by Piper Aircraft."], "747-100": ["The 747-100 is a wide-body aircraft with four engines.", "The 747-100 was first introduced in 1968 and was the first model of the 747 aircraft.", "The 747-100 was the first production version of the 747 and was the first wide-body airliner.", "The 747-100 is a wide-body jet airliner that was built by Boeing in the early 1970s.", "The 747-100 aircraft is a large, long-range airliner with four engines mounted on pylons under the wings.", "The 747-100 was the first 747 model, and was launched in 1966.", "The 747-100 aircraft is a four-engine, wide-body commercial jet liner that was produced from 1968 to 1986.", "The Boeing 747-100 was the first 747 model produced, and was the first wide-body commercial airplane manufactured by Boeing.", "The 747-100 was the first 747 model produced, and was the first wide-body jetliner built.", "The 747-100 is a four-engine jet airliner that was manufactured by Boeing between 1968 and 1980.", "The first 747-100 aircraft was delivered to Pan American World Airways in 1970.", "The 747-100 is a widebody commercial airliner that was produced by Boeing between 1968 and 1981.", "The 747-100 was the first variant of the 747 and was succeeded by the 747-200.", "The 747-100 is a wide-body aircraft with a double-deck configuration and a capacity of up to 366 passengers in a three-class cabin layout, or up to 524 passengers in a two-class layout.", "The 747-100 is a large, long-range jetliner originally designed to be a transcontinental airliner, but was later modified to a international wide-body airliner.", " Designed in the 1960s, the Boeing 747-100 was the first 747 model produced.", "The 747-100 was the very first model of the 747, and was first flown in 1969.", "The 747-100 is a jumbo jet airliner that was first introduced in 1970.", "A 747-100 is a large, long-range jetliner that was first introduced in 1970.", "The 747-100 is a four-engine wide-body jet airliner, and was the first wide-body jetliner built."], "A380": ["The Airbus A380 is a four-engine long-range wide-body airliner with a capacity of up to 853 passengers in a three-class configuration.", "The A380 is the world's largest commercial passenger jet, with a flight deck that is almost two stories high and a wingspan that extends more than 80 meters from tip to tip.", "The Airbus A380 is a wide-body airliner manufactured by Airbus.", "The A380 aircraft is the world's largest passenger airliner, and is a double-deck, wide-body, four-engine jet airliner manufactured by Airbus.", "The A380 is an extra widebody, twin-deck airliner manufactured by Airbus.", "The A380 is a double-deck, wide-body, four-engine jet airliner manufactured by Airbus.", "The A380 is a large, double-decked airliner with four engines.", "The A380 is a wide-body aircraft manufactured by Airbus.", "The Airbus A380 is the world's largest commercial jet.", "The A380 is among the world\u2019s largest airliner, a wide-body aircraft manufactured by Airbus.", "The A380 is a wide-body, long-range commercial jetliner.", "Free-body diagram of an A380 aircraft.", "The A380 is a large, long-range jet airliner designed to carry up to 853 passengers.", "An A380 is a double-deck, wide-body, four-engine jet airliner manufactured by Airbus.", "The A380 is a double-deck, wide-body, four-engine jet airliner manufactured by Airbus.", "The A380 is a wide-body aircraft manufactured by Airbus SE.", "The A380 is a double-deck, wide-body, four-engine airliner manufactured by Airbus.", "An A380 is a double-deck, wide body, four-engine jet airliner.", "The Airbus A380 is a double-deck, twin-engine airliner manufactured by Airbus.", "The A380 is an ultra-large, long-range commercial passenger jet manufactured by European aerospace manufacturer Airbus."], "C-130": ["The Lockheed C-130 Hercules is an American four-engine turboprop military transport aircraft designed and built originally by Lockheed.", "The Lockheed C-130 Hercules is a four-engine turboprop military transport aircraft designed and built by Lockheed.", "The C-130 is a four-engine turboprop transport aircraft used for hauling cargo, carrying troops, and conducting airdrops.", "The Lockheed C-130 Hercules is an American four-engine turboprop military transport aircraft designed and built originally by Lockheed.", "The Lockheed C-130 Hercules is an American four-engine turboprop military transport aircraft designed and built originally by Lockheed.", "The C-130 is a four-engine turboprop transport aircraft designed and built by Lockheed Martin.", "The Lockheed C-130 Hercules is an American four-engine turboprop military transport aircraft designed and built originally by Lockheed.", "The Lockheed C-130 Hercules is an American four-engine turboprop military transport aircraft designed and built originally by Lockheed (now Lockheed Martin).", "The C-130 is a four-engine turboprop military transport aircraft designed and built by Lockheed.", "The Lockheed C-130 Hercules is an American four-engine turboprop military transport aircraft designed and built originally by Lockheed.", "The Lockheed C-130 Hercules is an American four-engine turboprop military transport aircraft designed and built originally by Lockheed.", "The Lockheed C-130 Hercules is an American four-engine turboprop military transport aircraft designed and built originally by Lockheed.", "A C-130 aircraft is a four-engine turboprop military transport plane.", "The Lockheed C-130 Hercules is an American four-engine turboprop military transport aircraft designed and built originally by Lockheed.", "The Lockheed Martin C-130J Super Hercules is an American four-engine turboprop military transport aircraft.", "A C-130 aircraft is a four-engine turboprop military transport plane.", "The Lockheed C-130 Hercules is an American four-engine turboprop military transport aircraft designed and built originally by Lockheed.", "The Lockheed C-130 Hercules is an American four-engine turboprop military transport aircraft designed and built originally by Lockheed.", "The Lockheed C-130 Hercules is an American four-engine turboprop military transport aircraft designed and built originally by Lockheed.", "A C-130 aircraft is a four-engine turboprop military transport plane."], "A310": ["The Airbus A310 is a medium- to long-range twin-engined wide-body jet airliner that was introduced in 1983.", "The Airbus A310 is a medium- to long-range twin-engined wide-body jet airliner that was developed and manufactured by Airbus.", "The A310 is a twin-engined wide-body aircraft produced by Airbus Industrie, the european consortium.", "The Airbus A310 is a two-engine, wide-body commercial passenger jet aircraft.", "The A310 is a twin-engine, long-range passenger jetliner that was developed and manufactured by Airbus.", "The A310 is a twin-engine, wide-body jetliner that was produced by Airbus from 1983 to 2007.", "The A310 is a twin-engine, widebody aircraft created by Airbus.", "The A310 is a twin-engined, long-range passenger jetliner that was manufactured by Airbus.", "Developed in the 1970s by Airbus, the A310 is a two-engine, long-range commercial aircraft.", "The A310 is a twin-engined, long-range widebody airliner with a capacity of up to 210 passengers.", "The A310 is a medium-to-long range twin-engined widebody passenger airliner developed and manufactured by Airbus.", "The Airbus A310 is a twin-engine, long-range commercial passenger jet airliner that was operated by Lufthansa from 1983 to 1991.", "An A310 aircraft is a large twin-engine jet airliner that was manufactured by Airbus.", "An A310 aircraft is a twin-engine, long-range commercial jetliner.", "The A310 is a twinjets medium-range airliner created by Airbus.", "The Airbus A310 is a twin-engined, long-range passenger jetliner that was manufactured by Airbus.", "The A310 is a twin-engined, long-range passenger jet airliner.", "The A310 is a long-range, twin-engine, wide-body airliner manufactured by Airbus Industrie, then known as European Aeronautic Defence and Space Company (EADS).", "The Airbus A310 is a twin-engined wide-body airliner that was manufactured by Airbus.", "An Airbus A310 is a twin-engined long-range wide-body aircraft produced by Airbus."], "727-200": ["The 727-200 is a twin-engine, medium-range jet airliner that was first introduced in 1963 by Boeing.", "The 727-200 is a narrow-body airliner produced by Boeing Commercial Airplanes.", "The Boeing 727 is a jet airliner.", "The 727-200 is a twin-engine jetliner that was first introduced by Boeing in 1963.", "The 727-200 is a twin-engined short- to medium-range narrow-body airliner with a capacity of maximum 149 passengers produced by Boeing.", "The 727-200 is a twin-engined narrow-body aircraft produced by Boeing Commercial Airplanes.", "- designed as a shorter, range-extended successor to the 707-120/-220\n- first 727-200 delivered to launch customer United Airlines on December 28, 1967\n- 2,831 built\n- typical configuration.", " (as of 2016)The 727-200 was first introduced in 1963 and was in production until 1984.", "The 727-200 is a twin-engined narrow-body airliner with a capacity of up to 149 passengers produced by Boeing Commercial Airplanes.", "Boeing 727-200 aircraft are twin-engine, long-range jets that can carry up to 189 passengers.", "The 727-200 is a twin-engine, narrow-body jet airliner.", "The 727-200 is a mid-size, wide-body jetliner that was first introduced in 1963.", "The 727-200 is a mid-size, twin-engine jet airliner that was produced by Boeing Commercial Airplanes from 1963 to 1984.", "The 727-200 is a twin-engined, narrow-body airliner designed and built by Boeing.", "A 727-200 is a twin-engined, medium-range airliner that was first introduced in 1963.", "The 727-200 was the workhorse of the commercial aviation industry in the 1960s and 1970s.", "Type: Twin JetSeats: 128-189Range: 2,600-3,900 milesCost: $20.", "A 727-200 is an American narrow-body jet airliner that was produced by Boeing Commercial Airplanes.", "The 727-200 is a twin-engined mid-size narrow-body aircraft produced by Boeing Commercial Airplanes from 1963 to 1984.", "\nThe 727-200 is a narrow-body airliner produced by Boeing."], "L-1011": ["The Lockheed L-1011 TriStar, commonly referred to as the L-1011 or TriStar, is a medium- to long-range, wide-body jet airliner that was first introduced in 1972.", "The L-1011 aircraft is a twin-engine, Wide-body aircraft that was manufactured by Lockheed.", "The Lockheed L-1011 TriStar, commonly referred to as the L-1011 or TriStar, is a medium- to long-range, wide-body airliner produced by the American manufacturer Lockheed Corporation.", "The Lockheed L-1011 TriStar, commonly referred to as the L-1011 or TriStar, is a medium- to long-range, wide-body trijet airliner.", "The Lockheed L-1011 TriStar, commonly referred to as the L-1011 or TriStar, is a medium- to long-range, wide-body trijet airliner.", "The Lockheed L-1011 TriStar, commonly referred to as the L-1011 or TriStar, is a medium- to long-range, wide-body trijet airliner manufactured by Lockheed Corporation.", "The Lockheed L-1011 TriStar, commonly referred to as the L-1011 or TriStar, is a medium-to-long-range, wide-body trijet airliner.", "The L-1011 is a wide-bodied aircraft with three engines and a capacity of up to 400 passengers.", "The Lockheed L-1011 TriStar, commonly referred to as the L-1011 or TriStar, is a medium- to long-range, wide-body trijet airliner manufactured by Lockheed Corporation.", "The Lockheed L-1011 TriStar, commonly referred to as the L-1011 or TriStar, is a medium-to-long-range, wide-body trijet airliner by Lockheed Corporation.", "The Lockheed L-1011 TriStar, commonly referred to as the L-1011 or TriStar, is a medium-to-long-range, wide-body trijet airliner by Lockheed Corporation.", "The Lockheed L-1011 TriStar, commonly referred to as the L-1011 or TriStar, is a medium-to-long-range, wide-body three-engine jet airliner that was produced by Lockheed.", "A Lockheed L-1011 TriStar, also referred to as an L-1011 or TriStar, is a medium- to long-range, wide-body trijet aircraft manufactured by Lockheed Corporation.", "The Lockheed L-1011 TriStar, commonly referred to as the L-1011 or TriStar, is a medium-to-large capacity long-range wide-body triple-engine jet airliner.", "The L-1011 is a wide-body aircraft that was produced by the US-based manufacturer Lockheed Corporation.", "The Lockheed L-1011 TriStar, commonly referred to as the L-1011 (pronounced \"L-ten-eleven\") or TriStar, is a medium-to-long-range, wide-body trijet.", "The Lockheed L-1011 TriStar, commonly referred to as the L-1011 or TriStar, is a medium-to-long-range, wide-body trijet airliner produced by Lockheed Corporation.", "An L-1011 aircraft is a wide-body jet airliner that was produced by Lockheed Corporation between 1968 and 1984.", "The L-1011 is a wide-body aircraft manufactured by Lockheed.", "The Lockheed L-1011 TriStar, commonly referred to as the L-1011 or TriStar, is a medium-to-long-range, wide-body trijet airliner produced by Lockheed Corporation."], "A321": ["The A321 is a twin-engine, single-aisle plane that can carry up to 185 passengers.", "The A321 is a narrow-body aircraft produced by Airbus.", "The A321 is a twin-engine, single-aisle aircraft that is part of the A320 family of aircraft.", "The A321 is a single aisle, twin engine jet manufactured by Airbus.", "The A321 is a single-aisle, twin-engine jetliner that was first delivered in 1987.", "The A321 is a single-aisle, twin-engine jetliner that offers a quiet, comfortable ride with the widest seats in its class.", "The A321 is a twin-engine, single-aisle plane that can seat up to 185 passengers.", "The A321 aircraft is a narrow-body, twin-engine jetliner that is produced by Airbus.", "The A321 is a single-aisle, twin-engine jetliner that was designed for short to medium-haul flights.", "The A321 aircraft is a single aisle, twin-engine plane that can seat up to 185 passengers.", "An A321 aircraft is a large single-aisle commercial passenger airliner typically used on medium-haul routes.", "The A321 is a single-aisle, twin-engine jetliner.", "The A321 is a narrow-body, long-range jetliner manufactured by Airbus.", "The A321 is a twin-engine aircraft that can carry up to 220 passengers.", "The A321 is a twin-engine, single-aisle aircraft that can carry up to 185 passengers.", "The A321 is a single-aisle aircraft that can seat up to 185 passengers.", "An A321 is a narrow-body aircraft with two aisles, manufactured by Airbus.", "The A321 is a single-aisle, twin-engine jet airliner that was developed by Airbus.", "The Airbus A321 is a single-aisle, twin-engine jetliner typically configured with 185 seats.", "The A321 is a single-aisle, twin-engine jetliner that is part of the Airbus A320 family."], "A319": ["The A319 is a narrow-body aircraft that is part of the A320 family.", "The Airbus A319 is a member of the A320 family of short- to medium-range, narrow-body, commercial passenger twin-engine jet airliners manufactured by Airbus.", "The A319 is a narrow-body aircraft that is often used for short to medium-haul flights.", "The A319 aircraft seats up to 160 passengers and has a range of 3,700 nautical miles.", "The A319 is a twin-engine, single-aisle commercial jet developed by Airbus.", "The A319 is a narrow-body aircraft produced by Airbus.", "The A319 is a twin-engine, single-aisle commercial jet airliner manufactured by Airbus.", "The A319 is a short- to medium-range twin-engined narrow-body aircraft manufactured by Airbus.", "The A319 is a twin-engine, single-aisle commercial jet.", "The A319 is a narrow-body aircraft that is typically used for short to medium-haul flights.", "The A319 is a short to medium range, single aisle commercial jet airliner that is manufactured by Airbus.", "An A319 is a short- to medium-range narrow-body aircraft manufactured by Airbus.", "An A319 aircraft is a jet airplane typically used for commercial flights.", "The A319 is a single-aisle, twin-engine jetliner that is part of the Airbus A320 family of aircraft.", "The A319 is a popular commercial passenger jet produced by Airbus.", "An A319 is a narrow-body aircraft that normally seats 124-156 passengers.", "The A319 is a narrow-body aircraft that is often used for short to medium-haul flights.", "An Airbus A319 is a single-aisle commercial jet airplane manufactured by Airbus.", "The A319 is a single-aisle commercial jet aircraft manufactured by Airbus.", "The A319 is a twin-engine, narrow-body aircraft that has a capacity of 140-156 passengers."], "MD-90": ["The MD-90 is a twin-engine short- to medium-range commercial airliner.", "The McDonnell Douglas MD-90 is a twin-engine, short- to medium-range commercial jet airliner.", "The McDonnell Douglas MD-90 is a twin-engine short- to medium-range airliner.", "The MD-90 is a twin-engine, short- to medium-range commercial airliner.", "The McDonnell Douglas MD-90 is a twin-engine, short- to medium-range commercial airliner.", "The MD-90 is a twin-engine, single-aisle commercial jetliner that was introduced in October 1995 by McDonnell Douglas.", "The McDonnell Douglas MD-90 is a twin-engine, single-aisle jetliner.", "The McDonnell Douglas MD-90 is a twin-engine, short- to medium-range commercial jet airliner.", "The MD-90 is a twin-engine, narrow-body airliner manufactured by McDonnell Douglas.", "The MD-90 is a twin-engine, narrow-body jet airliner manufactured by McDonnell Douglas (now part of Boeing).", "The McDonnell Douglas MD-90 is a twin-engine, short- to medium-range commercial passenger jet.", "The McDonnell Douglas MD-90 is a twin-engine, short- to medium-range commercial airliner.", "The McDonnell Douglas MD-90 is a twin-engine, short-range commercial jet airliner.", "The MD-90 is a twin-engine, short- to medium-range commercial jet airliner.", "The McDonnell Douglas MD-90 is a twin-engine, short-range commercial jetliner.", "The McDonnell Douglas MD-90 is a twin-engine, short- to medium-range commercial airliner.", "The McDonnell Douglas MD-90 is a twin-engine, short- to medium-range commercial jet airliner.", "The McDonnell Douglas MD-90 is a twin-engine, short- to medium-range commercial jet airliner.", "The McDonnell Douglas MD-90 is a twin-engine, short- to medium-range commercial jet airliner.", "A McDonnell Douglas MD-90 is a twin-engine, short- to medium-range commercial jet airliner."], "Fokker 50": ["The Fokker 50 is a twin-turboprop passenger aircraft, introduced in 1985.", "The Fokker 50 is a twin-turboprop passenger airline aircraft.", "The Fokker 50 is a twin-turboprop aircraft manufactured by the Dutch aircraft manufacturer Fokker.", "The Fokker 50 is a medium-sized, twin-engined turboprop passenger airliner.", "The Fokker 50 is a twin-turboprop passenger aircraft, introduced in 1985.", "The Fokker 50 is a twin-turboprop commuter aircraft designed and built by Fokker.", "The Fokker 50 is a twin-turboprop regional airliner with short take-off and landing (STOL) capability.", "The Fokker 50 aircraft is a twin-engine turboprop passenger plane that can seat up to 50 passengers.", "The Fokker 50 is a Dutch turboprop-powered airliner, designed as a refinement of and successor to the highly successful Fokker F27 Friendship.", "The Fokker 50 is a turboprop-powered airliner, designed as an improvement over the earlier Fokker F27 Friendship.", "The Fokker 50 is a twin-turboprop passenger aircraft designed and built by Fokker.", "The Fokker 50 is a twin-turboprop passenger aircraft, manufactured by the Dutch aircraft manufacturer Fokker.", "A Fokker 50 is a regional turboprop airliner produced by the Dutch aerospace manufacturer Fokker.", "The Fokker 50 is a twin-turboprop commuter airliner designed and built by the Dutch aerospace manufacturer Fokker.", "The Fokker 50 is a turboprop-powered airliner, designed and built by the Dutch aircraft manufacturer Fokker.", "The Fokker 50 is a twin-turboprop passenger aircraft, seating up to 80 passengers in a pressurised cabin.", "The Fokker 50 is a twin-turboprop small airliner designed and built by the now-defunct Fokker company.", "The Fokker 50 is a Dutch turboprop-powered airliner, designed as a refinement of and successor to the highly successful Fokker F27 Friendship.", "The Fokker 50 is a twin-turboprop passenger aircraft designed by the Dutch company Fokker.", "The Fokker 50 is a Dutch turboprop-powered airliner, designed as a refinement of and successor to the highly successful Fokker F27 Friendship."], "767-400": ["The aircraft is a wide-body twinjet airliner with a capacity of 350 passengers.", "The 767-400 is a twin-engined wide-body airliner with a capacity of up to 375 passengers, developed by Boeing Commercial Airplanes.", "The 767-400 is a long-range, wide-body twin-engine jet airliner that was developed by Boeing Commercial Airplanes.", "The 767-400 is a twin-engine wide-body jetliner produced by Boeing Commercial Airplanes.", "The 767-400 is a wide-body airliner produced by Boeing Commercial Airplanes.", "The 767-400 is a wide-body airliner produced by Boeing Commercial Airplanes.", "The 767-400 is a mid-size, twin-engine jetliner that was introduced in 2000.", "The 767-400 is a wide-body airliner produced by Boeing Commercial Airplanes.", "The 767-400 is a twin-engined short- to medium-range commercial airliner with a capacity of 250 passengers, derived from the 767-300.", "The 767-400 is a mid-size, twin-engine jet airliner that was introduced in 2000.", "The 767-400 is a wide-body aircraft with a capacity of up to 375 passengers.", "The 767-400 is a wide-body jetliner that was introduced in 2000.", "The 767-400 is a wide-body airplane produced by Boeing Commercial Airplanes.", "The 767-400 is a twin-engined wide-body jet airliner with a capacity of 375 passengers, developed by Boeing Commercial Airplanes.", "A 767-400 aircraft is a twin-engine, wide-body commercial airliner with a capacity of up to 375 passengers.", "A 767-400 aircraft is a twin-engine, wide-body jet that can seat up to 375 passengers.", "The 767-400 is a wide-body airliner produced by BoeingCommercial Airplanes.", "The 767-400 is a wide-body twin-engine jetliner produced by Boeing Commercial Airplanes.", "The 767-400 is a wide-body jet airliner produced by Boeing Commercial Airplanes.", "The 767-400 is a mid-size, wide-body twin-engine jetliner that was introduced in 2000."], "BAE 146-300": ["The BAE 146-300 aircraft is a short-haul airliner that was manufactured by British Aerospace.", "The BAE 146-300 is a high-performance turbofan-powered airliner.", "The BAE 146-300 is a high-performance turbofan-powered regional airliner.", "The BAE 146-300 is a short-haul aircraft manufactured by British Aerospace.", "The BAE 146-300 aircraft is a short-haul passenger jet that can seat up to 100 passengers.", "The BAE 146-300 is a twin-engine regional airliner that was introduced in 1983.", "The BAE 146-300 is a high-performance jetliner that offers superior comfort and a smooth ride.", "The BAE 146-300 is a turbofan-powered airliner.", "The BAE 146-300 is a short-haul passenger plane that can seat up to 119 passengers.", "The BAE 146-300 is an aircraft that was manufactured by British Aerospace.", "The BAE 146-300 is a short-haul airliner that was introduced in 1995.", "The BAE 146-300 is a short-haul aircraft with a capacity of up to 130 passengers.", "The BAE 146-300 is a short-haul passenger aircraft.", "The BAE 146-300 is a short-haul passenger jet designed for regional airlines.", "The BAE 146-300 is a short-haul aircraft manufactured by British Aerospace.", "The BAE 146-300 is a turbofan-powered regional airliner with a trijet layout.", "The BAE 146-300 is a short-haul airliner that was produced by British Aerospace (now BAE Systems).", "A BAE 146-300 is a British four-engined turboprop regional airliner with a seating capacity of up to 146 passengers, manufactured by British Aerospace (now BAE Systems).", "The BAE 146-300 is a British Short-Haul Airliner that was manufactured by British Aerospace.", "A BAE 146-300 aircraft is a twin-engine, short-haul airliner that was manufactured by British Aerospace (now BAE Systems)."], "E-190": ["The Embraer E-190 is a narrow-body, twin-engine, jet airliner manufactured by Embraer, a Brazilian aerospace company.", "The E-190 aircraft is a twin-engine, single-aisle jet that can seat up to 110 passengers.", "The E-190 aircraft is a twin-engine regional jet that was designed and manufactured by Embraer, a Brazilian aerospace company.", "The E-190 aircraft is a narrow-body, twin-engine jetliner manufactured by Embraer, a Brazilian aerospace company.", "The Embraer E-190 is a twin-engine aircraft with a capacity of up to 114 passengers.", "The E-190 is a twin-engine, single-aisle jet aircraft manufactured by Embraer.", "The E-190 aircraft is a narrow-body, twin-engine jet airliner manufactured by Brazilian aerospace company Embraer.", "The E-190 is a single-aisle turbofan jet airliner manufactured by Embraer, a Brazilian aerospace company.", "The Embraer 190 is a narrow-body jet airliner manufactured by Embraer, a Brazilian aerospace company.", "The Embraer 190 is a twin-engine jet airliner manufactured by Embraer, a Brazilian aerospace company.", "The E-190 aircraft is a twin-engine jet Airliner manufactured by Embraer.", "The E-190 is a twin-engine, single-aisle commercial jet.", "An E-190 aircraft is a twin engine commercial jet that can seat up to 114 passengers.", "The E-190 aircraft is a twin-engine, single-aisle jetliner that is designed for short-haul flights.", "The E-190 aircraft is a narrow-body, twin-engine jet airliner manufactured by Embraer.", "The Airbus A-319 is a single-aisle, twin-engine jetliner typically configured with 124 seats.", "The Embraer E-190 is a Brazilian twin-engine turbofan airliner.", "The E-190 is a twin-engine, single-aisle jet aircraft manufactured by Brazilian aerospace company Embraer.", "An E-190 aircraft is a narrow-bodied, twin-engine jetliner manufactured by Embraer, a Brazilian aerospace company.", "The E-190 is a twin-engine, single aisle jet commercial airliner."], "737-800": ["The 737-800 is a twin-engined short-to-medium-range narrow-body airliner with a capacity of162 passengers produced by the American manufacturer Boeing Commercial Airplanes.", "The 737-800 is a twin-engine short-to-medium-range narrowbody airliner with a capacity of 162 passengers in a two-class configuration.", "The 737-800 is a twin-engined short-to-medium-range narrow-body airliner with a capacity of 162 passengers, produced by American manufacturer Boeing Commercial Airplanes.", "The 737-800 is a twin-engined short-haul aircraft with a capacity of 162 passengers.", "The 737-800 is a short-to-medium range, single-aisle airliner.", ".", "The 737-800 is a twin-engine jet airliner typically used for short-haul and long-haul flights.", "The 737-800 is a popular short-to-medium range narrowbody airliner.", "The 737-800 is a narrow-body aircraft produced by Boeing Commercial Airplanes.", "The 737-800 is a twin-engine short-to-medium-range narrow-body airliner.", "The 737-800 is a twin-engined short-to-medium-range narrow-body airliner with a capacity of 162 passengers, produced by the American manufacturer Boeing Commercial Airplanes.", "The 737-800 is a twin-engined short-to-medium-range narrow-body airliner with a capacity of 162 passengers, produced by the American manufacturer Boeing Commercial Airplanes.", "A 737-800 is a twin-engine short-to-medium-range narrow-body airliner with a capacity of 162 passengers.", "A Boeing 737-800 is a plane typically used for short to medium-haul flights.", "The 737-800 is a short-to-medium range, single-aisle jet airliner.", "The 737-800 is a twin-engine short- to medium-range narrowbody airliner with a capacity of 162 passengers produced by Boeing Commercial Airplanes.", "The 737-800 is a twin-engine, short-to-medium-range airplane that first flew in 1991.", "The 737-800 is a member of the 737 Next Generation family of Passenger airplanes.", "A Boeing 737-800 is a twin-engine short-to-medium range airplane.", "The Boeing 737-800 is a twin-engined short-to-medium-range narrow-body airliner with a capacity of 162 passengers, produced by the American manufacturer Boeing Commercial Airplanes."], "Embraer Legacy 600": ["The Embraer Legacy 600 is a twin-engine business jet that was introduced in 1995.", "The Embraer Legacy 600 is a mid-size business jet produced by Brazilian aircraft manufacturer Embraer.", "The Embraer Legacy 600 is a business jet manufactured by Embraer.", "The Embraer Legacy 600 is a Brazilian business jet manufactured by Embraer.", "The Embraer Legacy 600 is a business jet aircraft produced by Brazilian manufacturer Embraer.", "The Embraer Legacy 600 is a twin-engine business jet.", ";The Embraer Legacy 600 is a business jet aircraft produced by Brazilian manufacturer Embraer.", "The Embraer Legacy 600 is a twin-engine business jet aircraft developed by Brazilian aerospace manufacturer Embraer.", "The Embraer Legacy 600 is a business jet aircraft manufactured by Embraer.", "The Embraer Legacy 600 is a medium-size twin-engine business jet manufactured by Brazilian aerospace manufacturer Embraer.", "The Embraer Legacy 600 is a medium-size, twin-engine corporate jet that seats up to 13 passengers.", "The Embraer Legacy 600 is a midsize business jet that was introduced in 2003.", "Embraer's Legacy 600 is a super-midsize business jet that offers comfortable seating for up to 13 passengers.", "The Embraer Legacy 600 is a large business jet aircraft produced by the Brazilian manufacturer Embraer.", "The Embraer Legacy 600 is a business jet aircraft manufactured by Brazilian aerospace manufacturer Embraer.", "The Embraer Legacy 600 is a twin-engine business jet that can seat up to 13 passengers.", "The Embraer Legacy 600 is a twin-engine business jet aircraft produced by Brazilian manufacturer Embraer.", "The Embraer Legacy 600 is a midsize business jet aircraft produced by Brazilian manufacturer Embraer.", "The Legacy 600 is a twin-engine business jet produced by Brazilian aerospace manufacturer Embraer.", "The Embraer Legacy 600 is a business jet aircraft produced by Brazilian manufacturer Embraer."], "737-200": ["The 737-200 aircraft was first introduced in 1967 and was in production until 1988.", "The 737-200 is a twin-engined short-haul jet airliner with a capacity of maximum 149 passengers produced by the American manufacturer Boeing Commercial Airplanes.", "The 737-200 is a twin-engined short-to-medium-range aircraft, with a capacity of 130 passengers and a range of 2, 950km.", "The 737-200 is a twin-engined short-to-medium-range narrow-body jet airliner which was produced by Boeing Commercial Airplanes.", "The 737-200 is a twin-engined short-to-medium-range narrow-body jetsliner produced by Boeing Commercial Airplanes.", "The 737-200 is a twin-engined short-to-medium-range narrow-body airliner with a capacity of maximum 149 passengers produced by Boeing Commercial Airplanes.", "The 737-200 is a twin-engined short-to medium-range narrowbody airliner developed and manufactured by Boeing Commercial Airplanes.", "The 737-200 is a twin-engined short-haul aircraft with a range of about 2,000 kilometers.", "The Boeing 737-200 is a twin-engined short-to-medium-range narrowbody airliner with a capacity of maximum 149 passengers produced by the American manufacturer Boeing Commercial Airplanes.", "The Boeing 737-200 is a twin-engined short-to-medium-range narrow-body airliner developed and manufactured by Boeing Commercial Airplanes.", "The 737-200 aircraft is a twin-engined, short- to medium-range passenger jetliner.", "The 737-200 is a twin-engined short-to-medium-range narrow-body jet airliner.", "The 737-200 is a narrow-body aircraft produced by Boeing Commercial Airplanes from 1967 to 1988.", "The 737-200 is a twin-engine, short-to-medium-range airliner.", "The 737-200 is a twin-engined short-to-medium-range narrowbody aircraft with a capacity of maximum 149 passengers produced by Boeing Commercial Airplanes.", "The 737-200 is a twin-engined short-haul airliner with a capacity of up to 140 passengers, produced by Boeing Commercial Airplanes from 1967 to 1988.", "The 737-200 is a twin-engine, narrow-body jet airliner that was produced by Boeing Commercial Airplanes from 1967 to 1988.", "The 737-200 is a twin-engined short-to-medium-range narrow-body jet airliner.", "The Boeing 737-200 is a twin-engined short-to-medium-range narrowbody aircraft with a capacity of maximum 148 passengers produced by the American manufacturer Boeing Commercial Airplanes.", "The Boeing 737-200 is a twin-engined short-to-medium-range narrow-body airliner with a capacity of maximum 149 passengers produced by the American manufacturer Boeing Commercial Airplanes."], "737-600": ["The 737-600 is a twin-engine short-to-medium-range narrowbody airliner, typically seating 132 passengers in a two-class configuration.", "The 737-600 is a twin-engined short-to-medium-range narrow-body airliner with a capacity of 108 passengers, produced by Boeing Commercial Airplanes.", "The 737-600 is a twin-engine, short-to-medium-range airplane.", "The 737-600 is a narrow-bodied aircraft that seats up to 132 passengers.", "The 737-600 is a twin-engine short-to-medium-range narrow-body airliner.", "The Boeing 737-600 is a twin-engine short-to-medium-range narrow-body airliner.", "The 737-600 is a narrow-body aircraft produced by Boeing.", "The 737-600 aircraft is a narrow-bodied, twin-engined jet airliner.", "The 737-600 is a twin-engined short-haul jetliner with a capacity of 108 passengers, designed by Boeing Commercial Airplanes.", "The 737-600 is a twin-engine short-to-medium range narrowbody airliner.", "The 737-600 is a twin-engine short-to-medium-range narrow-body jet airliner.", "The 737-600 is a twin-engine, single-aisle jetliner that seats up to 132 passengers.", "The 737-600 is a twin-engine short-to-medium-range narrowbody airliner.", "The 737-600 is a twin-engined short-haul aircraft flying at low-altitudes.", "A 737-600 aircraft is a narrow-body, twin-engine jet plane typically used for short-haul flights.", "The 737-600 is a twin-engine short-to-medium range passenger jetliner.", "The 737-600 is a twin-engine jet airliner that typically seats 110 passengers.", "The 737-600 is a twin-engined short-to-medium-range narrow-body aircraft with a capacity of maximum 149 passengers produced by the American manufacturer Boeing Commercial Airplanes.", "The 737-600 is a twin-engine, single-aisle commercial jetliner that was first introduced in 1998 by Boeing.", "The 737-600 is a twin-engined short-to-medium-range narrowbody airliner with a capacity of 132 passengers, produced by Boeing Commercial Airplanes."], "A330-300": ["The A330-300 is a twin-engine wide-body Airbus A330 aircraft.", "The A330-300 is a long-range, wide-body twin-engine jet airliner made by Airbus.", "The Airbus A330-300 is a twin-aisle, wide-body aircraft produced by Airbus.", "The A330-300 is a twin-engine, wide-body aircraft produced by Airbus.", "The A330-300 is a twin-engine, wide-body aircraft produced by Airbus.", "The A330-300 is a long-range, wide-body airliner produced by Airbus.", "The A330-300 is a twin-engine, wide-body airliner manufactured by Airbus.", "The A330-300 is a twin-engine, wide-body aircraft produced by Airbus.", "The A330-300 is a twin-aisle, twin-engine aircraft that can seat up to 300 passengers.", "The A330-300 is a twin-aisle, wide-body aircraft with a maximum capacity of 300 passengers.", "An A330-300 aircraft has a Wingspan of 197 ft.", "The Airbus A330-300 is a twin-engine, wide-body aircraft produced by Airbus.", "The Airbus A330-300 is a wide-body aircraft produced by Airbus.", "The A330-300 is a wide-body aircraft produced by Airbus.", "The A330-300 is a twin-engine widebody jet Airliner with a capacity of 300 passengers.", "An A330-300 is a twin-engined, wide-body aircraft manufactured by Airbus.", "The A330-300 is a wide-body aircraft with two aisles and a maximum capacity of 300 passengers.", "The A330-300 is a twin-aisle, wide-body aircraft with a maximum seating capacity of 300 passengers.", "The A330-300 is a wide-body airliner produced by Airbus.", "An A330-300 aircraft typically has a range of approximately 14,000km and can seat between 250 and 300 passengers."], "DH-82": ["The de Havilland Canada DHC-2 Beaver is a single-engined, high-wing, fixed-tricycle-gear general aviation aircraft manufactured by de Havilland Canada.", "The DH-82 is a single-engine, high-wing aircraft used for training and general aviation purposes.", "The DH-82 aircraft is a British-built twin-engined light transport aircraft.", "The de Havilland Canada DHC-8, also known as the Dash 8, is a series of turboprop-powered regional airliners.", "The de Havilland Canada DHC-8, commonly known as the Dash 8, is a series of twin-engined, medium-range, turboprop airliners.", "The de Havilland Canada DHC-8, commonly known as the Dash 8, is a series of twin-engine, turboprop regional airliners.", "The de Havilland Canada DHC-82 Tiger Moth is a biplane designed by Geoffrey de Havilland and operated primarily by the Royal Air Force (RAF) and other European air forces during World War II.", "The de Havilland DH 82 Tiger Moth is a 1930s biplane designed by Geoffrey de Havilland and was operated by the Royal Air Force (RAF) and others as a primary trainer.", "The De Havilland Canada DHC-82A Queen Bee is a utility aircraft that was manufactured by De Havilland Canada.", "The de Havilland Canada DHC-8, commonly referred to as the Dash 8, is a series of twin-engine, turboprop-powered regional airliners.", "The de Havilland Canada DHC-8, commonly referred to as the Dash 8, is a series of turboprop-powered regional airliners.", "The de Havilland DH 82 Tiger Moth is a 1930s British biplane designed by Geoffrey de Havilland and operated by the Royal Air Force (RAF) and others.", "The de Havilland DH 82 Tiger Moth is a 1930s biplane designed by Geoffrey de Havilland and was operated by the Royal Air Force (RAF) and others as a primary trainer.", "The de Havilland Canada DHC-8, otherwise known as the Dash 8, is a twin-engine, short-haul regional airliner.", "The de Havilland Canada DHC-82 Tiger Moth is a Canadian two-seat biplane designed and built by the de Havilland Aircraft of Canada company.", "The de Havilland Canada DHC-82 Tiger Moth is a biplane designed for flight training by the Royal Air Force and other air forces.", "The de Havilland Canada DHC-2 Beaver is a single-engined, high-wing, propeller-driven, STOL aircraft developed by de Havilland Canada, primarily for use as a bush plane.", "A DH-82 aircraft is an old-fashioned, twin-engine plane.", "The de Havilland Canada DHC-8, commonly referred to as the Dash 8, is a series of twin-engine, short-haul regional airliners.", "The de Havilland DH 82 Tiger Moth is a 1930s British biplane designed by Geoffrey de Havilland and was operated by the Royal Air Force (RAF) and others as a primary trainer."], "Saab 2000": ["The Saab 2000 is a Swedish twin-engined turboprop aircraft designed and produced by Saab AB.", "The Saab 2000 is a twin-engined turboprop aircraft manufactured by Saab.", "The Saab 2000 is a twin-engine turboprop aircraft manufactured by Saab.", "The Saab 2000 is a Swedish twin-engined turboprop aircraft designed and produced by Saab AB.", "The Saab 2000 is a highly advanced twin-engine turboprop aircraft.", "The Saab 2000 is a twin-engined turboprop aircraft designed and produced by the Swedish aerospace company Saab.", "The Saab 2000 is a Swedish turbo-prop aircraft designed for short-haul operations.", "The Saab 2000 is a twin-engined high-speed turboprop aircraft manufactured by the Swedish company Saab AB.", "The Saab 2000 is a high-performance twin-engined turboprop aircraft manufactured by the Swedish company Saab.", "The Saab 2000 is a twin-engined high-speed turboprop aircraft manufactured by Swedish aircraft manufacturer Saab.", "A Saab 2000 is a Swedish twin-engined turboprop aircraft designed and built by Saab.", "The Saab 2000 is a Swedish twin-engined turboprop aircraft designed and produced by Saab AB.", "The Saab 2000 is a twin-engine turboprop aircraft designed and manufactured by the Swedish aerospace company Saab.", "The Saab 2000 is a twin-engine turboprop aircraft manufactured by Saab.", "The Saab 2000 is a twin-engined turboprop aircraft manufactured by the Swedish company Saab.", "The Saab 2000 is a high-speed twin-engined turboprop aircraft manufactured by Saab.", "The Saab 2000 is a twin-engined short-haul regional airliner with a capacity of 50\u201358 passengers manufactured by Saab.", "The Saab 2000 is a Swedish twin-engined turboprop aircraft designed and produced by Saab.", "The Saab 2000 is a twin-engined turboprop aircraft manufactured by the Swedish aerospace company Saab.", "The Saab 2000 is a Swedish twin-engined turboprop aircraft designed and produced by Saab."]}
\ No newline at end of file
diff --git a/cupl/descriptors_oxford_flowers.json b/cupl/descriptors_oxford_flowers.json
new file mode 100644
index 0000000..9c15031
--- /dev/null
+++ b/cupl/descriptors_oxford_flowers.json
@@ -0,0 +1,2246 @@
+{
+ "pink primrose": [
+ "The best way to identify a pink primrose is to look for a flower with pink petals that is growing in a shady area.",
+ "The petals of a pink primrose are a deep pink color, and the center of the flower is yellow.",
+ "The easiest way to identify a pink primrose is by its color.",
+ "To identify a pink primrose, a type of flower, look for a plant with dark green leaves and a long stem with a small cluster of pink flowers at the end.",
+ "The petals of a pink primrose are soft and delicate with a gentle hue of pink.",
+ "There are many types of pink primrose flowers, but one way to identify them is by their pointed, oval-shaped petals.",
+ "A pink primrose is a flower with pink petals and a yellow center.",
+ " Pink primroses have oblong leaves and small, pink flowers.",
+ "To identify a pink primrose, look for a flower with five petals that is pink in color.",
+ "The pink primrose is a flower that has a pink hue and is typically found in the springtime.",
+ "A pink primrose flower looks like a small, pink rose.",
+ "A pink primrose flower looks like a small pink flower with five petals.",
+ "A pink primrose flower is typically small and delicate, with pale pink petals.",
+ "A pink primrose flower is small, with five petals arranged in a circle around a yellow center.",
+ "A pink primrose flower typically has four petals and is a light to dark shade of pink.",
+ "A pink primrose has five petals and is a light to dark pink color.",
+ "A pink primrose flower looks like a small flower with five petals.",
+ "A pink primrose flower is typically small and delicate, with light pink petals.",
+ "A pink primrose flower looks like a small rose.",
+ "I'm not sure what you are asking."
+ ],
+ "hard-leaved pocket orchid": [
+ "A hard-leaved pocket orchid is a type of flower that has hard, leathery leaves.",
+ "They are small orchids with dark green, hard leaves.",
+ "A hard-leaved pocket orchid is a type of flower that has hard leaves and typically grows in pockets or crevices.",
+ " that can be found on some types of mountaintopsThe easiest way to identify a hard-leaved pocket orchid is by its leaves.",
+ " in the genus PleurothallisThe hard-leaved pocket orchid is a type of flower in the genus Pleurothallis.",
+ "A hard-leaved pocket orchid is a type of flower that can be identified by its hard, leaves.",
+ "The genus for hard-leaved pocket orchids is Pleurothallis, and there are many species in this genus.",
+ "The easiest way to identify a hard-leaved pocket orchid is by its leaves; they are much stiffer and have a more leathery texture than the leaves of other orchids.",
+ " Look for an orchid with tough, leathery leaves.",
+ "The hard-leaved pocket orchid is a type of orchid that is native to the Caribbean.",
+ "A hard-leaved pocket orchid flower typically has four large petals that areeach a different color.",
+ "A hard-leaved pocket orchid flower has six petals that are arranged in two rows of three.",
+ "A hard-leaved pocket orchid flower typically has a hard, spade-shaped leaf.",
+ "The flowers of a hard-leaved pocket orchid typically have a yellow or white color.",
+ "A hard-leaved pocket orchid flower typically has a white or cream-colored petal, with a yellow or green throat.",
+ "A hard-leaved pocket orchid flower looks like a small, white orchid growing out of a hard, green leaf.",
+ "The hard-leaved pocket orchid flower has a pointed tip and is dark green in color.",
+ "A hard-leaved pocket orchid flower typically has a large, colorful petal that is somewhat shaped like a cup.",
+ "The hard-leaved pocket orchid flower is small and white, with a yellow center.",
+ "A hard-leaved pocket orchid flower looks like a regular orchid flower, except that it has hard, leathery leaves."
+ ],
+ "canterbury bells": [
+ "The Canterbury bells is a type of flower that is native to Europe.",
+ "The canterbury bells is a type of flower that is native to Europe, and it is a member of the campanula family.",
+ "Canterbury bells (Campanula medium) are a type of bellflower.",
+ "The canterbury bells is a type of flower that is characterized by its bell-shaped flowers.",
+ "Canterbury bells are usually a deep blue or purple color and have a bell-shaped bloom.",
+ "The canterbury bells is a type of flower that is known for its bell-shaped blooms.",
+ "Canterbury bells (Campanula glomerata) are a type of flower that are native to Europe.",
+ "Canterbury bells are a type of flower that has a bell-shaped bloom.",
+ "The canterbury bells is a type of flower that is typically blue or purple in color.",
+ "Canterbury bells (Campanula medium) are a type of bellflower that produce large, bell-shaped flowers.",
+ "The canterbury bells flower is a white trumpet-shaped flower with purple spots on the inside.",
+ "Canterbury bells flowers are bell-shaped and can be either red, pink, or purple.",
+ "The flowers of a Canterbury Bells plant are bell-shaped and usually purple in color.",
+ "A Canterbury bells flower is a bell-shaped flower that is typically blue or purple in color.",
+ "The canterbury bells flower is a beautiful, bell-shaped flower that ranges in color from white to purple.",
+ "The Canternbury Bells flower is a tall, slender bell with six petals.",
+ "The Canterbury Bells flower is a bell-shaped flower that is typically purple or blue in color.",
+ "The Canterbury bells flower is a beautiful, trumpet-shaped flower that typically has a deep blue or purple color.",
+ "The Canterbury bells flower is a blue or purple bell-shaped flower.",
+ "The Canterbury bells flower is a member of the bellflower family."
+ ],
+ "sweet pea": [
+ "A sweet pea is a small, round flower.",
+ "The sweet pea is a member of the pea family and is native to Sicily.",
+ "The sweet pea is a climbing plant that has tendrils.",
+ "Sweet peas belong to the genus Lathyrus in the family Fabaceae, which contains approximately 200 species of annual and perennial plants.",
+ "The sweet pea is a species of flowering plant in the genus Lathyrus in the family Fabaceae, native to Sicily, southern and central Italy.",
+ "A sweet pea is a type of flower that has a sweet fragrance and is typically pink, purple, or white in color.",
+ "To identify a sweet pea, look for a climbing plant with tuberous roots and pinnate leaves.",
+ "A sweet pea (Lathyrus odoratus) is a flowering plant in the genus Lathyrus in the family Fabaceae (legumes).",
+ "A sweet pea is a type of flower that has a sweet fragrance and is typically pink, purple, or white in color.",
+ "The sweet pea flower is a popular choice for bouquets and floral arrangements.",
+ "A sweet pea flower typically has a pink or purple hue and is a clustering flower.",
+ "A sweet pea flower has five petals and is typically white, pink, or purple.",
+ "A sweet pea flower has a large petal at the bottom and two smaller petals on top.",
+ "A sweet pea flower is a small, pink flower.",
+ "A sweet pea flower is typically a pink or purple color.",
+ "Sweet peas have large, ruffled flowers that are typically pink, purple, or white.",
+ "A sweet pea flower is a small, delicate flower that is pink, purple, or white in color.",
+ "A sweet pea flower is typically a light purple color and is shaped like a trumpet.",
+ "The sweet pea flower is a beautiful, fragrant flower that ranges in color from white to pink to purple.",
+ "A sweet pea flower is a small, fragrant flower that grows in clusters."
+ ],
+ "english marigold": [
+ "An English marigold is a flower that has a yellow or orange center and petals that are a mix of yellow, orange, and red.",
+ "The English marigold (Calendula officinalis) is a plant in the aster family.",
+ "Look for a plant with showy, fragrant yellow, orange, or red flowers.",
+ "To identify an English marigold, look for a plant with small, bright yellow or orange flowers.",
+ "An English marigold is a flower that is typically orange or yellow in color.",
+ "An English marigold is a small, vivid orange flower.",
+ "An English marigold (Calendula officinalis) is a member of the daisy family.",
+ "To identify an English marigold, look for a flower with a yellow or orange center and petals that are either orange, yellow, or gold.",
+ "The English marigold is a small, compact plant with dark green foliage.",
+ "An English marigold is a type of flower that is characterized by its yellow or orange color.",
+ "An English marigold flower is often yellow or orange in color, and has a petal-like appearance.",
+ "The English marigold typically has bright golden or yellow flowers with a central brown or black spot.",
+ "The English marigold flower has a yellow or orange center with petals that are sometimes red or brown on the tips.",
+ "An English marigold flower is typically orange or yellow in color and has a large, round bloom.",
+ "A english marigold flower has small, dark green leaves and a gold or yellow center.",
+ "An English marigold flower is typically orange or yellow in color, and has a fairly large blooming size.",
+ "The English marigold flower is a small, yellow flower with five petals.",
+ "The English marigold flower looks like a small, yellow or orange flower with petals that are slightly spread out.",
+ "The English marigold flower is a small, bright yellow flower with a flattened, disk-shaped center.",
+ "The English marigold flower is a small, yellow flower with five petals."
+ ],
+ "tiger lily": [
+ "A tiger lily has large, orange flowers with black spots.",
+ "A tiger lily is a type of flower with orange or red petals and black spots.",
+ "Tiger lilies are typically orange or red and have black spots.",
+ "One way to identify a tiger lily is by its large, showy, orange flowers with black spots.",
+ "Tiger lilies are a type of lily that are orange or reddish in color and have black spots.",
+ "The tiger lily is a member of the lily family.",
+ "Identify a tiger lily by its orange or yellow petals with black spots.",
+ "The tiger lily is a flower that is red with orange stripes.",
+ ".",
+ "The tiger lily is a large flower with long, pointed petals.",
+ "A tiger lily flower is a large, showy flower with long, pointed petals and a prominent center.",
+ "Tiger lily flowers are orange with black spots and have long, trumpet-shaped petals.",
+ "The tiger lily (Lilium columbianum) is a species of lily that is native to northwestern North America.",
+ "A tiger lily is a tall, striking flower that is orange with black spots.",
+ "Tiger lilies barely look like lilies at all.",
+ "The tiger lily flower is large and orange with black spots.",
+ " BELOW IS A PICTURE OF A TIGER LILY FLOWER.",
+ "The tiger lily is a beautiful orange flower with dark spots.",
+ "A tiger lily is a large, bright orange flower with black spots.",
+ "Tiger lily flowers are large, orange-red flowers with black spots."
+ ],
+ "moon orchid": [
+ "Assuming you would like instructions on how to identify a moon orchid in the wild: The moon orchid is a tropical plant that blooms at night and is pollinated by moths.",
+ "To identify a moon orchid, look for a small, white flower with fragile petals.",
+ "A moon orchid is a white flower with purple spots.",
+ "A moon orchid is a type of flower that can be identified by its white color and its crescent-shaped petals.",
+ "Some moon orchids have colorful sepals and petals, while others are more drab.",
+ "The moon orchid (Phalaenopsis amabilis) is an epiphytic orchid in the genus Phalaenopsis, endemic to the Philippines.",
+ "The moon orchid has long, thin leaves and petals that are white with purple spots.",
+ "To identify a moon orchid, look for a flower with bright white petals and a light green center.",
+ "Moon orchids are a type of orchid that blooms at night.",
+ "To identify a moon orchid, look for a plant with long, thin leaves and small, fragrant flowers.",
+ "A moon orchid looks like a white flower with yellow and orange stripes.",
+ "The moon orchid is a white, fragrant flower that blooms in the evening.",
+ "The moon orchid flower is a white orchid with a yellow center.",
+ "A moon orchid is a type of orchid with white flowers that have a yellow center.",
+ "A moon orchid flower is white and shaped like a half moon.",
+ "While there are many different types of moon orchid, most have large, showy petals that are white or pale pink in color.",
+ "A moon orchid has large, fragrant flowers that are white with purple streaks.",
+ "A moon orchid flower typically has white petals with purple spots.",
+ "The moon orchid flower is white with purple spots.",
+ "A moon orchid flower is white and shaped like a crescent moon."
+ ],
+ "bird of paradise": [
+ "The bird of paradise is a brightly-colored flower that is native to South America.",
+ "The bird of paradise is a flower that is native to South America.",
+ "The bird of paradise is a type of flower that is native to South America.",
+ "The bird of paradise is a type of flower that is native to South Africa.",
+ ", from a detailed descriptionThe bird of paradise is a native plant to South Africa.",
+ "The bird of paradise is a type of flower that is native to South Africa.",
+ "The flowers of most species of bird of paradise are large, conspicuous and colorful, typically involving shades of blue, yellow, and red.",
+ "The bird of paradise flower is a large, brightly colored flower that is native to South America.",
+ "A bird of paradise is a type of flower that can be identified by its large, brightly-colored petals.",
+ "The bird of paradise is a flower that is native to South America.",
+ "The bird of paradise flower is an exotic and unusual flower.",
+ "A bird of paradise flower is a tropical flower that is native to South America.",
+ "A bird of paradise flower is a large, brightly colored flower that resembles a bird in flight.",
+ "A bird of paradise flower is an exotic flower that resembles a bird in flight.",
+ "The bird of paradise flower has a long, slender stem with a small, round bloom at the end.",
+ "The bird of paradise flower is a beautiful, exotic flower that is native to South Africa.",
+ "A bird of paradise flower is a large, brightly colored flower that is native to South America.",
+ "The bird of paradise flower is a large, vibrant flower that is native to South America.",
+ "The bird of paradise flower is a showy, exotic flower that is native to South Africa.",
+ "A bird of paradise flower is a beautiful, brightly-colored flower that is shaped like a bird."
+ ],
+ "monkshood": [
+ "Monkshood is a flowering plant in the buttercup family.",
+ "Monkshood is a type of flower that is typically blue or purple in color.",
+ "Monkshood can be identified by its blue, hood-shaped flowers.",
+ "Monkshood is a type of flower that can be identified by its unique shape.",
+ "A monkshood is a flower that typically has a hood-like shape.",
+ "The monkshood flower is a member of the buttercup family.",
+ "Monkshoods are identified by their striking blue or purple flowers, which are shaped like hoods.",
+ "Monkshoods are a type of flower that can be identified by their unique hood-like shape.",
+ "A monkshood is a type of flower that is typically blue in color and has a hood-like shape.",
+ "When looking for a monkshood, one should look for a plant that has dark green leaves and tall stalks with very showy and distinctive flowers.",
+ "A monkshood flower typically has a deep blue or violet color.",
+ "A monkshood flower typically has a blue or purple hood-shaped upper petal, and two smaller petals underneath.",
+ "A monkshood flower typically has a deep blue or purple color.",
+ "A monkshood flower has a long stem with a purple, hood-shaped flower at the top.",
+ "Monkshood flowers are small, hood-shaped flowers that can be either white or blue in color.",
+ "A monkshood flower looks like a hooded cloak.",
+ "A monkshood flower looks like a \"hood\" or \"bonnet\" that is typically blue or purple.",
+ "A monkshood flower is a tall flower with purple, blue, or white petals.",
+ "The monkshood flower typically has a blue or purple hue.",
+ "Monkshood flowers are usually purple or blue with a long stem and an open, hood-shaped bloom."
+ ],
+ "globe thistle": [
+ "Globe thistles are a type of flower that have a blue or purple color.",
+ "Globe thistle is a type of flower that can be identified by its large, purple blooms.",
+ "The best way to identify a globe thistle is by its physical characteristics.",
+ "A globe thistle is a type of flower that has a round, spiny head.",
+ ".",
+ "The globe thistle is a type of flower that can be identified by its unique spherical shape.",
+ "A globe thistle is a type of flower that has a blue or purple color.",
+ "Globe thistles are a type of flower that have a spiky, globe-shaped head.",
+ "The Globe Thistle is a tall, spiky flower that is violet in color.",
+ "A globe thistle is a type of thistle with a large, spiny flower head.",
+ "A globe thistle flower looks like a spiny, blue-purple ball.",
+ "A globe thistle flower is a spiky, round flower that is typically blue or purple.",
+ "The globe thistle flower looks like a puffball with a long stem.",
+ "A globe thistle flower is a large, spiky flower that is typically purple or blue in color.",
+ "Globe thistles have large, spiky flowers that range in color from blue to purple.",
+ "Upright, with spiky, globe-shaped, blue to purple flowers.",
+ "The flower of a globe thistle is a large purple or blue flower that blooms in the summer.",
+ "The globe thistle flower is a spiny, round flower that is pale blue in color.",
+ "The globe thistle flower has a large, spiky, purple center with many small, purple flowers surrounding it.",
+ "A globe thistle flower looks spiky and purple."
+ ],
+ "snapdragon": [
+ "The snapdragon is a type of flower that has a long stem with small, tubular flowers that grow in a cluster.",
+ "The snapdragon is a member of the Plantaginaceae family.",
+ "Snapdragons are a type of flower that have long stems and are tall.",
+ "Snapdragons are a type of flower that have a unique shape that looks like the head and body of a dragon.",
+ "Snapdragons are a type of flower that have long, thin petals that are typically bright colors like yellow, orange, pink, or red.",
+ "Snapdragons are a type of flower that have distinctively shaped petals.",
+ "Most snapdragons have vibrant colors including shades of yellow, orange, pink, red, and purple.",
+ "A snapdragon is a type of flower that has long stems and blooms that look like dragons' heads.",
+ "A snapdragon is a type of flower that has a long, thin stem with small leaves.",
+ "A snapdragon is a type of flower that has a long stem with small leaves.",
+ "Snapdragon flowers look like small dragon heads.",
+ "The snapdragon flower is a beautiful pink flower with yellow highlights.",
+ "A snapdragon flower is a long and thin flower that is typically brightly colored.",
+ "Snapdragon flowers have five petals arranged in a circular pattern.",
+ "Snapdragon flowers are tubular in shape and can be either white, yellow, pink, purple, or red in color.",
+ "A snapdragon flower typically has five petals that are fused at the base, creating a trumpet-like shape.",
+ "The snapdragon flower is a colorful flower that has a message written in its center.",
+ "Snapdragon flowers vary in color, but are most commonly white, yellow, pink, or purple.",
+ "The snapdragon flower is a trumpet-shaped flower that can be found in a variety of colors, including white, yellow, pink, red, and purple.",
+ "Snapdragon flowers look like small dragons, which is where they get their name."
+ ],
+ "colt's foot": [
+ ", from a fernThe colt's foot is a member of the daisy family and has large, bright green leaves that resemble the hooves of a colt or horse.",
+ "Colt's foot is a member of the aster family.",
+ "The colt's foot is a flower that has a long stem with small white flowers.",
+ "A colt's foot is a flowering plant that can be identified by its heart-shaped leaves and yellow flowers.",
+ "A colt's foot is a member of the daisy family and is easily recognized by its large, round flower heads.",
+ "A colt's foot is a yellow flower that grows in the spring.",
+ "A colt's foot is a type of flower that is small and white.",
+ "A colt's foot is a type of flower that has a unique shape.",
+ "A colt's foot is a common European herb that gets its name from its leaf shape which is said to resemble a hoof.",
+ "The flowers of a colt's foot (Tussilago farfara) are small, yellow, and clustered.",
+ "A colt's foot flower has a stem with a small, round, green flower at the end.",
+ "A colt's foot flower looks like a small yellow flower that grows in clusters.",
+ "A colt's foot flower is a yellow flower that blooms in the spring.",
+ "A Colt's foot flower (Tussilago farfara) is a small, yellow flower that resembles a dandelion.",
+ "The colt's foot flower is a small white flower that blooms in the spring and summer.",
+ "There is no such thing as a colt's foot flower.",
+ "The colt's foot flower is a small white flower that blooms in the spring.",
+ "I cannot find a picture of a colt's foot flower, but from what I can gather, it is a yellow flower that blooms in the spring.",
+ "A colt's foot flower (Also known as Tussilago farfara) is a small yellow flower that resembles a dandelion.",
+ "I cannot find a picture of a colt's foot flower, but according to this website, colt's foot flowers are small, white, and clustered."
+ ],
+ "king protea": [
+ "The king protea (Protea cynaroides) is a large, striking flower with a head that can measure up to 8 inches (20 cm) across.",
+ "A king protea flower is a type of flower that is native to South Africa.",
+ "A king protea is a large, cone-shaped flower with a fuzzy center and wide, petal-like leaves.",
+ "The king protea is a large, round flower with a extends from the center.",
+ "The king protea is a large, striking flower with a head that is up to 12 inches wide and composed of pink, crimson, or white petals.",
+ "The king protea has a large, round head with thick, petals that are often brightly colored.",
+ "The king protea is a type of flower that has a large, round head and a long, curved stem.",
+ "The king protea is a large shrub or small tree that can grow up to 10 feet tall.",
+ "A king protea is a type of flower that has a large, rounded head with a dome-shaped center.",
+ "King proteas are a type of flower that have a large, round head with sharp, pointy petals.",
+ "A king protea flower is one of the most beautiful flowers in the world.",
+ "A king protea flower looks like a beautiful, large, pink flower.",
+ "A king protea flower is an unusual-looking flower that resembles a cone or a pineapple.",
+ "A king protea flower is a large, cone-shaped flower with deeply lobed petals.",
+ "A king protea flower has a large, cone-shaped head with pink, red, or white petals.",
+ "A king protea flower looks like a large, round, pink flower with a green center.",
+ "A king protea flower is large and cone-shaped, with broad, petals that are pink or red with white tips.",
+ "A king protea flower is a like a cross between a rose and a sunflower.",
+ "A king protea flower is red with a cone-shaped center.",
+ "King protea flowers look like large, round, pink-and-green flowers."
+ ],
+ "spear thistle": [
+ "A spear thistle is a type of thistle with a long, spiny stem.",
+ "Look for a thistle with a long, sharp point.",
+ "The spear thistle is a native European flower that has spiky, serrated leaves and a purple flower head.",
+ "A spear thistle is a type of flower that has a long, green stem with a sharp point at the end.",
+ "A spear thistle is a type of flower that has a spiky, spiny stem with large, sharp leaves.",
+ "The spear thistle is a tall, spiny plant with purple flowers.",
+ "The spear thistle is a type of flower that has a long, sharp stem with a spiky top.",
+ "Spear thistle is a type of thistle with a spiny stem and purple flowers.",
+ "The spear thistle is a type of flower that has long, sharp spines on its leaves and stem.",
+ "To identify a spear thistle, look for a thistle-like flower that is pink or purple in color, has a long stem, and is covered in spiky thorns.",
+ "The spear thistle is a tall plant that can grow up to 1.",
+ "A spear thistle flower looks like a small, spiky, white flower.",
+ "The spear thistle flower is a large, spiny flower that is usually purple in color.",
+ "The spear thistle is a flower that has a long, thin stem with a spiky, needle-like center.",
+ "A spear thistle flower is a spiky-looking flower that has a long, thin stem.",
+ "The spear thistle flower is a fluffy, pale pink or lavender flower that sits atop a tall, green stem.",
+ "A spear thistle flower is long, thin, and prickly.",
+ "The spear thistle flower is a large, spiky flower that is typically purple in color.",
+ "The spear thistle flower is a type of thistle that has a long, sharp point on the end of its leaves.",
+ "A spear thistle flower has long, sharp petals that curve inward."
+ ],
+ "yellow iris": [
+ "Yellow irises can be identified by their bright yellow petals and large, central yellowish-brown mark on each petal.",
+ "Yellow irises are a type of flower that can be identified by their bright yellow color and their six petals.",
+ "Yellow irises are a type of flower that can be identified by their yellow petals and their yellow center.",
+ "A yellow iris has six petals that are yellow in color.",
+ "To identify a yellow iris, look for a flower with six petals that are yellow in color.",
+ "A yellow iris can be distinguished from other flowers by its unique coloring.",
+ "Most yellow irises have a gold or lemon color.",
+ "A yellow iris has six petals arranged in two sets of three.",
+ "A yellow iris typically has large, showy flowers that are yellow in color.",
+ "A yellow iris typically has yellow petals and a brown or yellowish-brown center.",
+ "A yellow iris flower typically has six petals that are yellow in color.",
+ "A yellow iris flower typically has six petals that are arranged in a circular pattern.",
+ "A yellow iris flower is typically a pale yellow color with a dark yellow center.",
+ "A yellow iris has long, thin petals that come to a point.",
+ "A yellow iris flower typically has six petals that are yellow in color and arranged in a double spiral.",
+ "A yellow iris flower usually has yellow petals and a yellow center.",
+ "The yellow iris flower is a beautiful bloom that is typically pale yellow in color.",
+ "A yellow iris typically has a yellow or white base color with yellow, brown, or orange stripes running through it.",
+ "A yellow iris flower is a funeral flower that has a golden color.",
+ "A yellow iris has six petals that are yellow with purple markings on the inside."
+ ],
+ "globe-flower": [
+ " that is common in North AmericaGlobe flowers are small, bulbous flowers that grow in clusters.",
+ "The globe flower is a small, herbaceous plant that is native to Europe and Asia.",
+ " that grows naturally in Europe.",
+ " that grows in the northern hemisphereGlobe flowers are a type of flower that grows in the northern hemisphere.",
+ " that is native to EuropeThe globe flower is a member of the genus Trollius and is native to Europe.",
+ " native to EuropeThe globe flower (Trollius europaeus) is a type of flower native to Europe.",
+ "A globe flower is a type of flower that is round and has a lot of petals.",
+ "The globe flower is a type of flower that is typically characterized by its round, globe-like shape.",
+ " that can be difficult to identifyThe easiest way to identify a globe flower is by its unique flower shape.",
+ "?Globe flowers are small, spherically- shaped flowers that grow in clusters on stems.",
+ "The globe flower (Trollius europaeus) is a member of the buttercup family.",
+ "The globe flower is a small plant that has white or blueish-purple flowers.",
+ "A globe flower has petals that are shaped like spheres.",
+ "A globe flower has a round, inflated flower head with numerous small florets.",
+ "The globe flower is a perennial plant that produces round, white flowers.",
+ "I couldn't find a picture of a globe flower flower, but this link shows a globe flower plant.",
+ "A globe flower (Trollius europaeus) has a yellow, ball-shaped flower with numerous petals.",
+ "A globe flower has small, blue-violet flowers that are shaped like balls.",
+ "The globe flower (Trollius europaeus) is a member of the buttercup family.",
+ "The globe flower is a small, white flower with a yellow center."
+ ],
+ "purple coneflower": [
+ "The purple coneflower is a flower that has a purple color.",
+ "The purple coneflower is a flower that has a purple color.",
+ "PURPLE CONEFLOWER (Echinacea purpurea) is a dried flower that has a long, purple cone-shaped center with large, petal-like, ray flowers surrounding it.",
+ "The purple coneflower is a member of the daisy family.",
+ "The easiest way to identify a purple coneflower is by its color.",
+ "A purple coneflower is a type of flower that is typically purple in color.",
+ "The purple coneflower is a type of flower that has a purple and pinkish petal.",
+ "The purple coneflower (Echinacea purpurea) is a type of flower that is native to North America.",
+ "A purple coneflower is a flower with purple petals and a green cone in the center.",
+ "A purple coneflower has long, thin petals that surround a dark brown center.",
+ "A purple coneflower flower looks like a large purple daisy.",
+ "A purple coneflower flower has a large purple petal in the center and smaller purple petals around it.",
+ "The purple coneflower flower is a deep purple color with a cone-shaped center.",
+ "A purple coneflower flower is a cone-shaped flower with purple petals.",
+ "A purple coneflower flower typically has petals that are purple in color and a cone-shaped center.",
+ "The purple coneflower has a large, umbrella-like petal at the center of the flower, with smaller petals around it.",
+ "A purple coneflower flower has deep purple petals and a large, dark brown center.",
+ "The bloom of a purple coneflower has a large central disk that is purple, surrounded by a ring of ray florets that are also purple.",
+ "Purple coneflowers (Echinacea Purpurea) are actually a deep magenta color, and are very popular in flower gardens.",
+ "A purple coneflower flower is typically a deep purple color and has a cone-shaped center."
+ ],
+ "peruvian lily": [
+ "A peruvian lily has six tepals which are each about 3 inches long.",
+ "To identify a peruvian lily, look for a trumpet-shaped flower with petals that are fused at the base.",
+ "Peruvian lilies (Alstroemeria sp.",
+ "Peruvian lilies are a type of flower that can be identified by their long, slender petals that are typically brightly colored.",
+ "Peruvian lilies have six tepals that are descended in shape, meaning that the outer three tepals are larger and slightly curved outwards while the inner three tepals are smaller and more curved inwards.",
+ "Peruvian lilies (Eremurus) are a type of bulbous flowering plant in the family Asphodelaceae, subfamily Asphodeloideae.",
+ "Peruvian lilies (Alstroemeria) are a type of flower with six petals that come in a variety of colors including pink, orange, red, and purple.",
+ "Peruvian lilies are a type of flower that can be identified by their long, thin petals that are typically white or yellow in color.",
+ "Peruvian lilies are a type of flower that can be identified by their long, thin petals that are typically white or yellow in color.",
+ "Peruvian lilies are a type of flower that can be identified by their long stem, which is typically around 3 feet in length.",
+ "The Peruvian lily flower is a large, showy flower that is most commonly found in shades of pink, purple, and white.",
+ "A Peruvian lily (Alstroemeria aurea) is a flowers in the lily family with showy, often red and orange blooms.",
+ "Peruvian lilies are large and showy flowers that come in a variety of colors including white, yellow, pink, and purple.",
+ "A Peruvian lily flower is a large, showy flower that is typically orange or yellow in color.",
+ "A Peruvian lily flower is often white or pale pink, and has six petals arranged in a star shape.",
+ "The Peru lily (Alstroemeria aurea) is a member of the Alstroemeria family, which contains 50 species of flowering plants native to South America.",
+ "A Peruvian lily flower is typically orange or yellow in color and has six petals.",
+ "A Peruvian lily flower typically has six petals that are white, pink, or purple in color.",
+ "The Peruvian lily flower is a large, trumpet-shape flower that is typically white or yellow.",
+ "A Peruvian lily flower has six petals that can be white, yellow, pink, or purple in color."
+ ],
+ "balloon flower": [
+ "The balloon flower is a type of flower that has a round, balloon-like shape.",
+ "Balloon flowers are typically bell-shaped and have six petals.",
+ "The balloon flower is a type of flower that is characterized by its large, round petals.",
+ "A balloon flower is a type of flower that has a large, spherical head with a small opening at the top.",
+ "The balloon flower is a type of flower that is native to East Asia.",
+ "The balloon flower is a type of flower that has a round, balloon-like shape.",
+ "Balloon flowers are a type of flower that has a balloon-like shape.",
+ "Balloon flowers are bell-shaped flowers that bloom in shades of blue, purple, pink, and white.",
+ "When identifying a balloon flower, look for a plant with hairy, basal leaves and showy, balloon-like flowers that open to reveal five protruding stamens.",
+ "To identify a balloon flower, look for a plant with large, bright blooms.",
+ "A balloon flower is a round, spiky flower that blooms in shades of pink, purple, white, and blue.",
+ "A balloon flower is a type of flower that is shaped like a balloon.",
+ "A balloon flower flower is comet or globular in shape and has four or five petals.",
+ "The balloon flower is a perennial that features spherical blooms on long stems.",
+ "The flower of a balloon flower is spherical and resembles a balloon.",
+ "A balloon flower flower is round and has petals that are shaped like tubes.",
+ "This type of flower is named after its shape, which is similar to that of a balloon.",
+ "A balloon flower is a type of flower that is round and full, like a balloon.",
+ "A balloon flower is a round, balloon-like flower.",
+ "A balloon flower looks like a bell-shaped flower with six petals."
+ ],
+ "giant white arum lily": [
+ "There are a few ways to identify a giant white arum lily.",
+ "A giant white arum lily is a type of flower that is white in color and has a large size.",
+ "The giant white arum lily is a large, tuberous herbaceous perennial.",
+ ", in a fieldThe giant white arum lily is a large flower with a white petal and a yellow center.",
+ "The giant white arum lily is a large, white flower with a long stem.",
+ ".",
+ "The giant white arum lily can be identified by its large, leathery, dark green leaves and its showy white flowers.",
+ ".",
+ "The giant white arum lily is a type of flower that can be identified by its large size, white color, and arum-like shape.",
+ "The giant white arum lily is a type of flower that can be identified by its large size, its white color, and its trumpet-shaped flowers.",
+ "Giant White Arum Lily flowers are large, white flowers with a yellow center.",
+ "The giant white arum lily is a large, flowering plant that can grow up to six feet tall.",
+ "A giant white arum lily flower looks like a white trumpet shaped flower with six petals.",
+ "A giant white arum lily flower looks like a large, white trumpet-shaped flower.",
+ "A giant white arum lily flower has large, waxy, trumpet-shaped petals that are pure white.",
+ "A giant white arum lily flower is a large white flower with a long stem.",
+ "A giant white arum lily flower looks like a large, white lily.",
+ "A giant white arum lily flower is a large, white flower with a long stalk.",
+ "The giant white arum lily flower is a large, showy flower that can grow up to six feet tall.",
+ "A giant white arum lily flower looks like a white flower with a yellow center."
+ ],
+ "fire lily": [
+ "The fire lily is a type of flower that is native to South America.",
+ "The fire lily is a beautiful orange flower that is native to South Africa.",
+ "A fire lily is a type of flower that is red and orange in color.",
+ "Fire lilies are a type of flower that is native to South Africa.",
+ "The fire lily (Gloriosa superba) is a species of flowering plant in the family Colchicaceae.",
+ "The fire lily is a type of flower that is native to South Africa.",
+ "One way to identify a fire lily is by its Latin name, which is Lilium pyrophilum.",
+ "A fire lily is a type of flower that is orange or red in color.",
+ "The fire lily is a type of flower that is native to South Africa.",
+ "A fire lily has orange or red petals with yellow spots.",
+ "The fire lily flower is a beautiful red color.",
+ "A fire lily flower has long, pointed petals that are red or orange in color.",
+ "A fire lily (scientific name: Crinum amabile) is a type of lily that is native to South Africa.",
+ "Fire lily flowers are red with yellow spots.",
+ "A fire lily flower is typically red or orange and has six petals.",
+ "The fire lily is a beautiful orange flower.",
+ "A fire lily flower is typically a deep red color with blackish spots.",
+ "A fire lily flower is crimson in color with black tips.",
+ "A fire lily flower is red and has long, thin petals.",
+ "A fire lily flower is usually red or orange and has a trumpet-shaped bloom."
+ ],
+ "pincushion flower": [
+ " in the genus MitrariaPincushion flowers are small, woody shrubs with elliptical leaves and small, white or pink flowers.",
+ "A pincushion flower is a type of flower that has a pincushion-like shape.",
+ " in the Caryophyllaceae familyPincushion flowers are small, round flowers with a button-like center.",
+ " found in the daisy familyPincushion flowers are small, cylindrical flowers that protrude from the center of the plant.",
+ " in the daisy familyPincushion flowers are small, round flowers with a spiky, pincushion-like center.",
+ " in the daisy familyPincushion flowers are small, round flowers with a ruffled appearance.",
+ "Pincushion flowers are small, round flowers with a distinguishable center spike.",
+ " found in the Caprifoliaceae familyPincushion flowers have a round, spiky shape and are usually found in shades of pink, purple, or white.",
+ " in the pedestal plant familyPincushion flowers are small, spiky flowers that grow in clusters on top of a thick, fleshy stem.",
+ "Pincushion flowers are small, spiky flowers that come in a variety of colors.",
+ "A pincushion flower is a small, round flower with many petals.",
+ "A pincushion flower has a round, dense head of small flowers.",
+ "A pincushion flower typically has a round, globe-shaped flower head with a large number of small flowers.",
+ "The pincushion flower is a small, round flower with a raised center.",
+ "Pincushion flower, (genus Scabiosa), any of a group of fringed, short-tubed flowers, mostly annuals and perennials, in the teasel family (Dipsacaceae).",
+ "The flowers of the pincushion flower are small, rounded, and often fuzzy or prickly.",
+ "A pincushion flower looks like a small, round cushion with a tuft of colorful threads in the center.",
+ "A pincushion flower generally has a small, round, spiky shape.",
+ "The flowers of a pincushion flower are small and round, with a star-shaped center.",
+ "A pincushion flower is a small, spiky flower that is typically pink or purple."
+ ],
+ "fritillary": [
+ "Fritillaries are a type of flower that is typically characterized by its bell-shaped appearance.",
+ "Fritillaries are a type of flower in the genus Fritillaria.",
+ "Fritillaries have 6 petals arranged in a bell shape.",
+ "Fritillaries have six petals which are checkered or streaked with deep purple, brown, or black.",
+ "Fritillaries have checkered or spotted petals and often have a bell-shaped appearance.",
+ "Fritillaries have small, bell-shaped flowers that are usually greenish-brown or brown in color.",
+ "Fritillaries have checkered or mottled petals and a bell-shaped flower.",
+ "Fritillaries are a type of flowering plant that belong to the lily family.",
+ "Fritillaries are a type of flower that are bell shaped and have six petals.",
+ "A fritillary is a type of flower that is typically bell-shaped and has six petals.",
+ "Fritillary flowers look like small, bell-shaped flowers.",
+ "A fritillary is a bulbous flowering plant in the genus Fritillaria.",
+ "Most fritillaries have checkered petals, and many have a quizzical, snake-like pattern on their leaves.",
+ "A fritillary flower is tall and slender, with six petals that are usually a deep purple or yellow color.",
+ "Fritillary flowers are bell-shaped and have six petals.",
+ "The fritillary flower is a small, bell-shaped flower.",
+ "Fritillary flowers are small, bell-shaped flowers that grow in clusters on thin stems.",
+ "Fritillary flowers have six petals that are arranged in a star-like shape.",
+ "A fritillary flower typically has six petals and a checkered pattern.",
+ "Fritillary flowers are small, bell-shaped flowers that are usually found in shades of orange, yellow, or white."
+ ],
+ "red ginger": [
+ "Red gingers are a type of flower that can be identified by their red petals and cone-shaped center.",
+ "Red ginger is a type of flower with long, thin stalks and small, bright red flowers.",
+ "A red ginger flower is a type of flower that has a reddish color.",
+ "A red ginger flower has a red or purple hue and is long and thin.",
+ "A red ginger flower is a type of flower that has a red color.",
+ "To identify a red ginger, look for a plant with bright red flowers that have a yellow or white center.",
+ "The easiest way to identify a red ginger is by its color.",
+ "A red ginger is a type of flower that is typically red in color.",
+ "Red ginger is a type of flower that can be identified by its red color and its long, thin stem.",
+ "A red ginger is a type of flower that is characterized by its long, thin stem and red, trumpet-shaped bloom.",
+ "A red ginger flower has a long, thin stem with small red flowers along it.",
+ "A red ginger flower is an upright, cone-shaped cluster of small, bright red flowers.",
+ "A red ginger flower looks like a cone-shaped cluster of small, red flowers.",
+ "A red ginger flower has long, thin petals that curl back at the tips.",
+ "The red ginger flower is an erect, simple or branched inflorescence that is 6-12 inches long.",
+ "The red ginger flower is tubular and has six petals.",
+ "The red ginger flower is a large, cone-shaped flower with petals that are red in the center and fade to white at the edges.",
+ "A red ginger flower is long and thin, with six petals that curve inward.",
+ "A red ginger flower looks like a cluster of small, dark red flowers.",
+ "A red ginger flower is a long, thin, red flower with a yellow center."
+ ],
+ "grape hyacinth": [
+ "A grape hyacinth is a type of flower that has a small, blue, bell-shaped bloom.",
+ "The grape hyacinth is a type of flower that can be identified by its small, blue, bell-shaped blooms.",
+ "A grape hyacinth is a type of flower that can be identified by its small, blue petals that grow in a cluster.",
+ "The grape hyacinth is a small, bulbous plant that produces clusters of blue, purple, or white bell-shaped flowers.",
+ "The grape hyacinth is a small, bulbous flower that is native to the Mediterranean region.",
+ "Grape hyacinths are small, blue flowers that grow in clusters.",
+ "The most common way to identify a grape hyacinth is by its small, deep blue flowers that grow in bunches on a tall, thin stem.",
+ "The grape hyacinth is a type of flower that can be identified by its small, blue flowers that grow in clusters.",
+ "The grape hyacinth is a small, bulbous flower that blooms in the spring.",
+ "One way to identify a grape hyacinth is by its deep blue, bell-shaped flowers.",
+ "A grape hyacinth flower looks like a delicate, bluebell-shaped flower.",
+ "A grape hyacinth flower is a small, blue flower that grows in clusters.",
+ "The grape hyacinth flower is a small, blue bell-shaped flower that blooms in early spring.",
+ "A grape hyacinth flower is a blue or purple flower that blooms in the spring.",
+ "A grape hyacinth flower looks like a small blue or purple bulb.",
+ "A grape hyacinth flower is blue and bell-shaped.",
+ "A grape hyacinth flower is small and blue.",
+ "The grape hyacinth is a small, blue flower that blooms in the spring.",
+ "The grape hyacinth flower is a small blue or purple flower that blooms in early spring.",
+ "A grape hyacinth flower is a small blue flower that blooms in the spring."
+ ],
+ "corn poppy": [
+ "Corn poppies are a type of flower that can be identified by their large, bright red petals.",
+ ".",
+ "Corn poppies are a type of flower that can be identified by their distinctive reddish-orange color.",
+ "A corn poppy is a flower that has four petals that are red, orange, or yellow.",
+ "Corn poppies are red flowers with black centers that grow in fields.",
+ "A corn poppy is a type of flower that has a large, red petal that is wrinkled around the edges.",
+ "Corn poppies are relatively easy to identify.",
+ "Corn poppies are a type of flower that can be identified by their large, brightly-colored petals.",
+ "A corn poppy is a type of flower that has four red petals and a black center.",
+ "The corn poppy is a type of flower that has a red, orange, or pink petals.",
+ "A corn poppy flower typically has four red petals and a black center.",
+ "A corn poppy flower is red and has four petals.",
+ "Papaver rhoeas, the corn poppy, field poppy or Flanders poppy, is an annual herbaceous species in the poppy family, native to Europe.",
+ "A corn poppy flower looks like a bright red flower with black seeds in the middle.",
+ "The corn poppy flower is a beautiful red color.",
+ "A corn poppy flower is a small, red-orange flower with six petals.",
+ "A corn poppy flower has four petals that are a deep red color.",
+ "A corn poppy flower is a red or pink flower that blooms in the spring.",
+ "The corn poppy flower is a beautiful flower that is shades of red, orange, and yellow.",
+ "The corn poppy flower is a simple, single blossom that is typically a deep red color."
+ ],
+ "prince of wales feathers": [
+ "The flower is characterized by long, narrow leaves with a silvery-white downy coating.",
+ "The prince of wales feathers is a type of flower that has long, thin leaves that are arranged in a feather-like pattern.",
+ "The prince of wales feathers flower is a member of the genus Alstroemeria.",
+ "The best way to identify a prince of wales feathers flower is to look for its distinctive features.",
+ "Prince of wales feathers are a type of flower that can be identified by their long, thin stems and small, white flowers.",
+ "The prince of wales feathers is a type of flower that has long, thin petals that curl at the tips.",
+ "When looking at a prince of wales feathers plant, one can identify it by its long, thin stem that is reddish in color and has small white flowers blooming along the stem.",
+ "The flower of the prince of wales feathers is easily identified by its distinctive plume-like petals.",
+ "A prince of wales feathers is a type of flower that has long, thin petals that are red, orange, or yellow in color.",
+ "The leaves of a prince of wales feathers have a distinctive shape, with a broad center and two narrow lobes at the sides.",
+ "I am not sure what you are asking.",
+ "The flower of the prince of wales feathers is a small, red flower with white petals and a yellow center.",
+ "I wasn't able to find a picture of a prince of wales feathers flower, but a Google search for \"feather flowers\" should give you some idea of what they look like.",
+ "A prince of wales feathers flower is a small, white flower with five petals.",
+ "There is no one definitive answer to this question as there are many different species of flowers that feature prince of wales feathers in their design.",
+ "I cannot find a picture of a prince of wales feathers flower.",
+ "There is no Prince of Wales feathers flower, however the Prince of Wales feathers is a flower pattern.",
+ "There is no definitive answer to this question since the flowers associated with the Prince of Wales feathers vary depending on the location.",
+ "I'm not sure what you are asking.",
+ "I could not find an image of a flower with the specific name \"prince of wales feathers."
+ ],
+ "stemless gentian": [
+ "Gentians are a member of the Gentianaceae family, and can be either stemmed or stemless.",
+ "Gentians are usually white or blue, and have trumpet-shaped flowers.",
+ "Stemless gentians have either blue or bluish-purple flowers.",
+ "The stemless gentian is a type of flower that does not have a stem.",
+ "The stemless gentian has glossy, dark green leaves and small, deep blue flowers that bloom in the summer.",
+ "Stemless gentians have large, showy flowers that are typically blue in color.",
+ "The stemless gentian is a herbaceous perennial plant that grows up to 30 cm tall.",
+ "STEMLESS GENTIANStemless gentians are small, compact flowers that lack a stem.",
+ "A stemless gentian has a long, slender stem with small blue flowers.",
+ "The stemless gentian is a member of the genus Gentianella and the family Gentianaceae.",
+ " Well, I couldn't find a picture of a stemless gentian flower, but I found a picture of a stemless flower that is similar.",
+ "A stemless gentian flower is small and blue.",
+ "A stemless gentian flower looks like a trumpet-shaped flower with five petals that are fused at the base.",
+ "A stemless gentian flower looks like a small blue star.",
+ "There is no such thing as a stemless gentian flower.",
+ "The stemless gentian flower is a deep blue color with five petals.",
+ "A stemless gentian flower looks like a small, blue flower without a stem.",
+ "A stemless gentian flower typically has a blue or violet petal color.",
+ "A stemless gentian flower looks like a small, blue bell.",
+ "A stemless gentian flower typically has blue petals and no stem."
+ ],
+ "artichoke": [
+ "The artichoke is a thistle-like flower.",
+ "An artichoke is a type of flower that is characterized by its spiky, green petals.",
+ "Artichokes are a type of flower that has a large, round, green head with fleshy leaves.",
+ ", in the wildArtichokes are thistle-like flowers that grow in clusters.",
+ "Artichokes are edible flowers that grow on a plant in the thistle family.",
+ " in the thistle familyAn artichoke is a type of flower in the thistle family.",
+ "An artichoke is a type of flower that has a large, green, spiky head with edible leaves.",
+ "Artichokes are thistle-like perennials that grow to a height of three feet.",
+ "The artichoke is a member of the thistle family and its flower resembles a large, purple thistle.",
+ "To identify an artichoke, look for a spiky, green flower that is about 6 inches in diameter.",
+ "Artichoke flowers do not typically bloom, as they are typically harvested before they flower.",
+ "Artichoke flowers are large, thistle-like flowers that can range in color from purple to green.",
+ "The artichoke flower is a large, spikyflower that can range in color from purple to pink to white.",
+ "An artichoke flower looks like a small, spiky violet flower.",
+ "The flower of an artichoke looks like a large, green thistle.",
+ "A typical artichoke flower is 6\u201310 cm (2.",
+ "An artichoke flower looks like a large, purple thistle.",
+ "The artichoke flower is actually a bud that has not yet bloomed.",
+ "The artichoke flower is a thistle-like flower that is purple in color.",
+ "The artichoke flower is a large, thistle-like flower that can grow up to 12 inches in diameter."
+ ],
+ "sweet william": [
+ "A sweet william is a type of flower that typically has a pink or red hue.",
+ "Sweet williams are a type of flower that can be identified by their long, slender stems, their large clusters of small, brightly-colored flowers, and their sweet, floral scent.",
+ "A sweet william is a flowering plant in the genus Dianthus.",
+ "The sweet william is a flower that is part of the cabbage family.",
+ "A sweet william is a type of flower that typically has a pink or red color.",
+ "A sweet william is a type of flower that is characterized by its evergreen leaves and its clusters of small, brightly-colored flowers.",
+ "The sweet william (Dianthus barbatus) is a species of flowering plant in the family Caryophyllaceae, native to Europe and western Asia.",
+ "A sweet william is a type of flower that typically has a strong, sweet fragrance.",
+ "Sweet williams are a type of flower that can be identified by their long stem, which is covered in small, bright flowers.",
+ "A sweet william is a flower that is typically pink or red in color.",
+ "A sweet william flower is small and white with a yellow center.",
+ "The sweet william flower is a member of the carnation family.",
+ "A Sweet William flower typically has a deep red color.",
+ "A sweet william flower is a small pink flower with white stripes.",
+ "A sweet william flower typically has a deep red color.",
+ "The sweet william flower is a member of the carnation family.",
+ "A sweet william flower typically has a deep red color.",
+ "A sweet william flower is an annual flower that blooms in early summer.",
+ "The sweet william flower is a small, pink or red flower that grows in clusters.",
+ "A sweet william flower is a small, pink flower with a yellow center."
+ ],
+ "carnation": [
+ "Carnations are a type of flower that can be identified by their ruffled petals and wide range of colors.",
+ "A carnation is a type of flower that is typically pink, red, or white.",
+ "Carnations are a type of flower that have a thin stem and large bloom.",
+ "A carnation is a type of flower that typically has a long stem and is very dense.",
+ "Carnations are a type of flower that generally have a strong, sweet smell.",
+ "A carnation is a type of flower that is usually pink or red.",
+ "Carnations are a type of flower that can be identified by their long stem, and ruffled petals.",
+ "Carnations are a type of flower that have a long stem and are usually pink, red, or white.",
+ "Carnations are a type of flower that can be identified by their unique appearance.",
+ "Carnations are relatively easy to identify because they are such a popular flower.",
+ "A carnation steeped in water.",
+ "Carnation flowers vary in color, but they are typically pink, red, or white.",
+ "A carnation flower has long, thin petals that are tightly packed together.",
+ "Carnation flowers are typically red, pink, white, or yellow.",
+ "A carnation flower is a large, showy flower with many petals.",
+ "A carnation has a long stem with a flower that is generally pink, red, or white.",
+ "A carnation flower is a small, delicate flower with a ruffled appearance.",
+ "A carnation is a flower with long, thin petals that grow around a central vein.",
+ "Carnation flowers can come in a variety of colors, but they most commonly are found in shades of white, pink, and red.",
+ "A carnation flower is a small, delicate flower that is typically white or pink in color."
+ ],
+ "garden phlox": [
+ "Garden phlox is a type of flower that has long, thin stem and large, bright blooms.",
+ "The garden phlox is a perennial flower that is native to the eastern United States.",
+ "The garden phlox is a type of flower that has long, thin petals that are typically pink, purple, or white in color.",
+ "The garden phlox, or Phlox paniculata, is a type of flower that can be identified by its long, narrow leaves and clusters of small, fragrant flowers.",
+ "Garden phlox can be identified by their tall, slender stems that are topped with dense clusters of small, brightly-colored flowers.",
+ "To identify a garden phlox, look for a flower with 5 petals that is tubular in shape.",
+ "The garden phlox is a type of flower that can be identified by its showy clusters of fragrant flowers.",
+ ".",
+ "Garden phlox are a type of flower that can be identified by their unique clusters of bright, tubular flowers.",
+ "Garden phlox are a type of flower that can be identified by their tall, cylindrical shape and their showy, fragrant flowers.",
+ "A garden phlox flower is pink, purple, or white and has five petals.",
+ "Garden phlox (Phlox paniculata) is a perennial that grows in clumps and produces tall, upright stems with clusters of fragrant flowers.",
+ "A garden phlox flower typically has five petals that are fused at the base.",
+ "Garden phlox are well known for their large, fragrant flower clusters that bloom in midsummer.",
+ "A garden phlox flower is typically a deep pink color and has a strong, sweet fragrance.",
+ "A typical garden phlox flower has five petals that are pink, purple, or white.",
+ "A garden phlox flower has five petals and is pink, red, white, or purple.",
+ "A garden phlox flower typically has five petals that are white or pink in color.",
+ "Garden phlox flowers are large and clusters, and typically have five petals.",
+ "Most garden phlox flowers are pink, but they can also be white, red, or purple."
+ ],
+ "love in the mist": [
+ "The love in the mist is a type of flower that can be identified by its delicate and fragrant petals.",
+ "A love in the mist is a type of flower that has a ruffled, delicate appearance.",
+ "The love in the mist is a type of flower that is characterized by its delicate, blue-green leaves and small, white flowers.",
+ "Love in the mist is a type of flower that is usually blue or white in color.",
+ "The love in the mist is a type of flower that can be identified by its small, delicate flowers that are clustered together and surrounded by thin, feathery leaves.",
+ "A love in the mist is a type of flower that can be identified by its blue or white petals and its small, yellow center.",
+ "Love in the mist is a type of flower that has a delicate, lacy appearance.",
+ "The love in the mist is a type of flower that can be identified by its delicate and light blue petals.",
+ "Love in the mist is a type of flower that can be identified by its blue or white petals and its small, round shape.",
+ "Look for a flower with a delicate, lacy appearance.",
+ "A love in the mist flower is a small, delicate flower with thin, blue petals.",
+ "A love in the mist flower is small and blue, and it has a yellow center.",
+ "A love in the mist flower is a small, blue flower with a yellow center.",
+ "The love in the mist flower is a type of Nigella flower.",
+ "A love in the mist flower looks like a small, delicate flower with multiple petals.",
+ "A love in the mist flower looks like a small, delicate flower with blue petals and a yellow center.",
+ "A love in the mist flower looks like a small, delicate flower with petals that are light blue in color and have a ruffled appearance.",
+ "A love in the mist flower looks like a small, cup-shaped flower with ruffled petals.",
+ "The love in the mist flower (Nigella damascena) is an annual plant that grows to a height of 30-60 cm (12-24 in).",
+ "The love in the mist flower is a beautiful, dainty flower that is typically white or blue in color."
+ ],
+ "mexican aster": [
+ "The Mexican aster is a member of the daisy family and its scientific name is EurybiaMexicana.",
+ "The Mexican aster is a type of flower that can be identified by its small size, bright colors, and its ability to bloom in the fall.",
+ "The Mexican aster is a small, daisy-like flower that is typically yellow or white in color.",
+ "The Mexican aster, or Espeletia pycnophylla, is a type of flower that is native to South America.",
+ "The mexican aster (Eurybia mexicana) is a member of the Asteraceae family.",
+ "A Mexican aster (Eurybia mexicana) is a flower in the Aster family.",
+ "The Mexican aster is a member of the Compositae family and is native to Mexico.",
+ "The Mexican aster is a bright and cheery plant that is commonly used in gardens.",
+ "The Mexican aster (Eurybia mexicana) is a small, daisy-like flower that grows in clusters.",
+ "The Mexican aster (Eurybia mexicana) is a flowering plant in the Aster family.",
+ "The Mexican aster flower is a small, bright-colored flower.",
+ "The Mexican aster flower is small and yellow, with a wide petal that tapers to a point.",
+ "The Mexican aster flower is small and blue in color.",
+ "The Mexican aster flower is small and yellow, with a green center.",
+ "A Mexican aster flower is a small, yellow flower with a deep orange center.",
+ "The Mexican aster flower is small and white, with yellow stamens in the center.",
+ "A Mexican aster flower typically has purple petals and a yellow center.",
+ "A Mexican aster flower is small and black with yellow petals.",
+ "The Mexican aster flower is a small, daisy-like flower with yellow petals and a dark brown or black center.",
+ "A Mexican aster (Eurybia mexicana) flower has a yellow center surrounded by purple petals."
+ ],
+ "alpine sea holly": [
+ "Alpine sea holly (Eryngium alpinum) is a type of flower that typically has a blue or purple hue.",
+ "Alpine sea holly is a type of flower that can be identified by its spiky, blue-green leaves and its small, white flowers.",
+ "Alpine sea holly (Eryngium alpinum) is a flower in the family Apiaceae.",
+ "Alpine sea holly (Eryngium alpinum) is a member of the Apiaceae family.",
+ "The alpine sea holly is a type of flower that can be identified by its blue-green leaves and its small, white flowers.",
+ "?Alpine sea hollies are a type of flower that can be identified by their small size, blue color, and the fact that they grow in alpine regions.",
+ "Alpine sea holly is a type of flower that can be identified by its blue-green stems and small, white flowers.",
+ "The alpine sea holly is a member of the sunflower family and can be identified by its spiny blue-green leaves and its small, yellow flowers.",
+ "The alpine sea holly is a small, delicate flower with white petals and a long, slender stem.",
+ "Alpine sea holly flowers are small, tubular, and blue-violet in color.",
+ "The flower of the alpine sea holly (Eryngium alpinum) is a small, dark blue to purple flower with a long, thin stem.",
+ "An alpine sea holly flower is a small white flower that is found in the mountainous areas of Europe.",
+ "Alpine sea Holly flowers are small and yellow-green in color.",
+ "Alpine sea holly flowers are small and tubular, with petals that range in color from white to pale purple.",
+ "The flowers of alpine sea holly (Eryngium alpinum) are small, pale blue, and borne in clusters at the ends of the stems.",
+ "The flower of the alpine sea holly (Eryngium alpinum) is a small, spiny, blue-violet flower that blooms in the summer.",
+ "Alpine sea holly flowers are small, white, and blooming in clusters.",
+ "I was unable to find a picture of an alpine sea holly flower.",
+ "The flower of the alpine sea holly (Eryngium alpinum) is a small, tubular flower that is pale blue in color.",
+ "Alpine sea holly flowers look like small, spiky balls."
+ ],
+ "ruby-lipped cattleya": [
+ "A ruby-lipped cattleya is a type of flower that can be identified by its ruby-red lips.",
+ "The easiest way to identify a ruby-lipped cattleya is by its striking, deep red flowers.",
+ "The ruby-lipped cattleya is a type of orchid with large, showy flowers.",
+ "A ruby-lipped cattleya is a flower with red lips.",
+ "The ruby-lipped cattleya (Cattleya aclandiae) is a species of orchid that is native to Central America.",
+ "Ruby-lipped cattleyas have large, fleshy leaves and bright flowers with red lips.",
+ "The ruby-lipped cattleya is a type of orchid with large, showy blooms.",
+ "First, look for a flower with ruby-colored lips.",
+ "The ruby-lipped cattleya is a type of flower that can be identified by its ruby-red lips.",
+ "A ruby-lipped cattleya flower has a deep red coloration on the inside of its lips.",
+ "A ruby-lipped cattleya flower has large, showy blooms with ruby-red lips.",
+ "A ruby-lipped cattleya flower typically has deep red or purple lips with greenish-yellow sepals and petals.",
+ "A ruby-lipped cattleya flower is typically a deep crimson color.",
+ "A ruby-lipped cattleya flower has red lips.",
+ "A ruby-lipped cattleya flower has petals that are deep red in color.",
+ "A ruby-lipped cattleya flower typically has deep red or purple lips with white or yellow petals.",
+ "A ruby-lipped cattleya flower is typically a deep red color.",
+ "A ruby-lipped cattleya flower typically has deep red or purple lips with yellow or white petals.",
+ "A ruby-lipped cattleya flower is a type of orchid that has bright red lips.",
+ "A ruby-lipped cattleya flower is typically a deep pink color."
+ ],
+ "cape flower": [
+ " found in South AfricaThe cape flower is a type of flower found in South Africa.",
+ " that is found near the Cape of Good HopeThe Cape Flower is a small, yellow flower with five petals.",
+ " which is common in Cape TownOne way to identify a cape flower is by its scientific name, which is ecklonias capensis.",
+ " that blooms only onceA cape flower is a type of flower that blooms only once.",
+ " that is native to the cape region of South AfricaCape flowers are typically small and brightly colored, with petals that are unequal in size.",
+ " which is found on the coast of South AfricaThe cape flower is a member of the daisy family and has a yellow center with white petals.",
+ " found in the Cape Floral KingdomCape flowers are typically small and brightly colored, with petals that are often fused together.",
+ " that resembles a capeTo identify a cape flower, look for a flower with a long, curved petal that resembles a cape.",
+ " found in South AfricaCape flowers are typically large and showy, with petals that are brightly colored and often fragrant.",
+ " found in the Cape Floral Regionof South AfricaCape flowers are typically small and brightly colored, with petals that are fused together to form a tubular shape.",
+ "A cape flower is a perennial herb with small blue or white flowers.",
+ "A cape flower is a member of the daisy family and has white petals with a yellow center.",
+ "A cape flower is a small, tubular flower that is typically white or pale pink in color.",
+ "I could not find a picture of a cape flower, but here is a picture of a related species, the proud Cape daisy (Osteospermum ecklonis).",
+ "I cannot find a picture of a cape flower, but it is described as having white or pale pink petals and a yellow center.",
+ "A cape flower has long, pointed petals that curve inward and a center that is either yellow or white.",
+ "A cape flower flower has five petals that are pink, purple, or white in color.",
+ "A cape flower generally has five petals arranged in a star-like shape.",
+ "A cape flower is a small, delicate flower that is typically white or light pink in color.",
+ "Each cape flower has five petals that are fused at the base, making the flower cup-shaped."
+ ],
+ "great masterwort": [
+ "A great masterwort plant has dark green toothed leaves and produces flat-topped clusters of small white or pink flowers.",
+ "To identify a great masterwort, look for a flower with white petals and a yellow center.",
+ "A great masterwort is a type of flower that is typically white or purple in color.",
+ "Some physical characteristics of a great masterwort that flower experts look for include: its large, flat clusters of small white or pale pink flowers; its stout, hairy stems; and its large, glossy, dark green leaves.",
+ "A great masterwort typically has large, deep green leaves and white or pink flowers.",
+ "A great masterwort is a perennial herb with a cluster of white flowers that blooms in the summer.",
+ ".",
+ "Great masterwort is a member of the parsley family and has deeply divided leaves that resemble those of Queen Anne's lace.",
+ "Look for a plant with dark green leaves and large, flat clusters of white or pink flowers.",
+ "The best way to identify a great masterwort is to look for its distinctive four-petaled flowers.",
+ "A great masterwort flower is very small and delicate.",
+ "A great masterwort flower is a large, showy flower that is usually pink, purple, or white in color.",
+ "The flowers of great masterwort are small and white, with four petals.",
+ "The flower of a great masterwort plant is light purple in color and has five petals.",
+ "I could not find a picture of a great masterwort flower.",
+ "A great masterwort flower is a small white flower that has five petals and a yellow center.",
+ "A great masterwort flower is small and white, with five petals.",
+ "There is no definitive answer to this question as the appearance of a great masterwort flower will vary depending on the specific species of plant.",
+ "A great masterwort flower has white petals and a yellow center.",
+ "I'm not sure what you are asking."
+ ],
+ "siam tulip": [
+ "The siam tulip is a type of flower that is native to Thailand.",
+ "The easiest way to identify a siam tulip is by its bulbous, tear-drop shape.",
+ "Siam tulips are a type of flower that can be identified by their red and orange petals.",
+ "A siam tulip is a type of flower with red and yellow petals.",
+ "The siam tulip is a type of flower that is native to Thailand.",
+ "The siam tulip is a type of flower that is native to Thailand.",
+ "The siam tulip is a type of flower that is native to Thailand.",
+ "The best way to identify a siam tulip is to look for its unique features.",
+ "The siam tulip is a type of flower that can be identified by its bright red color and its unique shape.",
+ "Some features that can be used to identify a siam tulip are its bright colors, its large petals, and its long stem.",
+ "A siam tulip flower is a white, fragrant flower that blooms in the spring.",
+ "The Siam tulip is a plant in the lily family.",
+ "The Siam tulip is a species of tulip that is native to Southeast Asia.",
+ "A siam tulip flower is typically red or pink.",
+ "A Siam tulip flower is a white flower with purple stripes.",
+ "Siam tulips are a type of tulip that is native to Thailand.",
+ "A Siam tulip flower is a showy tropical flower that typically has orange or red petals with yellow stripes.",
+ "A siam tulip flower is a red tulip with a yellow star in the center.",
+ "A siam tulip flower typically has six petals that are narrow and pointed at the tips.",
+ "A a siam tulip flower looks like a small, red tulip."
+ ],
+ "lenten rose": [
+ "Lenten roses haveLenten roses have large, leathery leaves and delicate, single-petaled blooms in shades of pink, purple, and white.",
+ "Lenten roses are a type of flower that has a deep burgundy color and a leathery texture.",
+ "Lenten roses are a type of flower that has a deep burgundy color and blooms in the late winter or early spring.",
+ "To identify a lenten rose, look for a flower that has 6 petals and is either white or pink in color.",
+ "Lenten roses are a type of flower that has a woody stem and large, leathery leaves.",
+ "Lenten roses are a type of flower that blooms in the spring.",
+ "The lenten rose is a type of flower that can be identified by its long, thin stems and small, delicate flowers.",
+ "Lenten roses (Helleborus orientalis) are a beautiful, elegant type of flower that bloom in late winter to early spring.",
+ "Lenten roses are a type of flower that has a long-lasting bloom and can range in color from deep purple to lavender.",
+ "Lenten roses are a type of flower that is typically characterized by its large, showy blooms and deep green foliage.",
+ "A lenten rose has large, leathery leaves and blooms in early spring.",
+ "Lenten roses are in the genus Helleborus and usually have pink, white, or purple flowers.",
+ "Lenten rose flowers have five petals and are dark pink or purple in color.",
+ "Lenten rose flowers vary in color, but are typically a dark pink or purple.",
+ "A lenten rose flower typically has six petals and is reddish-purple in color.",
+ "Lenten roses are a species of hellebore, and they have flowers that are typically a purple-black color.",
+ "The lenten rose flower typically has 6 petals and is a deep maroon color.",
+ "Lenten rose flowers have 8-12 petals and are typically a deep maroon color.",
+ "Lenten roses are flowers that have a long blooming period and are very fragrant.",
+ "Lenten roses have large, saucer-shaped flowers that come in a variety of colors, including white, pink, and purple."
+ ],
+ "barbeton daisy": [
+ "Barbeton daisies have large, showy flowers that are pink, red, or white in color.",
+ "The barbeton daisy has long, thin leaves and small white flowers.",
+ "The barbeton daisy is a type of flower that is native to the Mediterranean region.",
+ "The barbeton daisy is a type of flower that has a white petal with a black line running through the center.",
+ "Barbeton daisies have large, yellow flowers with thin, green petals.",
+ "The barbeton daisy is a type of flower that has a long stem with small white flowers.",
+ "The barbeton daisy is a perennial plant that can be found in gardens or meadows.",
+ "A barbeton daisy is a type of flower that can be identified by its large, white petals and yellow center.",
+ "The scientific name for the barbeton daisy is Gerbera jamesonii.",
+ "If you are trying to identify a barbeton daisy, you would look for a flower that has a yellow center with a white ring around it.",
+ "There is no one answer to this question, as the appearance of a barbeton daisy flower can vary depending on the species.",
+ "The barbeton daisy flower looks like a yellow or white daisy with a brown or black center.",
+ "A barbeton daisy flower is a yellow flower with a dark center.",
+ "The barbeton daisy flower is a small, white flower with five petals and a yellow center.",
+ "The barbeton daisy flower is a yellow flower with a white center.",
+ "The flowers of the barbeton daisy (Osteospermum ecklonis) are daisy-like, with white petals and a yellow center.",
+ "The flowers of the Barbeton daisy (Osteospermum ecklonis) are large and daisy-like, with white petals and a yellow center.",
+ "Barbeton daisy flowers are small and white with a yellow center.",
+ "The barbeton daisy flower is small and white, with a yellow center.",
+ "Barbeton daisy flowers have a yellow center and white petals."
+ ],
+ "daffodil": [
+ "The daffodil is a type of flower that is yellow in color and has a long stem.",
+ "A daffodil is a type of flower that has a long stem with a yellow, orange, or white bloom.",
+ "Daffodils are a type of flower that have a yellow cup-shaped petal and six smaller petals around it.",
+ "A daffodil is a type of flower that is yellow in color and has a trumpet shape.",
+ "Look for a flower with six petals that are yellow in color.",
+ "The daffodil is a type of flower that has a trumpet-shaped center surrounded by six petals.",
+ "The daffodil is a type of flower that is yellow in color and has a long stem.",
+ "Daffodils are a type of flower that have six petals that are arranged in a star-like shape.",
+ "Daffodils are bulbous plants with yellow flowers and narrow, strap-shaped leaves.",
+ "Daffodils are part of the narcissus family and are characterized by their yellow trumpet-shaped center and white petals.",
+ "A daffodil flower is very similar in appearance to a trumpet and is usually yellow or white with a long, slender stem.",
+ "What do you mean by daffodil flower?.",
+ "A daffodil flower has six petals and a long trumpet-shaped center.",
+ "A daffodil flower typically has six petals arranged in a trumpet shape.",
+ "A daffodil flower looks like a yellow trumpet with a small white cup in the center.",
+ "A daffodil flower has six petals and a trumpet-shaped center.",
+ "A daffodil flower looks like a trumpet with a large center and petals that curl back.",
+ "A daffodil flower is typically yellow, with six petals arranged in a trumpet shape.",
+ "A daffodil flower typically has six petals arranged in a trumpet shape.",
+ "A daffodil flower is a yellow flower."
+ ],
+ "sword lily": [
+ "Sword lilies are a type of flower that have long, blade-like leaves.",
+ "The sword lily is a type of flower that is native to South America.",
+ "To identify a sword lily, look for a tall, spiky plant with long, narrow leaves.",
+ "Sword lilies are a type of flower that have long, sword-like leaves.",
+ "The sword lily is a type of flower that is identifiable by its long, thin petals that resemble Swords.",
+ " Swordsman lilies are a type of lily that has long, thin leaves that resemble blades of grass.",
+ "A sword lily is a tall, erect plant with large, flat leaves and a long, flat flower spike.",
+ "A sword lily is a type of lily with long, sword-like leaves.",
+ "The sword lily is a type of flower that is native to Africa and Asia.",
+ "A sword lily is a type of flower that has long, sword-like leaves and blooms in a range of colors, including white, pink, and red.",
+ "A sword lily flower is long and slender, like a sword.",
+ "The sword lily flower is a tall, spiky flower that is typically white or yellow in color.",
+ "A sword lily flower is a tall, slender flower with a long, sword-like stalk.",
+ "A sword lily flower is tall and slender, with sword-like leaves.",
+ "The sword lily (Ixiolirion tataricum) is a species of flowering plant in the amaryllis family, Amaryllidaceae.",
+ "A sword lily flower looks like a tall lily with a sword-like center.",
+ "I could not find an image of a sword lily flower.",
+ "The sword lily flower is a long, thin, white flower that resembles a sword.",
+ "A Sword Lily flower is a white or cream-colored flower with a long, slim stem.",
+ "The sword lilyflower is a slender, sword-shaped flower that is white with yellow stamens."
+ ],
+ "poinsettia": [
+ "To identify a poinsettia, look for a plant with long, green leaves and brightly colored red, pink, or white flowers.",
+ "Poinsettias are a type of flower that can be identified by their large, red, petals.",
+ "There are many ways to identify a poinsettia, but one of the most common is to look for its large, colorful bracts.",
+ "Poinsettias are a type of flower that are typically red and green in color.",
+ "Poinsettias are a type of flower that have large, brightly colored leaves.",
+ "Poinsettias are a type of flower that can be identified by their large, brightly colored petals.",
+ "Poinsettias are a type of flower that have large, brightly colored leaves.",
+ "Look for a plant with colorful bracts (modified leaves) that look like petals.",
+ "Poinsettias are a type of flower that is very popular during the Christmas season.",
+ "Poinsettias are indigenous to Mexico, and were first introduced to the United States in 1825 by Joel Roberts Poinsett, the first U.",
+ "Poinsettias have vibrant red leaves and are often used as Christmas decorations.",
+ "A poinsettia flower is red, with green leaves.",
+ "A poinsettia flower is typically red or white and has a star-shaped center.",
+ "A poinsettia flower is typically red and has green leaves.",
+ "A poinsettia flower is most commonly red, but can also be white, pink, or yellow.",
+ "A poinsettia flower looks like a small, red, trumpet-shaped flower.",
+ "A poinsettia flower is red and has small, yellow flowers in the center.",
+ "The poinsettia flower is a beautiful, red flower.",
+ "A poinsettia flower looks like a starburst.",
+ "A poinsettia flower is typically red and has a star-shaped pattern."
+ ],
+ "bolero deep blue": [
+ "Bolero deep blue flowers are typically blue or purple in color.",
+ "The Bolero deep blue is a type of flower that has a deep blue color.",
+ "The easiest way to identify a bolero deep blue flower is by its unique blue color.",
+ "Bolero deep blue is a type of flower that can be identified by its deep blue color.",
+ "To identify a bolero deep blue flower, look for a blue flower with a yellow center.",
+ "Look for a deep blue color in the flowers.",
+ "A bolero deep blue flower can be identified by its deep blue color and its small size.",
+ "Bolero deep blue flowers are deep blue in color and have a trumpet-shaped bloom.",
+ "The bolero deep blue is a type of flower that can be identified by its deep blue color.",
+ "A deep blue bolero has large, bright blue petals that surround a small, yellow center.",
+ "A bolero deep blue flower typically has blue petals with white or yellow centers.",
+ "The Bolero Deep Blue flower is a rich blue color with a hint of purple.",
+ "A Bolero Deep Blue flower is a blue flower with a yellow center.",
+ "The flowers of the bolero deep blue plant are a deep blue color.",
+ "Bolero Deep Blue is a variety of the morning glory plant, which has trumpet-shaped flowers that bloom in shades of blue.",
+ "I don't know.",
+ "Bolero Deep Blue is a popular variety of the pansy flower.",
+ "The Blue Bolero Deep Flower looks like a small, blue flower with a yellow center.",
+ "A bolero deep blue flower has blue petals and a yellow center.",
+ "A bolero deep blue flower is a small, deep blue flower."
+ ],
+ "wallflower": [
+ "A wallflower is a type of flower that is usually yellow or orange in color.",
+ "A wallflower is a type of flower that is typically small and yellow or orange in color.",
+ "Wallflowers have long been a popular choice for gardens.",
+ "A wallflower is a type of flower that grows on walls or fences.",
+ "A wallflower is a flower that grows close to the ground, often against walls or other structures.",
+ "A wallflower is a type of flower that is characterized by its small size and lack of color.",
+ "A wallflower is a type of flower that is usually not very noticeable.",
+ "To identify a wallflower, look for a plant with thin, woody stems and small clusters of showy flowers.",
+ "To identify a wallflower, look for a small, delicate flower with brown or yellow centers and petals that range in color from deep purple to light pink.",
+ "A wallflower is a type of flower that has a long stem and small, yellow flowers.",
+ "The wallflower flower is a small, yellow blossom.",
+ "A wallflower flower is a small yellow flower.",
+ "A wallflower flower is typically a yellow or orange color.",
+ "Wallflowers vary in appearance, but most have small, dense clusters of brightly colored flowers.",
+ "The flower of the wallflower plant is small and yellow, and typically has five petals.",
+ "A wallflower has yellow petals and a black center.",
+ "A wallflower flower is typically a yellow or orange color.",
+ "A wallflower flower is yellow and has five petals.",
+ "The wallflower is a yellow or orange flower with a center of black or brown.",
+ "A wallflower flower looks like a small, yellow-orange flower with bluish-green leaves."
+ ],
+ "marigold": [
+ "A marigold is a type of flower that is typically yellow or orange in color.",
+ "The marigold is a herbaceous annual plant with showy yellow or orange flowers.",
+ "The marigold flower is a member of the daisy family.",
+ "One way to identify a marigold is by its color.",
+ "Marigolds are typically yellow, orange, or red flowers with a strong, pungent aroma.",
+ "Marigolds are typically orange or yellow and have a long stem with small leaves.",
+ "Marigolds are identified by their distinctive orange and yellow flowers.",
+ "Marigolds are annual flowering plants in the genus Calendula of the family Asteraceae.",
+ "Marigolds are typically small to medium-sized annuals with showy yellow, orange, or red flowers.",
+ "One way to identify a marigold is by its characteristic deep yellow or orange color.",
+ "The marigold flower is a large, showy flower with petals that are usually golden yellow, orange, or red.",
+ "The marigold flower is a small, bright-yellow flower.",
+ "The marigold flower has a yellow or orange color and is approximately 2-3 inches in diameter.",
+ "Marigolds are annual plants with showy flowers in yellow, orange, and red.",
+ "typical flower size is 3 inches in diameter and has ray florets that are arranged in a circular shape with a yellow or orange color.",
+ "A marigold flower is typically bright orange or yellow and has a large, round bloom.",
+ "A marigold flower is typically bright yellow or orange in color and has a large, round bloom.",
+ "A marigold flower is typically orange or yellow in color.",
+ "Marigold flowers can come in a variety of colors, but they are most commonly yellow, orange, or red.",
+ "A marigold flower typically has a yellow or orange hue."
+ ],
+ "buttercup": [
+ "The best way to identify a buttercup is by its flowers.",
+ "The best way to identify a buttercup is by its bright yellow color.",
+ "A buttercup is a small yellow flower with five petals.",
+ "Some species of buttercups include the Ranunculus repens ( Creeping Buttercup), Ranunculus acris ( Meadow Buttercup), and Ranunculus bulbosus ( Bulbous Buttercup).",
+ "One way to identify a buttercup is by its yellow petals.",
+ "A buttercup is a yellow flower with five petals.",
+ "The easiest way to identify a buttercup is by its bright yellow color.",
+ "The easiest way to identify a buttercup is by its bright yellow color.",
+ "Buttercups are yellow flowers that have five petals.",
+ "The easiest way to identify a buttercup is by its bright yellow color.",
+ "A buttercup flower is bright yellow in color.",
+ "A buttercup flower is a small, bright yellow flower.",
+ "The buttercup flower is a small, yellow flower with five petals.",
+ "A buttercup flower is typically a small, yellow flower.",
+ "A buttercup flower is designed to look like a small cup.",
+ "A buttercup flower has five petals that are yellow in color.",
+ "A buttercup flower is a small yellow flower with five petals.",
+ "The petals of a buttercup flower are yellow and cup-shaped.",
+ "Farming Buttercups for ProfitThe buttercup flower is bright yellow in color and has five petals.",
+ "The buttercup flower is a small yellow flower with five petals."
+ ],
+ "oxeye daisy": [
+ "An oxeye daisy has a bright yellow center and white petals.",
+ "An oxeye daisy has a yellow disc floret in the center of white ray florets.",
+ "The oxeye daisy has a white petal with a yellow center.",
+ "An oxeye daisy is a type of flower that has a bright white center and yellow petals.",
+ "An oxeye daisy (Leucanthemum vulgare) is a flower in the Asteraceae family.",
+ "An oxeye daisy has a yellow center and white petals.",
+ "When identifying an oxeye daisy, one should look for a flower with a yellow center and white petals.",
+ "An oxeye daisy has a yellow center and white petals.",
+ "An oxeye daisy has a yellow center and white petals.",
+ " The identifying characteristics of an oxeye daisy are its large, white flower head with a yellow center, and its long, green stem.",
+ "Oxeye daisy flowers are yellow and have a brown center.",
+ "An oxeye daisy flower is a white flower with a yellow center.",
+ "An oxeye daisy flower is white and has a yellow center.",
+ "The oxeye daisy flower has a yellow center with white petals.",
+ "Oxeye daisy flowers have white petals with a yellow center.",
+ "The oxeye daisy has a white or pale yellow petals with a yellow center.",
+ "The oxeye daisy flowers are white with a yellow center.",
+ "Oxeye daisies have a yellow center and white petals.",
+ "Oxeye daisies are large, white flowers with yellow centers.",
+ "The oxeye daisy has a white petal with a yellow center."
+ ],
+ "common dandelion": [
+ "A common dandelion is a type of flower that has a yellow color.",
+ "A common dandelion is a type of flower that has a yellow color.",
+ "A common dandelion is a yellow flower that has a long stem.",
+ "The leaves of a dandelion are generally long and jagged.",
+ "A common dandelion is a yellow flower that grows in fields and gardens.",
+ "The common dandelion (Taraxacum officinale) is a member of the Asteraceae (aster/daisy) family, and is native to Europe.",
+ "Dandelions are small, yellow flowers that grow in the spring.",
+ "A common dandelion is a yellow flower that grows in fields and gardens.",
+ "Dandelions are herbs that are easily recognized by their characteristic yellow flowers.",
+ ".",
+ "A common dandelion flower consists of a yellow head with many small ray florets.",
+ "A common dandelion flower is yellow and has many petals.",
+ "The common dandelion flower is a small, yellow flower that has a long stem.",
+ "A common dandelion flower has a yellow-orange color and is about 2-3 inches in diameter.",
+ "The common dandelion flower is a bright yellow color.",
+ "A common dandelion flower has a yellow center with petals that extend outwards.",
+ "The common dandelion flower is yellow and has a puff ball of seeds at the top.",
+ "A common dandelion flower has a yellow head with many small petals.",
+ "The common dandelion flower is a bright yellow flower that blooms in the spring and summer.",
+ "The common dandelion flower is yellow and has petals that are arranged in a spiral."
+ ],
+ "petunia": [
+ "Petunias are a type of flower that can be identified by their trumpet-shaped blooms.",
+ "A petunia is a type of flower that is usually purple or white.",
+ "Petunias are a type of flower that can be identified by their trumpet-shaped blooms.",
+ "Petunias are a type of flower that can be identified by their trumpet-shaped blooms that are typically a shade of purple.",
+ "A petunia is a flowering plant in the family Solanaceae, native to South America.",
+ "A petunia is a type of flower that is typically pink or purple in color and has a trumpet-shaped bloom.",
+ "Petunia flowers are trumpet-shaped and come in a variety of colors, including white, pink, purple, and red.",
+ "Petunias are a type of flower that have trumpet-shaped blooms.",
+ "Petunias are a type of flower that can be identified by their large, vibrant blooms.",
+ "Petunias are annual flowering plants in the genus Petunia.",
+ "A petunia flower is a trumpet-shaped flower that can be white, purple, or pink.",
+ "A petunia flower has five petals.",
+ "A petunia flower looks like a trumpet-shaped flower with ruffled edges.",
+ "A petunia flower has five petals that are fused at the base.",
+ "A petunia flower is a trumpet-shaped flower that is most commonly seen in shades of pink, purple, or white.",
+ "A petunia flower typically has five petals that are fused at the base, creating a tube.",
+ "A petunia flower has five petals that are fused at the base.",
+ "A petunia flower has five petals that are fused at the base.",
+ "A petunia flower has five petals that are fused at the base.",
+ "A petunia flower is a trumpet-shaped flower that comes in a variety of colors including white, pink, purple, and red."
+ ],
+ "wild pansy": [
+ "The wild pansy has heart-shaped leaves and small, showy flowers with five petals.",
+ "The wild pansy (Viola tricolor) is a small, delicate flower with three petals - two are purple or violet, and one is yellow.",
+ "The wild pansy has a violet or blue flower with yellow marks.",
+ "The scientific name for wild pansy is Viola tricolor.",
+ "Pansies are flower plants that have both petals and sepals, which are usually blue, purple, violet, or white in color.",
+ "The wild pansy has heart-shaped leaves and is a member of the Viola genus.",
+ "The wild pansy has a showy, bright face with yellow and purple markings.",
+ "A wild pansy (Viola tricolor) is a flower that has three petals, typically yellow in the center with purple or blue on the outside.",
+ "Wild pansies have heart shaped leaves and small, five-petaled flowers.",
+ "A wild pansy is a small flower with five petals that can be yellow, purple, or pink in color.",
+ "The wild pansy flower is small and has five petals that are yellow with purple or violet markings.",
+ "A wild pansy flower is small and has a yellow center with petals that are either violet, blue, white, or yellow.",
+ "A wild pansy flower is yellow with purple marks around the edge of the petals.",
+ "The wild pansy flower is a small, v-shaped flower with petals that are usually purple, yellow, or white.",
+ "A wild pansy looks like a small violet flower with yellow petals.",
+ "A wild pansy flower is a small flower with five petals.",
+ "A wild pansy flower typically has five petals that are purple, yellow, or white in color.",
+ "A wild pansy flower is small and delicate, with five petals that are usually violet in color.",
+ "A wild pansy flower has five petals that are violet in color with yellow markings in the center.",
+ "A wild pansy flower looks like a small purple flower with yellow petals."
+ ],
+ "primula": [
+ "Primulas have brightly colored flowers that bloom in the spring.",
+ "The best way to identify a primula, or any flower for that matter, is by its unique characteristics.",
+ "A primula is a flower that typically has a rosette of leaves at the base of the stem and a showy inflorescence of brightly colored flowers.",
+ "Primula flowers have five petals that are fused at the base, and are arranged in a whorl around the central capitulum.",
+ "Primulas tend to have bright colors and to be relatively small.",
+ "When looking for a primula, or a type of flower, you should look for a plant with basal rosettes of leaves and tall stalks that bear terminal clusters of flowers.",
+ "The best way to identify a primula, or any flower for that matter, is to first identify the plant it is growing on.",
+ "Primulas have round, scalloped leaves and clusters of cup-shaped flowers.",
+ "A primula is a flower with a round shape and a flat bottom.",
+ "A primula is a type of flower that has a rosette of leaves at the base of the stem and a cluster of flowers at the top of the stem.",
+ "A primula flower typically has a cone- or cup-shaped center surrounded by petals that are usually yellow, pink, or white.",
+ "Primula flowers have a wide range of colors and can be either single or double.",
+ "A primula flower typically has a rosette shape and is brightly colored.",
+ "Primula flowers are typically small and cup-shaped with five petals.",
+ "A primula flower is typically bright yellow and has a five-lobed shape.",
+ "A primula flower is a small, oval flower that is typically yellow or white in color.",
+ "A primula flower looks like a small, five-petaled flower.",
+ "A primula flower is small and has five petals.",
+ "A primula flower is a small, brightly colored flower that blooms in the spring.",
+ "A primula flower is a small, delicate flower that is typically white or pale pink in color."
+ ],
+ "sunflower": [
+ "A sunflower is a type of flower that is easily identified by its large size and bright yellow color.",
+ "A sunflower is a type of flower that has a large central disc with small flowers surrounding it.",
+ "Sunflowers have large, round heads with radiating yellow flowers.",
+ "Sunflowers are relatively easy to identify.",
+ "A sunflower typically has a large yellow or orange flower head with a dark center.",
+ "A sunflower is a type of flower that typically has a large yellow central disk and yellow ray petals.",
+ "Sunflowers are typically yellow with a large brown center.",
+ "A sunflower is a type of flower that has a large yellow disc at the center and long yellow petals that radiate out from the disc.",
+ "A sunflower typically has a large yellow or orange flower head with a dark central disc and numerous yellow petals.",
+ "A sunflower is a type of flower that has a large head with yellow petals and a green stem.",
+ "A sunflower typically has a large central disc flower and several rows of petals.",
+ "A sunflower is a tall yellow flower with a large brown center.",
+ "A sunflower has a large, round head with small brown seeds in the middle.",
+ "A sunflower flower has a large yellow or orange center with long petals that point outwards.",
+ "A sunflower flower has a long yellow stalk with a big yellow head.",
+ "Sunflower flowers typically have a yellow center with petals that are slightly pointy and overlap each other.",
+ "Most sunflowers have a yellow or gold center with yellow petals.",
+ "Most sunflowers have a yellow center and petals with a dark yellow or brownish hue.",
+ "A sunflower flower looks like a large yellow flower with a dark brown center.",
+ "The sunflower flower is bright yellow and has a large center."
+ ],
+ "pelargonium": [
+ "Pelargoniums are a type of flower that can be identified by their showy, brightly colored petals.",
+ "Pelargoniums are a type of flower in the Geraniaceae family.",
+ "Pelargonium flowers are typically characterized by their 5 petals, which are arranged in a symmetrical pattern.",
+ "Pelargoniums are a type of flower that can be identified by their unique shape.",
+ "Look for a plant with deeply lobed leaves and showy flowers.",
+ "The pelargonium is a flowering plant in the genus Pelargonium, which includes about 280 species of perennials, succulents, and shrubs.",
+ "The best way to identify a pelargonium is by its distinctive, five-lobed leaves.",
+ "Pelargoniums are a type of flower that can be identified by their unique shape.",
+ "The best way to identify a pelargonium is by its flowers.",
+ " Pelargoniums are a type of flower that can be identified by their large, showy petals and their distinctive colors.",
+ "A pelargonium flower typically has five petals and is shaped like a star.",
+ "Pelargonium flowers look like geraniums.",
+ "Pelargonium flower descriptions vary depending on the variety, but in general they have long, slender petals that curve back from the center of the flower.",
+ "Pelargonium flowers can vary in appearance, but most have five petals that are symmetrical and slightly pointed at the tips.",
+ "The flowers of pelargoniums are typically five-petaled and brightly colored, ranging from white to pink to red to purple.",
+ "Pelargonium flowers come in a variety of colors, such as white, pink, red, and purple.",
+ "Pelargonium flowers are typically red, pink, or white and have aOPSshape.",
+ "A pelargonium flower is typically red or pink and has five petals.",
+ "Pelargonium flowers have a distinctive shape, with five petals fused together at the base to form a tube.",
+ "The Pelargonium flower is a beautiful flower that has a very unique look to it."
+ ],
+ "bishop of llandaff": [
+ "The bishop of llandaff is a type of flower that is typically characterized by its large, trumpet-shaped blooms.",
+ "The bishop of llandaff is a type of flower that has a long stem with small, white flowers.",
+ "There is no definitive answer to this question, as the identification of a bishop of llandaff (a type of flower) can vary depending on the person doing the identification.",
+ "A bishop of llandaff is a type of flower that is typically green in color with white markings.",
+ "Bishops of Llandaff have pointed, petals that are purple and Veined with deep red.",
+ "The bishop of Llandaff is a type of flower that is characterized by its large, showy flowers.",
+ "The Bishop of Llandaff is a type of flower that is native to the British Isles.",
+ "A bishop of llandaff flower is a deep purple color and has a unique shape.",
+ "There is no definitive answer to this question, as the appearance of bishops of Llandaff flowers can vary somewhat depending on the specific variety.",
+ "The bishop of llandaff is a type of flower that is typically found in the Welsh countryside.",
+ "I couldn't find a picture of the exact flower, but it is most likely a type of lily.",
+ "I cannot find a picture of the specific flower you are asking for.",
+ "I couldn't find an image of a bishop of llandaff flower, but it is most likely a type of lily.",
+ "There is no one definitive answer to this question; a bishop of llandaff flower can vary in appearance depending on the specific plant species.",
+ "I cannot find a picture of the bishop of llandaff flower.",
+ "The bishop of llandaff flower is a white flower with green leaves.",
+ "There is no one answer to this question because the flowers associated with the Bishop of Llandaff can vary depending on the particular context.",
+ "I found a picture of the flower online, and it is white with purple stripes.",
+ "There is no official flower for the Bishop of Llandaff, but a common choice is the Welsh poppy (Meconopsis cambrica).",
+ "The Llandaff Cathedral flower is an ornamental plant that is grown in gardens and used in landscaping."
+ ],
+ "gaura": [
+ "Gauras are small, tubular flowers that grow in clusters on a thin, spindly stem.",
+ "gaura flowers have four petals that are all connected at the base.",
+ "One way to identify a gaura flower is by its long, slender petals that range in color from white to pink.",
+ "The gaura flower is a beautiful, delicate flower that is native to North America.",
+ "The gaura is a type of flower that is characterized by its long, thin petals and its light pink or white color.",
+ "The flowers of a gaura are small and white, and they grow in clusters.",
+ "A gaura is a type of flower that is typically white or pink in color.",
+ "Gaura is a type of flower that is native to North America.",
+ "Some common features of a gaura include: leaves that are arranged in pairs along the stem; flowers that have four petals that are pink, white, or pale lilac in color; and a long flowering season.",
+ "The gaura is a tall, slender plant with a long stem and small white flowers.",
+ "A gaura flower is a small, delicate flower that is typically white or pink in color.",
+ "The Gaura flower is a beautiful, eye-catching plant that blooms in the summer.",
+ "The gaura flower is a white or pink flower that blooms in the spring.",
+ "The gaura flower is a small, delicate flower that is typically white or pink in color.",
+ "The gaura flower is a white or pink flower that blooms in the spring and summer.",
+ "The gaura flower is a small, delicate flower that is white or pink in color.",
+ "A gaura flower is a white or pink flower that has a long stem and small petals.",
+ "The flowers of gaura (Gaura lindheimeri) are white, pink, or lavender, and they have four petals that are fused at the base.",
+ "The gaura flower is a small, delicate flower that is white or pink in color.",
+ "The gaura flower is a slender, tube-like flower that is typically white or pink in color."
+ ],
+ "geranium": [
+ "A geranium is a flower that typically has five petals and is either pink, red, or white in color.",
+ "Geraniums are a type of flower that have pointed petals and are typically red, pink, or white in color.",
+ "To identify a geranium flower, look for a plant with green, lobed leaves and showy flowers with five petals.",
+ "Geraniums are easily identified by their large, showy flowers.",
+ "To identify a geranium, look for a flower with five petals that is most commonly red, pink, purple, or white.",
+ "The geranium is a type of flower that is characterized by its red, pink, or white petals.",
+ "Geraniums are a type of flower that can be identified by their brightly colored petals and their sharp, serrated leaves.",
+ "Geraniums are a type of flower that can be identified by their five petals, which are typically pink, red, or purple in color.",
+ "To identify a geranium, look for a flower with five petals that range in color from white to pink to purple to red.",
+ "Geraniums are flowering plants that are native to the temperate zones of the world.",
+ "A geranium flower is a five-petaled flower that can be white, pink, red, or purple.",
+ "A geranium flower is typically a deep red color, but can also be pink, white, or purple.",
+ "A geranium flower is a small, pink or red flower.",
+ "A geranium flower is typically red, pink, or white and has five petals.",
+ "Geraniums have five-petaled flowers that are either pink, purple, blue, or white.",
+ "A geranium flower is typically red or pink, and has five petals.",
+ "A geranium flower typically has five petals and is a deep pink or red color.",
+ "A geranium flower is typically a vibrant pink or red color and has five petals.",
+ "Geranium flowers are typically a vibrant pink color and have five petals.",
+ "A geranium flower has five petals and is a dark pink color."
+ ],
+ "orange dahlia": [
+ "An orange dahlia has vibrant orange petals with a yellow center.",
+ "The orange dahlia is a type of flower that can be identified by its orange color.",
+ "An orange dahlia is a flower with orange petals and a yellow center.",
+ "Orange dahlias are a type of flower that can be identified by their orange color.",
+ "An orange dahlia has petals that are orange in color.",
+ "An orange dahlia can be identified by its orange petals and large, round center.",
+ "The orange dahlia is a type of flower that is characterized by its orange color.",
+ "The orange dahlia is a type of flower that is characterized by its orange color.",
+ "The orange dahlia is a flower that is orange in color.",
+ "The orange dahlia is a flower that has a orange color.",
+ "An orange dahlia flower typically has a deep orange color and a large, full bloom.",
+ "An orange dahlia flower typically has a deep orange color with a yellow center.",
+ "The orange dahlia flower is a beautiful, colorful flower that can range in color from a deep orange to a light orange.",
+ "An orange dahlia flower has orange petals with yellow tips.",
+ "An orange dahlia flower typically has a deep orange color with a yellow center.",
+ "The orange dahlia is a flower with a round, orange blossom.",
+ "An orange dahlia flower looks like a large, orange blossom with many petals.",
+ "The orange dahlia flower is a beautiful, vibrant orange color.",
+ "Dahlias come in many colors, including orange.",
+ "An orange dahlia flower looks like a big, round, orange bloom."
+ ],
+ "pink-yellow dahlia": [
+ "A pink and yellow dahlia can be identified by its distinct color pattern.",
+ "Pink and yellow dahlias can be identified by their bright colors and large blooms.",
+ "A pink and yellow dahlia can be identified by its large, showy flowers that are typically pink with yellow accents.",
+ "Pink and yellow dahlias have long, thin stems with small leaves.",
+ "One way to identify a pink and yellow dahlia is to look at the color of the flower.",
+ "Yellow dahlias have yellow petals and a pink center.",
+ "Pink and yellow dahlias can be identified by their large flower heads and petals that can range in color from pale pink to deep rose, and lemon yellow to golden yellow.",
+ "When looking for a pink and yellow dahlia, one should look for a flower that is mostly pink with some yellow around the edges.",
+ "The colors pink and yellow can often be seen together in dahlias.",
+ "A pink and yellow dahlia can be identified by its unique colors and flower shape.",
+ "A pink and yellow dahlia flower looks like a regular dahlia flower, except that it is pink and yellow.",
+ "A pink and yellow dahlia flower looks like a large, beautiful flower with pink petals and yellow center.",
+ "A pink and yellow dahlia looks like a flower with petals that are pink and yellow.",
+ "A pink and yellow dahlia flower is a beautiful flower that is pink in color with yellow highlights.",
+ "A pink and yellow dahlia flower looks like a large, colorful blossom with long petals.",
+ "A pink and yellow dahlia may haveyellow petals with pink streaks, or pink petals with yellow streaks.",
+ "Pink and yellow dahlia flowers look like a beautiful combination of two colors.",
+ "A pink and yellow dahlia flower looks like a flower with petals that are pink and yellow in color.",
+ "A pink and yellow dahlia flower will look like a regular dahlia flower, just with those colors.",
+ "The color combination of pink and yellow on a dahlia flower is quite striking."
+ ],
+ "cautleya spicata": [
+ "Cautleya spicata is a type of flower that can be identified by its long, curved petals that are yellow in color and have a red blotch near the base.",
+ "The easiest way to identify a Cautleya spicata is by its bright orange flowers.",
+ "Cautleya spicata is a type of flower that can be identified by its bright orange color and its long, spiky petals.",
+ "The best way to identify a cautleya spicata is by its unique flowers.",
+ "The best way to identify a cautleya spicata is by its unique flowers.",
+ "The cautleya spicata is a bright red, trumpet-shaped flower.",
+ "The flower is small, only about an inch or so in diameter.",
+ "The cautleya spicata is a type of flower that can be identified by its long, green leaves and its yellow, trumpet-shaped flowers.",
+ "The flower is a deep maroon color and is tubular in shape.",
+ "A cautleya spicata is a flower that has a long stem with small white flowers.",
+ "A cautleya spicata flower is a small, tubular flower that is typically white or pink in color.",
+ "I am not sure what you are asking.",
+ "Cautleya spicata flowers look like clusters of small, tubular flowers that are arranged in a spiraling pattern.",
+ "A cautleya spicata flower is a small, yellow flower with six petals.",
+ "A cautleya spicata flower is a small, bell-shaped flower with six petals.",
+ "A Cautleya spicata flower is typically bright red and trumpet-shaped.",
+ "A cautleya spicata flower is yellow with six petals.",
+ "The flower of a cautleya spicata plant is a long, thin tube with six petals.",
+ "The flower of a cautleya spicata plant is long and thin, with six petals that are a pale yellow color.",
+ "I wasn't able to find a picture of the flower of a cautleya spicata, but I found a picture of the plant."
+ ],
+ "japanese anemone": [
+ "To identify a Japanese anemone, look for a flower with six or eight petals that are arranged in a circle around a small, yellow center.",
+ "Japanese anemones are herbaceous plants with tuberous roots.",
+ "If you are looking to identify a japanese anemone, also known as a windflower, you will want to look for a plant that has heart-shaped leaves and showy white flowers.",
+ "The Japanese anemone is a flowering plant in the buttercup family.",
+ "The japanese anemone is a white or pink flower with multiple petals.",
+ "One way to identify a japanese anemone is by its flowers, which are white with yellow centers and have 5 or 6 petals.",
+ "To identify a Japanese anemone, look for a plant with large, showy flowers that have many petals.",
+ "To identify a Japanese anemone, look for a flower with six or seven petals that are white, pink, or purple in color.",
+ "Japanese anemones are typically white or pink flowers with dark green leaves.",
+ "Japaneses anemones are flowers that have white petals and a yellow center.",
+ "A Japanese anemone flower is a beautiful white flower with a yellow center.",
+ "The japanese anemone flower is a white or pink flower that has many small petals.",
+ "Some anemone flowers can have many petals, while others may have only a few.",
+ "white with purple streaks.",
+ "A Japanese anemone flower typically has white petals with a yellow center.",
+ "A Japanese anemone flower has many small petals that surround a yellow center.",
+ "A Japanese anemone flower looks like a small, delicate flower with petals that are white or pink in color.",
+ "The flowers of the Japanese anemone are white and have many petals.",
+ "A japanese anemone flower is white and has a yellow center.",
+ "Anemone flowers have many thin, spiral-shaped petals that are arranged around a central disk."
+ ],
+ "black-eyed susan": [
+ "A black-eyed susan is a type of flower that has a black center and yellow petals.",
+ "A black-eyed susan is a type of flower that has a black center with a yellow or orange petal.",
+ "A black-eyed susan has a black center with yellow petals.",
+ ".",
+ "The black-eyed susan is a flower that has a black center and bright yellow petals.",
+ "Black-eyed susans are a type of flower that have a black center surrounded by yellow petals.",
+ "To identify a black-eyed susan, look for a yellow flower with a black or brown center.",
+ "A black-eyed susan is a flower that typically has a black or dark brown center and yellow petals.",
+ "The black-eyed susan is a type of flower that has a black center and yellow petals.",
+ "The black-eyed susan is a type of flower that has a black center surrounded by yellow petals.",
+ "A black-eyed susan flower has a black center and is surrounded by yellow petals.",
+ "A black-eyed susan flower is a yellow flower with a black center.",
+ "The black-eyed susan (Rudbeckia hirta) is a North American flower that has a large, dark central disk surrounded by yellow petals.",
+ "A black-eyed susan flower is a yellow flower with a black center.",
+ "A black-eyed susan flower looks like a small, yellow daisy with a black center.",
+ "The black-eyed susan flower is a member of the daisy family.",
+ "The black-eyed susan flower is a member of the Asteraceae family and is native to North America.",
+ "A black-eyed susan flower is yellow with a black center.",
+ "A black-eyed susan flower has black petals with a yellow center.",
+ "Black-eyed susans have yellow petals with a black center."
+ ],
+ "silverbush": [
+ "A silverbush is a type of flower that is silver in color and has a bush-like appearance.",
+ "The silverbush is a small, silver-leafed shrub with white or pink flowers.",
+ "The silverbush is a flowering plant that is native to the Mediterranean region.",
+ "Silverbushes are related to the pea family and have leaves that are arranged in pairs along the stem.",
+ "The silverbush is a type of flower that is silver in color.",
+ "A silverbush is a type of flower that has silvery-white leaves.",
+ "The leaves of a silverbush are silvery in color and the flowers are small and white.",
+ "The leaves of a silverbush are usually lance-shaped and come to a point.",
+ "The silverbush is a type of flower that is characterized by its silver-colored leaves.",
+ "The silverbush is a small, silver-gray flower that blooms in early spring.",
+ "The silverbush flower is a white, five-petaled flower with a yellow center.",
+ "A silverbush flower is small and white, with five petals.",
+ "The silverbush flower is small and white, with five petals.",
+ "I cannot find a picture of a silverbush flower.",
+ "A silverbush flower is small, white, and has five petals.",
+ "A silverbush flower is a small whiteflower that blooms in the spring.",
+ "A silverbush flower is small and silver in color.",
+ "A silverbush flower is white, and has five petals.",
+ "The flowers of silverbush are small and white, growing in clusters on the ends of the branches.",
+ "A silverbush flower is a small, white flower that blooms in the spring."
+ ],
+ "californian poppy": [
+ "A californian poppy is a flower with bright orange petals and a yellow center.",
+ "The best way to identify a California poppy is to look for a plant with fine, blue-green leaves and small, yellow flowers.",
+ "The californian poppy (Eschscholzia californica) is a species of flower in the Papaveraceae family.",
+ "The californian poppy is a type of flower that is native to the state of California.",
+ "The californian poppy (Eschscholzia californica) is a type of flower that can be identified by its bright orange color and its petals that are shaped like cups.",
+ "The californian poppy is a type of flower that typically has a yellow or orange hue.",
+ "Line drawing of a californian poppy plant with the text \"A californian poppy has long, divided leaves and cup-shaped flowers with four petals.",
+ "The californian poppy (Eschscholzia californica) is a species of flowering plant in the papaveraceae family, native to the United States and Mexico.",
+ "Some californian poppy flowers have a mix of orange and yellow petals, while others are mostly orange, yellow, or red.",
+ "The californian poppy is a type of flower that is usually orange in color.",
+ "A California poppy flower typically has four petals that are each pointy and end in a downward-curving point.",
+ "A California poppy flower has four petals that are each about 2-3 centimeters long.",
+ "A California poppy flower is orange and yellow, and has a reflexed petal.",
+ "The California poppy flower is a beautiful orange color.",
+ "A California poppy flower has four petals that are each ovate in shape and come to a point at the end.",
+ "A californian poppy flower is yellow and has four petals.",
+ "A californian poppy flower typically has four orange petals and a yellow center.",
+ "The California poppy (Eschscholzia californica) is a species of flowering plant in the Papaveraceae family, native to the United States and Mexico.",
+ "The californian poppy flower is a bright orange color.",
+ "The californian poppy flower has four petals that are orange, yellow, or red in color."
+ ],
+ "osteospermum": [
+ "Osteospermums are daisy-like flowers with long, thin petals.",
+ "Osteospermum is a type of flower in the daisy family.",
+ "Osteospermums are members of the daisy family and are native to Africa.",
+ "An osteospermum flower can be identified by its large, daisy-like flowers with several petals.",
+ "One way to identify an osteospermum, or African daisy, is by its flower head.",
+ "The petals of an osteospermum are fused into a cup-shaped tube.",
+ "If you are trying to identify an osteospermum, or African daisy, you should look for a flower with a yellow center and petals that are purple, pink, or white.",
+ "Some osteospermums have very large flowers measuring up to 10 cm across.",
+ "An osteospermum is a type of flower that is native to Africa.",
+ "Osteospermum is a type of flower in the daisy family.",
+ "An osteospermum flower typically has five petals that are white, yellow, purple, or pink in color.",
+ "Osteospermums are African daisies with showy flowers.",
+ "The petals of an osteospermum flower are long and narrow, and they can be either single or double.",
+ "An osteospermum flower typically has a yellow center with white or purple petals.",
+ "The flower of an osteospermum looks like a daisy with a yellow center and purple petals.",
+ "An osteospermum flower has five petals that are fused at the base, creating a cup-shaped flower.",
+ "An osteospermum flower looks like a small sunflower.",
+ "Osteospermum flowers look like daisies.",
+ "Osteospermums are daisy-like flowers with petals that spread outward from the center of the flower.",
+ "The flower of an osteospermum plant is white, yellow, or purple, and has a diameter of about 2."
+ ],
+ "spring crocus": [
+ "A spring crocus is a small plant with cup-shaped flowers that come in a variety of colors, including purple, yellow, and white.",
+ "The first step is to look for blooming crocus flowers in the late winter or early spring.",
+ "Spring crocuses are small, delicate flowers that bloom in early spring.",
+ "Spring crocuses are small, thin flowers that come in a variety of colors including white, yellow, purple, and pink.",
+ "Spring crocuses are small, bright flowers that bloom in early spring.",
+ "The best way to identify a spring crocus is to look for its purple, red, or white flowers.",
+ "Spring crocuses are small, fragile-looking flowers that are typically deep purple or white with yellow centers.",
+ "The spring crocus is a small, fragile flower that blooms early in the spring.",
+ "The spring crocus is a small, delicate flower that blooms in early spring.",
+ "Spring crocus are small, delicate flowers that bloom in early spring.",
+ "A spring crocus flower is small and has six petals that can be purple, white, or yellow.",
+ "The flower of a spring crocus is typically a pale purple or lavender color.",
+ "A spring crocus flower is a small, delicate flower that is usually white or pale blue.",
+ "There are many types of spring crocus flowers, but they generally have small, brightly colored petals.",
+ "A spring crocus flower is typically small and yellow, and blooms in the springtime.",
+ "A spring crocus flower is a small, cup-shaped flower that typically has six petals.",
+ "A spring crocus flower is a small, bright flower that typically blooms in the springtime.",
+ "A spring crocus has pale, delicate petals and a yellow or purple center.",
+ "A spring crocus flower is small and has six petals that are purple, white, or yellow.",
+ "The spring crocus flower is a small, delicate flower that blooms in early spring."
+ ],
+ "bearded iris": [
+ "A bearded iris is a type of flower that can be identified by its long, thin petals and its furry, brownish-purple center.",
+ "The easiest way to identify a bearded iris is by its flowers.",
+ "Iris flowers are usually easy to identify because they have six petals: three outer, curved petals (called \"falls\") and three inner, upright petals (called \"standards\").",
+ "The easiest way to identify a bearded iris is by its bloom.",
+ "The easiest way to identify a bearded iris is by looking at the flower.",
+ "Bearded irises have a beard-like tuft of fuzzy fibers on the lower petals of the flower.",
+ "Bearded irises have a beard-like appendage on the lower petal, which is typically long, white, and fuzzy.",
+ "The bearded iris is a type of flower that can be identified by its long, thin petals that curl back at the end, as well as its furry, beard-like appendage in the center of the flower.",
+ "Bearded irises have six petals: three petals that point upward and three petals that point downward.",
+ "The bearded iris is a rhizomatous perennial that typically grows to 28-48\u201d tall.",
+ "A bearded iris flower typically has six petals and six sepals that are all pointing downwards.",
+ "The bearded iris flower is one of the most popular flowers in the world.",
+ "The bearded iris flower has six petals, three of which point upward and three of which point downward.",
+ "A bearded iris has six petals: three upright petals and three drooping petals.",
+ "The beard on a bearded iris is a tuft of hair-like growths attached to the falls (the lower petals) of the flower.",
+ "A bearded iris flower is long and thin, with six petals arranged in two rows.",
+ "A bearded iris flower has six petals that are arranged in two rows.",
+ "Iris flowers are classified by their shape.",
+ "A bearded iris flower has six petals: three outer petals that are larger and three inner petals that are smaller.",
+ "Bearded iris flowers are large, showy flowers that grow on a tall stalk."
+ ],
+ "windflower": [
+ "Windflowers have long thin stems and leaves, and their flowers have six petals arranged in a star shape.",
+ "The windflower (Anemone coronaria) is a flower that has a black center and white petals.",
+ "The scientific name for a windflower is Anemone.",
+ ".",
+ "The windflower (Anemone nemorosa) is a perennial herbaceous plant that blooms in the spring.",
+ "Windflowers are a type of flower that typically have brightly colored petals and a long stem.",
+ "Windflowers are a type of flower that is native to North America.",
+ "Windflowers are small, yellow or white flowers that grow in clusters.",
+ "A windflower is a type of flower that has long petals that blow in the wind.",
+ "A windflower is a flower that blows in the wind.",
+ "The windflower flower is a small flower that typically has four petals.",
+ "The windflower flower is a beautiful, blue flower that grows in the wild.",
+ "The flowers of the windflower or wood anemone (Anemone quinquefolia) are white and have five petals.",
+ "A windflower is a white or pale blue flower that blooms in the spring.",
+ "The flowers of a windflower are small and white, and they grow in clusters.",
+ "Most windflowers have small, single flowers with four petals that are arranged in a cross.",
+ "Windflower flowers look like small white or blue stars.",
+ "Windflower flowers have tubular petals that are yellow in the center and purple on the outside.",
+ "A windflower's flower is a small, white, cup-shaped blossom with five petals.",
+ "The windflower is an annual plant that grows to be about two feet tall."
+ ],
+ "tree poppy": [
+ ", using the five sensesThe tree poppy has a light, citrusy smell.",
+ ", in the wildA tree poppy (Papaver arboreum) is a type of flower that can be found in the wild in the western United States.",
+ "Tree poppies have large, showy flowers that are usually red, pink, or orange.",
+ "Tree poppies are large, colorful flowers that are native to tropical and subtropical regions.",
+ "To identify a tree poppy, look for a plant with large, showy flowers that are typically yellow, orange, or red in color.",
+ "The tree poppy (Papaver arboreum) is a species of poppy that is native to Afghanistan, Pakistan, and India.",
+ "The tree poppy is a type of flower that has a long stem with a bulbous yellow or orange flower at the end.",
+ "A tree poppy is a type of flower that has a large, cup-shaped petal at the center of the bloom.",
+ "The tree poppy (Papaver arboreum) is a type of flower in the poppy family.",
+ "A tree poppy is a type of flower that has a large, yellow bloom.",
+ "The tree poppy flower is a'single flower with five petals that can be either white or yellow in color.",
+ "The tree poppy flower is a large, beautiful flower that can be various shades of yellow, orange, or red.",
+ "The tree poppy flower looks like a yellow or white poppy flower.",
+ "The tree poppy (Dendromecon harfordii) is a native Californian plant in the poppy family.",
+ "The tree poppy flower looks like a large pink or white flower with many petals.",
+ "A tree poppy flower is a large, showy flower that grows on a tree.",
+ "The tree poppy flower is a beautiful yellow flower.",
+ "An tree poppy flower is orange and yellow with a black center.",
+ "The tree poppy flower is a beautiful, bright yellow flower.",
+ "The tree poppy flower is white and has a yellow center."
+ ],
+ "gazania": [
+ "The best way to identify a gazania is to look for its distinctive features.",
+ "Gazanias are a type of flower that can be identified by their orange and yellow petals.",
+ "A gazania is a type of flower that typically has brightly-colored petals.",
+ "The easiest way to identify a gazania is by its bright, daisy-like flowers.",
+ "When trying to identify a gazania, it is important to look for some key characteristics that are unique to this type of flower.",
+ "The flower gazania is of the daisy family.",
+ "A gazania has bright, daisy-like flowers and is often used as a bedding plant.",
+ "The flowers of a gazania are daisy-like with overlapping petals in shades of yellow, orange, and red.",
+ "A gazania is typically an orange or yellow flower with black spots.",
+ "A gazania is a perennial flowering plant in the daisy family.",
+ "The gazania flower is a stunning flower that has a wide range of colors.",
+ "A gazania flower typically has a bright yellow or orange petals with black or brown spots.",
+ "Gazania flowers are typically yellow with black or brown markings.",
+ "The Gazania flower is a daisy-like flower that has a yellow center with a crimson outer ring.",
+ "A gazania flower is a yellow or orange flower with black spots.",
+ "A gazania flower looks like a small daisy with a yellow or orange center.",
+ "The Gazania is a flower that has a lot of different colors.",
+ "The flower of the plant Gazania is typically yellow, orange, or white, with large ray petals and a small, dark center.",
+ "A gazania flower is a small, daisy-like flower with a deep yellow center and petals that are usually reddish, orange, or yellow.",
+ "A gazania flower has small, thin petals that are typically yellow, orange, red, or white."
+ ],
+ "azalea": [
+ "azaleas have large, showy flowers that bloom in a wide range of colors including white, pink, purple, orange, and red.",
+ "Azaleas are flowering shrubs in the genus Rhododendron, particularly the former sections Tsutsuji and Pentanthera.",
+ "An azalea is a flowering shrub with large, showy flowers.",
+ "The azalea is a member of the genus Rhododendron.",
+ "Azaleas are a type of flower that can be identified by their pointed petals and brightly colored blooms.",
+ "Azaleas are shrubs that produce small, funnel-shaped flowers.",
+ "One way to identify an azalea is by its smooth, oval-shaped leaves.",
+ "Azaleas are a type of flowering shrub.",
+ "Azaleas are characterized by their single flowers that have five petals.",
+ "The azalea is a type of flower that is characterized by its large, showy blooms.",
+ "An azalea flower is a small, trumpet-shaped flower that is typically pink or white in color.",
+ "An azalea flower is a small, tubular flower that can be either red, pink, or white in color.",
+ "Azalea flowers are most commonly white or pink, but can be found in a variety of colors including red, purple, and yellow.",
+ "An azalea flower is fragile and delicate, with a wide range of colors that can be found naturally.",
+ "An azalea flower has five petals and is typically white or pink.",
+ "An azalea flower is a small flower with five petals.",
+ "An azalea flower is a small, delicate flower that is typically pink or white in color.",
+ "An azalea flower is usually pink or white and has a lot of petals.",
+ "An azalea flower is like a small trumpet.",
+ "An azalea flower has five petals that are white or pink."
+ ],
+ "water lily": [
+ "A water lily is a type of flower that has a large, round, flat bloom that floats on the surface of the water.",
+ "Water lilies are a type of flower that generally has a large, round, flat leaf and a long stem.",
+ "Water lilies are a type of flower that have large, flat leaves that float on the surface of the water.",
+ "Water lilies are a type of floating aquatic plant that has large, flat, round leaves and showy flowers.",
+ "A water lily is a type of flower that has a large, round, flat petal and a short stem.",
+ "Water lilies are flowers that grow in ponds and other bodies of water.",
+ "Water lilies have smooth, glossy, yellow-green, elliptical leaves with curved, overlapping margins.",
+ "Nymphaea flowers are generally held above the surface of the water on long stems.",
+ "A water lily is a type of flower that has a large, round petal and a small, yellow center.",
+ "Water lilies have large, round leaves that float on the surface of the water.",
+ "A water lily flower is typically white, pink, or yellow and has a large petal at the center with smaller petals around the outside.",
+ "A water lily flower has a large, round, petal.",
+ "A water lily has a large, flat, round flower that usually has white petals with yellow stamens in the center.",
+ "A water lily has large, round, green leaves that float on the surface of the water.",
+ "A water lily flower typically has a large, circular bloom with petals that are white, pink, yellow, or blue.",
+ "A waterlily flower typically has white petals with yellow stamens in the center.",
+ "A water lily flower is generally white or yellow, has a large number of petals, and floats on the surface of the water.",
+ "Water lily flowers come in a variety of colors, including white, pink, yellow, and blue.",
+ "A water lily flower is a beautiful, fragrant flower that floats on the surface of water.",
+ "A water lily flower has a large, flat, round petal that is often white or yellow."
+ ],
+ "rose": [
+ "The easy way to identify a rose is by its characteristic thorny stem and four-petaled flower.",
+ "One way to identify a rose is by its thorns.",
+ "The rose is a type of flower that is typically identified by its red color.",
+ "There are many types of roses, but they all have certain characteristics in common.",
+ "The base of a rose is woody and the stem is covered in sharp thorns.",
+ "A rose is a type of flower that has a long stem with thorns on it.",
+ "A rose is a type of flower that has a very distinct shape.",
+ "A rose is a type of flower that has a lot of petals and is usually red, pink, or white.",
+ "The rose is a flower that has a round shape with petals that are soft to the touch.",
+ "A rose is a type of flower that has a lot of petals and is typically red.",
+ "A rose flower typically has a red, pink, or white petals arranged in a spiral pattern around a central receptacle.",
+ "A rose flower typically has five petals and is pink in color.",
+ "A rose flower typically has five petals that are arranged in a spiral.",
+ "A rose flower typically has five petals, each petal having a different meaning.",
+ "A rose flower has five petals and is pink in color.",
+ "A rose flower typically has five petals and is shades of red, pink, or white.",
+ "A rose flower typically has a reddish color, with petals that are soft to the touch.",
+ "A rose flower typically has five petals and is a pink or red color.",
+ "A rose flower typically has five petals that are arranged in a spiral pattern.",
+ "A rose flower typically has five petals, is red in color, and has a diameter of about two inches."
+ ],
+ "thorn apple": [
+ "The thorn apple is a member of the nightshade family and can be identified by its large, white or purple trumpet-shaped flowers.",
+ "A thorn apple flower is a small, tubular flower that has five petals.",
+ "The thorn apple is a type of flower that has thorns on its stem.",
+ "The thorn apple is a type of flower that has thorns on its stem.",
+ "The stem of a thorn apple is hairy, and the leaves are alternate, egg-shaped, and have serrated margins.",
+ "The thorn apple is a type of flower that has thorns on the stem.",
+ "Thorn apples are a type of flower that has thorns on the stem.",
+ "The thorn apple flower is a small, orange-yellow flower with five petals.",
+ "The thorn apple is a member of the nightshade family and is characterized by its small, white, trumpet-shaped flowers.",
+ "A thorn apple is a type of flower that has a unique appearance.",
+ "The Thornapple flower is a small, white, five-petaled flower.",
+ "The flower of a thorn apple tree is white and has five petals.",
+ "The flower of a thorn apple looks like a small, white, trumpet-shaped flower.",
+ "The flowers of the thorn apple (Datura stramonium) are large, white and trumpet-shaped.",
+ "The flower of a thorn apple tree is white with five petals.",
+ "The flower of a thorn apple typically has five petals that are white or pale pink in color.",
+ "The thorn apple flower is small and white, and it has five petals.",
+ "The flower of the thorn apple (Datura stramonium) is white and has five petals.",
+ "The Thorn Apple flower is a small, white, 5-petaled flower.",
+ "The thorn apple flower is a small, white flower that blooms in the spring and summer."
+ ],
+ "morning glory": [
+ "Morning glories are a type of flowering plant that typically have large, trumpet-shaped flowers.",
+ "The morning glory is a type of flower that has a long, slender stem with large, funnel-shaped flowers.",
+ "Morning glory flowers are commonly trumpet-shaped and can be found in a variety of colors including blue, pink, purple, and white.",
+ "Morning glories are a type of flower that have a trumpet-shape and are typically blue or white.",
+ "The morning glory is a type of flower that has a vine-like growth habit and large, trumpet-shaped flowers.",
+ " Morning glories are a type of flower that have a long tap root and small, delicate leaves.",
+ "The morning glory is a type of flower that typically has a trumpet-shaped blooming flower.",
+ "Morning glories are trumpet-shaped flowers that open in the morning and close at night.",
+ "I Morning glory flowers are typically trumpet-shaped and can be found in a variety of colors, including white, pink, purple, blue, and red.",
+ "To identify a morning glory, look for a climbing plant with heart-shaped leaves and showy, trumpet-shaped flowers.",
+ "The morning glory flower is a slender, trumpet-shaped bloom that comes in a variety of colors, including white, pink, purple, and blue.",
+ "The morning glory flower is a vine that has heart-shaped leaves and trumpet-shaped flowers.",
+ "A morning glory flower is a trumpet-shaped flower that typically has a white or pale blue petals and a deep blue or purple center.",
+ "A morning glory flower is a small, trumpet-shaped flower that can be white, pink, purple, or blue.",
+ "A morning glory flower is a funnell-shaped flower that has a wide range of color variation.",
+ "A morning glory flower looks like a funnel-shaped flower with deep purple petals and a yellow center.",
+ "A morning glory flower is usually a deep blue or purple color and has a trumpet-shaped bloom.",
+ "A morning glory flower has a long, trumpet-shaped petal that is white, pink, purple, or blue.",
+ "The morning glory flower is a species of flowering plant that typically has a twining vine-like growth habit.",
+ "The morning glory flower is a trumpet-shaped flower that can be either white, red, pink, purple, or blue in color."
+ ],
+ "passion flower": [
+ "The passion flower is a climbing vine with striking flowers.",
+ "Passion flowers are tendril-bearing vines that are native to tropical and subtropical regions.",
+ "Passion flowers are usually large, showy flowers with brightly colored petals.",
+ "The passion flower is a type of flower that has a rich history.",
+ "Passion flowers are most easily identified by their flowers, which are large, showy, and often brightly colored.",
+ "The easiest way to identify a passion flower is by its unique flower.",
+ "The passion flower is a vine with large, colorful flowers.",
+ "A passion flower typically has a white or purple base with a yellow or white center.",
+ "Passion flowers are tropical vines with showy flowers.",
+ "A passion flower typically has a white, blue, or purple flower with intricate details.",
+ "A passion flower flower is typically either white or purple, and has a unique, intricately shaped petal structure.",
+ "There are many varieties of passion flowers, but most share some common features.",
+ "The passion flower flower is a beautiful, exotic flower that typically has a purple or blue-violet color.",
+ "A passion flower flower has five parts, including petals that can be white, purple, or blue.",
+ "A passion flower has a distinctively shaped flower with a central structure that resembles a bird or a butterfly.",
+ "A passion flower has a large, intricate flower with many colorful petals.",
+ "A passion flower has a five-lobed white flower with a purple and white center.",
+ "A passion flower has a distinctive, deeply lobed flower with a corona in the center.",
+ "A passion flower has a white or light purple flower with a yellow center.",
+ "A passion flower has a large, showy flower with five petals."
+ ],
+ "lotus": [
+ "The lotus (Nelumbo nucifera) is a sacred flower and a symbol of purity in Hinduism and Buddhism.",
+ "The lotus is a water plant with large, round, flat leaves.",
+ "To identify a lotus flower, look for a large, showy flower with petals that are arranged in a spiral.",
+ "A lotus is a type of flower that is typically found in ponds and other bodies of water.",
+ "A lotus is a type of flower that is typically pink or white in color.",
+ "If you want to identify a lotus, you should look for a flower that has a large, showy blossoming and a cup-shaped nectar.",
+ "The lotus flower is a beautiful and unique flower that has several identifying features.",
+ "The lotus is a flower that has a large and showy bloom.",
+ "Lotuses have large, round, flat leaves that float on the water's surface.",
+ "A lotus is a type of flower that typically has a large, round petal in the center, with smaller petals around it.",
+ "A lotus flower typically has very large, thick petals that are a deep pink or purple color.",
+ "A lotus flower is a beautiful pink, white, or purple flower that blooms in ponds and rivers.",
+ "A lotus flower is a pink or white flower that grows underwater in a pond or river.",
+ "The lotus flower is a beautiful flower that has a white or pink petals and a yellow center.",
+ "The lotus flower is white with pink or purple highlights.",
+ "Some lotus flowers have very large petals, while others have small, delicate petals.",
+ "A lotus flower typically has a large central blossom with many smaller blossoms on the same plant.",
+ "Sansevieria cylindrica is a species of plant in the genus Sansevieria, native to tropical West Africa from Nigeria east to the Congo.",
+ "A lotus flower typically has a large number of petals that are arranged in a radial symmetry.",
+ "The lotus flower is a pink or white flower that grows in ponds and streams."
+ ],
+ "toad lily": [
+ "Toad lilies are part of the Tricyrtis genus and can be identified by their unique, upright blooms that resemble orchids.",
+ "A toad lily is a member of the plant family Tricyrtidaceae.",
+ "The toad lily is a perennial plant that can reach up to 3 feet in height.",
+ "The toad lily is a type of flower that can be identified by its unique shape and color.",
+ "Toad lilies are flowering plants in the genus Tricyrtis.",
+ "The toad lily is a plant that has lily-like flowers that grow on a stem.",
+ "A toad lily is a type of flower that can be identified by its shape, which is similar to that of a lily, and by the spots on its petals, which are said to resemble those on a toad.",
+ "Toad lilies are small, trumpet-shaped flowers that come in a variety of colors including white, pink, purple, and yellow.",
+ "Toad lilies are flowering plants in the genus Tricyrtis.",
+ "Toad lilies (Trillium spp.",
+ "Toad lily flowers typically have six petals and are usually a deep purple color.",
+ "The toad lily flower looks like a white or light pink lily.",
+ "The flower of a toad lily (Tricyrtis sp.",
+ "A toad lily flower looks like a small lily with speckles on it.",
+ "A toad lily flower can vary in color, but is typically some shade of yellow, white, or purple.",
+ "Toad lilies have delicate flowers that come in many colors, including white, pink, purple, and yellow.",
+ "A toad lily flower typically has six petals that are arranged in a star-like shape.",
+ "A toad lily flower typically has six petals that are arranged in a star-like shape.",
+ "A toad lily flower has six petals that are brownish-purple on the outside and white on the inside.",
+ "A toad lily is a flower that is found in the wild."
+ ],
+ "anthurium": [
+ "An anthurium is a type of flower that can be identified by its heart-shaped, red blooms.",
+ "There are over 600 species of anthurium, so it is difficult to give a single way to identify them.",
+ "Anthuriums are flowering plants that are native to the Americas.",
+ "To identify an anthurium, look for a tropical plant with glossy, heart-shaped leaves and brightly colored flowers.",
+ "Anthuriums are easily recognizable by their large, heart-shaped leaves and showy, bright red flowers.",
+ "Anthuriums are a type of flower that can be identified by their light green, heart-shaped leaves and red, yellow, or pink blooms.",
+ "An anthurium is a type of flower that has a long stem and glossy, dark green leaves.",
+ "An anthurium is a type of flower that is typically red, pink, or white and has a long, slender stem.",
+ "Anthuriums are flowering plants native to the Americas.",
+ "Anthuriums are characterized by their glossy, heart-shaped leaves and brightly colored flowers.",
+ "An anthurium flower looks like a heart with red and green petals.",
+ "An anthurium flower is red and heart shaped.",
+ "An anthurium flower is typically red and has a long, thick stem.",
+ "An anthurium flower has a long stem with a bright red, heart-shaped bloom at the end.",
+ "Anthurium flowers have a waxy, bright red, heart-shaped spathe.",
+ "The anthurium flower is a long, bright red flower that has a long stem and a small black center.",
+ "An anthurium flower has a fleshy stem and a waxy, heart-shaped flower.",
+ "The anthurium flower is a beautiful, heart-shaped flower that comes in a variety of colors.",
+ "The anthurium flower is a spiky, heart-shaped flower that come in a variety of colors including red, pink, purple, and white.",
+ "The anthurium flower is a beautiful, heart-shaped flower that comes in a variety of colors."
+ ],
+ "frangipani": [
+ "The frangipani has long, bright green leaves and large, fragrant flowers.",
+ "Frangipanis are easily recognizable by their large, showy flowers.",
+ "Frangipanis can be identified by their large, bright flowers and glossy leaves.",
+ "One way to identify a frangipani is by its distinctivefeatures, which include: egg-shaped leaves that are glossy andgreen; flowers that are large, showy, and often fragrant; and abloom that typically lasts around.",
+ "The frangipani is a tropical flower that has a very distinct look.",
+ "Frangipani flowers are large and have a strong fragrance.",
+ "The frangipani (Plumeria alba) is a type of flower that can be identified by its white or yellow color and its strong, sweet fragrance.",
+ "Frangipani flowers are large and have a very distinct shape.",
+ "One way to identify a frangipani is by its color.",
+ "A frangipani is a tropical flower that has a strong, sweet fragrance.",
+ "A frangipani flower is a white or yellow flower with five petals.",
+ "The frangipani flower is a large, beautiful blossom that is often used in tropical bouquets and arrangements.",
+ "A frangipani flower has a large central stalk with five petals that are slightly curved inward.",
+ "A frangipani flower typically has five petals that are in the shape of a star.",
+ "A frangipani flower is white with a yellow or orange center.",
+ "A frangipani flower is typically a white or yellow color, and has a strong fragrance.",
+ "A frangipani flower has five petals that are each a different color.",
+ "The frangipani flower is a translucent white or pink flower with delicate petals.",
+ "A frangipani flower is a white or yellow flower with a strong, sweet smell.",
+ "A frangipani flower typically has five petals that are each shaped like a narrow oval."
+ ],
+ "clematis": [
+ "The easiest way to identify a clematis is by its flowers.",
+ "The easiest way to identify a clematis is by its flowers.",
+ "Clematis is a flowering plant in the buttercup family.",
+ "Clematis flowers are typically large, showy, and long-lasting.",
+ "A clematis is a type of flowering vine that has large, showy flowers.",
+ "To identify a clematis, look for a climbing vine with large, showy flowers.",
+ "A clematis is a climbing plant with long, thin stems and large, bright flowers.",
+ "The clematis is a type of flower that has a long stem with a small cluster of brightly colored flowers at the top.",
+ "Some clematis have showy flowers, while others are more subdued.",
+ "Clematis flowers have four petals that are typically white or purple.",
+ "A clematis flower has five or six petals that are white or pale purple.",
+ "The clematis flower is a climbing plant that has long, thin stems.",
+ "A clematis flower has four petals that are typically blue, purple, or white.",
+ "The clematis flower is a type of climbing vine that has large, showy flowers.",
+ "There are many varieties of clematis, but most have large, showy flowers with four or more petals.",
+ "A clematis flower has four petals that are typically purple, pink, or white.",
+ "There are many types of clematis flowers, but most have large, showy petals in shades of white, pink, or purple.",
+ "A clematis flower has four petals that are arranged in a cross shape.",
+ "A clematis flower typically has four petals that are arranged in a star shape.",
+ "A clematis flower is a large, showy flower with petals that overlap in a spiral pattern."
+ ],
+ "hibiscus": [
+ "Hibiscus flowers are large and showy, with colors ranging from white to pink to red to purple.",
+ "Hibiscus flowers have large, showy petals and come in a wide range of colors, from white and yellow to pink, red, and purple.",
+ "Hibiscus flowers are generally large and brightly colored, with five or more petals.",
+ "Hibiscus flowers are large, trumpet-shaped flowers with brightly colored petals.",
+ "The hibiscus flower is a large, trumpet-shaped flower that typically has a deep red hue.",
+ "Hibiscus flowers are generally large and brightly colored, with distinctively shaped petals.",
+ "Hibiscus flowers are large, showy flowers with bright colors.",
+ "Hibiscus flowers are large and have a trumpet-shaped structure.",
+ "Hibiscus flowers have large, showy petals that can be red, pink, orange, or yellow.",
+ "There are many species of hibiscus, but all have large, showy flowers.",
+ "Hibiscus flowers usually have five petals and are large and showy, with colors ranging from white to pink to red to purple.",
+ "Hibiscus flowers have a wide range of colors and shapes, but are generally large and brightly-colored.",
+ "A hibiscus flower typically has five or six petals and is bright red, pink, or orange.",
+ "A hibiscus flower typically has five petals and is red, pink, purple, or white.",
+ "Hibiscus flowers vary in appearance, but are generally large and brightly colored, with five or more petals.",
+ "A hibiscus flower typically has five petals that are arranged in a star shape.",
+ "Hibiscus flowers can vary in appearance, but they are usually large and brightly colored.",
+ "A hibiscus flower is typically red, pink, or purple, has broad petals, and is about 6 inches in diameter.",
+ "Hibiscus flowers can come in many colors, such as white, yellow, pink, red, and purple.",
+ "A hibiscus flower typically has five petals that are arranged in a circular pattern."
+ ],
+ "columbine": [
+ "Columbine is a type of flower that has long, pointy petals that are generally a deep red color.",
+ "Columbine flowers have five petals that are fused at the base, with four sepals extending outwards.",
+ "The columbine is a member of the genus Aquilegia.",
+ "A columbine flower has long, pointy petals that curve inward and come to a point.",
+ "Colorado's state flower is the columbine (Aquilegia coerulea).",
+ "Columbine flowers are characterized by having spreading sepals and petals that are often fringed and spurred.",
+ "A columbine flower has five petals that are fused at the base and arranged in a pinwheel shape.",
+ "A columbine is a type of flower with long, thin petals that curve backwards and come to a point.",
+ "The Columbine flower is a member of the buttercup family and is native to Europe.",
+ "The columbine is a member of the buttercup family.",
+ "A columbine flower typically has five petals that are each shaped like a narrow inverted cone.",
+ "The columbine flower is a member of the buttercup family and is native to Europe.",
+ "A columbine flower may have yellow, blue, purple, or white petals that are arranged in a pinwheel pattern.",
+ "A columbine flower typically has five petals that are arranged in a pinwheel shape.",
+ "A columbine flower typically has five petals that are arranged like the petals of a rose, except that they are often longer and more pointed.",
+ "The columbine flower is a member of the buttercup family.",
+ "The columbine flower is an erect perennial herb with palmately lobed leaves and showy, iridescent flowers.",
+ "A columbine flower is a small flower with five petals.",
+ " Columbine flowers are usually red, yellow, or blue, and have five petals.",
+ "A columbine flower typically has five petals that are arranged in a pinwheel shape."
+ ],
+ "desert-rose": [
+ "A desert-rose is a type of flower that is typically found in desert climates.",
+ "A desert-rose is a type of flower that is typically red, pink, or white in color.",
+ "Assuming you would like tips on how to identify a desert rose: The desert rose (Adenium obesum) is a beautiful flower that is native to Africa, Arabia, and Madagascar.",
+ "The desert rose is a type of flower that is native to the deserts of Africa.",
+ "A desert-rose is a type of flower that is typically pink, red, or white in color.",
+ "The most common way to identify a desert-rose is by its distinctive shape.",
+ "Desert-roses have long, thin stems with small leaves.",
+ "The desert-rose is a type of flower that is native to arid regions.",
+ "A desert rose is a type of flower that can be identified by its bold colors and unique shape.",
+ "Desert-roses have large, fleshy petals that are often pink or red.",
+ "The desert-rose flower is a type of rose that is native to desert regions.",
+ "A desert rose flower typically has a deep red color with yellow highlights.",
+ "The desert-rose flower is a type of rose that is native to arid regions.",
+ "A desert rose is a type of flower that looks like a rose.",
+ "A desert-rose flower is typically a deep pink color and has a bulbous shape.",
+ "The flower of a desert rose is typically pink or white and has a wide, trumpet-shaped petal.",
+ "The desert-rose flower is a beautiful pink flower that blooms in the desert.",
+ "A desert-rose flower looks like a pink or red rose with long, thin petals.",
+ "The flowers of most species have five petals, though a few have only four.",
+ "A desert-rose flower has a light pink or white petals and a yellow center."
+ ],
+ "tree mallow": [
+ "A tree mallow is a type of flower that is usually white or pink in color.",
+ "The tree mallow is a large, shrub-like herbaceous perennial that can grow up to 6 m in height.",
+ "Tree mallows are a type of flower that has a bell-shaped bloom.",
+ "The tree mallow is a member of the Malvaceae family and can be identified by its large, trumpet-shaped flowers.",
+ "The tree mallow (Lavatera arborea) is a flowering plant in the family Malvaceae, native to the Mediterranean region.",
+ "The tree mallow is a type of flower that is native to Europe and parts of Asia.",
+ "Tree mallows are small, pink flowers that have five petals and grow in clusters.",
+ "A tree mallow is a member of the Malvaceae family and can be identified by its heart-shaped leaves and hibiscus-like flowers.",
+ "They are small, pink, and have five petals.",
+ "The tree mallow is a type of flower that has a broad, heart-shaped leaf and a tall, slender stem.",
+ "The tree mallow flower is a small, white flower with five petals.",
+ "The flowers of tree mallows are white or pink and have five petals.",
+ "The tree mallow flower looks like a small, pale purple flower.",
+ "A tree mallow flower looks like a small, delicate white flower.",
+ "A tree mallow flower has five petals and is white with a hint of pink.",
+ "Tree mallows have small, pink flowers that grow in clusters.",
+ "The flowers of the tree mallow (Lavatera arborea) are white with pinkish streaks, and they grow in clusters.",
+ "A tree mallow flower looks like a small tree.",
+ "Tree mallows have small, white, five-petaled flowers.",
+ "The tree mallow flower has a deep pink or purple color and is about 3-4 cm in diameter."
+ ],
+ "magnolia": [
+ "The simplest way to identify a magnolia is by its large, simple leaves and its showy, fragrant flowers.",
+ "The magnolia is a large, flowering tree.",
+ "To identify a magnolia, look for a flower with large, showy petals that are pink, purple, or white in color.",
+ "There are over 200 species of magnolias, so it is impossible to give a definitive answer to this question.",
+ "Magnolia flowers are large and white, with many petals.",
+ "To identify a magnolia, look for a flower with 8-16 petals that are arranged in a spiral pattern.",
+ "The magnolia is a broadleaf evergreen tree that can grow to be quite large.",
+ "The easiest way to identify a magnolia is by its large, showy flowers.",
+ "The easiest way to identify a magnolia is by its flowers.",
+ "To identify a magnolia, look for a tree with large, leathery leaves and showy flowers.",
+ " Magnolia flowers have large, showy petals that are typically white or pink.",
+ "A magnolia flower can vary in appearance, but typically has large, petals that are white or pale pink in color.",
+ "A magnolia flower is typically white and has a large, round bloom.",
+ "A magnolia flower is a large, round flower with petals that are thick and stiff.",
+ "A magnolia flower is beautiful and fragrant.",
+ "The magnolia flower is a large, showy flower that is white, pink, or purple in color.",
+ "A white or creamy-white magnolia flower has 6-12 petals and is 3-6 inches in diameter.",
+ "Image of a magnolia flower: https://en.",
+ "A magnolia flower has six petals and is white with a touch of pink.",
+ "The magnolia flower is white and tulip-shaped."
+ ],
+ "cyclamen": [
+ "A cyclamen has a unique flower shape that sets it apart from other flowers.",
+ "Cyclamen have heart-shaped leaves and grow from a tuber.",
+ "Cyclamen are a type of flower that have 8 petals that are curved backwards, and a long stem.",
+ "Cyclamens are a type of flower that have petals that curve back away from the center of the flower.",
+ "Cyclamen are a type of flower that have inconspicuous petals and a cluster of small flowers in the center.",
+ "Cyclamen have heart-shaped leaves and small, often fragrant flowers with upswept petals.",
+ "There are many species of cyclamen, but they all have tubers and heart-shaped leaves.",
+ "Cyclamen have heart-shaped leaves and flowers with 5-9 petals that bloom in shades of pink, red, or white.",
+ "A cyclamen is a flower with a tubular shape and spiraling petals.",
+ "Cyclamen have heart-shaped leaves and flowers with five petals that have reflexed lobes, meaning that they curve backwards.",
+ "The cyclamen flower is a small, fragrant flower that blooms in the fall and winter.",
+ "The cyclamen flower is a bulbous plant with a thick, fleshy root.",
+ "Cyclamen flowers look like small trumpets with curved petals.",
+ "Cyclamen flowers have many petals that range in color from pink to purple.",
+ "A cyclamen flower has a long stem with a small, brightly-colored flower at the end.",
+ "A cyclamen flower is a small, fragile flower with petals that curl back on themselves.",
+ "A cyclamen has heart-shaped leaves and a flower with five petals.",
+ "A cyclamen flower typically has five petals that curve back from the center of the flower.",
+ "A cyclamen flower has a distinctive appearance, with a curved petal that resembles a dolphin's nose.",
+ "A cyclamen flower is a small, heart-shaped flower with petals that curl back."
+ ],
+ "watercress": [
+ "The watercress is a succulent, aromatic plant that has small, dark green leaves and white flowers.",
+ "Watercress\u2013\u2013Nasturtium officinale--is a flower that is part of the mustard family.",
+ "Watercress is a type of flower that can be identified by its small, white flowers and its long, green leaves.",
+ "Watercress is a member of the mustard family and can be identified by its small, white flowers and rounded, serrated leaves.",
+ "Watercress is a member of the mustard family.",
+ "Watercress (Nasturtium officinale) is an aquatic flowering plant in the family Brassicaceae.",
+ "Watercress is a flowering herb that grows in water.",
+ "Watercress is a type of flower that grows in water.",
+ "Watercress is a flowering plant in the cabbage family whose leaves and shoots are used as food.",
+ "Watercress is a type of flowering plant in the mustard family.",
+ "Watercress flowers are white and have four petals.",
+ "A watercress flower is small and white.",
+ "Watercress flowers are white and have four petals.",
+ "Watercress flowers are small and white, and they grow in clusters.",
+ "Watercress flowers look like small white or yellow blossoms that grow in clusters.",
+ "The watercress flower is a small, white, four-petaled flower.",
+ "A watercress flower is a small white flower that blooms in clusters.",
+ "I cannot find a picture of a watercress flower, but here is a picture of watercress plants.",
+ "Watercress flowers are white, four-petaled, and about 1/4 inch wide.",
+ "Watercress flowers have four white petals that are arranged in the shape of a cross."
+ ],
+ "canna lily": [
+ "Canna lilies are large, showy flowers that come in a variety of colors including red, orange, yellow, and pink.",
+ "The canna lily is a type of flower that has a long, thick stem and large, green leaves.",
+ "A canna lily is a type of flower that can be identified by its large, fleshy leaves and its showy, brightly-colored flowers.",
+ "Canna lilies have large, bright, and showy flowers.",
+ "The canna lily is a type of flowering plant.",
+ "One way to identify a canna lily is by its large, banana-shaped leaves.",
+ "Canna lilies are usually identified by their large, banana-like leaves and tall, showy flowers.",
+ "The canna lily is a flower that is native to Asia, Africa, and the Americas.",
+ "Canna lilies can be identified by their large, bright leaves and showy flowers.",
+ "Canna lilies are large, tropical flowers that come in a variety of colors including yellow, orange, pink, and red.",
+ "A canna lily flower resembles a banana and typically blooms in shades of yellow, pink, orange, or red.",
+ "A canna lily flower is yellow or orange and has six petals.",
+ "A canna lily flower is typically large and showy, with six petals that are often brightly colored.",
+ "The canna lily flower is large and showy, typically red, pink, orange, or yellow.",
+ "The flowers of a canna lily are large, showy, and brightly colored.",
+ "A canna lily flower looks like a large, showy flower with brightly-colored petals.",
+ "A canna lily flower typically has six bright petals that can be red, yellow,orange, or pink in color.",
+ "A canna lily flower typically has six petals that are each 2-6 inches long and come in a variety of colors including yellow, orange, red, and pink.",
+ "A canna lily flower is a large, showy flower that comes in a variety of colors, including red, orange, yellow, and pink.",
+ "A canna lily has a large, showy flower that is typically red, orange, or yellow."
+ ],
+ "hippeastrum": [
+ "Hippeastrum flowers are large and showy, with six petals that are often brightly colored.",
+ "The easiest way to identify a hippeastrum is by its large, trumpet-shaped flowers.",
+ "Hippeastrums are a type of flower that can be identified by their large, showy blooms.",
+ "Hippeastrum flowers are large, showy flowers that come in a variety of colors including pink, red, white, and orange.",
+ "The easiest way to identify a hippeastrum is by its large, showy flowers.",
+ "The hippeastrum is a type of flower that is native to South America.",
+ "A hippeastrum is a type of flower that can be identified by its large, showy blooms.",
+ "Hippeastrums are a type of flower in the Amaryllidaceae family.",
+ "Hippeastrum is a genus of about 90 species of flowering plants in the family Amaryllidaceae, native to tropical and subtropical regions of the Americas.",
+ "The Hippeastrum is a large genus of about 90 species of flowering plants native to tropical and subtropical regions of the Americas.",
+ "Hippeastrum flowers are large and showy, with six petals that can be white, pink, red, or orange.",
+ "A hippeastrum flower typically has six petals that are neon pink, red, or white in color.",
+ "The flower of a hippeastrum is typically trumpet-shaped and has six petals that can be red, pink, orange, or white.",
+ "The flowers of hippeastrum plants are large and showy, with six petals that may be shades of red, pink, or white.",
+ "The Hippeastrum flower is a bulbous plant that has large, showy flowers.",
+ "A hippeastrum flower typically has six petals that are variably colored.",
+ "The hippeastrum flower is a large, showy flower that is often used in floral arrangements.",
+ "A Hippeastrum flower is generally large and showy, with six petals that are often striped or spotted.",
+ "A hippeastrum flower has six petals and is trumpet-shaped.",
+ "Hippeastrum flowers are typically large, showy, and red, pink, or white."
+ ],
+ "bee balm": [
+ "The bee balm is a flower with a bright red or purple-red color.",
+ " bee balm can be identified by its red, tubular flowers that bloom in the summer.",
+ "In its simplest form, bee balm (Monarda didyma) is a native North American wildflower that has been used medicinally by Native Americans for centuries.",
+ "The bee balm flower is a member of the mint family and is easily identified by its large, showy flowers.",
+ "Bee balm flowers are typically red, pink, or lavender and have a long, tubular shape.",
+ "Bee balm is a member of the mint family and can be identified by its square stem, opposite leaves, and showy flowers.",
+ "A bee balm is a type of flower that is typically red, pink, or purple in color.",
+ "Bee balm can be identified by its small, tubular flowers that are arranged in a cluster at the end of the stem.",
+ "Bee balm is a type of flower that is typically red, pink, or purple in color.",
+ " Bee balm flowers are large and showy, with a tubular shape and a five-lobed mouth.",
+ "The flower of a bee balm (Monarda didyma) is a showy, tubular flower that is typically pink, purple, or red in color.",
+ "A bee balm flower is a small, bright-colored flower that typically blooms in shades of pink, purple, or white.",
+ "A bee balm flower is a deep red color and has a tubular shape.",
+ "Bees balm flowers look like small, tubular flowers that grow in clusters.",
+ "There are many different species of bee balm, so the flowers can vary somewhat in appearance.",
+ "A bee balm flower looks like a cluster of small tubular flowers.",
+ "Bee balm flowers look like tubular shaped flowers that are brightly colored.",
+ "The flower of a bee balm (Monarda didyma) is a tubular shape with petals that flare out at the top.",
+ "Bee balm flowers are tubular and can be either red, pink, purple, or white.",
+ "A bee balm flower is typically red or pink and has a tubular shape."
+ ],
+ "ball moss": [
+ "An air plant is a type of flower that gets its name from its ability to grow without soil.",
+ "There are many different types of air plants, but one of the most common is the Tillandsia.",
+ "To identify an air plant, look for a plant with long, thin leaves that grow out from a central stem.",
+ "First, look for a plant with long, thin leaves that grow from a central stem.",
+ "Air plants are a type of flower that grows without soil.",
+ "less plant that gets its nutrition from the air and rainwaterAn air plant is a type of flowerless plant that gets its nutrition from the air and rainwater.",
+ "An air plant is a type of flower that typically has small, green leaves and a white or pink blooming flower.",
+ "less plant that gets nutrition from water and humidity in the airAn air plant can be identified by its leaves, which are typically thin and scale-like, and its root system, which is very small.",
+ "To identify an air plant, look for a small, green plant with thin, long leaves.",
+ "An air plant is a type of flower that does not need soil to grow.",
+ "The flowers of air plants vary in size, shape, and color depending on the species.",
+ "Air plant flowers are small and vary in color, but are typically white, pink, or purple.",
+ "An air plant flower looks like a small, white cluster of flowers.",
+ "An air plant flower resembles a small, white balloon with a thin, green stem.",
+ "Air plant flowers are small and tubular.",
+ "Air plant flowers are small and tubular, and they grow in clusters.",
+ "The air plant flower typically blooms into a cluster of small, tubular flowers.",
+ "An air plant flower can look like a lot of different things, depending on the species of air plant.",
+ "Air plants have small, colorful flowers that appear in the spring or summer.",
+ "Air plant flowers are small and inconspicuous."
+ ],
+ "foxglove": [
+ "class=\"MsoNormal\">The flowers of the foxglove are tubular and come in shades of white, pink, and purple.",
+ "A foxglove is a type of flower that has bell-shaped petals and is usually white, pink, or purple in color.",
+ "Foxgloves are tall, spiky flowers with bell-shaped blooms.",
+ "Foxgloves are tall, spiky flowers that are typically purple, although they can also be white, pink, or yellow.",
+ "Foxgloves are tall, spiky flowers that are typically purple, white, or pink.",
+ "Foxgloves are tall, spiky flowers that come in a range of colors including white, pink, purple, and yellow.",
+ "If you are looking for a foxglove in the wild, you should look for a tall plant with spiky, Lilac-colored flowers.",
+ "A foxglove plant has leaves that look like hearts at the base of the plant and have a purple, white, or yellow flower that blooms in a column on a tall stem.",
+ " foxgloves are easily recognized by their tall spires of large, tube-shaped flowers.",
+ "The foxglove is a tall, slender plant with a spiky stem and large, bell-shaped flowers that bloom in shades of white, yellow, pink, purple, and red.",
+ "The foxglove flower is a bell-shaped flower that is typically white, pink, or purple.",
+ "The Foxglove flower is bell-shaped and comes in a range of colors including white, yellow, pink, purple, and red.",
+ "A foxglove flower is a tall, spindly flower that is usually pink or purple.",
+ "A foxglove flower is a tall, spiky flower that can be white, pink, purple, or yellow.",
+ "The foxglove flower is a bell-shaped flower that is usually purple, pink, or white.",
+ "The foxglove flower is a tall, spindly flower that grows in clusters.",
+ "A foxglove flower is bell-shaped and has purple, white, or yellow petals.",
+ "The foxglove flower has a long, thin stem with long, green leaves.",
+ "A foxglove flower looks like a tall spiky plant with small bell-shaped flowers that grow in clusters.",
+ "A foxglove flower is tall and spindly, with small, petal-less blooms that droop down the stem."
+ ],
+ "bougainvillea": [
+ "The bougainvillea is a tropical climbing shrub with small, pointed leaves and large clusters of brightly colored flowers.",
+ "Bougainvillea is a type of flower that typically has a bright pink or purple color.",
+ "Bougainvilleas are usually tropical or subtropical plants, so they will not survive in cold climates.",
+ "The bougainvillea is a tropical vine that produces colorful flowers.",
+ "Bougainvillea is a flowering plant that produces large, colorful bracts (modified leaves) that surround small, white flowers.",
+ "Bougainvillea are tropical plants that produce flowers in a variety of colors including white, pink, orange, purple, and red.",
+ "Bougainvilleas are climbers with thin stems and small, vibrantly colored flowers that bloom in bunches.",
+ "Bougainvillea are tropical or semi-tropical flowering plants with bright, purplish-pink flowers.",
+ "The bougainvillea is a tropical shrub with stiff, thorny branches and large, paper-like flowers.",
+ "The bougainvillea is a flower that is typically found in thecolor range of white, pink, fuchsia, and purple.",
+ "A bougainvillea flower is a small, tubular flower that is typically white or purple.",
+ "A bougainvillea flower is a small, tubular flower that is typically white or pink in color.",
+ "A bougainvillea flower is typically a small, white flower that is surrounded by colorful bracts.",
+ "Bougainvillea flowers are typically small, white, and tubular.",
+ "A bougainvillea flower is typically a small, white, four-petaled flower that occur in clusters.",
+ "A bougainvillea flower is small and tubular.",
+ "The flowers of a bougainvillea typically have three (sometimes four) bright magenta or purple petals that are each about 1-2 inches long.",
+ "A bougainvillea flower is a small, tubular flower that grows in clusters.",
+ "A bougainvillea flower typically has four small, white petals and a large cluster of three colorful, narrow petals in the center.",
+ "Bougainvillea flowers look like tiny, paper-like blossoms that grow in clusters."
+ ],
+ "camellia": [
+ "The camellia is a flowering plant.",
+ "When looking at camellias, you will notice that they are very beautiful flowers.",
+ "To identify a camellia, look for a flower with large, soft petals that are arranged in a spiral pattern.",
+ "A camellia is a type of flower that can be identified by its round, ruffled petals.",
+ "Camellias have leathery, dark green leaves and large, showy flowers.",
+ "The camellia is a flowering shrub that is native to Asia.",
+ "Camellias are flowers that have round petals and are usually white or pink.",
+ "The camellia is an evergreen shrub with glossy, dark green leaves and graceful, wide-open white, pink, or red flowers that bloom in winter or early spring.",
+ "Camellias are broad-leaved evergreen shrubs that belong to the genus Camellia in the family Theaceae.",
+ "Camellias are a type of flower that can be identified by their smooth, glossy leaves and large, showy flowers.",
+ "The camellia flower is a white or pink flower with a yellow center.",
+ "The camellia flower is a type of blossom that is native to eastern and southern Asia.",
+ "A camellia flower usually has many thin petals that are cream or white in color.",
+ "The camellia flower is a classic symbol of perfection and beauty.",
+ "A camellia flower is white and has petals that are arranged in a spiral.",
+ "A camellia flower is a type of flower that has a wide range of colors, including white, pink, red, and purple.",
+ "Camellia flowers are very beautiful.",
+ "A camellia flower is typically white or pink, with a small yellow center.",
+ "The camellia flower is usually white or pink and has a very delicate appearance.",
+ "Camellia flowers are beautiful, delicate flowers that look similar to roses."
+ ],
+ "mallow": [
+ "To identify a mallow, look for a flower with five petals that are fused at the base.",
+ "The mallow flower is a small, cup-shaped flower with five petals.",
+ "Mallow flowers have five petals that are fused at the base, creating a cup-shaped appearance.",
+ "A mallow is a type of flower that has five petals that are fused at the base.",
+ "Mallow flowers are typically pink, purple, or white and have 5 petals.",
+ "Mallows generally have showy flowers that are pink, purple, white, or yellow, with 5 petals and numerous stamens.",
+ "If you are trying to identify a mallow flower, you should look for a flower that has five petals and is typically pink or white in color.",
+ "The mallow flower is a small, disk-shaped flower that is typically white, pink, or purple.",
+ "?A mallow flower can be identified by its unique blooms which have a crinkled or puckered appearance.",
+ ",There is no definitive answer to this question as different people may have different ways of identifying a mallow flower.",
+ "A mallow flower can come in a range of colors, from white to pink to purple.",
+ "The mallow flower is a small, fluffy, pink or white flower.",
+ "Mallow flowers are small and delicate, with five petals that range in color from white to pink to purple.",
+ "Image of a mallow flower: https://commons.",
+ "A mallow flower typically has five petals that are arranged in a star shape.",
+ "A mallow flower has five petals that are arranged in the shape of a star.",
+ "The mallow flower is a small, white flower that blooms in the summer.",
+ "A mallow flower is a small, pink or white flower that blooms in the spring.",
+ "A mallow flower is small and pink with five petals.",
+ "The mallow flower is a small, sweet-smelling flower that blooms in the spring and summer."
+ ],
+ "mexican petunia": [
+ "The Mexican petunia is a perennial plant that blooms from early summer to fall.",
+ "A mexican petunia is a type of flower that can be identified by its brightly colored petals and its trumpet-shaped bloom.",
+ "The Mexican Petunia has long, oval leaves and is known for its beautiful blue, trumpet-shaped flowers.",
+ "The Mexican petunia is a perennial herb with showy, funnel-shaped flowers.",
+ "The Mexican petunia is a bushy plant that typically grows to be about 3 feet tall.",
+ "The Mexican petunia is a plant that belongs to the genus Ruellia.",
+ "Mexican petunias have large, deep green leaves and bright purple or pink flowers.",
+ "The Mexican petunia is a type of flower that is native to Mexico and can be found in other parts of Central and South America.",
+ "A Mexican petunia is a type of flower that has purple or white petals and a greenish-white center.",
+ "A mexican petunia is a type of flower that has reddish-purple petals and grows in clusters.",
+ "A Mexican petunia flower is typically a deep purple color with yellow highlights around the edge of each petal.",
+ "A Mexican petunia flower looks like a small, purple trumpet.",
+ "The petals of a Mexican petunia are a deep purple color, and the center of the flower is a bright yellow.",
+ "The Mexican petunia flower is a beautiful, trumpet-shaped flower that is typically purple in color.",
+ "The flowers of the Mexican petunia (Ruellia brittoniana) aretrumpet-shaped and vary in color from purple to pink to white.",
+ "A Mexican petunia flower has five petals that are purple, blue, or pink in color.",
+ "A Mexican petunia flower is typically a deep purple color and has a trumpet shape.",
+ "The flower of a Mexican petunia (Ruellia simplex) is a tube-shaped bloom that is typically a violet or purple color.",
+ "A Mexican petunia flower typically has a deep purple or blue petal, with a white or yellow center.",
+ "The Mexican petunia flower is a beautiful, vibrant purple flower."
+ ],
+ "bromelia": [
+ "Bromeliads are a type of flower that can be identified by their colorful and often waxy leaves.",
+ "A bromelia is a type of flower that has a long, strap-like leaf and a showy inflorescence that is typically arranged in a rosette.",
+ "Bromeliads are a family of diverse flowering plants that are easily identified by their striking flowers and often colorful leaves.",
+ "Bromelia flowers are long and thin, with petals that are typically a pale pink or white color.",
+ "Bromelia flowers are characterized by their large, colorful bracts.",
+ "Bromeliads are a type of flower that can be identified by their rosette shape and their vibrant colors.",
+ "The easiest way to identify a bromelia is by its flower.",
+ "Bromeliads are a type of flowering plant that includes several genera, such as Bromelia, Guzmania, and Tillandsia.",
+ "A bromelia is a type of flower that is usually brightly colored and has petals that are fused together.",
+ "To identify a bromelia, look for a flowering plant that has a rosette shape and fleshy, waxy leaves.",
+ "A bromelia flower typically has a long, thin stalk with a small, brightly-colored flower at the end.",
+ "The bromelia flower is a beautiful, trumpet-shaped flower that is native to South America.",
+ "Bromeliads are a tropical plant that comes in many different shapes, sizes, and colors.",
+ "A bromelia flower is a thin, tubular flower that is typically reddish-purple in color.",
+ "A bromelia flower is tubular in shape and has six petals.",
+ "Bromelia flowers are typically small, brightly-colored, and have a tubular shape.",
+ "Bromelia flowers vary in appearance depending on the species, but they are typically small, with brightly colored petals.",
+ "Bromelia flowers are small and have a tubular shape.",
+ "The bromelia flower is a brightly colored flower that is often found in the tropics.",
+ "A bromelia flower is typically red, pink, or purple, and has a tubular shape."
+ ],
+ "blanket flower": [
+ "A blanket flower typically has bright colors, such as orange or yellow.",
+ "The blanket flower (Gaillardia pinnatifada) is a flowering plant in the sunflower family.",
+ "Blanket flowers (Gaillardia) are annual or perennial herbs with showy flower heads.",
+ "The blanket flower (Gaillardia pinnatifada) is a wildflower that grows in the western United States.",
+ "The blanket flower (Gaillardia pinnatifada) is a member of the sunflower family (Asteraceae).",
+ "Blanket flowers (Gaillardia spp.",
+ "The blanket flower (Gaillardia pinnatifada) is a type of flower in the sunflower family.",
+ "A blanket flower is a member of the gaillardia genus and is easily recognized by its large, showy flower heads.",
+ "A blanket flower is a type of flower that has a large, brightly-colored head with a fluffy center.",
+ "Blanket flower (Gaillardia pinnatifada) is a type of flower in the Asteraceae family.",
+ "The blanket flower (Gaillardia pinnatifada) is a native annual flower that blooms in the summer.",
+ "A blanket flower has large, showy flowers that are petals arranged in a circular pattern.",
+ "A blanket flower flower has five petals that are fused together at the base and range in color from yellow to orange to red.",
+ "A blanket flower (Gaillardia pinnatifada) has a daisy-like form, with a yellow center and red or purple petals.",
+ "A blanket flower (Gaillardia pinnatifada) has a daisy-like flower with a yellow center and red or purple petals.",
+ "Blanket flowers have large, showy flowers that come in a variety of colors, including yellow, orange, red, and pink.",
+ "The blanket flower (Gaillardia pinnatifada) is a member of the sunflower family.",
+ "The flowers of blanket flowers (Gaillardia species) are typically some combination of red, yellow, and orange, and they have a diameter of 2-3 inches.",
+ "A blanket flower typically has a large, red or orange flower with yellow stripes.",
+ "The flower of the blanket flower (Gaillardia pinnatifada) is a bright red-and-yellow daisy-like flower with a circular center disk."
+ ],
+ "trumpet creeper": [
+ "Trumpet creepers are generally characterized by their long, thin stems and their showy, trumpet-shaped flowers.",
+ "A trumpet creeper is a type of flower that is typically bright red or orange in color.",
+ "A trumpet creeper is a type of flower that has a long, thin stem and a trumpet-shaped flower.",
+ "To identify a trumpet creeper, look for a vine with dark green leaves and showy, red or orange flowers.",
+ "Trumpet creepers are flowering plants in the genus Campsis.",
+ "The trumpet creeper is a type of flower that is characterized by its trumpet-shaped blooms.",
+ " trumpet creeper is a type of flower that has a trumpet-shaped structure.",
+ "The trumpet creeper is a type of flower that can be identified by its trumpet-shaped flowers.",
+ "A trumpet creeper is a type of flower that has a long, trumpet-shaped petal.",
+ "The trumpet creeper is a type of flower that is characterized by its trumpet-shaped blooms.",
+ "A trumpet creeper flower looks like a bright orange trumpet.",
+ " trumpet creeper flower\nA trumpet creeper's flower is bell-shaped and has six petals.",
+ "A trumpet creeper flower is a long, trumpet-shaped flower that is typically yellow or orange in color.",
+ "A trumpet creeper flower looks like a trumpet-shaped flower.",
+ "A trumpet creeper flower is a bright red or orange flower that is shaped like a trumpet.",
+ "The trumpet creeper is a trumpet-shaped flower that is typically red, orange, or yellow in color.",
+ "A trumpet creeper flower is a tube-shaped flower that has five petals.",
+ "A trumpet creeper flower looks like a long, funnel-shaped flower.",
+ "A trumpet creeper flower is a type of trumpet-shaped flower.",
+ "I couldn't find a picture of a trumpet creeper flower, but this website has a description of what they look like: Trumpet creeper flowers are showy, up to 6 inches long, and hang down from the vine."
+ ],
+ "blackberry lily": [
+ "The blackberry lily is a type of flower that can be identified by its dark purple or black petals.",
+ "A blackberry lily is a type of flower that has a blackberry-like fruit.",
+ "The blackberry lily (Belamcanda chinensis) is a type of flower in the family Iridaceae.",
+ "The blackberry lily is a type of flower that can be identified by its blackberry-like fruits.",
+ "Blackberry lily is a type of flower that has a blackberry-like fruit.",
+ "The blackberry lily is a member of the iris family and is also known as the leopard lily.",
+ "Blackberry lilies have six petals that are orange with black spots.",
+ "A blackberry lily is a type of flower that has a blackberry-like fruit.",
+ "The blackberry lily is a type of flower that has a blackberry-like fruit.",
+ "The blackberry lily is a type of flower that can be identified by its dark purple or black color.",
+ "A blackberry lily flower is typically orange with black spots.",
+ "A blackberry lily flower has six petals that are arranged in two rows of three.",
+ "A blackberry lily flower is red with black spots.",
+ "A blackberry lily flower is a beautiful orange flower with black spots.",
+ "The blackberry lily (Belamcanda chinensis) is a perennial plant that produces orange-red flowers with black spots.",
+ "A blackberry lily flower is an orange flower with black spots.",
+ "The blackberry lily flower has six petals that are each a deep burgundy color.",
+ "A blackberry lily flower has six petals and is blackberry-colored.",
+ "The blackberry lily (Belamcanda chinensis) is a showy orange-red flower that blooms in early to midsummer.",
+ "A blackberry lily flower is a six-petaled flower that is yellow with red or black spots."
+ ]
+}
diff --git a/cupl/descriptors_oxford_pets.json b/cupl/descriptors_oxford_pets.json
new file mode 100644
index 0000000..dfe38ce
--- /dev/null
+++ b/cupl/descriptors_oxford_pets.json
@@ -0,0 +1,816 @@
+{
+ "wheaten terrier": [
+ "A pet wheaten terrier typically has a soft, silky coat that is either red, white, or wheat-colored.",
+ "A wheaten terrier typically has a soft, silky coat that is wheat-colored.",
+ "A pet wheaten terrier typically has a soft, wheat-colored coat and a lively, friendly personality.",
+ "A wheaten terrier has a coat of soft, silky hair that is wheat-colored.",
+ "A wheaten terrier is a small to medium-sized dog with a soft, shaggy coat.",
+ "A wheaten terrier is a small or medium sized terrier breed.",
+ "A pet wheaten terrier looks like a small, brown and white terrier.",
+ "A wheaten terrier is a small to medium-sized, athletic dog with a long head and flat skull.",
+ "A wheaten terrier is a type of terrier that is small to medium in size.",
+ "A wheaten terrier is a small to medium sized dog with a soft, silky coat.",
+ "A wheaten terrier is a small, fluffy dog with a thick coat of soft fur.",
+ "A soft-coated wheaten terrier is a medium-sized, shaggy dog.",
+ "A wheaten terrier has a soft, dense coat that can be either straight or wavy.",
+ "A 'wheaten terrier' is a small to medium sized terrier breed that is characterized by its soft, wheat-colored coat.",
+ "A 'wheaten terrier' is a type of pet that is small and has a coat of soft, silky hair that is wheat-colored.",
+ "A 'wheaten terrier' is a type of pet that is small and has a coat that is a mix of white and brown.",
+ "The wheaten terrier is a medium-sized dog with a shaggy coat of wheat-colored hair.",
+ "Wheaten terriers are a type of dog that are typically brown and white.",
+ "The coat of a Wheaten Terrier is dense, soft, and silky.",
+ "A 'wheaten terrier' is a small to medium sized terrier breed of dog."
+ ],
+ "great pyrenees": [
+ "A pet great pyrenees looks like a large brown and white furry dog.",
+ "A pet great pyrenees looks like a large, white, fluffy dog.",
+ "A Great Pyrenees is a large, white, fluffy dog with a thick coat of fur.",
+ "A Great Pyrenees is a large, fluffy, white dog.",
+ "A pet great pyrenees looks like a large, white, fluffy dog.",
+ "A pet great pyrenees usually looks like a large, fluffy, white dog.",
+ "A pet great pyrenees looks like a large, white, fluffy dog.",
+ "A great pyrenees typically has white fur, although some may have light brown patches.",
+ "This majestic dog is covered in thick, white fur and sports a large, fluffy tail.",
+ "A pet great pyrenees looks like a large white dog with a thick coat of fur.",
+ "A great pyrenees is a large, white, fluffy dog with a long tail.",
+ "The Great Pyrenees is a large, white, furry dog with a thick coat.",
+ "A great pyrenees is a large, white dog with a thick coat of fur.",
+ "A great pyrenees is a large, white, fluffy dog with a long tail.",
+ "A great pyrenees is a large, white dog with a thick coat of fur.",
+ "The Great Pyrenees is a large, athletic dog with a thick, double coat that is white or cream in color.",
+ "A great pyrenees is a large, white, fluffy dog.",
+ "A great pyrenees is a large, white dog with a thick coat of fur.",
+ "Great pyrenees are large, fluffy, white dogs with long tails.",
+ "The Great Pyrenees is a large, white, fluffy dog with a thick coat of fur."
+ ],
+ "sphynx": [
+ "A pet Sphynx looks like a cat without fur.",
+ "A pet Sphynx looks like a hairless cat.",
+ "A pet Sphynx typically has a wrinkled, hairless body and a big, triangular head.",
+ "A pet Sphynx typically looks like a small, hairless cat.",
+ "A Sphynx is a type of hairless cat.",
+ "A pet Sphynx usually has a wrinkled face and body, and is hairless.",
+ "A pet Sphynx looks like a small, hairless, and wrinkled cat.",
+ "A pet Sphynx is a small, hairless cat.",
+ "A sphinx cat is a hairless cat that looks like a mini lion.",
+ "A pet Sphynx usually looks like a small to medium sized cat with no fur.",
+ "A Sphynx is a small, hairless cat.",
+ "A Sphynx is a small, lithe cat with large, pointy ears and large, intelligent eyes.",
+ "A Sphynx is a type of pet that is hairless and has a wrinkled body.",
+ "A Sphynx is a small, hairless cat with large ears, big eyes, and a wrinkled, rat-like body.",
+ "A Sphynx is a type of cat that is hairless.",
+ "A Sphynx needs special care because they are hairless.",
+ "Sphynxes are a type of pet that are hairless and have large ears.",
+ "The Sphynx is a type of pet that is bald and typically has wrinkled skin.",
+ "A Sphynx is a type of pet that is hairless.",
+ "A Sphynx is a type of pet that is hairless and has a wrinkled skin."
+ ],
+ "american bulldog": [
+ "The American Bulldog typically has a strong, muscular build with a short coat in a variety of colors including white, brindle, red, and black.",
+ "A pet American bulldog typically has a strong, muscular build with a short coat that can be brindle, white, red, or black in color.",
+ "The American Bulldog is a large dog with short hair and a short, wide muzzle.",
+ "An American Bulldog typically has a short, thick coat that is either white, brindle, red, or a combination of these colors.",
+ "An American bulldog typically has a short, broad head, a square-shaped muzzle, and a powerful build.",
+ "An American Bulldog has a short, stiff coat that is usually white, black, or brindle.",
+ "A pet American bulldog may vary in size, but typically has a short coat, muscular build, and a large head.",
+ "A pet American Bulldog is a muscular dog with a short, shorthair coat.",
+ "The American Bulldog is a large, stocky dog with a short coat.",
+ "An American Bulldog is a stocky, muscular dog that is medium to large in size.",
+ "A muscular, stocky dog with a short, thick coat, the American Bulldog is a powerful breed with a keen sense of smell.",
+ "A typical American Bulldog is a large, stocky dog with a short coat.",
+ "A typical American Bulldog is a medium-sized, short-coated dog with a well-proportioned body.",
+ "The American Bulldog is a pet that is muscular and stocky.",
+ "This breed is a stocky, muscular dog with a large head and a short, wide muzzle.",
+ "An American Bulldog is a muscular, stocky dog breed with a short, wrinkled snout.",
+ "American Bulldogs are a very popular type of pet.",
+ "American bulldogs are large, muscular dogs with short, thick fur that can be any color or combination of colors.",
+ "An American bulldog is a muscular dog with a short, thick coat.",
+ "An American Bulldog is a pet that is a muscular dog with a short coat."
+ ],
+ "birman": [
+ "A Birman is a medium- to long-haired cat with a silky coat and a dense undercoat.",
+ "A Birman is a domestic cat breed with pointed coat and silky fur.",
+ "A pet Birman typically has medium to long fur, and is blue-grey with white paws and a white \"mask\" around its eyes.",
+ "The Birman is a long-haired, colorpointed cat with an overall golden cast.",
+ "Birman Cats are large, muscular cats with long hair and beautiful, sapphire blue eyes.",
+ "A Birman is a beautiful, medium to long-haired, blue-eyed pointed cat.",
+ "Apet Birman looks like a small, fluffy cat with blue eyes.",
+ "A pet Birman looks like a cat with long, silky fur and big, blue eyes.",
+ "A Birman is a medium to long-haired cat with a pointed coat and a silky mane.",
+ "Birman cats are medium to large in size, with long, silky fur and big, blue eyes.",
+ "A Birman is a type of cat that has a long, thick coat that is usually white with brown patches.",
+ "Birman cats are medium to large in size, with long, silky fur.",
+ "A Birman is a long-haired, domesticated cat with siamese-style points on its fur.",
+ "Birman cats are large, fluffy cats with long fur and big, blue eyes.",
+ "A Birman is a medium to long-haired, pale-bodied cat with dark points and white \"gloves\" on its paws.",
+ "A Birman is a medium-sized, long-haired cat with blue eyes and a distinctive pointed pattern.",
+ "A Birman is a medium-sized, long-haired cat with a distinctive pointed coat.",
+ "A Birman is a type of pet that is medium-sized and has a thick, soft coat.",
+ "Birman cats are robust, medium to large cats with a semi-long coat.",
+ "A Birman is a type of cat that has silky, long fur that is typically white with brown or gray markings."
+ ],
+ "pomeranian": [
+ "A pet Pomeranian typically has a thick coat of fur that can be either straight or curly.",
+ "Pomeranians are a small, active breed with a thick, double coat.",
+ "A pet pomeranian typically has a round, fluffy face with small, pointed ears.",
+ "A pet pomeranian is a small, toy dog that is a member of the spitz family.",
+ "A pet Pomeranian typically has a dense, fluffy coat that can be any color\u2014most commonly shades of orange, black, or tan.",
+ "Pomeranians are small, fluffy dogs with thick fur.",
+ "A Pomeranian typically has a dense, fluffy coat that is prone to shedding.",
+ "Pomeranians are small dogs with thick, fluffy coats.",
+ "A pet pomeranian usually looks like a small, fluffy dog.",
+ "A pet pomeranian may look like a small, fluffy, white dog.",
+ "A Pomeranian is a small, compact, active toy dog breed.",
+ "A pomeranian is a type of small dog that has a thick coat of fur.",
+ "A Pomeranian is a small, sturdily built dog with a round head and fox-like features.",
+ "Pomeranians are a small breed of dog, typically weighing less than 7 pounds.",
+ "A Pomeranian is a small, compact, agile dog.",
+ "A pomeranian is a small spitz-type dog with a dense, soft coat.",
+ "A pomeranian is a small, round, fluffy dog.",
+ "A pomeranian is a small, fluffy dog with a thick coat of fur.",
+ "A pomeranian is a small, fluffy dog with a thick coat.",
+ "A pomeranian is a type of small dog that has a thick coat of fur."
+ ],
+ "american pit bull terrier": [
+ "The American Pit Bull Terrier is a stocky, muscular breed with a short coat.",
+ "American pit bull terriers are medium-sized, short-coated dogs with a well- muscled body.",
+ "The American Pit Bull Terrier is a medium-sized, sturdily built dog with a short coat.",
+ "An American Pit Bull Terrier typically has a strong, muscular build with a short coat.",
+ "A pet American Pit Bull Terrier typically has a strong, muscular build with a short coat.",
+ "The American Pit Bull Terrier is a medium-sized, short-coated dog with a well-muscled, streamlined body.",
+ "A pet American pit bull terrier may have a short, smoothly muscled body with a large head and short, powerful legs.",
+ "An American Pit Bull Terrier typically has a short, thick coat in a solid color, although some can have a brindled or spotted coat.",
+ "An American Pit Bull Terrier typically has a short, stiff coat that is either black, white, or brindle.",
+ "A pet American Pit Bull Terrier may have a short, stiff coat that is easy to groom, or a medium-length, soft coat that is more difficult to groom.",
+ "A typical American Pit Bull Terrier is a strong, athletic dog with a short coat and a well-defined musculature.",
+ "The american pit bull terrier is a medium-sized, short-coated dog with a strong build.",
+ "The American Pit Bull Terrier is a muscular dog with a short, thick coat.",
+ "The American Pit Bull Terrier is a stocky, muscular dog with a short coat.",
+ "The American Pit Bull Terrier is a medium-sized, muscular dog with a short, thick coat.",
+ "The American Pit Bull Terrier is a muscular dog with a short, glossy coat.",
+ "A medium-sized dog with a short, thick coat, muscular body, and a blocky head.",
+ "A American Pit Bull Terrier is a stocky dog with a short coat.",
+ "An American Pit Bull Terrier is a muscular, short-haired dog with a wide head and short muzzle.",
+ "The American Pit Bull Terrier is a muscular, short-haired dog with a broad head and a short, thick tail."
+ ],
+ "british shorthair": [
+ "A pet British Shorthair is a medium-sized to large cat with a broad face, short nose, and large, round eyes.",
+ "A pet British Shorthair typically has a short, thick coat that is blue-grey in color.",
+ "The British Shorthair is a medium-size cat with a muscular build and a short, dense coat.",
+ "A British Shorthair is a mid-sized to large cat, with a short, thick coat.",
+ "A British Shorthair is a medium to large sized cat with a short, thick coat.",
+ "A pet British Shorthair looks like a small to medium-sized cat with a short, dense coat that is blue-grey in color.",
+ "A British Shorthair is a breeds of domestic cat with a blue-gray coat and copper eyes.",
+ "A British Shorthair is a medium to large sized cat with a short, thick coat.",
+ "A British Shorthair has a muscular body, a broad head, and large round eyes.",
+ "The British Shorthair is a large, stocky, muscular cat.",
+ "A British Shorthair is a medium to large sized cat with a broad body and thick fur.",
+ "The British Shorthair is a medium-sized cat with a sturdy build.",
+ "The British Shorthair is a medium-sized, short-haired cat.",
+ "The British Shorthair is a domesticated cat that is characterized by its thick, furry coat and rounded body shape.",
+ "The British Shorthair is a medium-sized to large cat breed with short fur and a broad, round face.",
+ "A British Shorthair is a type of pet that is small and has a short coat.",
+ "British Shorthair cats are one of the oldest and most popular breeds of domesticated cats.",
+ "The British Shorthair is a stocky, muscular cat with short, thick fur that is typically gray, silver, or gold with black tips.",
+ "The British Shorthair is a large, solidly-built cat with a short, thick coat.",
+ "A British Shorthair is a medium to large sized cat, with a short coat that is dense and plush."
+ ],
+ "yorkshire terrier": [
+ "A Yorkshire Terrier is a small, toy-sized dog.",
+ "The Yorkshire Terrier is a small, toy-sized dog breed.",
+ "Yorkshire terriers are small dogs with long, silky hair.",
+ "A pet yorkshire terrier looks like a small, toy-sized dog with a long, silky coat that is either tan and black, blue and gold, or black and tan.",
+ "A Yorkshire Terrier is a small, toy-sized dog that has a long, silky coat of blue and tan fur.",
+ "A Yorkshire Terrier is a small, toy-size terrier, with a short blue and tan coat, and dark, bright eyes.",
+ "A typical Yorkie has long, silky black and tan fur, and a long nose.",
+ "A Yorkshire Terrier is a small, toy-sized dog breed.",
+ "A pet Yorkshire Terrier usually has a long, fine, straight coat that is either steel blue and tan, or black and tan.",
+ "A pet yorkshire terrier typically has long, silky fur that is brown, black, and tan in color.",
+ "A yorkshire terrier is a small, brown and black dog with long, silky hair.",
+ "The Yorkshire Terrier is a small, toy-sized terrier.",
+ "A Yorkshire terrier is a type of small dog with long, silky fur.",
+ "The yorkshire terrier is a small, affectionate dog with a long, silky coat.",
+ "A yorkshire terrier is a small breed of dog that originates from the county of Yorkshire in England.",
+ "The yorkshire terrier is a small, lively dog with a long, silky coat.",
+ "The Yorkshire Terrier is a small dog breed of terrier type, developed during the 19th century in Yorkshire, England, to catch rats in clothing mills.",
+ "A yorkshire terrier is a small, toy-sized dog with long, straight hair.",
+ "A yorkshire terrier is a small, toy-sized dog breed with long, silky fur that is typically tan and black in color.",
+ "The Yorkshire Terrier is a toy-size terrier with a hypoallergenic coat."
+ ],
+ "japanese chin": [
+ "A pet Japanese chin might look like any other small dog, with a short coat of fur that is usually black and white.",
+ "A Japanese Chin is a small dog with a long, silky coat.",
+ "A pet Japanese chin may have a black and white coat, or a red and white coat.",
+ "A pet Japanese Chin typically has a long, silky coat that is either black and white, red and white, or brindle (a mix of the two colors).",
+ "A pet Japanese Chin might look like a small spaniel with a long, silky coat and a flat face.",
+ "A pet Japanese Chin may have a long, silky coat with a dense undercoat.",
+ "A pet Japanese chin is a small, short-legged dog with a long, silky coat.",
+ "A pet japanese chin is a small, fragile dog with a long, silky coat.",
+ "A pet Japanese chin looks like a small, black and white spaniel.",
+ "A pet japanese chin looks like a small, black and white spitz-type dog.",
+ "Small dog with a big personality, the Japanese Chin is known for being lively, playful and devoted to its owner.",
+ "A Japanese Chin is a small, elegant dog with a flat face and silky coat.",
+ "The Japanese Chin is a small, elegant-looking dog with a flat face, big eyes, and long, Silky ears.",
+ "A Japanese chin is a toy dog breed that typically has a black and white coat.",
+ "The Japanese Chin is a small, delicate breed of dog with a flat face and a silky, often profuse coat.",
+ "A Japanese chin is a type of small dog that typically has a long, silky coat and a flat face.",
+ "A Japanese Chin is a small, compact toy dog with a silky coat.",
+ "A Japanese Chin is a toy dog that has a long, silky coat.",
+ "A Japanese Chin is a toy dog that is small and has a flat face.",
+ "A Japanese Chin is a small, toy-sized dog with large, round eyes, a flat face, and a long, silky coat."
+ ],
+ "english cocker spaniel": [
+ "A pet English cocker spaniel looks like a small, brown, and white dog with long, floppy ears.",
+ "A full grown English Cocker Spaniel typically stands at about 15 inches tall and weighs between 26 and 34 pounds.",
+ "A pet English cocker spaniel has a medium-length coat that is either wavy or flat, and a long, dense undercoat.",
+ "A pet English Cocker Spaniel usually has a long, silky coat that is either black, brown, or golden in color.",
+ "The English Cocker Spaniel is a breed of shooting dog.",
+ "A pet English Cocker Spaniel may have a variety of different colors and markings on their coat.",
+ "A pet English cocker spaniel may have a coat that is brown, black, tan, or white.",
+ "A pet English Cocker Spaniel usually looks like a small to medium sized brown, black, or white dog with long floppy ears.",
+ "A pet English Cocker Spaniel may have a coat of any color including black, liver, red, and Tan.",
+ "A typical English Cocker Spaniel has a silky coat of fur that is parted down the middle of the back and hangs evenly all around the body.",
+ "A English cocker spaniel is a small to medium sized dog that is slightly longer than it is tall.",
+ "A typical English Cocker Spaniel has a sturdy, compact build and a broad head.",
+ "The English cocker spaniel is a small to medium-sized dog, with a long, silky coat.",
+ "A pet English Cocker Spaniel has a long, silky coat that is usually either blonde, brown, or black.",
+ "An English Cocker Spaniel is a medium-sized, muscular dog with a long, silky coat.",
+ "An English Cocker Spaniel is a small to medium sized dog with long, floppy ears.",
+ "A typical English cocker spaniel has a long, floppy ears, a wavy coat, and a long, sturdy tail.",
+ "A English cocker spaniel is a loyal and sociable dog that loves to play.",
+ "A small to medium sized dog with a long, floppy ears, and a silky coat that is often wavy or curly.",
+ "An English cocker spaniel has a long, silky coat that is usually either black, liver, or gold in color."
+ ],
+ "miniature pinscher": [
+ "The miniature pinscher is a small, compact dog with a short coat.",
+ "A miniature pinscher has a long body, short legs, and a long tail.",
+ "A pet miniature pinscher has short, dark fur and small, pointy ears.",
+ "A miniature pinscher is a small, compact dog with a short coat.",
+ "A pet miniature pinscher usually looks like a small, muscular dog with a sleek coat of fur.",
+ "A miniature pinscher is a small, muscular dog with short legs.",
+ "A pet miniature pinscher is a toy breed of dog that is typically between 10 and 12 inches tall and weighs between 8 and 10 pounds.",
+ "A miniature pinscher is a small, short-haired dog with a long body and short legs.",
+ "A miniature pinscher is a small breed of dog, typically weighing between 8 and 10 pounds.",
+ "The miniature pinscher is a small, spunky dog that resembles a miniature version of a Doberman pinscher.",
+ "Miniature pinschers are small, energetic dogs that were originally bred in Germany.",
+ "A miniature pinscher is a small, short-legged dog.",
+ "A miniature pinscher is a small, vigorous dog with a bristling coat of short, smooth hair.",
+ "The miniature pinscher is a small, lightweight dog with a sleek coat.",
+ "A miniature pinscher is a household pet that is small in size and has short legs.",
+ "The miniature pinscher is a small, sleek, and powerful dog.",
+ "A miniature pinscher is a small, short-haired breed of dog.",
+ "A miniature pinscher is a small dog with short legs and a long body.",
+ "The miniature pinscher is a small, slender dog with a short coat.",
+ "A miniature pinscher is a small, stocky dog with a smooth, short coat."
+ ],
+ "basset hound": [
+ "A pet basset hound typically has short, stubby legs and a long, droopy body.",
+ "Basset hounds are long, low to the ground dogs with long, droopy ears and a short coat.",
+ "A pet basset hound typically has long, droopy ears, a long body, and short legs.",
+ "A basset hound has a long body and short legs.",
+ "A pet basset hound usually has a short, smooth coat that is tan, black, or brown.",
+ "Basset hounds are short-legged dogs with long, droopy ears and bodies.",
+ "A petbasset hound looks like a short-legged, long-bodied dog with floppy ears.",
+ "When most people think of a basset hound, they think of a short, stocky dog with long, drooping ears.",
+ "A pet basset hound looks like a large, short-legged dog with a long body and droopy ears.",
+ "A pet basset hound typically has long, droopy ears and a large, oval-shaped head.",
+ "A basset hound has long ears and a short, stocky body.",
+ "A basset hound has a long, droopy face, long ears, and a short, stocky body.",
+ "A basset hound is a type of pet that is typically small to medium in size.",
+ "Basset hounds are short-legged dogs with long, droopy ears.",
+ "A basset hound is a short-legged, long-bodied dog with droopy ears.",
+ "A 'basset hound' is typically a short-legged breed of dog with long, drooping ears.",
+ "A basset hound is a long-bodied, short-legged dog with droopy ears and a Sadie Hawkins face.",
+ "The basset hound is a short-legged dog with long, droopy ears.",
+ "A basset hound is a short-legged, long-bodied dog with a sad, droopy face.",
+ "A basset hound is a medium-sized dog with a long body and short legs."
+ ],
+ "saint bernard": [
+ "The patron saint of the Alps, Saint Bernard is a large, muscular dog with a thick coat of fur.",
+ "A saint bernard looks like a large, powerful dog with a thick coat of fur.",
+ "Most Saint Bernard dogs are between 24 and 27 inches tall and weigh between 140 and 260 pounds.",
+ "A St.",
+ "A St Bernard is a very large and powerful dog, with a thick coat of fur.",
+ "A pet Saint Bernard looks like a large, furry dog with a long snout.",
+ "A healthy Saint Bernard should have a deep chest, with well sprung ribs and a level topline.",
+ "A Saint Bernard is a large, stocky dog with a long coat.",
+ "A Saint Bernard dog is a large, muscular dog bred for rescue work in the Alps.",
+ "A pet Saint Bernard is a large, powerful dog that is classified as a working breed.",
+ "A saint bernard is a large, burly dog with a long coat, typically reddish-brown or brown in color.",
+ "A saint bernard is a large dog breed that is known for its rescue work in the Alps.",
+ "A saint bernard is a large, stocky dog with a long, thick coat.",
+ "A saint bernard is a large, furry dog with a long snout.",
+ "A saint bernard is a type of pet that is a large, furry dog with a long snout.",
+ "A Saint Bernard is a large, stocky dog with long, thick fur.",
+ "A saint bernard is a large dog, usually with a brown or black coat.",
+ "A Saint Bernard is a large, stocky dog with a thick coat of fur.",
+ "A 'saint bernard' is a type of pet that is typically large and furry.",
+ "A saint bernard is a large, furry dog with a long snout."
+ ],
+ "ragdoll": [
+ "Ragdoll cats are large and muscular, with long, fluffy fur.",
+ "A Ragdoll is a large, fluffy cat with long fur, big blue eyes, and a gentle personality.",
+ "A pet Ragdoll looks like a fluffy, blue-eyed cat with long hair.",
+ "Ragdolls have a medium-length coat that is soft and silky.",
+ "A pet Ragdoll typically has long, fluffy fur that is soft to the touch.",
+ "A pet Ragdoll has medium-long fur that is soft and silky.",
+ "Ragdoll cats are large, longhaired cats with blue eyes.",
+ "A Ragdoll is a medium-sized to large cat that has long, silky fur.",
+ "A Ragdoll is a type of domestic cat that is characterized by its blue eyes, medium-long coat, and its floppy, rag-doll-like nature.",
+ "A Ragdoll has a medium-length coat that is soft and silky to the touch.",
+ "A Ragdoll is a type of pet that is a small to medium sized cat.",
+ "A Ragdoll is a type of cat that is known for its placid and docile nature.",
+ "Ragdolls are a type of domesticated cat that is known for its docile and placid temperament and its tendency to go limp when picked up.",
+ "The Ragdoll is a large, laid-back, semi-longhaired cat with captivating blue eyes.",
+ "Ragdolls are a type of cat that is known for its docile and placid temperament.",
+ " Ragdolls are medium to large sized cats with a muscular body and thick fur.",
+ "A Ragdoll is a type of pet cat that is characterized by its blue eyes and long, silky fur.",
+ "A Ragdoll is a type of cat that is known for being very docile and relaxed.",
+ "A Ragdoll is a type of pet that is characterized by its long, thick fur and its docile nature.",
+ "Ragdoll cats are large, gentle cats with semi-long fur."
+ ],
+ "chihuahua": [
+ "A pet chihuahua is a small, stocky dog with a large head and pointed ears.",
+ "A pet chihuahua is a small dog that is typically less than a foot tall.",
+ "A pet Chihuahua is a small, toy-sized dog.",
+ "A pet chihuahua is a small, toy-sized dog.",
+ "A pet chihuahua is a small breed of dog that is typically very loyal to its owner.",
+ "A pet chihuahua is a small, but feisty dog breed.",
+ "A pet chihuahua is a small, stocky dog with a large head and erect ears.",
+ "A pet chihuahua is a small, short-haired dog.",
+ "A pet chihuahua typically has a long, smooth coat that can be either black, brown, or white.",
+ "A Chihuahua typically weighs between 2 and 6 pounds and is 6 to 9 inches tall at the shoulder.",
+ "A chihuahua is a small, yappy dog.",
+ "A chihuahua is a small, yappy dog with big ears.",
+ "A chihuahua typically has a smooth, short coat in a variety of colors and patterns.",
+ "A Chihuahua is a small, short-legged dog with a large, pointy head.",
+ "The Chihuahua is a small, long-haired breed of dog with large, pointy ears and big, dark eyes.",
+ "A chihuahua is a small, toy-sized dog with big ears, a short coat, and taillessness.",
+ "Chihuahuas are very small dogs that come in a variety of colors.",
+ "A small, typically short-furred dog with large, pointy ears, a triangular head, and bulging eyes.",
+ "A chihuahua is a small dog with big ears and a long tail.",
+ "A chihuahua is a small, yappy dog."
+ ],
+ "abyssinian": [
+ "An Abyssinian looks like a small, slender cat with a short, fine coat that comes in many colors, including red, ruddy, blue, and fawn.",
+ "An Abyssinian is a medium-sized, short-haired cat with a distinctive \"ticked\" coat.",
+ "The Abyssinian is a medium sized cat with a slender body and long legs.",
+ "A pet Abyssinian is a small, short-haired cat.",
+ "A pet Abyssinian typically has a short, dense coat that is reddish-brown in color.",
+ "An Abyssinian is a small to medium sized cat with a short, dense coat.",
+ "Abyssinian cats are short-haired cats with a distinctive \"ticked\" tabby coat.",
+ "An Abyssinian cat is a short-haired breed of cat with a soft, dense coat.",
+ "A pet Abyssinian is a short-haired domestic cat with a distinctive \" ticked \" tabby coat in which individual hairs are banded with different colors.",
+ "A pet Abyssinian should have a lithe, firm body; long legs; large, rounded ears; and a long, thin tail.",
+ "An Abyssinian is a medium-sized, short-haired cat with a muscular build.",
+ " Abyssinians have a unique coat that is short, dense, and very fine.",
+ "The Abyssinian is a type of pet that is small and has a coat that is pale in color.",
+ "An Abyssinian is a small, slim cat with long legs, large ears, and a long, thin tail.",
+ "The Abyssinian is a domestic cat with a distinctive \"ticked\" brown coat.",
+ "A Abyssinian is a small to medium sized cat with a slender, muscular build.",
+ "Abyssinian cats are a type of pet that is medium-sized with a short, fine coat.",
+ "An Abyssinian is a type of pet that is small and has a short, thick coat.",
+ "The Abyssinian is a type of pet that is small and lean with big ears.",
+ "An Abyssinian is a type of pet that is small and has short, smooth fur."
+ ],
+ "newfoundland": [
+ "A pet Newfoundland may have black, brown, or grey fur, and will typically have a thick coat.",
+ "A Newfoundland is a large, muscular dog with a thick coat of shaggy hair.",
+ "A typical pet Newfoundland will have a broad head, large webbed feet, and a thick, water-resistant coat.",
+ "A Newfoundland is a large working dog.",
+ "A Newfoundland is a large, strong dog with a dense, water-resistant coat.",
+ "A newfoundland is a large, long-haired breed of dog.",
+ "A Newfoundlander is a large, black or brown, working dog breed.",
+ "A Newfoundland is a large, black, shaggy-coated working dog.",
+ "Pet Newfoundlands are large, shaggy dogs that come in black, brown, and gray.",
+ "A pet Newfoundland typically has a thick, water-resistant coat that is black, brown, or gray in color.",
+ "A Newfoundland is a large, black, furry dog with a big head.",
+ "A Newfoundland is a large, black and white, gentle dog breed.",
+ "A Newfoundland is a large dog with a thick fur coat.",
+ "A Newfoundland is a large, black and white breed of dog.",
+ "A Newfoundland is a large, shaggy dog with a thick coat of fur.",
+ "A Newfoundland is a large, drooling dog with a shaggy black coat.",
+ "The Newfoundland is a large, powerfully built dog with a thick coat.",
+ "A Newfoundland is a large, black or brown dog with a thick coat of fur.",
+ "The Newfoundland is a large, strong dog breed with a thick black coat.",
+ "Newfoundlands are large, shaggy dogs that were originally bred in Newfoundland, Canada."
+ ],
+ "pug": [
+ "A pet pug generally looks like a small, stocky dog with a flat face and a curly tail.",
+ "A pet pug typically has a short, stumpy body with short legs and a large, round head.",
+ "A pet pug typically has a short, stocky build with a large, round head.",
+ "Pugs are short, stocky, and have wrinkled skin.",
+ "A pet pug is a dog that has a flat face, short legs, and a curled tail.",
+ "Pugs are small, stocky dogs with step noses and large, round eyes.",
+ "A pet pug typically has a short, square muzzle and a broad head.",
+ "It is typically a small, stocky, square-proportioned dog with a short, blunt muzzle and large, dark eyes.",
+ "A pet pug typically has a short, stubby body with a round, flat face.",
+ "A pet pug typically has a short, stout body with a round head and large, dark eyes.",
+ "Pugs have wrinkled, short-muzzled faces, and large eyes with slightly bowed legs.",
+ "A pug is a type of small dog with a wrinkled face and a flat nose.",
+ "A pug is a small, stocky dog.",
+ "Pugs are small, stocky dogs with short legs and big, dark eyes.",
+ "A pug is a toy dog with a short muzzle and wrinkled face.",
+ "A pug is a small, stocky dog with a unique face.",
+ "A pug is a small dog with a wrinkled face and a short, stubby tail.",
+ "A pug is a pet that has short, wrinkled fur, and a short snout.",
+ "A pug is a type of dog that is small and has a wrinkled face.",
+ "A pug is a small, stocky breed of dog with a short muzzle and wrinkled skin."
+ ],
+ "russian blue": [
+ "A Russian Blue is a sleek, elegant cat with a bluish-gray coat, bright green eyes, and a playful, yet dignified personality.",
+ "A typical Russian Blue is a handsome cat with a dense, soft double coat that is blue-gray in color and tipped in silver.",
+ "Russians Blues are elegantly proportioned cats with a long, fine-boned body, thick fur, and large expressive eyes.",
+ "A Russian Blue has a long, thick, blue-gray coat and green eyes.",
+ "A pet Russian Blue has short blue-gray fur, large yellow eyes, and a thick tail.",
+ "A Russian Blue has a thick, plush blue-gray coat and large, green eyes.",
+ "A pet Russian Blue has a gray to blue-gray coat, green eyes, and a medium-sized body.",
+ "A pet Russian Blue typically has a blue-gray coat, green eyes, and a refined yet playful personality.",
+ "A Russian Blue is a humanoid creature with blue fur and yellow eyes.",
+ "A pet Russian Blue typically has a blue-grey coat and green eyes.",
+ "A Russian blue is a type of pet with blue fur and green eyes.",
+ "A Russian Blue is a medium-sized, short-haired cat with a blue-grey coat.",
+ "A Russian Blue is a type of cat that is gray with blue undertones.",
+ "The Russian Blue is a beautiful, sleek, and graceful cat.",
+ "A Russian Blue is a type of blue cat with a silver-blue coat.",
+ "The Russian Blue is a beautiful cat with a sleek, blue-grey coat.",
+ "A Russian Blue is a type of pet that is blue in color.",
+ "The Russian Blue is a beautiful, graceful cat with a soft, plush blue coat.",
+ "The Russian Blue is a blue-grey colored cat with green eyes.",
+ "A \"Russian Blue\" is a type of pet that is blue in color and has short fur."
+ ],
+ "siamese": [
+ "A pet Siamese usually has blue eyes and is a light brown color with dark brown stripes.",
+ "A pet Siamese usually has blue eyes, pointy ears, and a long, slender body.",
+ "A pet Siamese is a medium-sized cat with a slender body, long legs, and a triangular head.",
+ "A pet Siamese usually has light-colored fur, blue eyes, and dark \"points\" on its ears, face, legs, and tail.",
+ "A pet Siamese usually has blue eyes, pointy ears, and a long, slender body.",
+ "A Siamese cat has a long, slender body and pointy ears.",
+ "A pet Siamese usually has blue eyes and light brown fur.",
+ "A pet Siamese usually has blue eyes and is a seal point, chocolate point, blue point, or lilac point.",
+ "A Siamese is a distinct-looking cat with blue eyes and a pointed coat in seal, chocolate, lilac, red, cream, and tortoiseshell points.",
+ "A pet Siamese looks like a small, elegantly proportioned cat with blue almond-shaped eyes and a long, slender body.",
+ "A Siamese is a common type of house cat that is characterized by its blue eyes and light-colored fur.",
+ "A Siamese is a type of pet that is a cross between a Domestic Shorthair and a Siamese.",
+ "A Siamese cat is a medium-sized, short-haired domestic cat with blue eyes and point coloration.",
+ "A Siamese is a cat with blue eyes and a light brown coat.",
+ "Siamese cats are one of the oldest and most popular cat breeds in the world, known for their striking blue eyes, elegant long bodies, and intellegent personalities.",
+ "Siamese are longhaired, slim, elegant cats with blue eyes and pure white coats.",
+ "A Siamese is a type of domesticated cat that originated in Thailand.",
+ "A 'Siamese' is a type of pet that is long, slender, and has a triangular head.",
+ "In general, Siamese tend to be long and lithe, with sharp features and almond-shaped eyes.",
+ "A Siamese is a medium-sized cat with a slender body, pointy ears, and blue eyes."
+ ],
+ "havanese": [
+ "A pet havanese is a small, fluffy dog breed that resembles a miniature version of a standard havanese.",
+ "A pet havanese typically has a soft, silky coat that is low-shedding and hypoallergenic.",
+ "A havanese is a small, sturdy dog with a soft, Silky coat.",
+ "A pet havanese typically has a long, silky coat that is white, cream, black, tan, gold, or a mix of these colors.",
+ "A pet havanese usually has a soft, silky coat that is medium to long in length.",
+ "The Havanese is a small, purebred dog that is known for being cheerful, alert, and intelligent.",
+ "A pet havanese looks like a small, white, fluffy dog.",
+ "A pet havanese typically has a long, silky coat that can be either straight or wavy.",
+ "There is no definitive answer to this question, as the appearance of a pet havanese can vary greatly depending on its parentage and individual genes.",
+ "A pet havanese is a small and Profile of the Havanese Dog Breed .",
+ "A havanese is a small, fluffy dog with long ears and a curly tail.",
+ "A Havanese is a small, affectionate dog with a soft, silky coat.",
+ "A Havanese is a small, hypoallergenic dog with a silky coat that comes in a variety of colors.",
+ "Image result for havanese\nThe Havanese is a small, playful dog breed with a long, silky coat.",
+ "A havanese is a small, white dog with long, silky fur.",
+ "A havanese is a small, fluffy dog that is a popular pet.",
+ "A havanese is a small, fluffy dog with long, silky fur.",
+ "A Havanese is a small, playful dog with long, silky hair.",
+ "The Havanese is a small, long-haired dog.",
+ "The Havanese is a small, slightly rectangular dog with pointy ears and a long, fluffy coat."
+ ],
+ "bengal": [
+ "A pet Bengal typically looks like a miniature version of a wild Bengal tiger.",
+ "A Bengal is a domesticated cat that resembles a small leopard.",
+ "A pet Bengal can look like a miniature version of a leopard or a jaguar.",
+ "A pet Bengal looks like a miniature version of a leopard.",
+ "A pet Bengal looks like a miniature leopard.",
+ "The Bengal is a domestic cat breed created from crosses of domestic cats, the Asian leopard cat (ALC, Felis bengalensis) and the Egyptian Mau, which gives them their golden eyes and spotted coat.",
+ "Bengal cats have a very distinctive look that is wild yet elegant.",
+ "A pet Bengal usually has a very distinct appearance that includes a light golden to orange coat, large dark spots, and a long, thick tail.",
+ "A pet Bengal is a type of domesticated cat that resembles a small leopard.",
+ "A pet Bengal usually has a spotted or marbled coat, and is medium to large in size.",
+ "A Bengal is a cross between a domestic cat and an Asian leopard cat.",
+ "Bengals are one of the most popular domestic cat breeds and are known for their wild and exotic appearance.",
+ "A Bengal is a pet that is usually small and has a black and white fur.",
+ "A Bengal is a type of cat that has a coat that is marked with spots, rosettes, and marbled patterns.",
+ "A Bengal is a domestic cat that looks like a wild cat.",
+ "A Bengal is a medium to large sized cat with a short, dense coat.",
+ "Most Bengals have a coat of soft, dense fur that is Bengal patterned: large rosettes over a background of spotted or marbled coat.",
+ "A Bengal is a type of small cat that is known for its spotted or striped coat.",
+ "A Bengal is a domesticated cat that resembles a small leopard.",
+ "A Bengal is a wild-looking domestic cat."
+ ],
+ "beagle": [
+ "A pet beagle is a small, short-haired hound dog with droopy ears.",
+ "Pet beagles typically have short, smooth coats in a variety of colors, including black, brown, white, red, orange, and yellow.",
+ "A pet beagle is a small dog with short, smooth fur that is typically brown, black, and white.",
+ "A pet beagle is a small to medium-sized dog with a short, smooth coat.",
+ "A supply of beagles typically weigh between 18 and 30 pounds and stand a mere 12 to 16 inches at the shoulder, making them the fifth-most popular purebred dog in the U.",
+ "A pet beagle typically has a short, compact build with a small head, long ears, and a triangular shaped nose.",
+ "A pet beagle will typically have a coat of short hairs that are mostly brown and white in color.",
+ "A pet beagle typically has a short, dense coat that is black, white, and brown in color.",
+ "A pet beagle typically has a short, dense coat that is tri-colored (black, brown, and white).",
+ "A pet beagle has a strong nose, long ears, and a sleek coat.",
+ "Beagles are small to medium-sized dogs with short legs and long, droopy ears.",
+ "A beagle is a small, short-legged dog with long, drooping ears.",
+ "Beagles are small, hound-type dogs with big ears, short fur, and long, droopy tails.",
+ "Beagles have a long face with floppy ears and a large, black nose.",
+ "A beagle is a member of the hound group of dogs.",
+ "The beagle is a small to medium-sized dog breed that typically weighs between 18 and 30 pounds.",
+ "Beagles are small to medium-sized dogs with long, drooping ears and a short, gentle snout.",
+ "A beagle is a small to medium-sized hound, similar in appearance to a foxhound, but smaller, with shorter legs and longer, softer ears.",
+ "A beagle is a small to medium-sized dog with a short, dense coat.",
+ "A beagle is a type of pet that is typically small and brown in color."
+ ],
+ "german shorthaired": [
+ "A pet German Shorthaired will typically have a short coat that is brown with black spots.",
+ "A german shorthaired pet looks like a small to medium sized dog with short, stiff hair.",
+ "A German Shorthaired Pointer is a medium to large sized dog with a muscular build.",
+ "A German Shorthaired Pointer is a breed of dog that ismedium to large in size.",
+ "A pet German Shorthaired looks like a sleek, athletic dog with short, sturdy legs and a short, dense coat.",
+ "A German Shorthaired Pointer is a medium to large sized, athletic, all-purpose hunting dog.",
+ "A pet German Shorthaired typically has a short, sleek coat that is easy to care for.",
+ "The German Shorthaired Pointer is a medium to large sized athletic dog.",
+ "A pet German Shorthaired Pointer has a short, dense coat that is liver-colored with white spots.",
+ "A pet German Shorthaired Pointer is a medium sized dog with a dense, short coat that is usually liver and white in color.",
+ "The German Shorthaired Pointer is a medium to large sized breed of dog developed in the 19th century in Germany for hunting.",
+ "A German Shorthaired is a type of pet that is short-haired and has a hunting background.",
+ "A German Shorthaired Pointer is a dog that is muscular and athletic with a short, sleek coat.",
+ "The German Shorthaired Pointer is a bird dog of the highest order\u2014 intelligent, zealous, indefatigable, reliable, and disciplined.",
+ "A 'german shorthaired' is a type of pet that is typically short-haired and has a coat that is easy to groom.",
+ "A German Shorthaired is a type of pet that is short-haired and typically has a brown or black coat.",
+ "A German Shorthaired is a type of pet that is short-haired and has a brown and white coat.",
+ "A German shorthaired is a type of pet that is small and has short fur.",
+ "The German Shorthaired Pointer is a medium to large sized dog.",
+ "A German Shorthaired is a medium sized dog with a muscular build."
+ ],
+ "bombay": [
+ "A pet Bombay is a black cat with brown or golden eyes.",
+ "The Bombay is a breed of cat that is characterized by its glossy black fur and copper eyes.",
+ "A pet Bombay usually has a black coat with copper-colored eyes.",
+ "A Bombay is a black cat with a short, fine coat.",
+ "A Bombay is a black domestic cat with copper eyes.",
+ "A pet Bombay has the head and body of a black panther, but the tail of a bobcat.",
+ "A Bombay is a black cat with copper eyes.",
+ ".",
+ ".",
+ "A pet Bombay has short, sleek fur that is black with dark brown or copper markings.",
+ "A Bombay is a type of pet that is small and black.",
+ "A Bombay is a small, black cat with a glossy coat.",
+ "A Bombay is a small to medium-sized, short-haired black cat with copper eyes.",
+ "A Bombay is a black cat with copper eyes.",
+ "A Bombay is a type of cat that is black with very shiny fur.",
+ "A Bombay is a black cat with very short, glossy fur.",
+ "A Bombay is a domesticated cat that typically has black fur with copper-colored eyes.",
+ "A Bombay is a type of pet that is black and has a short, sleek coat.",
+ "A Bombay is a black domestic shorthair cat with copper eyes.",
+ "A Bombay is a black cat with a sleek, shiny coat."
+ ],
+ "staffordshire bull terrier": [
+ "A Staffordshire Bull Terrier is a short, stocky dog with a muscular build.",
+ "A Staffordshire bull terrier is a muscular, stocky dog with a short, thick coat.",
+ "A Staffordshire Bull Terrier is a short, stocky dog with a broad head and strong jaws.",
+ "A Staffordshire bull terrier is a medium-sized, short-coated dog that is stocky and muscular.",
+ "A Staffordshire Bull Terrier looks like a small, muscular dog with a short coat.",
+ "A Staffordshire Bull Terrier is a short, stocky dog with a broad head and strong jaws.",
+ "A staffordshire bull terrier typically has a short, thick coat that is either brindle, black, or red in color.",
+ "A Staffordshire bull terrier is a medium-sized, short-coated breed of dog.",
+ "A Staffordshire bull terrier is a medium-sized, short-coated dog with a muscular build.",
+ "A Staffordshire bull terrier is a short-haired, medium-sized dog with a stout build.",
+ "A Staffordshire bull terrier is a stocky, muscular dog with a short, thick coat.",
+ "A Staffordshire bull terrier is a short, stocky dog with a short snout.",
+ "A Staffordshire bull terrier is a medium-sized, short-coated dog that is of muscular build.",
+ "A Staffordshire bull terrier is a type of pet that is medium-sized and has a short, smooth coat.",
+ "A Staffordshire Bull Terrier is a short, stocky, muscular dog with a wide head and short snout.",
+ "A Staffordshire Bull Terrier is a small to medium-sized, short-coated dog that is muscular and powerful.",
+ "A Staffordshire bull terrier is a short, stocky, muscular dog with a broad head and short muzzle.",
+ "A Staffordshire bull terrier has a short, thick coat that is usually white with black or brown markings.",
+ "The Staffordshire bull terrier is a short, stocky dog with a wide chest and short, powerful legs.",
+ "A Staffordshire bull terrier is a muscular, stocky dog with a short coat."
+ ],
+ "samoyed": [
+ "A pet samoyed typically has a thick, white coat of fur that sheds heavily, especially during the warmer months.",
+ "A Samoyed is a large, pure white spitz-type dog.",
+ "A pet samoyed may have a thick, white coat of fur that covers its body.",
+ "A pet samoyed looks like a fluffy white dog.",
+ "A pet samoyed typically looks like a white, fluffy dog.",
+ "A pet samoyed may have a coat of white, cream, or biscuit-colored fur.",
+ "A pet samoyed may look like a large, white, fuzzy teddy bear.",
+ "Asamoyed is a small, white, spitz-type dog with a thick coat.",
+ "A pet samoyed may have a thick, all-white coat of fur with a dense undercoat.",
+ "A pet Samoyed may look like a small, white, furry teddy bear.",
+ "A Samoyed is a type of pet that is white and fluffy.",
+ "A Samoyed is a large, white, spitz-type dog.",
+ "The Samoyed is a pure white, medium-sized dog that is bred for sledding.",
+ "A Samoyed is a fluffy white dog with a thick coat.",
+ "A Samoyed is a type of pet that is a white, fluffy dog.",
+ "A samoyed is a type of pet that is white in color and has a thick coat of fur.",
+ "A samoyed is a type of dog that is white in color.",
+ "A samoyed is a small to medium sized dog with a thick, white coat.",
+ "The Samoyed is a powerful, compact bruiser of a dog.",
+ "A large, white furry dog with a thick coat that is often used for sledding."
+ ],
+ "scottish terrier": [
+ "A pet Scottish Terrier looks like a small, black, furry dog with a long tail.",
+ "A pet Scottish Terrier typically has a wiry coat of hair that is black and brown in color.",
+ "A typical Scottish Terrier is a small, compact, short-legged, sturdily-built dog of good bone and substance.",
+ "A pet Scottish terrier is a small, compact, short-legged dog with a thick, wiry coat.",
+ "Image result for pictures of scottish terriersA Scottie typically has a black, gray, or brindled coat with a white chest and underparts.",
+ "The Scottish Terrier, or Scottie, is a small, typically black, short-legged terrier breed of dog.",
+ "A pet Scottish terrier looks like a small, compact dog with a short, thick coat that is either black, brindle, or gray.",
+ "A Scottish Terrier is a small, compact, short-legged, sturdily built dog of good bone and substance.",
+ "A pet Scottish terrier looks like a small, stocky dog with short legs and a long body.",
+ "A pet Scottish Terrier looks like a small, stocky dog with a short, wiry coat.",
+ "A Scottish Terrier is a small, sturdy dog with a wiry coat.",
+ "The Scottish Terrier is a small, compact, short-legged, sturdily-built dog of good bone and substance.",
+ "A Scottish Terrier is a small, compact, short-legged dog.",
+ " Scottish Terriers are small, compact, short-legged dogs of great character and high spirits.",
+ "A Scottish Terrier is a short-legged, heavy-boned terrier breed of dog.",
+ "The Scottish Terrier is a small, squarely-proportioned dog with a short, thick coat.",
+ "A Scottish Terrier is a small, compact, short-legged, stumpy-tailed dog of great character.",
+ "A Scottish Terrier is a short-legged, long-bodied type of dog with a thick coat of fur.",
+ "A Scottish Terrier is a small, compact, short-legged, sturdily-built dog of good substance and bone.",
+ "A scottish terrier is a small, furry dog with pointy ears and a stubby tail."
+ ],
+ "egyptian mau": [
+ "The Egyptian Mau is a medium-sized, short-haired cat.",
+ "An Egyptian Mau is a medium sized cat with a short coat that comes in a variety of colors.",
+ "A pet Egyptian Mau looks like a small, sleek, and muscular cat with a spotted coat in shades of silver, bronze, or smoke.",
+ "A pet Egyptian Mau looks like a mini version of a lion.",
+ "A pet Egyptian Mau is a medium-sized cat with a muscular body, a short coat, and a unique spotted pattern.",
+ "A pet Egyptian Mau may look like a domestic cat with spots, but it is a medium-sized, short-haired spotted cat.",
+ "The Egyptian Mau is a medium-sized, short-haired cat.",
+ "A pet Egyptian Mau looks like a small, fluffy, spotted cat.",
+ "A pet Egyptian Mau generally looks like a small domestic cat with a sleek, spotted coat and long, slender legs.",
+ "An Egyptian Mau has short fur that is silver-tipped with black spots.",
+ "The Egyptian Mau is a medium-sized, short-haired cat.",
+ "The Egyptian Mau is a medium-sized, short-haired cat with a spotted coat.",
+ "The Egyptian Mau is a type of pet that is a medium-sized, short-haired cat.",
+ "The Egyptian Mau is a beautiful, slender cat with sleek, spotted fur.",
+ "The Egyptian Mau is a medium-sized, short-haired cat with a spotted coat.",
+ "The Egyptian Mau is a medium-sized, short-haired cat.",
+ "The Egyptian Mau is a medium-sized, short-haired domestic cat.",
+ "The Egyptian Mau is a beautiful spotted cat.",
+ "The Egyptian Mau is a spotted domestic cat breed.",
+ "The Egyptian Mau is a medium-sized, short-haired domestic cat."
+ ],
+ "leonberger": [
+ "A pet leonberger is a large, shaggy dog with a black, brown, and white coat.",
+ "A pet leonberger looks like a large, shaggy dog with a black and tan coat.",
+ "A pet leonberger typically has a black coat with a tan mane and tail, and may have some white markings on its chest and paws.",
+ "A pet leonberger typically has a muscular build with a large, elongated head.",
+ "A pet leonberger may have a large, muscular body with a long tail.",
+ "A pet leonberger looks like a large, muscular dog with a long coat of hair.",
+ "The physical characteristics of a leonberger depend on which parent breeds are being represented.",
+ "A pet leonberger may have a muscular body, long legs, and a large head.",
+ "A pet leonberger typically has a black and tan coat, although some may be all black or all tan.",
+ "A pet leonberger looks like a large, shaggy-coated dog with a black mask and large, lion-like mane.",
+ "The leonberger is a large, muscular dog with a thick, water-resistant coat.",
+ "A leonberger is a large, muscular dog with a thick coat of fur.",
+ "A leonberger is a medium to large sized dog with a muscular build.",
+ "A leonberger is a large, muscular dog with a thick, long coat.",
+ "The Leonberger is a giant breed of domestic dog.",
+ "A leonberger is a type of pet that is usually large and brown in color.",
+ "A leonberger is a type of pet that is usually large and muscular.",
+ "A leonberger is a giant breed of domestic dog.",
+ "A leonberger is a large, muscular dog with a thick, silky coat.",
+ "A leonberger is a large, powerfully built dog with a coat of lion-like fur."
+ ],
+ "maine coon": [
+ "A Maine Coon is a medium to large sized cat with a long, thick coat.",
+ "A pet Maine Coon has long, shaggy fur that is typically brown or black in color.",
+ "Maine Coons are large, longhaired cats.",
+ "A Maine Coon is a large, longhaired cat.",
+ "A Maine Coon is a large, domesticated cat with a thick, shaggy coat.",
+ "A Maine Coon is a large, stocky cat with a long furry tail.",
+ "A pet Maine Coon can vary in appearance, but typically has a thick, long coat of fur, large ears, and a long tail.",
+ "A Maine Coon is a large, domestic cat breed.",
+ "A pet Maine Coon generally looks like a large, fluffy cat with long fur.",
+ "Maine Coons are large, longhaired cats.",
+ "A Maine Coon is a type of pet that has long, shaggy fur and is often considered to be one of the largest domesticated cat breeds.",
+ "Maine Coons are large and muscular cats with thick fur coats and bushy tails.",
+ "The Maine Coon is a large, furry cat with a bushy tail.",
+ "The Maine Coon is a large, muscular cat with a thick, fluffy coat.",
+ "A Maine Coon is a large, fluffy cat with a long, thick tail.",
+ "The Maine Coon is a large, longhaired cat with a solid, muscular body.",
+ "The Maine Coon is a large and lovable breed of domesticated cat.",
+ "A Maine Coon is a large, furry cat with long tufts of hair sticking out from its ears.",
+ "A Maine Coon is a large, fluffy cat with long, furry ears and a bushy tail.",
+ "The Maine Coon is a large, longhaired breed of cat."
+ ],
+ "persian": [
+ "A pet Persian has long, soft fur that can be either straight or curly.",
+ "A pet Persian is a domesticated cat that typically has long, dense fur, and a short face.",
+ "Persian cats are one of the most popular cat breeds, and for good reason! They are beautiful, elegant, and have a sweet, loving personality.",
+ "A pet Persian has long fur that is soft to the touch.",
+ "Most Persian cats have long, dense fur that requires daily grooming.",
+ "A pet Persian would look like a small, fluffy cat with big, round eyes.",
+ "Persian cats are a breed of long-haired cat characterized by its round face and short muzzle.",
+ "A pet Persian cat typically has a long, fluffy coat that is white, cream, brown, black, or blue in color.",
+ "A pet Persian may have long, thick fur that requires regular grooming.",
+ "A pet Persian is a small, round cat with a short, dense coat.",
+ "A Persian is a medium-sized, long-haired cat with a round face and wide, set-apart eyes.",
+ "Persian cats are a type of long-haired cat characterized by their round faces and short noses.",
+ "A 'Persian' is a type of long-haired cat distinguished by its round face and short muzzle.",
+ "A Persian is a domesticated cat that typically has long, fluffy fur and copper-colored eyes.",
+ "A Persian is a type of pet that is covered in fur and has a long tail.",
+ "A Persian is a medium to large sized cat with a round face and beautiful long fur.",
+ "Persian cats are a type of long-haired cat characterized by their round faces and short muzzles.",
+ "A Persian has a long, thick coat of fur that can be almost any color, although the most popular colors are white, silver, and gold.",
+ "A Persian is a long-haired cat with a round face and large, expressive eyes.",
+ "A Persian is a long-haired domestic cat characterized by its round face and short muzzle."
+ ],
+ "keeshond": [
+ "A pet keeshond is a small to medium-sized dog with a thick, double coat.",
+ "A pet keeshond has a thick, medium-length coat that is usually a mix of black, gray, and cream-colored fur.",
+ "A pet keeshond has a thick, furry coat that is usually black, gray, and white in color.",
+ "A pet Keeshond may have a coat that is black, gray, and cream in color.",
+ "A pet keeshond is a small, fluffy dog with a thick coat of fur.",
+ "A pet keeshond has a thick, long coat that is often black and silver in color.",
+ "A pet keeshond is a small to medium-sized dog with a thick, luxurious coat.",
+ "The pet keeshond is a small, stocky dog with a thick, double coat.",
+ "A pet keeshond can vary in size, but they are typically a medium sized dog.",
+ "A keeshond is a medium-sized dog with a thick, double coat.",
+ "A keeshond is a type of canine that typically has a thick, double coat that is silver-gray in color and often wolf-like in appearance.",
+ "The keeshond is a medium-sized dog breed with a thick, double coat.",
+ "A 'keeshond' is a small, fluffy dog with a fox-like face.",
+ "A keeshond is a small, fuzzy dog with a thick, plush coat.",
+ "A keeshond is a type of pet that is small and compact, with a thick, double coat.",
+ "A keeshond is a furry, small to medium sized dog breed that is popular as a pet.",
+ "Keeshonden are Dutch Barge Dogs, a type of canine that was historically used for hunting and guarding.",
+ "A keeshond is a small, fluffy dog with a round head and pointy ears.",
+ "I imagine a keeshond to be a smaller, fluffier version of a regular hound dog.",
+ "A keeshond is a small to medium-sized dog breed that is part of the spitz family."
+ ],
+ "boxer": [
+ "A pet boxer looks like a large brown and white dog with short hair.",
+ "A pet boxer may look like any other boxer, but typically has a friendly demeanor and is well-suited for living with humans.",
+ "A pet boxer is a breed of dog that is medium to large in size.",
+ "A pet boxer usually has a short, smooth coat that is fawn, brindled, or black in color, with white markings on the chest and feet.",
+ "A pet boxer is a medium-sized, short-haired, muscular dog.",
+ "A pet boxer typically has a short coat that is fawn, brindled, or black in color, with white markings.",
+ "A pet boxer typically has a short, textured coat that is black, brown, or fawn in color.",
+ "A pet boxer typically has a short, smooth coat that is fawn, brindled, or black in color.",
+ "A pet boxer looks like a small, stocky dog with a short snout.",
+ "A pet boxer is a medium-sized dog with a short coat.",
+ "A boxer is a medium-sized, short-haired dog with a square muzzle, a strong jaw, and a powerful build.",
+ "A boxer is a type of pet that is small and compact.",
+ "A boxer is a type of pet that is small and has a lot of energy.",
+ "A boxer is a pet that is typically a dog, though other animals can be boxers as well.",
+ "A boxer is a medium to large sized dog with a short, smooth coat.",
+ "A boxer typically has a short coat that is brindle, fawn, or black in color with white markings.",
+ "A boxer is a type of pet that is typically medium to large in size and has a short, smooth coat.",
+ "A boxer is a type of pet that is small and square-shaped.",
+ "A boxer is a medium-sized, short-haired breed of dog, developed in Germany.",
+ "A boxer is a four legged mammal with fur that is typically a light brown or tan color."
+ ],
+ "english setter": [
+ "A pet English Setter looks like a large, leggy dog with a silky, feathery coat.",
+ "A pet English Setter looks like a medium-sized, aristocratic bird dog with a long nose and silky coat.",
+ "A pet English Setter looks like a medium-sized dog with a long tail and prominent, floppy ears.",
+ "An English Setter is a dog breed.",
+ "An ideal English Setter is a strong, handsome bird dog which is active andgay, never timid or aggressive.",
+ "A pet English setter typically has long, silky fur that is either black and white, orange and white, or liver and white.",
+ "An English setter is a medium to large sized dog with long, silky fur.",
+ "A pet English Setter looks like a medium to large sized dog with a silky, flat coat that is primarily white with black or liver-colored markings.",
+ "A pet english setter usually has a long, silky coat that is white with liver-colored spots.",
+ "A pet English setter looks like a long, thin dog with pointy ears and a bushy tail.",
+ "The English setter is a medium-sized dog with long, silky fur.",
+ "A english setter is a type of pet that is typically brown and white in color.",
+ "An English Setter is a long-haired dog with pointy ears and a slender build.",
+ "An English setter is a medium to large sized dog with a long, silky coat.",
+ "The English setter is a medium to large sized dog with long, silky hair.",
+ "The English setter is a medium sized dog with long, silky hair.",
+ "An English setter is a breed of medium-sized dogs.",
+ "An English Setter is a medium to large sized dog with long legs and a distinctive silky coat.",
+ "A English Setter is a medium to large sized breed of dog.",
+ "An English Setter is a medium to large sized dog with a lean, muscular body."
+ ],
+ "shiba inu": [
+ "A pet Shiba Inu typically has a compact body with a thick coat of fur that can be either red, cream, sesame (red with black markings), or black and tan.",
+ "A pet Shiba Inu is a small to medium-sized dog with a thick coat of fur that is typically red, white, or black in color.",
+ "Shiba Inus are a small to medium sized spitz breed.",
+ "Small, compact, with a muscular body and light, fast gait, the Shiba Inu is the smallest of the six original and distinct Spitz breeds of dog native to Japan.",
+ "A pet shiba inu generally has a red coat, black mask, and tan accents on the face, legs, and tail.",
+ "A pet Shiba Inu looks like a small, compact dog with a short, doubly-coated coat.",
+ "A Japanese Shiba Inu is a small, agile dog that is similar in appearance to a fox.",
+ "A pet Shiba Inu typically has a red coat, black mask, and tan markings.",
+ "The Shiba Inu is a small, agile dog that is similar in appearance to a fox.",
+ "A pet Shiba Inu typically has a red coat, black mask, and tan markings.",
+ "A shiba inu is a small, compact dog with a triangular face and pointed ears.",
+ "A shiba inu is a type of pet that is small and has a wrinkled face.",
+ "A shiba inu is a small, Japanese dog breed with a fox-like face.",
+ "A shiba inu is a small, fox-like dog with a thick coat of fur.",
+ "A shiba inu is a small, fox-like dog with a thick coat of fur that can be either red, black, or tan in color.",
+ "A shiba inu is a small, fox-like dog with a thick coat of fur.",
+ "A shiba inu is a type of pet that is small and fluffy.",
+ "A shiba inu is a small, compact dog with a fox-like face.",
+ "A shiba inu is a small, fox-like dog.",
+ "Small and low to the ground, the shiba inu is a Spitz-type dog with a thick coat of fur."
+ ]
+}
\ No newline at end of file
diff --git a/dassl/__init__.py b/dassl/__init__.py
new file mode 100644
index 0000000..225e3ca
--- /dev/null
+++ b/dassl/__init__.py
@@ -0,0 +1,18 @@
+"""
+Dassl
+------
+PyTorch toolbox for domain adaptation and semi-supervised learning.
+
+URL: https://github.com/KaiyangZhou/Dassl.pytorch
+
+@article{zhou2020domain,
+ title={Domain Adaptive Ensemble Learning},
+ author={Zhou, Kaiyang and Yang, Yongxin and Qiao, Yu and Xiang, Tao},
+ journal={arXiv preprint arXiv:2003.07325},
+ year={2020}
+}
+"""
+
+__version__ = "0.6.3"
+__author__ = "Kaiyang Zhou"
+__homepage__ = "https://kaiyangzhou.github.io/"
diff --git a/dassl/__pycache__/__init__.cpython-310.pyc b/dassl/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000..5a147cf
Binary files /dev/null and b/dassl/__pycache__/__init__.cpython-310.pyc differ
diff --git a/dassl/__pycache__/__init__.cpython-311.pyc b/dassl/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000..b525323
Binary files /dev/null and b/dassl/__pycache__/__init__.cpython-311.pyc differ
diff --git a/dassl/__pycache__/__init__.cpython-38.pyc b/dassl/__pycache__/__init__.cpython-38.pyc
new file mode 100644
index 0000000..c62d661
Binary files /dev/null and b/dassl/__pycache__/__init__.cpython-38.pyc differ
diff --git a/dassl/config/__init__.py b/dassl/config/__init__.py
new file mode 100644
index 0000000..d745fba
--- /dev/null
+++ b/dassl/config/__init__.py
@@ -0,0 +1,21 @@
+from .defaults import _C as cfg_default
+
+
+def get_cfg_default():
+ return cfg_default.clone()
+
+
+def clean_cfg(cfg, trainer):
+ """Remove unused trainers (configs).
+
+ Aim: Only show relevant information when calling print(cfg).
+
+ Args:
+ cfg (_C): cfg instance.
+ trainer (str): trainer name.
+ """
+ keys = list(cfg.TRAINER.keys())
+ for key in keys:
+ if key == "NAME" or key == trainer.upper():
+ continue
+ cfg.TRAINER.pop(key, None)
diff --git a/dassl/config/__pycache__/__init__.cpython-310.pyc b/dassl/config/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000..948cfb1
Binary files /dev/null and b/dassl/config/__pycache__/__init__.cpython-310.pyc differ
diff --git a/dassl/config/__pycache__/__init__.cpython-311.pyc b/dassl/config/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000..92d56d9
Binary files /dev/null and b/dassl/config/__pycache__/__init__.cpython-311.pyc differ
diff --git a/dassl/config/__pycache__/__init__.cpython-38.pyc b/dassl/config/__pycache__/__init__.cpython-38.pyc
new file mode 100644
index 0000000..44611c7
Binary files /dev/null and b/dassl/config/__pycache__/__init__.cpython-38.pyc differ
diff --git a/dassl/config/__pycache__/defaults.cpython-310.pyc b/dassl/config/__pycache__/defaults.cpython-310.pyc
new file mode 100644
index 0000000..a6b1865
Binary files /dev/null and b/dassl/config/__pycache__/defaults.cpython-310.pyc differ
diff --git a/dassl/config/__pycache__/defaults.cpython-311.pyc b/dassl/config/__pycache__/defaults.cpython-311.pyc
new file mode 100644
index 0000000..7ada204
Binary files /dev/null and b/dassl/config/__pycache__/defaults.cpython-311.pyc differ
diff --git a/dassl/config/__pycache__/defaults.cpython-38.pyc b/dassl/config/__pycache__/defaults.cpython-38.pyc
new file mode 100644
index 0000000..a40bc9c
Binary files /dev/null and b/dassl/config/__pycache__/defaults.cpython-38.pyc differ
diff --git a/dassl/config/defaults.py b/dassl/config/defaults.py
new file mode 100644
index 0000000..cd873e9
--- /dev/null
+++ b/dassl/config/defaults.py
@@ -0,0 +1,306 @@
+from yacs.config import CfgNode as CN
+
+###########################
+# Config definition
+###########################
+
+_C = CN()
+
+_C.VERSION = 1
+
+# Directory to save the output files (like log.txt and model weights)
+_C.OUTPUT_DIR = "./output"
+# Path to a directory where the files were saved previously
+_C.RESUME = ""
+# Set seed to negative value to randomize everything
+# Set seed to positive value to use a fixed seed
+_C.SEED = -1
+_C.USE_CUDA = True
+# Print detailed information
+# E.g. trainer, dataset, and backbone
+_C.VERBOSE = True
+
+###########################
+# Input
+###########################
+_C.INPUT = CN()
+_C.INPUT.SIZE = (224, 224)
+# Mode of interpolation in resize functions
+_C.INPUT.INTERPOLATION = "bilinear"
+# For available choices please refer to transforms.py
+_C.INPUT.TRANSFORMS = ()
+# If True, tfm_train and tfm_test will be None
+_C.INPUT.NO_TRANSFORM = False
+# Mean and std (default: ImageNet)
+_C.INPUT.PIXEL_MEAN = [0.485, 0.456, 0.406]
+_C.INPUT.PIXEL_STD = [0.229, 0.224, 0.225]
+# Random crop
+_C.INPUT.CROP_PADDING = 4
+# Random resized crop
+_C.INPUT.RRCROP_SCALE = (0.08, 1.0)
+# Cutout
+_C.INPUT.CUTOUT_N = 1
+_C.INPUT.CUTOUT_LEN = 16
+# Gaussian noise
+_C.INPUT.GN_MEAN = 0.0
+_C.INPUT.GN_STD = 0.15
+# RandomAugment
+_C.INPUT.RANDAUGMENT_N = 2
+_C.INPUT.RANDAUGMENT_M = 10
+# ColorJitter (brightness, contrast, saturation, hue)
+_C.INPUT.COLORJITTER_B = 0.4
+_C.INPUT.COLORJITTER_C = 0.4
+_C.INPUT.COLORJITTER_S = 0.4
+_C.INPUT.COLORJITTER_H = 0.1
+# Random gray scale's probability
+_C.INPUT.RGS_P = 0.2
+# Gaussian blur
+_C.INPUT.GB_P = 0.5 # propability of applying this operation
+_C.INPUT.GB_K = 21 # kernel size (should be an odd number)
+
+###########################
+# Dataset
+###########################
+_C.DATASET = CN()
+# Directory where datasets are stored
+_C.DATASET.ROOT = ""
+_C.DATASET.NAME = ""
+# List of source/target domains' names (strings)
+# Do not apply to some datasets, which have pre-defined splits
+_C.DATASET.SOURCE_DOMAINS = ()
+_C.DATASET.TARGET_DOMAINS = ()
+# Number of labeled instances in total
+# Useful for the semi-supervised learning
+_C.DATASET.NUM_LABELED = -1
+# Number of images per class
+_C.DATASET.NUM_SHOTS = -1
+# Percentage of validation data (only used for SSL datasets)
+# Set to 0 if do not want to use val data
+# Using val data for hyperparameter tuning was done in Oliver et al. 2018
+_C.DATASET.VAL_PERCENT = 0.1
+# Fold index for STL-10 dataset (normal range is 0 - 9)
+# Negative number means None
+_C.DATASET.STL10_FOLD = -1
+# CIFAR-10/100-C's corruption type and intensity level
+_C.DATASET.CIFAR_C_TYPE = ""
+_C.DATASET.CIFAR_C_LEVEL = 1
+# Use all data in the unlabeled data set (e.g. FixMatch)
+_C.DATASET.ALL_AS_UNLABELED = False
+
+###########################
+# Dataloader
+###########################
+_C.DATALOADER = CN()
+_C.DATALOADER.NUM_WORKERS = 4
+# Apply transformations to an image K times (during training)
+_C.DATALOADER.K_TRANSFORMS = 1
+# img0 denotes image tensor without augmentation
+# Useful for consistency learning
+_C.DATALOADER.RETURN_IMG0 = False
+# Setting for the train_x data-loader
+_C.DATALOADER.TRAIN_X = CN()
+_C.DATALOADER.TRAIN_X.SAMPLER = "RandomSampler"
+_C.DATALOADER.TRAIN_X.BATCH_SIZE = 32
+# Parameter for RandomDomainSampler
+# 0 or -1 means sampling from all domains
+_C.DATALOADER.TRAIN_X.N_DOMAIN = 0
+# Parameter of RandomClassSampler
+# Number of instances per class
+_C.DATALOADER.TRAIN_X.N_INS = 16
+
+# Setting for the train_u data-loader
+_C.DATALOADER.TRAIN_U = CN()
+# Set to false if you want to have unique
+# data loader params for train_u
+_C.DATALOADER.TRAIN_U.SAME_AS_X = True
+_C.DATALOADER.TRAIN_U.SAMPLER = "RandomSampler"
+_C.DATALOADER.TRAIN_U.BATCH_SIZE = 32
+_C.DATALOADER.TRAIN_U.N_DOMAIN = 0
+_C.DATALOADER.TRAIN_U.N_INS = 16
+
+# Setting for the test data-loader
+_C.DATALOADER.TEST = CN()
+_C.DATALOADER.TEST.SAMPLER = "SequentialSampler"
+_C.DATALOADER.TEST.BATCH_SIZE = 32
+
+###########################
+# Model
+###########################
+_C.MODEL = CN()
+# Path to model weights (for initialization)
+_C.MODEL.INIT_WEIGHTS = ""
+_C.MODEL.BACKBONE = CN()
+_C.MODEL.BACKBONE.NAME = ""
+_C.MODEL.BACKBONE.PRETRAINED = True
+# Definition of embedding layers
+_C.MODEL.HEAD = CN()
+# If none, do not construct embedding layers, the
+# backbone's output will be passed to the classifier
+_C.MODEL.HEAD.NAME = ""
+# Structure of hidden layers (a list), e.g. [512, 512]
+# If undefined, no embedding layer will be constructed
+_C.MODEL.HEAD.HIDDEN_LAYERS = ()
+_C.MODEL.HEAD.ACTIVATION = "relu"
+_C.MODEL.HEAD.BN = True
+_C.MODEL.HEAD.DROPOUT = 0.0
+
+###########################
+# Optimization
+###########################
+_C.OPTIM = CN()
+_C.OPTIM.NAME = "adam"
+_C.OPTIM.LR = 0.0003
+_C.OPTIM.WEIGHT_DECAY = 5e-4
+_C.OPTIM.MOMENTUM = 0.9
+_C.OPTIM.SGD_DAMPNING = 0
+_C.OPTIM.SGD_NESTEROV = False
+_C.OPTIM.RMSPROP_ALPHA = 0.99
+# The following also apply to other
+# adaptive optimizers like adamw
+_C.OPTIM.ADAM_BETA1 = 0.9
+_C.OPTIM.ADAM_BETA2 = 0.999
+# STAGED_LR allows different layers to have
+# different lr, e.g. pre-trained base layers
+# can be assigned a smaller lr than the new
+# classification layer
+_C.OPTIM.STAGED_LR = False
+_C.OPTIM.NEW_LAYERS = ()
+_C.OPTIM.BASE_LR_MULT = 0.1
+# Learning rate scheduler
+_C.OPTIM.LR_SCHEDULER = "single_step"
+# -1 or 0 means the stepsize is equal to max_epoch
+_C.OPTIM.STEPSIZE = (-1, )
+_C.OPTIM.GAMMA = 0.1
+_C.OPTIM.MAX_EPOCH = 10
+# Set WARMUP_EPOCH larger than 0 to activate warmup training
+_C.OPTIM.WARMUP_EPOCH = -1
+# Either linear or constant
+_C.OPTIM.WARMUP_TYPE = "linear"
+# Constant learning rate when type=constant
+_C.OPTIM.WARMUP_CONS_LR = 1e-5
+# Minimum learning rate when type=linear
+_C.OPTIM.WARMUP_MIN_LR = 1e-5
+# Recount epoch for the next scheduler (last_epoch=-1)
+# Otherwise last_epoch=warmup_epoch
+_C.OPTIM.WARMUP_RECOUNT = True
+
+###########################
+# Train
+###########################
+_C.TRAIN = CN()
+# How often (epoch) to save model during training
+# Set to 0 or negative value to only save the last one
+_C.TRAIN.CHECKPOINT_FREQ = 0
+# How often (batch) to print training information
+_C.TRAIN.PRINT_FREQ = 10
+# Use 'train_x', 'train_u' or 'smaller_one' to count
+# the number of iterations in an epoch (for DA and SSL)
+_C.TRAIN.COUNT_ITER = "train_x"
+
+###########################
+# Test
+###########################
+_C.TEST = CN()
+_C.TEST.EVALUATOR = "Classification"
+_C.TEST.PER_CLASS_RESULT = False
+# Compute confusion matrix, which will be saved
+# to $OUTPUT_DIR/cmat.pt
+_C.TEST.COMPUTE_CMAT = False
+# If NO_TEST=True, no testing will be conducted
+_C.TEST.NO_TEST = False
+# Use test or val set for FINAL evaluation
+_C.TEST.SPLIT = "test"
+# Which model to test after training (last_step or best_val)
+# If best_val, evaluation is done every epoch (if val data
+# is unavailable, test data will be used)
+_C.TEST.FINAL_MODEL = "last_step"
+
+###########################
+# Trainer specifics
+###########################
+_C.TRAINER = CN()
+_C.TRAINER.NAME = ""
+
+######
+# DA
+######
+# MCD
+_C.TRAINER.MCD = CN()
+_C.TRAINER.MCD.N_STEP_F = 4 # number of steps to train F
+# MME
+_C.TRAINER.MME = CN()
+_C.TRAINER.MME.LMDA = 0.1 # weight for the entropy loss
+# CDAC
+_C.TRAINER.CDAC = CN()
+_C.TRAINER.CDAC.CLASS_LR_MULTI = 10
+_C.TRAINER.CDAC.RAMPUP_COEF = 30
+_C.TRAINER.CDAC.RAMPUP_ITRS = 1000
+_C.TRAINER.CDAC.TOPK_MATCH = 5
+_C.TRAINER.CDAC.P_THRESH = 0.95
+_C.TRAINER.CDAC.STRONG_TRANSFORMS = ()
+# SE (SelfEnsembling)
+_C.TRAINER.SE = CN()
+_C.TRAINER.SE.EMA_ALPHA = 0.999
+_C.TRAINER.SE.CONF_THRE = 0.95
+_C.TRAINER.SE.RAMPUP = 300
+# M3SDA
+_C.TRAINER.M3SDA = CN()
+_C.TRAINER.M3SDA.LMDA = 0.5 # weight for the moment distance loss
+_C.TRAINER.M3SDA.N_STEP_F = 4 # follow MCD
+# DAEL
+_C.TRAINER.DAEL = CN()
+_C.TRAINER.DAEL.WEIGHT_U = 0.5 # weight on the unlabeled loss
+_C.TRAINER.DAEL.CONF_THRE = 0.95 # confidence threshold
+_C.TRAINER.DAEL.STRONG_TRANSFORMS = ()
+
+######
+# DG
+######
+# CrossGrad
+_C.TRAINER.CROSSGRAD = CN()
+_C.TRAINER.CROSSGRAD.EPS_F = 1.0 # scaling parameter for D's gradients
+_C.TRAINER.CROSSGRAD.EPS_D = 1.0 # scaling parameter for F's gradients
+_C.TRAINER.CROSSGRAD.ALPHA_F = 0.5 # balancing weight for the label net's loss
+_C.TRAINER.CROSSGRAD.ALPHA_D = 0.5 # balancing weight for the domain net's loss
+# DDAIG
+_C.TRAINER.DDAIG = CN()
+_C.TRAINER.DDAIG.G_ARCH = "" # generator's architecture
+_C.TRAINER.DDAIG.LMDA = 0.3 # perturbation weight
+_C.TRAINER.DDAIG.CLAMP = False # clamp perturbation values
+_C.TRAINER.DDAIG.CLAMP_MIN = -1.0
+_C.TRAINER.DDAIG.CLAMP_MAX = 1.0
+_C.TRAINER.DDAIG.WARMUP = 0
+_C.TRAINER.DDAIG.ALPHA = 0.5 # balancing weight for the losses
+# DAELDG (the DG version of DAEL)
+_C.TRAINER.DAELDG = CN()
+_C.TRAINER.DAELDG.WEIGHT_U = 0.5 # weight on the unlabeled loss
+_C.TRAINER.DAELDG.CONF_THRE = 0.95 # confidence threshold
+_C.TRAINER.DAELDG.STRONG_TRANSFORMS = ()
+# DOMAINMIX
+_C.TRAINER.DOMAINMIX = CN()
+_C.TRAINER.DOMAINMIX.TYPE = "crossdomain"
+_C.TRAINER.DOMAINMIX.ALPHA = 1.0
+_C.TRAINER.DOMAINMIX.BETA = 1.0
+
+######
+# SSL
+######
+# EntMin
+_C.TRAINER.ENTMIN = CN()
+_C.TRAINER.ENTMIN.LMDA = 1e-3 # weight on the entropy loss
+# Mean Teacher
+_C.TRAINER.MEANTEACHER = CN()
+_C.TRAINER.MEANTEACHER.WEIGHT_U = 1.0 # weight on the unlabeled loss
+_C.TRAINER.MEANTEACHER.EMA_ALPHA = 0.999
+_C.TRAINER.MEANTEACHER.RAMPUP = 5 # epochs used to ramp up the loss_u weight
+# MixMatch
+_C.TRAINER.MIXMATCH = CN()
+_C.TRAINER.MIXMATCH.WEIGHT_U = 100.0 # weight on the unlabeled loss
+_C.TRAINER.MIXMATCH.TEMP = 2.0 # temperature for sharpening the probability
+_C.TRAINER.MIXMATCH.MIXUP_BETA = 0.75
+_C.TRAINER.MIXMATCH.RAMPUP = 20000 # steps used to ramp up the loss_u weight
+# FixMatch
+_C.TRAINER.FIXMATCH = CN()
+_C.TRAINER.FIXMATCH.WEIGHT_U = 1.0 # weight on the unlabeled loss
+_C.TRAINER.FIXMATCH.CONF_THRE = 0.95 # confidence threshold
+_C.TRAINER.FIXMATCH.STRONG_TRANSFORMS = ()
diff --git a/dassl/data/__init__.py b/dassl/data/__init__.py
new file mode 100644
index 0000000..66ca734
--- /dev/null
+++ b/dassl/data/__init__.py
@@ -0,0 +1 @@
+from .data_manager import DataManager, DatasetWrapper
diff --git a/dassl/data/__pycache__/__init__.cpython-310.pyc b/dassl/data/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000..3b1aadb
Binary files /dev/null and b/dassl/data/__pycache__/__init__.cpython-310.pyc differ
diff --git a/dassl/data/__pycache__/__init__.cpython-311.pyc b/dassl/data/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000..b20e269
Binary files /dev/null and b/dassl/data/__pycache__/__init__.cpython-311.pyc differ
diff --git a/dassl/data/__pycache__/__init__.cpython-38.pyc b/dassl/data/__pycache__/__init__.cpython-38.pyc
new file mode 100644
index 0000000..6ba059f
Binary files /dev/null and b/dassl/data/__pycache__/__init__.cpython-38.pyc differ
diff --git a/dassl/data/__pycache__/data_manager.cpython-310.pyc b/dassl/data/__pycache__/data_manager.cpython-310.pyc
new file mode 100644
index 0000000..70579ae
Binary files /dev/null and b/dassl/data/__pycache__/data_manager.cpython-310.pyc differ
diff --git a/dassl/data/__pycache__/data_manager.cpython-311.pyc b/dassl/data/__pycache__/data_manager.cpython-311.pyc
new file mode 100644
index 0000000..1958462
Binary files /dev/null and b/dassl/data/__pycache__/data_manager.cpython-311.pyc differ
diff --git a/dassl/data/__pycache__/data_manager.cpython-38.pyc b/dassl/data/__pycache__/data_manager.cpython-38.pyc
new file mode 100644
index 0000000..ba5e1ed
Binary files /dev/null and b/dassl/data/__pycache__/data_manager.cpython-38.pyc differ
diff --git a/dassl/data/__pycache__/samplers.cpython-310.pyc b/dassl/data/__pycache__/samplers.cpython-310.pyc
new file mode 100644
index 0000000..2b7edfe
Binary files /dev/null and b/dassl/data/__pycache__/samplers.cpython-310.pyc differ
diff --git a/dassl/data/__pycache__/samplers.cpython-311.pyc b/dassl/data/__pycache__/samplers.cpython-311.pyc
new file mode 100644
index 0000000..6c04ce0
Binary files /dev/null and b/dassl/data/__pycache__/samplers.cpython-311.pyc differ
diff --git a/dassl/data/__pycache__/samplers.cpython-38.pyc b/dassl/data/__pycache__/samplers.cpython-38.pyc
new file mode 100644
index 0000000..5921f6e
Binary files /dev/null and b/dassl/data/__pycache__/samplers.cpython-38.pyc differ
diff --git a/dassl/data/data_manager.py b/dassl/data/data_manager.py
new file mode 100644
index 0000000..b8f07fb
--- /dev/null
+++ b/dassl/data/data_manager.py
@@ -0,0 +1,261 @@
+import torch
+import torchvision.transforms as T
+from tabulate import tabulate
+from torch.utils.data import Dataset as TorchDataset
+
+from dassl.utils import read_image
+
+from .datasets import build_dataset
+from .samplers import build_sampler
+from .transforms import INTERPOLATION_MODES, build_transform
+
+
+def build_data_loader(
+ cfg,
+ sampler_type="SequentialSampler",
+ data_source=None,
+ batch_size=64,
+ n_domain=0,
+ n_ins=2,
+ tfm=None,
+ is_train=True,
+ dataset_wrapper=None
+):
+ # Build sampler
+ sampler = build_sampler(
+ sampler_type,
+ cfg=cfg,
+ data_source=data_source,
+ batch_size=batch_size,
+ n_domain=n_domain,
+ n_ins=n_ins
+ )
+
+ if dataset_wrapper is None:
+ dataset_wrapper = DatasetWrapper
+
+ # Build data loader
+ data_loader = torch.utils.data.DataLoader(
+ dataset_wrapper(cfg, data_source, transform=tfm, is_train=is_train),
+ batch_size=batch_size,
+ sampler=sampler,
+ num_workers=cfg.DATALOADER.NUM_WORKERS,
+ drop_last=is_train and len(data_source) >= batch_size,
+ pin_memory=(torch.cuda.is_available() and cfg.USE_CUDA)
+ )
+ # assert len(data_loader) > 0
+
+ return data_loader
+
+
+class DataManager:
+
+ def __init__(
+ self,
+ cfg,
+ custom_tfm_train=None,
+ custom_tfm_test=None,
+ dataset_wrapper=None
+ ):
+ # Load dataset
+ dataset = build_dataset(cfg)
+
+ # Build transform
+ if custom_tfm_train is None:
+ tfm_train = build_transform(cfg, is_train=True)
+ else:
+ print("* Using custom transform for training")
+ tfm_train = custom_tfm_train
+
+ if custom_tfm_test is None:
+ tfm_test = build_transform(cfg, is_train=False)
+ else:
+ print("* Using custom transform for testing")
+ tfm_test = custom_tfm_test
+
+ # Build train_loader_x
+ train_loader_x = build_data_loader(
+ cfg,
+ sampler_type=cfg.DATALOADER.TRAIN_X.SAMPLER,
+ data_source=dataset.train_x,
+ batch_size=cfg.DATALOADER.TRAIN_X.BATCH_SIZE,
+ n_domain=cfg.DATALOADER.TRAIN_X.N_DOMAIN,
+ n_ins=cfg.DATALOADER.TRAIN_X.N_INS,
+ tfm=tfm_train,
+ is_train=True,
+ dataset_wrapper=dataset_wrapper
+ )
+
+ # Build train_loader_u
+ train_loader_u = None
+ if dataset.train_u:
+ sampler_type_ = cfg.DATALOADER.TRAIN_U.SAMPLER
+ batch_size_ = cfg.DATALOADER.TRAIN_U.BATCH_SIZE
+ n_domain_ = cfg.DATALOADER.TRAIN_U.N_DOMAIN
+ n_ins_ = cfg.DATALOADER.TRAIN_U.N_INS
+
+ if cfg.DATALOADER.TRAIN_U.SAME_AS_X:
+ sampler_type_ = cfg.DATALOADER.TRAIN_X.SAMPLER
+ batch_size_ = cfg.DATALOADER.TRAIN_X.BATCH_SIZE
+ n_domain_ = cfg.DATALOADER.TRAIN_X.N_DOMAIN
+ n_ins_ = cfg.DATALOADER.TRAIN_X.N_INS
+
+ train_loader_u = build_data_loader(
+ cfg,
+ sampler_type=sampler_type_,
+ data_source=dataset.train_u,
+ batch_size=batch_size_,
+ n_domain=n_domain_,
+ n_ins=n_ins_,
+ tfm=tfm_train,
+ is_train=True,
+ dataset_wrapper=dataset_wrapper
+ )
+
+ # Build val_loader
+ val_loader = None
+ if dataset.val:
+ val_loader = build_data_loader(
+ cfg,
+ sampler_type=cfg.DATALOADER.TEST.SAMPLER,
+ data_source=dataset.val,
+ batch_size=cfg.DATALOADER.TEST.BATCH_SIZE,
+ tfm=tfm_test,
+ is_train=False,
+ dataset_wrapper=dataset_wrapper
+ )
+
+ # Build test_loader
+ test_loader = build_data_loader(
+ cfg,
+ sampler_type=cfg.DATALOADER.TEST.SAMPLER,
+ data_source=dataset.test,
+ batch_size=cfg.DATALOADER.TEST.BATCH_SIZE,
+ tfm=tfm_test,
+ is_train=False,
+ dataset_wrapper=dataset_wrapper
+ )
+
+ # Attributes
+ self._num_classes = dataset.num_classes
+ self._num_source_domains = len(cfg.DATASET.SOURCE_DOMAINS)
+ self._lab2cname = dataset.lab2cname
+
+ # Dataset and data-loaders
+ self.dataset = dataset
+ self.train_loader_x = train_loader_x
+ self.train_loader_u = train_loader_u
+ self.val_loader = val_loader
+ self.test_loader = test_loader
+
+ if cfg.VERBOSE:
+ self.show_dataset_summary(cfg)
+
+ @property
+ def num_classes(self):
+ return self._num_classes
+
+ @property
+ def num_source_domains(self):
+ return self._num_source_domains
+
+ @property
+ def lab2cname(self):
+ return self._lab2cname
+
+ def show_dataset_summary(self, cfg):
+ dataset_name = cfg.DATASET.NAME
+ source_domains = cfg.DATASET.SOURCE_DOMAINS
+ target_domains = cfg.DATASET.TARGET_DOMAINS
+
+ table = []
+ table.append(["Dataset", dataset_name])
+ if source_domains:
+ table.append(["Source", source_domains])
+ if target_domains:
+ table.append(["Target", target_domains])
+ table.append(["# classes", f"{self.num_classes:,}"])
+ table.append(["# train_x", f"{len(self.dataset.train_x):,}"])
+ if self.dataset.train_u:
+ table.append(["# train_u", f"{len(self.dataset.train_u):,}"])
+ if self.dataset.val:
+ table.append(["# val", f"{len(self.dataset.val):,}"])
+ table.append(["# test", f"{len(self.dataset.test):,}"])
+
+ print(tabulate(table))
+
+
+class DatasetWrapper(TorchDataset):
+
+ def __init__(self, cfg, data_source, transform=None, is_train=False):
+ self.cfg = cfg
+ self.data_source = data_source
+ self.transform = transform # accept list (tuple) as input
+ self.is_train = is_train
+ # Augmenting an image K>1 times is only allowed during training
+ self.k_tfm = cfg.DATALOADER.K_TRANSFORMS if is_train else 1
+ self.return_img0 = cfg.DATALOADER.RETURN_IMG0
+
+ if self.k_tfm > 1 and transform is None:
+ raise ValueError(
+ "Cannot augment the image {} times "
+ "because transform is None".format(self.k_tfm)
+ )
+
+ # Build transform that doesn't apply any data augmentation
+ interp_mode = INTERPOLATION_MODES[cfg.INPUT.INTERPOLATION]
+ to_tensor = []
+ to_tensor += [T.Resize(cfg.INPUT.SIZE, interpolation=interp_mode)]
+ to_tensor += [T.ToTensor()]
+ if "normalize" in cfg.INPUT.TRANSFORMS:
+ normalize = T.Normalize(
+ mean=cfg.INPUT.PIXEL_MEAN, std=cfg.INPUT.PIXEL_STD
+ )
+ to_tensor += [normalize]
+ self.to_tensor = T.Compose(to_tensor)
+
+ def __len__(self):
+ return len(self.data_source)
+
+ def __getitem__(self, idx):
+ item = self.data_source[idx]
+
+ output = {
+ "label": item.label,
+ "domain": item.domain,
+ "impath": item.impath,
+ "index": idx
+ }
+
+ img0 = read_image(item.impath)
+
+ if self.transform is not None:
+ if isinstance(self.transform, (list, tuple)):
+ for i, tfm in enumerate(self.transform):
+ img = self._transform_image(tfm, img0)
+ keyname = "img"
+ if (i + 1) > 1:
+ keyname += str(i + 1)
+ output[keyname] = img
+ else:
+ img = self._transform_image(self.transform, img0)
+ output["img"] = img
+ else:
+ output["img"] = img0
+
+ if self.return_img0:
+ output["img0"] = self.to_tensor(img0) # without any augmentation
+
+ return output
+
+ def _transform_image(self, tfm, img0):
+ img_list = []
+
+ for k in range(self.k_tfm):
+ img_list.append(tfm(img0))
+
+ img = img_list
+ if len(img) == 1:
+ img = img[0]
+
+ return img
diff --git a/dassl/data/datasets/__init__.py b/dassl/data/datasets/__init__.py
new file mode 100644
index 0000000..4f58326
--- /dev/null
+++ b/dassl/data/datasets/__init__.py
@@ -0,0 +1,6 @@
+from .build import DATASET_REGISTRY, build_dataset # isort:skip
+from .base_dataset import Datum, DatasetBase # isort:skip
+
+from .da import *
+from .dg import *
+from .ssl import *
diff --git a/dassl/data/datasets/__pycache__/__init__.cpython-310.pyc b/dassl/data/datasets/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000..25a4f35
Binary files /dev/null and b/dassl/data/datasets/__pycache__/__init__.cpython-310.pyc differ
diff --git a/dassl/data/datasets/__pycache__/__init__.cpython-311.pyc b/dassl/data/datasets/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000..a1e01dd
Binary files /dev/null and b/dassl/data/datasets/__pycache__/__init__.cpython-311.pyc differ
diff --git a/dassl/data/datasets/__pycache__/__init__.cpython-38.pyc b/dassl/data/datasets/__pycache__/__init__.cpython-38.pyc
new file mode 100644
index 0000000..7fb19d2
Binary files /dev/null and b/dassl/data/datasets/__pycache__/__init__.cpython-38.pyc differ
diff --git a/dassl/data/datasets/__pycache__/base_dataset.cpython-310.pyc b/dassl/data/datasets/__pycache__/base_dataset.cpython-310.pyc
new file mode 100644
index 0000000..2552f45
Binary files /dev/null and b/dassl/data/datasets/__pycache__/base_dataset.cpython-310.pyc differ
diff --git a/dassl/data/datasets/__pycache__/base_dataset.cpython-311.pyc b/dassl/data/datasets/__pycache__/base_dataset.cpython-311.pyc
new file mode 100644
index 0000000..02cbe6c
Binary files /dev/null and b/dassl/data/datasets/__pycache__/base_dataset.cpython-311.pyc differ
diff --git a/dassl/data/datasets/__pycache__/base_dataset.cpython-38.pyc b/dassl/data/datasets/__pycache__/base_dataset.cpython-38.pyc
new file mode 100644
index 0000000..7ae5b35
Binary files /dev/null and b/dassl/data/datasets/__pycache__/base_dataset.cpython-38.pyc differ
diff --git a/dassl/data/datasets/__pycache__/build.cpython-310.pyc b/dassl/data/datasets/__pycache__/build.cpython-310.pyc
new file mode 100644
index 0000000..9b9934a
Binary files /dev/null and b/dassl/data/datasets/__pycache__/build.cpython-310.pyc differ
diff --git a/dassl/data/datasets/__pycache__/build.cpython-311.pyc b/dassl/data/datasets/__pycache__/build.cpython-311.pyc
new file mode 100644
index 0000000..8057bbf
Binary files /dev/null and b/dassl/data/datasets/__pycache__/build.cpython-311.pyc differ
diff --git a/dassl/data/datasets/__pycache__/build.cpython-38.pyc b/dassl/data/datasets/__pycache__/build.cpython-38.pyc
new file mode 100644
index 0000000..42a004b
Binary files /dev/null and b/dassl/data/datasets/__pycache__/build.cpython-38.pyc differ
diff --git a/dassl/data/datasets/base_dataset.py b/dassl/data/datasets/base_dataset.py
new file mode 100644
index 0000000..c7cafd0
--- /dev/null
+++ b/dassl/data/datasets/base_dataset.py
@@ -0,0 +1,237 @@
+import os
+import random
+import os.path as osp
+import tarfile
+import zipfile
+from collections import defaultdict
+import gdown
+
+from dassl.utils import check_isfile
+
+
+class Datum:
+ """Data instance which defines the basic attributes.
+
+ Args:
+ impath (str): image path.
+ label (int): class label.
+ domain (int): domain label.
+ classname (str): class name.
+ """
+
+ def __init__(self, impath="", label=0, domain=0, classname=""):
+ assert isinstance(impath, str)
+ assert check_isfile(impath)
+
+ self._impath = impath
+ self._label = label
+ self._domain = domain
+ self._classname = classname
+
+ @property
+ def impath(self):
+ return self._impath
+
+ @property
+ def label(self):
+ return self._label
+
+ @property
+ def domain(self):
+ return self._domain
+
+ @property
+ def classname(self):
+ return self._classname
+
+
+class DatasetBase:
+ """A unified dataset class for
+ 1) domain adaptation
+ 2) domain generalization
+ 3) semi-supervised learning
+ """
+
+ dataset_dir = "" # the directory where the dataset is stored
+ domains = [] # string names of all domains
+
+ def __init__(self, train_x=None, train_u=None, val=None, test=None):
+ self._train_x = train_x # labeled training data
+ self._train_u = train_u # unlabeled training data (optional)
+ self._val = val # validation data (optional)
+ self._test = test # test data
+ self._num_classes = self.get_num_classes(train_x)
+ self._lab2cname, self._classnames = self.get_lab2cname(train_x)
+
+ @property
+ def train_x(self):
+ return self._train_x
+
+ @property
+ def train_u(self):
+ return self._train_u
+
+ @property
+ def val(self):
+ return self._val
+
+ @property
+ def test(self):
+ return self._test
+
+ @property
+ def lab2cname(self):
+ return self._lab2cname
+
+ @property
+ def classnames(self):
+ return self._classnames
+
+ @property
+ def num_classes(self):
+ return self._num_classes
+
+ @staticmethod
+ def get_num_classes(data_source):
+ """Count number of classes.
+
+ Args:
+ data_source (list): a list of Datum objects.
+ """
+ label_set = set()
+ for item in data_source:
+ label_set.add(item.label)
+ return max(label_set) + 1
+
+ @staticmethod
+ def get_lab2cname(data_source):
+ """Get a label-to-classname mapping (dict).
+
+ Args:
+ data_source (list): a list of Datum objects.
+ """
+ container = set()
+ for item in data_source:
+ container.add((item.label, item.classname))
+ mapping = {label: classname for label, classname in container}
+ labels = list(mapping.keys())
+ labels.sort()
+ classnames = [mapping[label] for label in labels]
+ return mapping, classnames
+
+ def check_input_domains(self, source_domains, target_domains):
+ assert len(source_domains) > 0, "source_domains (list) is empty"
+ assert len(target_domains) > 0, "target_domains (list) is empty"
+ self.is_input_domain_valid(source_domains)
+ self.is_input_domain_valid(target_domains)
+
+ def is_input_domain_valid(self, input_domains):
+ for domain in input_domains:
+ if domain not in self.domains:
+ raise ValueError(
+ "Input domain must belong to {}, "
+ "but got [{}]".format(self.domains, domain)
+ )
+
+ def download_data(self, url, dst, from_gdrive=True):
+ if not osp.exists(osp.dirname(dst)):
+ os.makedirs(osp.dirname(dst))
+
+ if from_gdrive:
+ gdown.download(url, dst, quiet=False)
+ else:
+ raise NotImplementedError
+
+ print("Extracting file ...")
+
+ if dst.endswith(".zip"):
+ zip_ref = zipfile.ZipFile(dst, "r")
+ zip_ref.extractall(osp.dirname(dst))
+ zip_ref.close()
+
+ elif dst.endswith(".tar"):
+ tar = tarfile.open(dst, "r:")
+ tar.extractall(osp.dirname(dst))
+ tar.close()
+
+ elif dst.endswith(".tar.gz"):
+ tar = tarfile.open(dst, "r:gz")
+ tar.extractall(osp.dirname(dst))
+ tar.close()
+
+ else:
+ raise NotImplementedError
+
+ print("File extracted to {}".format(osp.dirname(dst)))
+
+ def generate_fewshot_dataset(
+ self, *data_sources, num_shots=-1, repeat=False
+ ):
+ """Generate a few-shot dataset (typically for the training set).
+
+ This function is useful when one wants to evaluate a model
+ in a few-shot learning setting where each class only contains
+ a small number of images.
+
+ Args:
+ data_sources: each individual is a list containing Datum objects.
+ num_shots (int): number of instances per class to sample.
+ repeat (bool): repeat images if needed (default: False).
+ """
+ if num_shots < 1:
+ if len(data_sources) == 1:
+ return data_sources[0]
+ return data_sources
+
+ print(f"Creating a {num_shots}-shot dataset")
+
+ output = []
+
+ for data_source in data_sources:
+ tracker = self.split_dataset_by_label(data_source)
+ dataset = []
+
+ for label, items in tracker.items():
+ if len(items) >= num_shots:
+ sampled_items = random.sample(items, num_shots)
+ else:
+ if repeat:
+ sampled_items = random.choices(items, k=num_shots)
+ else:
+ sampled_items = items
+ dataset.extend(sampled_items)
+
+ output.append(dataset)
+
+ if len(output) == 1:
+ return output[0]
+
+ return output
+
+ def split_dataset_by_label(self, data_source):
+ """Split a dataset, i.e. a list of Datum objects,
+ into class-specific groups stored in a dictionary.
+
+ Args:
+ data_source (list): a list of Datum objects.
+ """
+ output = defaultdict(list)
+
+ for item in data_source:
+ output[item.label].append(item)
+
+ return output
+
+ def split_dataset_by_domain(self, data_source):
+ """Split a dataset, i.e. a list of Datum objects,
+ into domain-specific groups stored in a dictionary.
+
+ Args:
+ data_source (list): a list of Datum objects.
+ """
+ output = defaultdict(list)
+
+ for item in data_source:
+ output[item.domain].append(item)
+
+ return output
diff --git a/dassl/data/datasets/build.py b/dassl/data/datasets/build.py
new file mode 100644
index 0000000..9de62c6
--- /dev/null
+++ b/dassl/data/datasets/build.py
@@ -0,0 +1,11 @@
+from dassl.utils import Registry, check_availability
+
+DATASET_REGISTRY = Registry("DATASET")
+
+
+def build_dataset(cfg):
+ avai_datasets = DATASET_REGISTRY.registered_names()
+ check_availability(cfg.DATASET.NAME, avai_datasets)
+ if cfg.VERBOSE:
+ print("Loading dataset: {}".format(cfg.DATASET.NAME))
+ return DATASET_REGISTRY.get(cfg.DATASET.NAME)(cfg)
diff --git a/dassl/data/datasets/da/__init__.py b/dassl/data/datasets/da/__init__.py
new file mode 100644
index 0000000..9c7b60f
--- /dev/null
+++ b/dassl/data/datasets/da/__init__.py
@@ -0,0 +1,7 @@
+from .digit5 import Digit5
+from .visda17 import VisDA17
+from .cifarstl import CIFARSTL
+from .office31 import Office31
+from .domainnet import DomainNet
+from .office_home import OfficeHome
+from .mini_domainnet import miniDomainNet
diff --git a/dassl/data/datasets/da/__pycache__/__init__.cpython-310.pyc b/dassl/data/datasets/da/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000..d155b38
Binary files /dev/null and b/dassl/data/datasets/da/__pycache__/__init__.cpython-310.pyc differ
diff --git a/dassl/data/datasets/da/__pycache__/__init__.cpython-311.pyc b/dassl/data/datasets/da/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000..1db8697
Binary files /dev/null and b/dassl/data/datasets/da/__pycache__/__init__.cpython-311.pyc differ
diff --git a/dassl/data/datasets/da/__pycache__/__init__.cpython-38.pyc b/dassl/data/datasets/da/__pycache__/__init__.cpython-38.pyc
new file mode 100644
index 0000000..0f1a1b3
Binary files /dev/null and b/dassl/data/datasets/da/__pycache__/__init__.cpython-38.pyc differ
diff --git a/dassl/data/datasets/da/__pycache__/cifarstl.cpython-310.pyc b/dassl/data/datasets/da/__pycache__/cifarstl.cpython-310.pyc
new file mode 100644
index 0000000..88388c5
Binary files /dev/null and b/dassl/data/datasets/da/__pycache__/cifarstl.cpython-310.pyc differ
diff --git a/dassl/data/datasets/da/__pycache__/cifarstl.cpython-311.pyc b/dassl/data/datasets/da/__pycache__/cifarstl.cpython-311.pyc
new file mode 100644
index 0000000..0967922
Binary files /dev/null and b/dassl/data/datasets/da/__pycache__/cifarstl.cpython-311.pyc differ
diff --git a/dassl/data/datasets/da/__pycache__/cifarstl.cpython-38.pyc b/dassl/data/datasets/da/__pycache__/cifarstl.cpython-38.pyc
new file mode 100644
index 0000000..3046ca8
Binary files /dev/null and b/dassl/data/datasets/da/__pycache__/cifarstl.cpython-38.pyc differ
diff --git a/dassl/data/datasets/da/__pycache__/digit5.cpython-310.pyc b/dassl/data/datasets/da/__pycache__/digit5.cpython-310.pyc
new file mode 100644
index 0000000..7a99aa3
Binary files /dev/null and b/dassl/data/datasets/da/__pycache__/digit5.cpython-310.pyc differ
diff --git a/dassl/data/datasets/da/__pycache__/digit5.cpython-311.pyc b/dassl/data/datasets/da/__pycache__/digit5.cpython-311.pyc
new file mode 100644
index 0000000..a9fa9d4
Binary files /dev/null and b/dassl/data/datasets/da/__pycache__/digit5.cpython-311.pyc differ
diff --git a/dassl/data/datasets/da/__pycache__/digit5.cpython-38.pyc b/dassl/data/datasets/da/__pycache__/digit5.cpython-38.pyc
new file mode 100644
index 0000000..08616b8
Binary files /dev/null and b/dassl/data/datasets/da/__pycache__/digit5.cpython-38.pyc differ
diff --git a/dassl/data/datasets/da/__pycache__/domainnet.cpython-310.pyc b/dassl/data/datasets/da/__pycache__/domainnet.cpython-310.pyc
new file mode 100644
index 0000000..2cf638d
Binary files /dev/null and b/dassl/data/datasets/da/__pycache__/domainnet.cpython-310.pyc differ
diff --git a/dassl/data/datasets/da/__pycache__/domainnet.cpython-311.pyc b/dassl/data/datasets/da/__pycache__/domainnet.cpython-311.pyc
new file mode 100644
index 0000000..a8841a1
Binary files /dev/null and b/dassl/data/datasets/da/__pycache__/domainnet.cpython-311.pyc differ
diff --git a/dassl/data/datasets/da/__pycache__/domainnet.cpython-38.pyc b/dassl/data/datasets/da/__pycache__/domainnet.cpython-38.pyc
new file mode 100644
index 0000000..f20bd17
Binary files /dev/null and b/dassl/data/datasets/da/__pycache__/domainnet.cpython-38.pyc differ
diff --git a/dassl/data/datasets/da/__pycache__/mini_domainnet.cpython-310.pyc b/dassl/data/datasets/da/__pycache__/mini_domainnet.cpython-310.pyc
new file mode 100644
index 0000000..c15b56f
Binary files /dev/null and b/dassl/data/datasets/da/__pycache__/mini_domainnet.cpython-310.pyc differ
diff --git a/dassl/data/datasets/da/__pycache__/mini_domainnet.cpython-311.pyc b/dassl/data/datasets/da/__pycache__/mini_domainnet.cpython-311.pyc
new file mode 100644
index 0000000..4a65a46
Binary files /dev/null and b/dassl/data/datasets/da/__pycache__/mini_domainnet.cpython-311.pyc differ
diff --git a/dassl/data/datasets/da/__pycache__/mini_domainnet.cpython-38.pyc b/dassl/data/datasets/da/__pycache__/mini_domainnet.cpython-38.pyc
new file mode 100644
index 0000000..a2a7be0
Binary files /dev/null and b/dassl/data/datasets/da/__pycache__/mini_domainnet.cpython-38.pyc differ
diff --git a/dassl/data/datasets/da/__pycache__/office31.cpython-310.pyc b/dassl/data/datasets/da/__pycache__/office31.cpython-310.pyc
new file mode 100644
index 0000000..90d6f64
Binary files /dev/null and b/dassl/data/datasets/da/__pycache__/office31.cpython-310.pyc differ
diff --git a/dassl/data/datasets/da/__pycache__/office31.cpython-311.pyc b/dassl/data/datasets/da/__pycache__/office31.cpython-311.pyc
new file mode 100644
index 0000000..25a71e2
Binary files /dev/null and b/dassl/data/datasets/da/__pycache__/office31.cpython-311.pyc differ
diff --git a/dassl/data/datasets/da/__pycache__/office31.cpython-38.pyc b/dassl/data/datasets/da/__pycache__/office31.cpython-38.pyc
new file mode 100644
index 0000000..ea1e006
Binary files /dev/null and b/dassl/data/datasets/da/__pycache__/office31.cpython-38.pyc differ
diff --git a/dassl/data/datasets/da/__pycache__/office_home.cpython-310.pyc b/dassl/data/datasets/da/__pycache__/office_home.cpython-310.pyc
new file mode 100644
index 0000000..9d0e600
Binary files /dev/null and b/dassl/data/datasets/da/__pycache__/office_home.cpython-310.pyc differ
diff --git a/dassl/data/datasets/da/__pycache__/office_home.cpython-311.pyc b/dassl/data/datasets/da/__pycache__/office_home.cpython-311.pyc
new file mode 100644
index 0000000..e1e55e8
Binary files /dev/null and b/dassl/data/datasets/da/__pycache__/office_home.cpython-311.pyc differ
diff --git a/dassl/data/datasets/da/__pycache__/office_home.cpython-38.pyc b/dassl/data/datasets/da/__pycache__/office_home.cpython-38.pyc
new file mode 100644
index 0000000..5b9a0ec
Binary files /dev/null and b/dassl/data/datasets/da/__pycache__/office_home.cpython-38.pyc differ
diff --git a/dassl/data/datasets/da/__pycache__/visda17.cpython-310.pyc b/dassl/data/datasets/da/__pycache__/visda17.cpython-310.pyc
new file mode 100644
index 0000000..e3ea9ff
Binary files /dev/null and b/dassl/data/datasets/da/__pycache__/visda17.cpython-310.pyc differ
diff --git a/dassl/data/datasets/da/__pycache__/visda17.cpython-311.pyc b/dassl/data/datasets/da/__pycache__/visda17.cpython-311.pyc
new file mode 100644
index 0000000..af08ffa
Binary files /dev/null and b/dassl/data/datasets/da/__pycache__/visda17.cpython-311.pyc differ
diff --git a/dassl/data/datasets/da/__pycache__/visda17.cpython-38.pyc b/dassl/data/datasets/da/__pycache__/visda17.cpython-38.pyc
new file mode 100644
index 0000000..2ec0d1c
Binary files /dev/null and b/dassl/data/datasets/da/__pycache__/visda17.cpython-38.pyc differ
diff --git a/dassl/data/datasets/da/cifarstl.py b/dassl/data/datasets/da/cifarstl.py
new file mode 100644
index 0000000..ca27eb1
--- /dev/null
+++ b/dassl/data/datasets/da/cifarstl.py
@@ -0,0 +1,68 @@
+import os.path as osp
+
+from dassl.utils import listdir_nohidden
+
+from ..build import DATASET_REGISTRY
+from ..base_dataset import Datum, DatasetBase
+
+
+@DATASET_REGISTRY.register()
+class CIFARSTL(DatasetBase):
+ """CIFAR-10 and STL-10.
+
+ CIFAR-10:
+ - 60,000 32x32 colour images.
+ - 10 classes, with 6,000 images per class.
+ - 50,000 training images and 10,000 test images.
+ - URL: https://www.cs.toronto.edu/~kriz/cifar.html.
+
+ STL-10:
+ - 10 classes: airplane, bird, car, cat, deer, dog, horse,
+ monkey, ship, truck.
+ - Images are 96x96 pixels, color.
+ - 500 training images (10 pre-defined folds), 800 test images
+ per class.
+ - URL: https://cs.stanford.edu/~acoates/stl10/.
+
+ Reference:
+ - Krizhevsky. Learning Multiple Layers of Features
+ from Tiny Images. Tech report.
+ - Coates et al. An Analysis of Single Layer Networks in
+ Unsupervised Feature Learning. AISTATS 2011.
+ """
+
+ dataset_dir = "cifar_stl"
+ domains = ["cifar", "stl"]
+
+ def __init__(self, cfg):
+ root = osp.abspath(osp.expanduser(cfg.DATASET.ROOT))
+ self.dataset_dir = osp.join(root, self.dataset_dir)
+
+ self.check_input_domains(
+ cfg.DATASET.SOURCE_DOMAINS, cfg.DATASET.TARGET_DOMAINS
+ )
+
+ train_x = self._read_data(cfg.DATASET.SOURCE_DOMAINS, split="train")
+ train_u = self._read_data(cfg.DATASET.TARGET_DOMAINS, split="train")
+ test = self._read_data(cfg.DATASET.TARGET_DOMAINS, split="test")
+
+ super().__init__(train_x=train_x, train_u=train_u, test=test)
+
+ def _read_data(self, input_domains, split="train"):
+ items = []
+
+ for domain, dname in enumerate(input_domains):
+ data_dir = osp.join(self.dataset_dir, dname, split)
+ class_names = listdir_nohidden(data_dir)
+
+ for class_name in class_names:
+ class_dir = osp.join(data_dir, class_name)
+ imnames = listdir_nohidden(class_dir)
+ label = int(class_name.split("_")[0])
+
+ for imname in imnames:
+ impath = osp.join(class_dir, imname)
+ item = Datum(impath=impath, label=label, domain=domain)
+ items.append(item)
+
+ return items
diff --git a/dassl/data/datasets/da/digit5.py b/dassl/data/datasets/da/digit5.py
new file mode 100644
index 0000000..4320005
--- /dev/null
+++ b/dassl/data/datasets/da/digit5.py
@@ -0,0 +1,124 @@
+import random
+import os.path as osp
+
+from dassl.utils import listdir_nohidden
+
+from ..build import DATASET_REGISTRY
+from ..base_dataset import Datum, DatasetBase
+
+# Folder names for train and test sets
+MNIST = {"train": "train_images", "test": "test_images"}
+MNIST_M = {"train": "train_images", "test": "test_images"}
+SVHN = {"train": "train_images", "test": "test_images"}
+SYN = {"train": "train_images", "test": "test_images"}
+USPS = {"train": "train_images", "test": "test_images"}
+
+
+def read_image_list(im_dir, n_max=None, n_repeat=None):
+ items = []
+
+ for imname in listdir_nohidden(im_dir):
+ imname_noext = osp.splitext(imname)[0]
+ label = int(imname_noext.split("_")[1])
+ impath = osp.join(im_dir, imname)
+ items.append((impath, label))
+
+ if n_max is not None:
+ items = random.sample(items, n_max)
+
+ if n_repeat is not None:
+ items *= n_repeat
+
+ return items
+
+
+def load_mnist(dataset_dir, split="train"):
+ data_dir = osp.join(dataset_dir, MNIST[split])
+ n_max = 25000 if split == "train" else 9000
+ return read_image_list(data_dir, n_max=n_max)
+
+
+def load_mnist_m(dataset_dir, split="train"):
+ data_dir = osp.join(dataset_dir, MNIST_M[split])
+ n_max = 25000 if split == "train" else 9000
+ return read_image_list(data_dir, n_max=n_max)
+
+
+def load_svhn(dataset_dir, split="train"):
+ data_dir = osp.join(dataset_dir, SVHN[split])
+ n_max = 25000 if split == "train" else 9000
+ return read_image_list(data_dir, n_max=n_max)
+
+
+def load_syn(dataset_dir, split="train"):
+ data_dir = osp.join(dataset_dir, SYN[split])
+ n_max = 25000 if split == "train" else 9000
+ return read_image_list(data_dir, n_max=n_max)
+
+
+def load_usps(dataset_dir, split="train"):
+ data_dir = osp.join(dataset_dir, USPS[split])
+ n_repeat = 3 if split == "train" else None
+ return read_image_list(data_dir, n_repeat=n_repeat)
+
+
+@DATASET_REGISTRY.register()
+class Digit5(DatasetBase):
+ """Five digit datasets.
+
+ It contains:
+ - MNIST: hand-written digits.
+ - MNIST-M: variant of MNIST with blended background.
+ - SVHN: street view house number.
+ - SYN: synthetic digits.
+ - USPS: hand-written digits, slightly different from MNIST.
+
+ For MNIST, MNIST-M, SVHN and SYN, we randomly sample 25,000 images from
+ the training set and 9,000 images from the test set. For USPS which has only
+ 9,298 images in total, we use the entire dataset but replicate its training
+ set for 3 times so as to match the training set size of other domains.
+
+ Reference:
+ - Lecun et al. Gradient-based learning applied to document
+ recognition. IEEE 1998.
+ - Ganin et al. Domain-adversarial training of neural networks.
+ JMLR 2016.
+ - Netzer et al. Reading digits in natural images with unsupervised
+ feature learning. NIPS-W 2011.
+ """
+
+ dataset_dir = "digit5"
+ domains = ["mnist", "mnist_m", "svhn", "syn", "usps"]
+
+ def __init__(self, cfg):
+ root = osp.abspath(osp.expanduser(cfg.DATASET.ROOT))
+ self.dataset_dir = osp.join(root, self.dataset_dir)
+
+ self.check_input_domains(
+ cfg.DATASET.SOURCE_DOMAINS, cfg.DATASET.TARGET_DOMAINS
+ )
+
+ train_x = self._read_data(cfg.DATASET.SOURCE_DOMAINS, split="train")
+ train_u = self._read_data(cfg.DATASET.TARGET_DOMAINS, split="train")
+ test = self._read_data(cfg.DATASET.TARGET_DOMAINS, split="test")
+
+ super().__init__(train_x=train_x, train_u=train_u, test=test)
+
+ def _read_data(self, input_domains, split="train"):
+ items = []
+
+ for domain, dname in enumerate(input_domains):
+ func = "load_" + dname
+ domain_dir = osp.join(self.dataset_dir, dname)
+ items_d = eval(func)(domain_dir, split=split)
+
+ for impath, label in items_d:
+ item = Datum(
+ impath=impath,
+ label=label,
+ domain=domain,
+ classname=str(label)
+ )
+ items.append(item)
+
+ return items
diff --git a/dassl/data/datasets/da/domainnet.py b/dassl/data/datasets/da/domainnet.py
new file mode 100644
index 0000000..8a703bf
--- /dev/null
+++ b/dassl/data/datasets/da/domainnet.py
@@ -0,0 +1,69 @@
+import os.path as osp
+
+from ..build import DATASET_REGISTRY
+from ..base_dataset import Datum, DatasetBase
+
+
+@DATASET_REGISTRY.register()
+class DomainNet(DatasetBase):
+ """DomainNet.
+
+ Statistics:
+ - 6 distinct domains: Clipart, Infograph, Painting, Quickdraw,
+ Real, Sketch.
+ - Around 0.6M images.
+ - 345 categories.
+ - URL: http://ai.bu.edu/M3SDA/.
+
+ Special note: the t-shirt class (327) is missing in painting_train.txt.
+
+ Reference:
+ - Peng et al. Moment Matching for Multi-Source Domain
+ Adaptation. ICCV 2019.
+ """
+
+ dataset_dir = "domainnet"
+ domains = [
+ "clipart", "infograph", "painting", "quickdraw", "real", "sketch"
+ ]
+
+ def __init__(self, cfg):
+ root = osp.abspath(osp.expanduser(cfg.DATASET.ROOT))
+ self.dataset_dir = osp.join(root, self.dataset_dir)
+ self.split_dir = osp.join(self.dataset_dir, "splits")
+
+ self.check_input_domains(
+ cfg.DATASET.SOURCE_DOMAINS, cfg.DATASET.TARGET_DOMAINS
+ )
+
+ train_x = self._read_data(cfg.DATASET.SOURCE_DOMAINS, split="train")
+ train_u = self._read_data(cfg.DATASET.TARGET_DOMAINS, split="train")
+ val = self._read_data(cfg.DATASET.SOURCE_DOMAINS, split="test")
+ test = self._read_data(cfg.DATASET.TARGET_DOMAINS, split="test")
+
+ super().__init__(train_x=train_x, train_u=train_u, val=val, test=test)
+
+ def _read_data(self, input_domains, split="train"):
+ items = []
+
+ for domain, dname in enumerate(input_domains):
+ filename = dname + "_" + split + ".txt"
+ split_file = osp.join(self.split_dir, filename)
+
+ with open(split_file, "r") as f:
+ lines = f.readlines()
+ for line in lines:
+ line = line.strip()
+ impath, label = line.split(" ")
+ classname = impath.split("/")[1]
+ impath = osp.join(self.dataset_dir, impath)
+ label = int(label)
+ item = Datum(
+ impath=impath,
+ label=label,
+ domain=domain,
+ classname=classname
+ )
+ items.append(item)
+
+ return items
diff --git a/dassl/data/datasets/da/mini_domainnet.py b/dassl/data/datasets/da/mini_domainnet.py
new file mode 100644
index 0000000..4a70869
--- /dev/null
+++ b/dassl/data/datasets/da/mini_domainnet.py
@@ -0,0 +1,58 @@
+import os.path as osp
+
+from ..build import DATASET_REGISTRY
+from ..base_dataset import Datum, DatasetBase
+
+
+@DATASET_REGISTRY.register()
+class miniDomainNet(DatasetBase):
+ """A subset of DomainNet.
+
+ Reference:
+ - Peng et al. Moment Matching for Multi-Source Domain
+ Adaptation. ICCV 2019.
+ - Zhou et al. Domain Adaptive Ensemble Learning.
+ """
+
+ dataset_dir = "domainnet"
+ domains = ["clipart", "painting", "real", "sketch"]
+
+ def __init__(self, cfg):
+ root = osp.abspath(osp.expanduser(cfg.DATASET.ROOT))
+ self.dataset_dir = osp.join(root, self.dataset_dir)
+ self.split_dir = osp.join(self.dataset_dir, "splits_mini")
+
+ self.check_input_domains(
+ cfg.DATASET.SOURCE_DOMAINS, cfg.DATASET.TARGET_DOMAINS
+ )
+
+ train_x = self._read_data(cfg.DATASET.SOURCE_DOMAINS, split="train")
+ train_u = self._read_data(cfg.DATASET.TARGET_DOMAINS, split="train")
+ test = self._read_data(cfg.DATASET.TARGET_DOMAINS, split="test")
+
+ super().__init__(train_x=train_x, train_u=train_u, test=test)
+
+ def _read_data(self, input_domains, split="train"):
+ items = []
+
+ for domain, dname in enumerate(input_domains):
+ filename = dname + "_" + split + ".txt"
+ split_file = osp.join(self.split_dir, filename)
+
+ with open(split_file, "r") as f:
+ lines = f.readlines()
+ for line in lines:
+ line = line.strip()
+ impath, label = line.split(" ")
+ classname = impath.split("/")[1]
+ impath = osp.join(self.dataset_dir, impath)
+ label = int(label)
+ item = Datum(
+ impath=impath,
+ label=label,
+ domain=domain,
+ classname=classname
+ )
+ items.append(item)
+
+ return items
diff --git a/dassl/data/datasets/da/office31.py b/dassl/data/datasets/da/office31.py
new file mode 100644
index 0000000..c2daca1
--- /dev/null
+++ b/dassl/data/datasets/da/office31.py
@@ -0,0 +1,63 @@
+import os.path as osp
+
+from dassl.utils import listdir_nohidden
+
+from ..build import DATASET_REGISTRY
+from ..base_dataset import Datum, DatasetBase
+
+
+@DATASET_REGISTRY.register()
+class Office31(DatasetBase):
+ """Office-31.
+
+ Statistics:
+ - 4,110 images.
+ - 31 classes related to office objects.
+ - 3 domains: Amazon, Webcam, Dslr.
+ - URL: https://people.eecs.berkeley.edu/~jhoffman/domainadapt/.
+
+ Reference:
+ - Saenko et al. Adapting visual category models to
+ new domains. ECCV 2010.
+ """
+
+ dataset_dir = "office31"
+ domains = ["amazon", "webcam", "dslr"]
+
+ def __init__(self, cfg):
+ root = osp.abspath(osp.expanduser(cfg.DATASET.ROOT))
+ self.dataset_dir = osp.join(root, self.dataset_dir)
+
+ self.check_input_domains(
+ cfg.DATASET.SOURCE_DOMAINS, cfg.DATASET.TARGET_DOMAINS
+ )
+
+ train_x = self._read_data(cfg.DATASET.SOURCE_DOMAINS)
+ train_u = self._read_data(cfg.DATASET.TARGET_DOMAINS)
+ test = self._read_data(cfg.DATASET.TARGET_DOMAINS)
+
+ super().__init__(train_x=train_x, train_u=train_u, test=test)
+
+ def _read_data(self, input_domains):
+ items = []
+
+ for domain, dname in enumerate(input_domains):
+ domain_dir = osp.join(self.dataset_dir, dname)
+ class_names = listdir_nohidden(domain_dir)
+ class_names.sort()
+
+ for label, class_name in enumerate(class_names):
+ class_path = osp.join(domain_dir, class_name)
+ imnames = listdir_nohidden(class_path)
+
+ for imname in imnames:
+ impath = osp.join(class_path, imname)
+ item = Datum(
+ impath=impath,
+ label=label,
+ domain=domain,
+ classname=class_name
+ )
+ items.append(item)
+
+ return items
diff --git a/dassl/data/datasets/da/office_home.py b/dassl/data/datasets/da/office_home.py
new file mode 100644
index 0000000..61996f2
--- /dev/null
+++ b/dassl/data/datasets/da/office_home.py
@@ -0,0 +1,63 @@
+import os.path as osp
+
+from dassl.utils import listdir_nohidden
+
+from ..build import DATASET_REGISTRY
+from ..base_dataset import Datum, DatasetBase
+
+
+@DATASET_REGISTRY.register()
+class OfficeHome(DatasetBase):
+ """Office-Home.
+
+ Statistics:
+ - Around 15,500 images.
+ - 65 classes related to office and home objects.
+ - 4 domains: Art, Clipart, Product, Real World.
+ - URL: http://hemanthdv.org/OfficeHome-Dataset/.
+
+ Reference:
+ - Venkateswara et al. Deep Hashing Network for Unsupervised
+ Domain Adaptation. CVPR 2017.
+ """
+
+ dataset_dir = "office_home"
+ domains = ["art", "clipart", "product", "real_world"]
+
+ def __init__(self, cfg):
+ root = osp.abspath(osp.expanduser(cfg.DATASET.ROOT))
+ self.dataset_dir = osp.join(root, self.dataset_dir)
+
+ self.check_input_domains(
+ cfg.DATASET.SOURCE_DOMAINS, cfg.DATASET.TARGET_DOMAINS
+ )
+
+ train_x = self._read_data(cfg.DATASET.SOURCE_DOMAINS)
+ train_u = self._read_data(cfg.DATASET.TARGET_DOMAINS)
+ test = self._read_data(cfg.DATASET.TARGET_DOMAINS)
+
+ super().__init__(train_x=train_x, train_u=train_u, test=test)
+
+ def _read_data(self, input_domains):
+ items = []
+
+ for domain, dname in enumerate(input_domains):
+ domain_dir = osp.join(self.dataset_dir, dname)
+ class_names = listdir_nohidden(domain_dir)
+ class_names.sort()
+
+ for label, class_name in enumerate(class_names):
+ class_path = osp.join(domain_dir, class_name)
+ imnames = listdir_nohidden(class_path)
+
+ for imname in imnames:
+ impath = osp.join(class_path, imname)
+ item = Datum(
+ impath=impath,
+ label=label,
+ domain=domain,
+ classname=class_name.lower(),
+ )
+ items.append(item)
+
+ return items
diff --git a/dassl/data/datasets/da/visda17.py b/dassl/data/datasets/da/visda17.py
new file mode 100644
index 0000000..48c1045
--- /dev/null
+++ b/dassl/data/datasets/da/visda17.py
@@ -0,0 +1,61 @@
+import os.path as osp
+
+from ..build import DATASET_REGISTRY
+from ..base_dataset import Datum, DatasetBase
+
+
+@DATASET_REGISTRY.register()
+class VisDA17(DatasetBase):
+ """VisDA17.
+
+ Focusing on simulation-to-reality domain shift.
+
+ URL: http://ai.bu.edu/visda-2017/.
+
+ Reference:
+ - Peng et al. VisDA: The Visual Domain Adaptation
+ Challenge. ArXiv 2017.
+ """
+
+ dataset_dir = "visda17"
+ domains = ["synthetic", "real"]
+
+ def __init__(self, cfg):
+ root = osp.abspath(osp.expanduser(cfg.DATASET.ROOT))
+ self.dataset_dir = osp.join(root, self.dataset_dir)
+
+ self.check_input_domains(
+ cfg.DATASET.SOURCE_DOMAINS, cfg.DATASET.TARGET_DOMAINS
+ )
+
+ train_x = self._read_data("synthetic")
+ train_u = self._read_data("real")
+ test = self._read_data("real")
+
+ super().__init__(train_x=train_x, train_u=train_u, test=test)
+
+ def _read_data(self, dname):
+ filedir = "train" if dname == "synthetic" else "validation"
+ image_list = osp.join(self.dataset_dir, filedir, "image_list.txt")
+ items = []
+ # There is only one source domain
+ domain = 0
+
+ with open(image_list, "r") as f:
+ lines = f.readlines()
+
+ for line in lines:
+ line = line.strip()
+ impath, label = line.split(" ")
+ classname = impath.split("/")[0]
+ impath = osp.join(self.dataset_dir, filedir, impath)
+ label = int(label)
+ item = Datum(
+ impath=impath,
+ label=label,
+ domain=domain,
+ classname=classname
+ )
+ items.append(item)
+
+ return items
diff --git a/dassl/data/datasets/dg/__init__.py b/dassl/data/datasets/dg/__init__.py
new file mode 100644
index 0000000..b94c35c
--- /dev/null
+++ b/dassl/data/datasets/dg/__init__.py
@@ -0,0 +1,7 @@
+from .pacs import PACS
+from .vlcs import VLCS
+from .wilds import *
+from .cifar_c import CIFAR10C, CIFAR100C
+from .digits_dg import DigitsDG
+from .digit_single import DigitSingle
+from .office_home_dg import OfficeHomeDG
diff --git a/dassl/data/datasets/dg/__pycache__/__init__.cpython-310.pyc b/dassl/data/datasets/dg/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000..ae0117e
Binary files /dev/null and b/dassl/data/datasets/dg/__pycache__/__init__.cpython-310.pyc differ
diff --git a/dassl/data/datasets/dg/__pycache__/__init__.cpython-311.pyc b/dassl/data/datasets/dg/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000..375a435
Binary files /dev/null and b/dassl/data/datasets/dg/__pycache__/__init__.cpython-311.pyc differ
diff --git a/dassl/data/datasets/dg/__pycache__/__init__.cpython-38.pyc b/dassl/data/datasets/dg/__pycache__/__init__.cpython-38.pyc
new file mode 100644
index 0000000..aa5000e
Binary files /dev/null and b/dassl/data/datasets/dg/__pycache__/__init__.cpython-38.pyc differ
diff --git a/dassl/data/datasets/dg/__pycache__/cifar_c.cpython-310.pyc b/dassl/data/datasets/dg/__pycache__/cifar_c.cpython-310.pyc
new file mode 100644
index 0000000..b93d6ec
Binary files /dev/null and b/dassl/data/datasets/dg/__pycache__/cifar_c.cpython-310.pyc differ
diff --git a/dassl/data/datasets/dg/__pycache__/cifar_c.cpython-311.pyc b/dassl/data/datasets/dg/__pycache__/cifar_c.cpython-311.pyc
new file mode 100644
index 0000000..8484811
Binary files /dev/null and b/dassl/data/datasets/dg/__pycache__/cifar_c.cpython-311.pyc differ
diff --git a/dassl/data/datasets/dg/__pycache__/cifar_c.cpython-38.pyc b/dassl/data/datasets/dg/__pycache__/cifar_c.cpython-38.pyc
new file mode 100644
index 0000000..07236a8
Binary files /dev/null and b/dassl/data/datasets/dg/__pycache__/cifar_c.cpython-38.pyc differ
diff --git a/dassl/data/datasets/dg/__pycache__/digit_single.cpython-310.pyc b/dassl/data/datasets/dg/__pycache__/digit_single.cpython-310.pyc
new file mode 100644
index 0000000..a50609c
Binary files /dev/null and b/dassl/data/datasets/dg/__pycache__/digit_single.cpython-310.pyc differ
diff --git a/dassl/data/datasets/dg/__pycache__/digit_single.cpython-311.pyc b/dassl/data/datasets/dg/__pycache__/digit_single.cpython-311.pyc
new file mode 100644
index 0000000..c0f4639
Binary files /dev/null and b/dassl/data/datasets/dg/__pycache__/digit_single.cpython-311.pyc differ
diff --git a/dassl/data/datasets/dg/__pycache__/digit_single.cpython-38.pyc b/dassl/data/datasets/dg/__pycache__/digit_single.cpython-38.pyc
new file mode 100644
index 0000000..79950e0
Binary files /dev/null and b/dassl/data/datasets/dg/__pycache__/digit_single.cpython-38.pyc differ
diff --git a/dassl/data/datasets/dg/__pycache__/digits_dg.cpython-310.pyc b/dassl/data/datasets/dg/__pycache__/digits_dg.cpython-310.pyc
new file mode 100644
index 0000000..1c826bd
Binary files /dev/null and b/dassl/data/datasets/dg/__pycache__/digits_dg.cpython-310.pyc differ
diff --git a/dassl/data/datasets/dg/__pycache__/digits_dg.cpython-311.pyc b/dassl/data/datasets/dg/__pycache__/digits_dg.cpython-311.pyc
new file mode 100644
index 0000000..5e15555
Binary files /dev/null and b/dassl/data/datasets/dg/__pycache__/digits_dg.cpython-311.pyc differ
diff --git a/dassl/data/datasets/dg/__pycache__/digits_dg.cpython-38.pyc b/dassl/data/datasets/dg/__pycache__/digits_dg.cpython-38.pyc
new file mode 100644
index 0000000..2e76b68
Binary files /dev/null and b/dassl/data/datasets/dg/__pycache__/digits_dg.cpython-38.pyc differ
diff --git a/dassl/data/datasets/dg/__pycache__/office_home_dg.cpython-310.pyc b/dassl/data/datasets/dg/__pycache__/office_home_dg.cpython-310.pyc
new file mode 100644
index 0000000..a724bb5
Binary files /dev/null and b/dassl/data/datasets/dg/__pycache__/office_home_dg.cpython-310.pyc differ
diff --git a/dassl/data/datasets/dg/__pycache__/office_home_dg.cpython-311.pyc b/dassl/data/datasets/dg/__pycache__/office_home_dg.cpython-311.pyc
new file mode 100644
index 0000000..aa36097
Binary files /dev/null and b/dassl/data/datasets/dg/__pycache__/office_home_dg.cpython-311.pyc differ
diff --git a/dassl/data/datasets/dg/__pycache__/office_home_dg.cpython-38.pyc b/dassl/data/datasets/dg/__pycache__/office_home_dg.cpython-38.pyc
new file mode 100644
index 0000000..698c384
Binary files /dev/null and b/dassl/data/datasets/dg/__pycache__/office_home_dg.cpython-38.pyc differ
diff --git a/dassl/data/datasets/dg/__pycache__/pacs.cpython-310.pyc b/dassl/data/datasets/dg/__pycache__/pacs.cpython-310.pyc
new file mode 100644
index 0000000..f8c7105
Binary files /dev/null and b/dassl/data/datasets/dg/__pycache__/pacs.cpython-310.pyc differ
diff --git a/dassl/data/datasets/dg/__pycache__/pacs.cpython-311.pyc b/dassl/data/datasets/dg/__pycache__/pacs.cpython-311.pyc
new file mode 100644
index 0000000..377215f
Binary files /dev/null and b/dassl/data/datasets/dg/__pycache__/pacs.cpython-311.pyc differ
diff --git a/dassl/data/datasets/dg/__pycache__/pacs.cpython-38.pyc b/dassl/data/datasets/dg/__pycache__/pacs.cpython-38.pyc
new file mode 100644
index 0000000..9c2db04
Binary files /dev/null and b/dassl/data/datasets/dg/__pycache__/pacs.cpython-38.pyc differ
diff --git a/dassl/data/datasets/dg/__pycache__/vlcs.cpython-310.pyc b/dassl/data/datasets/dg/__pycache__/vlcs.cpython-310.pyc
new file mode 100644
index 0000000..54ef3c6
Binary files /dev/null and b/dassl/data/datasets/dg/__pycache__/vlcs.cpython-310.pyc differ
diff --git a/dassl/data/datasets/dg/__pycache__/vlcs.cpython-311.pyc b/dassl/data/datasets/dg/__pycache__/vlcs.cpython-311.pyc
new file mode 100644
index 0000000..28f992d
Binary files /dev/null and b/dassl/data/datasets/dg/__pycache__/vlcs.cpython-311.pyc differ
diff --git a/dassl/data/datasets/dg/__pycache__/vlcs.cpython-38.pyc b/dassl/data/datasets/dg/__pycache__/vlcs.cpython-38.pyc
new file mode 100644
index 0000000..5fc6b23
Binary files /dev/null and b/dassl/data/datasets/dg/__pycache__/vlcs.cpython-38.pyc differ
diff --git a/dassl/data/datasets/dg/cifar_c.py b/dassl/data/datasets/dg/cifar_c.py
new file mode 100644
index 0000000..7d1e4f3
--- /dev/null
+++ b/dassl/data/datasets/dg/cifar_c.py
@@ -0,0 +1,123 @@
+import os.path as osp
+
+from dassl.utils import listdir_nohidden
+
+from ..build import DATASET_REGISTRY
+from ..base_dataset import Datum, DatasetBase
+
+AVAI_C_TYPES = [
+ "brightness",
+ "contrast",
+ "defocus_blur",
+ "elastic_transform",
+ "fog",
+ "frost",
+ "gaussian_blur",
+ "gaussian_noise",
+ "glass_blur",
+ "impulse_noise",
+ "jpeg_compression",
+ "motion_blur",
+ "pixelate",
+ "saturate",
+ "shot_noise",
+ "snow",
+ "spatter",
+ "speckle_noise",
+ "zoom_blur",
+]
+
+
+@DATASET_REGISTRY.register()
+class CIFAR10C(DatasetBase):
+ """CIFAR-10 -> CIFAR-10-C.
+
+ Dataset link: https://zenodo.org/record/2535967#.YFwtV2Qzb0o
+
+ Statistics:
+ - 2 domains: the normal CIFAR-10 vs. a corrupted CIFAR-10
+ - 10 categories
+
+ Reference:
+ - Hendrycks et al. Benchmarking neural network robustness
+ to common corruptions and perturbations. ICLR 2019.
+ """
+
+ dataset_dir = ""
+ domains = ["cifar10", "cifar10_c"]
+
+ def __init__(self, cfg):
+ root = osp.abspath(osp.expanduser(cfg.DATASET.ROOT))
+ self.dataset_dir = root
+
+ self.check_input_domains(
+ cfg.DATASET.SOURCE_DOMAINS, cfg.DATASET.TARGET_DOMAINS
+ )
+ source_domain = cfg.DATASET.SOURCE_DOMAINS[0]
+ target_domain = cfg.DATASET.TARGET_DOMAINS[0]
+ assert source_domain == self.domains[0]
+ assert target_domain == self.domains[1]
+
+ c_type = cfg.DATASET.CIFAR_C_TYPE
+ c_level = cfg.DATASET.CIFAR_C_LEVEL
+
+ if not c_type:
+ raise ValueError(
+ "Please specify DATASET.CIFAR_C_TYPE in the config file"
+ )
+
+ assert (
+ c_type in AVAI_C_TYPES
+ ), f'C_TYPE is expected to belong to {AVAI_C_TYPES}, but got "{c_type}"'
+ assert 1 <= c_level <= 5
+
+ train_dir = osp.join(self.dataset_dir, source_domain, "train")
+ test_dir = osp.join(
+ self.dataset_dir, target_domain, c_type, str(c_level)
+ )
+
+ if not osp.exists(test_dir):
+ raise ValueError
+
+ train = self._read_data(train_dir)
+ test = self._read_data(test_dir)
+
+ super().__init__(train_x=train, test=test)
+
+ def _read_data(self, data_dir):
+ class_names = listdir_nohidden(data_dir)
+ class_names.sort()
+ items = []
+
+ for label, class_name in enumerate(class_names):
+ class_dir = osp.join(data_dir, class_name)
+ imnames = listdir_nohidden(class_dir)
+
+ for imname in imnames:
+ impath = osp.join(class_dir, imname)
+ item = Datum(impath=impath, label=label, domain=0)
+ items.append(item)
+
+ return items
+
+
+@DATASET_REGISTRY.register()
+class CIFAR100C(CIFAR10C):
+ """CIFAR-100 -> CIFAR-100-C.
+
+ Dataset link: https://zenodo.org/record/3555552#.YFxpQmQzb0o
+
+ Statistics:
+ - 2 domains: the normal CIFAR-100 vs. a corrupted CIFAR-100
+ - 10 categories
+
+ Reference:
+ - Hendrycks et al. Benchmarking neural network robustness
+ to common corruptions and perturbations. ICLR 2019.
+ """
+
+ dataset_dir = ""
+ domains = ["cifar100", "cifar100_c"]
+
+ def __init__(self, cfg):
+ super().__init__(cfg)
diff --git a/dassl/data/datasets/dg/digit_single.py b/dassl/data/datasets/dg/digit_single.py
new file mode 100644
index 0000000..5490e92
--- /dev/null
+++ b/dassl/data/datasets/dg/digit_single.py
@@ -0,0 +1,124 @@
+import os.path as osp
+
+from dassl.utils import listdir_nohidden
+
+from ..build import DATASET_REGISTRY
+from ..base_dataset import Datum, DatasetBase
+
+# Folder names for train and test sets
+MNIST = {"train": "train_images", "test": "test_images"}
+MNIST_M = {"train": "train_images", "test": "test_images"}
+SVHN = {"train": "train_images", "test": "test_images"}
+SYN = {"train": "train_images", "test": "test_images"}
+USPS = {"train": "train_images", "test": "test_images"}
+
+
+def read_image_list(im_dir, n_max=None, n_repeat=None):
+ items = []
+
+ for imname in listdir_nohidden(im_dir):
+ imname_noext = osp.splitext(imname)[0]
+ label = int(imname_noext.split("_")[1])
+ impath = osp.join(im_dir, imname)
+ items.append((impath, label))
+
+ if n_max is not None:
+ # Note that the sampling process is NOT random,
+ # which follows that in Volpi et al. NIPS'18.
+ items = items[:n_max]
+
+ if n_repeat is not None:
+ items *= n_repeat
+
+ return items
+
+
+def load_mnist(dataset_dir, split="train"):
+ data_dir = osp.join(dataset_dir, MNIST[split])
+ n_max = 10000 if split == "train" else None
+ return read_image_list(data_dir, n_max=n_max)
+
+
+def load_mnist_m(dataset_dir, split="train"):
+ data_dir = osp.join(dataset_dir, MNIST_M[split])
+ n_max = 10000 if split == "train" else None
+ return read_image_list(data_dir, n_max=n_max)
+
+
+def load_svhn(dataset_dir, split="train"):
+ data_dir = osp.join(dataset_dir, SVHN[split])
+ n_max = 10000 if split == "train" else None
+ return read_image_list(data_dir, n_max=n_max)
+
+
+def load_syn(dataset_dir, split="train"):
+ data_dir = osp.join(dataset_dir, SYN[split])
+ n_max = 10000 if split == "train" else None
+ return read_image_list(data_dir, n_max=n_max)
+
+
+def load_usps(dataset_dir, split="train"):
+ data_dir = osp.join(dataset_dir, USPS[split])
+ return read_image_list(data_dir)
+
+
+@DATASET_REGISTRY.register()
+class DigitSingle(DatasetBase):
+ """Digit recognition datasets for single-source domain generalization.
+
+ There are five digit datasets:
+ - MNIST: hand-written digits.
+ - MNIST-M: variant of MNIST with blended background.
+ - SVHN: street view house number.
+ - SYN: synthetic digits.
+ - USPS: hand-written digits, slightly different from MNIST.
+
+ Protocol:
+ Volpi et al. train a model using 10,000 images from MNIST and
+ evaluate the model on the test split of the other four datasets. However,
+ the code does not restrict you to only use MNIST as the source dataset.
+ Instead, you can use any dataset as the source. But note that only 10,000
+ images will be sampled from the source dataset for training.
+
+ Reference:
+ - Lecun et al. Gradient-based learning applied to document
+ recognition. IEEE 1998.
+ - Ganin et al. Domain-adversarial training of neural networks.
+ JMLR 2016.
+ - Netzer et al. Reading digits in natural images with unsupervised
+ feature learning. NIPS-W 2011.
+ - Volpi et al. Generalizing to Unseen Domains via Adversarial Data
+ Augmentation. NIPS 2018.
+ """
+
+ # Reuse the digit-5 folder instead of creating a new folder
+ dataset_dir = "digit5"
+ domains = ["mnist", "mnist_m", "svhn", "syn", "usps"]
+
+ def __init__(self, cfg):
+ root = osp.abspath(osp.expanduser(cfg.DATASET.ROOT))
+ self.dataset_dir = osp.join(root, self.dataset_dir)
+
+ self.check_input_domains(
+ cfg.DATASET.SOURCE_DOMAINS, cfg.DATASET.TARGET_DOMAINS
+ )
+
+ train = self._read_data(cfg.DATASET.SOURCE_DOMAINS, split="train")
+ val = self._read_data(cfg.DATASET.SOURCE_DOMAINS, split="test")
+ test = self._read_data(cfg.DATASET.TARGET_DOMAINS, split="test")
+
+ super().__init__(train_x=train, val=val, test=test)
+
+ def _read_data(self, input_domains, split="train"):
+ items = []
+
+ for domain, dname in enumerate(input_domains):
+ func = "load_" + dname
+ domain_dir = osp.join(self.dataset_dir, dname)
+ items_d = eval(func)(domain_dir, split=split)
+
+ for impath, label in items_d:
+ item = Datum(impath=impath, label=label, domain=domain)
+ items.append(item)
+
+ return items
diff --git a/dassl/data/datasets/dg/digits_dg.py b/dassl/data/datasets/dg/digits_dg.py
new file mode 100644
index 0000000..43ccd6f
--- /dev/null
+++ b/dassl/data/datasets/dg/digits_dg.py
@@ -0,0 +1,97 @@
+import glob
+import os.path as osp
+
+from dassl.utils import listdir_nohidden
+
+from ..build import DATASET_REGISTRY
+from ..base_dataset import Datum, DatasetBase
+
+
+@DATASET_REGISTRY.register()
+class DigitsDG(DatasetBase):
+ """Digits-DG.
+
+ It contains 4 digit datasets:
+ - MNIST: hand-written digits.
+ - MNIST-M: variant of MNIST with blended background.
+ - SVHN: street view house number.
+ - SYN: synthetic digits.
+
+ Reference:
+ - Lecun et al. Gradient-based learning applied to document
+ recognition. IEEE 1998.
+ - Ganin et al. Domain-adversarial training of neural networks.
+ JMLR 2016.
+ - Netzer et al. Reading digits in natural images with unsupervised
+ feature learning. NIPS-W 2011.
+ - Zhou et al. Deep Domain-Adversarial Image Generation for Domain
+ Generalisation. AAAI 2020.
+ """
+
+ dataset_dir = "digits_dg"
+ domains = ["mnist", "mnist_m", "svhn", "syn"]
+ data_url = "https://drive.google.com/uc?id=15V7EsHfCcfbKgsDmzQKj_DfXt_XYp_P7"
+
+ def __init__(self, cfg):
+ root = osp.abspath(osp.expanduser(cfg.DATASET.ROOT))
+ self.dataset_dir = osp.join(root, self.dataset_dir)
+
+ if not osp.exists(self.dataset_dir):
+ dst = osp.join(root, "digits_dg.zip")
+ self.download_data(self.data_url, dst, from_gdrive=True)
+
+ self.check_input_domains(
+ cfg.DATASET.SOURCE_DOMAINS, cfg.DATASET.TARGET_DOMAINS
+ )
+
+ train = self.read_data(
+ self.dataset_dir, cfg.DATASET.SOURCE_DOMAINS, "train"
+ )
+ val = self.read_data(
+ self.dataset_dir, cfg.DATASET.SOURCE_DOMAINS, "val"
+ )
+ test = self.read_data(
+ self.dataset_dir, cfg.DATASET.TARGET_DOMAINS, "all"
+ )
+
+ super().__init__(train_x=train, val=val, test=test)
+
+ @staticmethod
+ def read_data(dataset_dir, input_domains, split):
+
+ def _load_data_from_directory(directory):
+ folders = listdir_nohidden(directory)
+ folders.sort()
+ items_ = []
+
+ for label, folder in enumerate(folders):
+ impaths = glob.glob(osp.join(directory, folder, "*.jpg"))
+
+ for impath in impaths:
+ items_.append((impath, label))
+
+ return items_
+
+ items = []
+
+ for domain, dname in enumerate(input_domains):
+ if split == "all":
+ train_dir = osp.join(dataset_dir, dname, "train")
+ impath_label_list = _load_data_from_directory(train_dir)
+ val_dir = osp.join(dataset_dir, dname, "val")
+ impath_label_list += _load_data_from_directory(val_dir)
+ else:
+ split_dir = osp.join(dataset_dir, dname, split)
+ impath_label_list = _load_data_from_directory(split_dir)
+
+ for impath, label in impath_label_list:
+ class_name = impath.split("/")[-2].lower()
+ item = Datum(
+ impath=impath,
+ label=label,
+ domain=domain,
+ classname=class_name
+ )
+ items.append(item)
+
+ return items
diff --git a/dassl/data/datasets/dg/office_home_dg.py b/dassl/data/datasets/dg/office_home_dg.py
new file mode 100644
index 0000000..ef08754
--- /dev/null
+++ b/dassl/data/datasets/dg/office_home_dg.py
@@ -0,0 +1,49 @@
+import os.path as osp
+
+from ..build import DATASET_REGISTRY
+from .digits_dg import DigitsDG
+from ..base_dataset import DatasetBase
+
+
+@DATASET_REGISTRY.register()
+class OfficeHomeDG(DatasetBase):
+ """Office-Home.
+
+ Statistics:
+ - Around 15,500 images.
+ - 65 classes related to office and home objects.
+ - 4 domains: Art, Clipart, Product, Real World.
+ - URL: http://hemanthdv.org/OfficeHome-Dataset/.
+
+ Reference:
+ - Venkateswara et al. Deep Hashing Network for Unsupervised
+ Domain Adaptation. CVPR 2017.
+ """
+
+ dataset_dir = "office_home_dg"
+ domains = ["art", "clipart", "product", "real_world"]
+ data_url = "https://drive.google.com/uc?id=1gkbf_KaxoBws-GWT3XIPZ7BnkqbAxIFa"
+
+ def __init__(self, cfg):
+ root = osp.abspath(osp.expanduser(cfg.DATASET.ROOT))
+ self.dataset_dir = osp.join(root, self.dataset_dir)
+
+ if not osp.exists(self.dataset_dir):
+ dst = osp.join(root, "office_home_dg.zip")
+ self.download_data(self.data_url, dst, from_gdrive=True)
+
+ self.check_input_domains(
+ cfg.DATASET.SOURCE_DOMAINS, cfg.DATASET.TARGET_DOMAINS
+ )
+
+ train = DigitsDG.read_data(
+ self.dataset_dir, cfg.DATASET.SOURCE_DOMAINS, "train"
+ )
+ val = DigitsDG.read_data(
+ self.dataset_dir, cfg.DATASET.SOURCE_DOMAINS, "val"
+ )
+ test = DigitsDG.read_data(
+ self.dataset_dir, cfg.DATASET.TARGET_DOMAINS, "all"
+ )
+
+ super().__init__(train_x=train, val=val, test=test)
diff --git a/dassl/data/datasets/dg/pacs.py b/dassl/data/datasets/dg/pacs.py
new file mode 100644
index 0000000..e0159d4
--- /dev/null
+++ b/dassl/data/datasets/dg/pacs.py
@@ -0,0 +1,94 @@
+import os.path as osp
+
+from ..build import DATASET_REGISTRY
+from ..base_dataset import Datum, DatasetBase
+
+
+@DATASET_REGISTRY.register()
+class PACS(DatasetBase):
+ """PACS.
+
+ Statistics:
+ - 4 domains: Photo (1,670), Art (2,048), Cartoon
+ (2,344), Sketch (3,929).
+ - 7 categories: dog, elephant, giraffe, guitar, horse,
+ house and person.
+
+ Reference:
+ - Li et al. Deeper, broader and artier domain generalization.
+ ICCV 2017.
+ """
+
+ dataset_dir = "pacs"
+ domains = ["art_painting", "cartoon", "photo", "sketch"]
+ data_url = "https://drive.google.com/uc?id=1m4X4fROCCXMO0lRLrr6Zz9Vb3974NWhE"
+ # the following images contain errors and should be ignored
+ _error_paths = ["sketch/dog/n02103406_4068-1.png"]
+
+ def __init__(self, cfg):
+ root = osp.abspath(osp.expanduser(cfg.DATASET.ROOT))
+ self.dataset_dir = osp.join(root, self.dataset_dir)
+ self.image_dir = osp.join(self.dataset_dir, "images")
+ self.split_dir = osp.join(self.dataset_dir, "splits")
+
+ if not osp.exists(self.dataset_dir):
+ dst = osp.join(root, "pacs.zip")
+ self.download_data(self.data_url, dst, from_gdrive=True)
+
+ self.check_input_domains(
+ cfg.DATASET.SOURCE_DOMAINS, cfg.DATASET.TARGET_DOMAINS
+ )
+
+ train = self._read_data(cfg.DATASET.SOURCE_DOMAINS, "train")
+ val = self._read_data(cfg.DATASET.SOURCE_DOMAINS, "crossval")
+ test = self._read_data(cfg.DATASET.TARGET_DOMAINS, "all")
+
+ super().__init__(train_x=train, val=val, test=test)
+
+ def _read_data(self, input_domains, split):
+ items = []
+
+ for domain, dname in enumerate(input_domains):
+ if split == "all":
+ file_train = osp.join(
+ self.split_dir, dname + "_train_kfold.txt"
+ )
+ impath_label_list = self._read_split_pacs(file_train)
+ file_val = osp.join(
+ self.split_dir, dname + "_crossval_kfold.txt"
+ )
+ impath_label_list += self._read_split_pacs(file_val)
+ else:
+ file = osp.join(
+ self.split_dir, dname + "_" + split + "_kfold.txt"
+ )
+ impath_label_list = self._read_split_pacs(file)
+
+ for impath, label in impath_label_list:
+ classname = impath.split("/")[-2]
+ item = Datum(
+ impath=impath,
+ label=label,
+ domain=domain,
+ classname=classname
+ )
+ items.append(item)
+
+ return items
+
+ def _read_split_pacs(self, split_file):
+ items = []
+
+ with open(split_file, "r") as f:
+ lines = f.readlines()
+
+ for line in lines:
+ line = line.strip()
+ impath, label = line.split(" ")
+ if impath in self._error_paths:
+ continue
+ impath = osp.join(self.image_dir, impath)
+ label = int(label) - 1
+ items.append((impath, label))
+
+ return items
diff --git a/dassl/data/datasets/dg/vlcs.py b/dassl/data/datasets/dg/vlcs.py
new file mode 100644
index 0000000..77218e2
--- /dev/null
+++ b/dassl/data/datasets/dg/vlcs.py
@@ -0,0 +1,60 @@
+import glob
+import os.path as osp
+
+from dassl.utils import listdir_nohidden
+
+from ..build import DATASET_REGISTRY
+from ..base_dataset import Datum, DatasetBase
+
+
+@DATASET_REGISTRY.register()
+class VLCS(DatasetBase):
+ """VLCS.
+
+ Statistics:
+ - 4 domains: CALTECH, LABELME, PASCAL, SUN
+ - 5 categories: bird, car, chair, dog, and person.
+
+ Reference:
+ - Torralba and Efros. Unbiased look at dataset bias. CVPR 2011.
+ """
+
+ dataset_dir = "VLCS"
+ domains = ["caltech", "labelme", "pascal", "sun"]
+ data_url = "https://drive.google.com/uc?id=1r0WL5DDqKfSPp9E3tRENwHaXNs1olLZd"
+
+ def __init__(self, cfg):
+ root = osp.abspath(osp.expanduser(cfg.DATASET.ROOT))
+ self.dataset_dir = osp.join(root, self.dataset_dir)
+
+ if not osp.exists(self.dataset_dir):
+ dst = osp.join(root, "vlcs.zip")
+ self.download_data(self.data_url, dst, from_gdrive=True)
+
+ self.check_input_domains(
+ cfg.DATASET.SOURCE_DOMAINS, cfg.DATASET.TARGET_DOMAINS
+ )
+
+ train = self._read_data(cfg.DATASET.SOURCE_DOMAINS, "train")
+ val = self._read_data(cfg.DATASET.SOURCE_DOMAINS, "crossval")
+ test = self._read_data(cfg.DATASET.TARGET_DOMAINS, "test")
+
+ super().__init__(train_x=train, val=val, test=test)
+
+ def _read_data(self, input_domains, split):
+ items = []
+
+ for domain, dname in enumerate(input_domains):
+ dname = dname.upper()
+ path = osp.join(self.dataset_dir, dname, split)
+ folders = listdir_nohidden(path)
+ folders.sort()
+
+ for label, folder in enumerate(folders):
+ impaths = glob.glob(osp.join(path, folder, "*.jpg"))
+
+ for impath in impaths:
+ item = Datum(impath=impath, label=label, domain=domain)
+ items.append(item)
+
+ return items
diff --git a/dassl/data/datasets/dg/wilds/__init__.py b/dassl/data/datasets/dg/wilds/__init__.py
new file mode 100644
index 0000000..2898f7c
--- /dev/null
+++ b/dassl/data/datasets/dg/wilds/__init__.py
@@ -0,0 +1,3 @@
+from .fmow import FMoW
+from .iwildcam import IWildCam
+from .camelyon17 import Camelyon17
diff --git a/dassl/data/datasets/dg/wilds/__pycache__/__init__.cpython-310.pyc b/dassl/data/datasets/dg/wilds/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000..3b2e2e2
Binary files /dev/null and b/dassl/data/datasets/dg/wilds/__pycache__/__init__.cpython-310.pyc differ
diff --git a/dassl/data/datasets/dg/wilds/__pycache__/__init__.cpython-311.pyc b/dassl/data/datasets/dg/wilds/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000..5fcc518
Binary files /dev/null and b/dassl/data/datasets/dg/wilds/__pycache__/__init__.cpython-311.pyc differ
diff --git a/dassl/data/datasets/dg/wilds/__pycache__/__init__.cpython-38.pyc b/dassl/data/datasets/dg/wilds/__pycache__/__init__.cpython-38.pyc
new file mode 100644
index 0000000..3832342
Binary files /dev/null and b/dassl/data/datasets/dg/wilds/__pycache__/__init__.cpython-38.pyc differ
diff --git a/dassl/data/datasets/dg/wilds/__pycache__/camelyon17.cpython-310.pyc b/dassl/data/datasets/dg/wilds/__pycache__/camelyon17.cpython-310.pyc
new file mode 100644
index 0000000..0c0670b
Binary files /dev/null and b/dassl/data/datasets/dg/wilds/__pycache__/camelyon17.cpython-310.pyc differ
diff --git a/dassl/data/datasets/dg/wilds/__pycache__/camelyon17.cpython-311.pyc b/dassl/data/datasets/dg/wilds/__pycache__/camelyon17.cpython-311.pyc
new file mode 100644
index 0000000..44227a4
Binary files /dev/null and b/dassl/data/datasets/dg/wilds/__pycache__/camelyon17.cpython-311.pyc differ
diff --git a/dassl/data/datasets/dg/wilds/__pycache__/camelyon17.cpython-38.pyc b/dassl/data/datasets/dg/wilds/__pycache__/camelyon17.cpython-38.pyc
new file mode 100644
index 0000000..48eb660
Binary files /dev/null and b/dassl/data/datasets/dg/wilds/__pycache__/camelyon17.cpython-38.pyc differ
diff --git a/dassl/data/datasets/dg/wilds/__pycache__/fmow.cpython-310.pyc b/dassl/data/datasets/dg/wilds/__pycache__/fmow.cpython-310.pyc
new file mode 100644
index 0000000..57b4074
Binary files /dev/null and b/dassl/data/datasets/dg/wilds/__pycache__/fmow.cpython-310.pyc differ
diff --git a/dassl/data/datasets/dg/wilds/__pycache__/fmow.cpython-311.pyc b/dassl/data/datasets/dg/wilds/__pycache__/fmow.cpython-311.pyc
new file mode 100644
index 0000000..89279fc
Binary files /dev/null and b/dassl/data/datasets/dg/wilds/__pycache__/fmow.cpython-311.pyc differ
diff --git a/dassl/data/datasets/dg/wilds/__pycache__/fmow.cpython-38.pyc b/dassl/data/datasets/dg/wilds/__pycache__/fmow.cpython-38.pyc
new file mode 100644
index 0000000..5185f55
Binary files /dev/null and b/dassl/data/datasets/dg/wilds/__pycache__/fmow.cpython-38.pyc differ
diff --git a/dassl/data/datasets/dg/wilds/__pycache__/iwildcam.cpython-310.pyc b/dassl/data/datasets/dg/wilds/__pycache__/iwildcam.cpython-310.pyc
new file mode 100644
index 0000000..1cca93f
Binary files /dev/null and b/dassl/data/datasets/dg/wilds/__pycache__/iwildcam.cpython-310.pyc differ
diff --git a/dassl/data/datasets/dg/wilds/__pycache__/iwildcam.cpython-311.pyc b/dassl/data/datasets/dg/wilds/__pycache__/iwildcam.cpython-311.pyc
new file mode 100644
index 0000000..9251036
Binary files /dev/null and b/dassl/data/datasets/dg/wilds/__pycache__/iwildcam.cpython-311.pyc differ
diff --git a/dassl/data/datasets/dg/wilds/__pycache__/iwildcam.cpython-38.pyc b/dassl/data/datasets/dg/wilds/__pycache__/iwildcam.cpython-38.pyc
new file mode 100644
index 0000000..6e4a865
Binary files /dev/null and b/dassl/data/datasets/dg/wilds/__pycache__/iwildcam.cpython-38.pyc differ
diff --git a/dassl/data/datasets/dg/wilds/__pycache__/wilds_base.cpython-310.pyc b/dassl/data/datasets/dg/wilds/__pycache__/wilds_base.cpython-310.pyc
new file mode 100644
index 0000000..939e813
Binary files /dev/null and b/dassl/data/datasets/dg/wilds/__pycache__/wilds_base.cpython-310.pyc differ
diff --git a/dassl/data/datasets/dg/wilds/__pycache__/wilds_base.cpython-311.pyc b/dassl/data/datasets/dg/wilds/__pycache__/wilds_base.cpython-311.pyc
new file mode 100644
index 0000000..15b2737
Binary files /dev/null and b/dassl/data/datasets/dg/wilds/__pycache__/wilds_base.cpython-311.pyc differ
diff --git a/dassl/data/datasets/dg/wilds/__pycache__/wilds_base.cpython-38.pyc b/dassl/data/datasets/dg/wilds/__pycache__/wilds_base.cpython-38.pyc
new file mode 100644
index 0000000..cad8e69
Binary files /dev/null and b/dassl/data/datasets/dg/wilds/__pycache__/wilds_base.cpython-38.pyc differ
diff --git a/dassl/data/datasets/dg/wilds/camelyon17.py b/dassl/data/datasets/dg/wilds/camelyon17.py
new file mode 100644
index 0000000..fade5eb
--- /dev/null
+++ b/dassl/data/datasets/dg/wilds/camelyon17.py
@@ -0,0 +1,24 @@
+from dassl.data.datasets import DATASET_REGISTRY
+
+from .wilds_base import WILDSBase
+
+
+@DATASET_REGISTRY.register()
+class Camelyon17(WILDSBase):
+ """Tumor tissue recognition.
+
+ 2 classes (whether a given region of tissue contains tumor tissue).
+
+ Reference:
+ - Bandi et al. "From detection of individual metastases to classification of lymph
+ node status at the patient level: the CAMELYON17 challenge." TMI 2021.
+ - Koh et al. "Wilds: A benchmark of in-the-wild distribution shifts." ICML 2021.
+ """
+
+ dataset_dir = "camelyon17_v1.0"
+
+ def __init__(self, cfg):
+ super().__init__(cfg)
+
+ def load_classnames(self):
+ return {0: "healthy tissue", 1: "tumor tissue"}
diff --git a/dassl/data/datasets/dg/wilds/fmow.py b/dassl/data/datasets/dg/wilds/fmow.py
new file mode 100644
index 0000000..d7398e0
--- /dev/null
+++ b/dassl/data/datasets/dg/wilds/fmow.py
@@ -0,0 +1,57 @@
+import os.path as osp
+
+from dassl.data.datasets import DATASET_REGISTRY
+
+from .wilds_base import WILDSBase
+
+CATEGORIES = [
+ "airport", "airport_hangar", "airport_terminal", "amusement_park",
+ "aquaculture", "archaeological_site", "barn", "border_checkpoint",
+ "burial_site", "car_dealership", "construction_site", "crop_field", "dam",
+ "debris_or_rubble", "educational_institution", "electric_substation",
+ "factory_or_powerplant", "fire_station", "flooded_road", "fountain",
+ "gas_station", "golf_course", "ground_transportation_station", "helipad",
+ "hospital", "impoverished_settlement", "interchange", "lake_or_pond",
+ "lighthouse", "military_facility", "multi-unit_residential",
+ "nuclear_powerplant", "office_building", "oil_or_gas_facility", "park",
+ "parking_lot_or_garage", "place_of_worship", "police_station", "port",
+ "prison", "race_track", "railway_bridge", "recreational_facility",
+ "road_bridge", "runway", "shipyard", "shopping_mall",
+ "single-unit_residential", "smokestack", "solar_farm", "space_facility",
+ "stadium", "storage_tank", "surface_mine", "swimming_pool", "toll_booth",
+ "tower", "tunnel_opening", "waste_disposal", "water_treatment_facility",
+ "wind_farm", "zoo"
+]
+
+
+@DATASET_REGISTRY.register()
+class FMoW(WILDSBase):
+ """Satellite imagery classification.
+
+ 62 classes (building or land use categories).
+
+ Reference:
+ - Christie et al. "Functional Map of the World." CVPR 2018.
+ - Koh et al. "Wilds: A benchmark of in-the-wild distribution shifts." ICML 2021.
+ """
+
+ dataset_dir = "fmow_v1.1"
+
+ def __init__(self, cfg):
+ super().__init__(cfg)
+
+ def get_image_path(self, dataset, idx):
+ idx = dataset.full_idxs[idx]
+ image_name = f"rgb_img_{idx}.png"
+ image_path = osp.join(self.dataset_dir, "images", image_name)
+ return image_path
+
+ def get_domain(self, dataset, idx):
+ # number of regions: 5 or 6
+ # number of years: 16
+ region_id = int(dataset.metadata_array[idx][0])
+ year_id = int(dataset.metadata_array[idx][1])
+ return region_id*16 + year_id
+
+ def load_classnames(self):
+ return {i: cat for i, cat in enumerate(CATEGORIES)}
diff --git a/dassl/data/datasets/dg/wilds/iwildcam.py b/dassl/data/datasets/dg/wilds/iwildcam.py
new file mode 100644
index 0000000..3d1f016
--- /dev/null
+++ b/dassl/data/datasets/dg/wilds/iwildcam.py
@@ -0,0 +1,32 @@
+import os.path as osp
+import pandas as pd
+
+from dassl.data.datasets import DATASET_REGISTRY
+
+from .wilds_base import WILDSBase
+
+
+@DATASET_REGISTRY.register()
+class IWildCam(WILDSBase):
+ """Animal species recognition.
+
+ 182 classes (species).
+
+ Reference:
+ - Beery et al. "The iwildcam 2021 competition dataset." arXiv 2021.
+ - Koh et al. "Wilds: A benchmark of in-the-wild distribution shifts." ICML 2021.
+ """
+
+ dataset_dir = "iwildcam_v2.0"
+
+ def __init__(self, cfg):
+ super().__init__(cfg)
+
+ def get_image_path(self, dataset, idx):
+ image_name = dataset._input_array[idx]
+ image_path = osp.join(self.dataset_dir, "train", image_name)
+ return image_path
+
+ def load_classnames(self):
+ df = pd.read_csv(osp.join(self.dataset_dir, "categories.csv"))
+ return dict(df["name"])
diff --git a/dassl/data/datasets/dg/wilds/wilds_base.py b/dassl/data/datasets/dg/wilds/wilds_base.py
new file mode 100644
index 0000000..33232e1
--- /dev/null
+++ b/dassl/data/datasets/dg/wilds/wilds_base.py
@@ -0,0 +1,110 @@
+import logging # isort:skip
+logging.disable(logging.WARNING) # isort:skip
+
+import pickle
+import logging
+import os.path as osp
+from wilds import get_dataset as wilds_get_dataset
+
+from dassl.data.datasets import Datum, DatasetBase
+
+
+class WILDSBase(DatasetBase):
+
+ dataset_dir = ""
+ relabel_domain = True
+
+ def __init__(self, cfg):
+ root = osp.abspath(osp.expanduser(cfg.DATASET.ROOT))
+ name = self.dataset_dir.split("_")[0]
+ self.dataset_dir = osp.join(root, self.dataset_dir)
+ self.preloaded = osp.join(self.dataset_dir, "zhou_preloaded.pkl")
+
+ self.label_to_name = self.load_classnames()
+ assert isinstance(self.label_to_name, dict)
+
+ if osp.exists(self.preloaded):
+ with open(self.preloaded, "rb") as file:
+ dataset = pickle.load(file)
+ train = dataset["train"]
+ val = dataset["val"]
+ test = dataset["test"]
+ else:
+ dataset = wilds_get_dataset(
+ dataset=name, root_dir=root, download=True
+ )
+ subset_train = dataset.get_subset("train")
+ subset_val = dataset.get_subset("val")
+ subset_test = dataset.get_subset("test")
+
+ train = self.read_data(subset_train)
+ val = self.read_data(subset_val)
+ test = self.read_data(subset_test)
+
+ # Save time for data loading next time
+ preloaded = {"train": train, "val": val, "test": test}
+ with open(self.preloaded, "wb") as file:
+ pickle.dump(preloaded, file, protocol=pickle.HIGHEST_PROTOCOL)
+
+ # Few-shot learning
+ k = cfg.DATASET.NUM_SHOTS
+ if k > 0:
+ groups = self.split_dataset_by_domain(train)
+ groups = list(groups.values())
+ groups = self.generate_fewshot_dataset(*groups, num_shots=k)
+ train = []
+ for group in groups:
+ train.extend(group)
+
+ super().__init__(train_x=train, val=val, test=test)
+
+ def load_classnames(self):
+ raise NotImplementedError
+
+ def get_image_path(self, dataset, idx):
+ image_name = dataset._input_array[idx]
+ image_path = osp.join(self.dataset_dir, image_name)
+ return image_path
+
+ def get_label(self, dataset, idx):
+ return int(dataset.y_array[idx])
+
+ def get_domain(self, dataset, idx):
+ return int(dataset.metadata_array[idx][0])
+
+ def read_data(self, subset):
+ items = []
+ indices = subset.indices
+ dataset = subset.dataset
+
+ for idx in indices:
+ image_path = self.get_image_path(dataset, idx)
+ label = self.get_label(dataset, idx)
+ domain = self.get_domain(dataset, idx)
+ classname = self.label_to_name[label]
+ item = Datum(
+ impath=image_path,
+ label=label,
+ domain=domain,
+ classname=classname
+ )
+ items.append(item)
+
+ if self.relabel_domain:
+ domains = set([item.domain for item in items])
+ mapping = {domain: i for i, domain in enumerate(domains)}
+
+ items_new = []
+
+ for item in items:
+ item_new = Datum(
+ impath=item.impath,
+ label=item.label,
+ domain=mapping[item.domain],
+ classname=item.classname
+ )
+ items_new.append(item_new)
+
+ return items_new
+
+ return items
diff --git a/dassl/data/datasets/ssl/__init__.py b/dassl/data/datasets/ssl/__init__.py
new file mode 100644
index 0000000..a6607dc
--- /dev/null
+++ b/dassl/data/datasets/ssl/__init__.py
@@ -0,0 +1,3 @@
+from .svhn import SVHN
+from .cifar import CIFAR10, CIFAR100
+from .stl10 import STL10
diff --git a/dassl/data/datasets/ssl/__pycache__/__init__.cpython-310.pyc b/dassl/data/datasets/ssl/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000..4794926
Binary files /dev/null and b/dassl/data/datasets/ssl/__pycache__/__init__.cpython-310.pyc differ
diff --git a/dassl/data/datasets/ssl/__pycache__/__init__.cpython-311.pyc b/dassl/data/datasets/ssl/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000..ba2f46f
Binary files /dev/null and b/dassl/data/datasets/ssl/__pycache__/__init__.cpython-311.pyc differ
diff --git a/dassl/data/datasets/ssl/__pycache__/__init__.cpython-38.pyc b/dassl/data/datasets/ssl/__pycache__/__init__.cpython-38.pyc
new file mode 100644
index 0000000..3708311
Binary files /dev/null and b/dassl/data/datasets/ssl/__pycache__/__init__.cpython-38.pyc differ
diff --git a/dassl/data/datasets/ssl/__pycache__/cifar.cpython-310.pyc b/dassl/data/datasets/ssl/__pycache__/cifar.cpython-310.pyc
new file mode 100644
index 0000000..1ee22c6
Binary files /dev/null and b/dassl/data/datasets/ssl/__pycache__/cifar.cpython-310.pyc differ
diff --git a/dassl/data/datasets/ssl/__pycache__/cifar.cpython-311.pyc b/dassl/data/datasets/ssl/__pycache__/cifar.cpython-311.pyc
new file mode 100644
index 0000000..4e012e5
Binary files /dev/null and b/dassl/data/datasets/ssl/__pycache__/cifar.cpython-311.pyc differ
diff --git a/dassl/data/datasets/ssl/__pycache__/cifar.cpython-38.pyc b/dassl/data/datasets/ssl/__pycache__/cifar.cpython-38.pyc
new file mode 100644
index 0000000..99d7f57
Binary files /dev/null and b/dassl/data/datasets/ssl/__pycache__/cifar.cpython-38.pyc differ
diff --git a/dassl/data/datasets/ssl/__pycache__/stl10.cpython-310.pyc b/dassl/data/datasets/ssl/__pycache__/stl10.cpython-310.pyc
new file mode 100644
index 0000000..e0e7201
Binary files /dev/null and b/dassl/data/datasets/ssl/__pycache__/stl10.cpython-310.pyc differ
diff --git a/dassl/data/datasets/ssl/__pycache__/stl10.cpython-311.pyc b/dassl/data/datasets/ssl/__pycache__/stl10.cpython-311.pyc
new file mode 100644
index 0000000..b2e000e
Binary files /dev/null and b/dassl/data/datasets/ssl/__pycache__/stl10.cpython-311.pyc differ
diff --git a/dassl/data/datasets/ssl/__pycache__/stl10.cpython-38.pyc b/dassl/data/datasets/ssl/__pycache__/stl10.cpython-38.pyc
new file mode 100644
index 0000000..a01be39
Binary files /dev/null and b/dassl/data/datasets/ssl/__pycache__/stl10.cpython-38.pyc differ
diff --git a/dassl/data/datasets/ssl/__pycache__/svhn.cpython-310.pyc b/dassl/data/datasets/ssl/__pycache__/svhn.cpython-310.pyc
new file mode 100644
index 0000000..cfec40b
Binary files /dev/null and b/dassl/data/datasets/ssl/__pycache__/svhn.cpython-310.pyc differ
diff --git a/dassl/data/datasets/ssl/__pycache__/svhn.cpython-311.pyc b/dassl/data/datasets/ssl/__pycache__/svhn.cpython-311.pyc
new file mode 100644
index 0000000..dc4bcf1
Binary files /dev/null and b/dassl/data/datasets/ssl/__pycache__/svhn.cpython-311.pyc differ
diff --git a/dassl/data/datasets/ssl/__pycache__/svhn.cpython-38.pyc b/dassl/data/datasets/ssl/__pycache__/svhn.cpython-38.pyc
new file mode 100644
index 0000000..259924c
Binary files /dev/null and b/dassl/data/datasets/ssl/__pycache__/svhn.cpython-38.pyc differ
diff --git a/dassl/data/datasets/ssl/cifar.py b/dassl/data/datasets/ssl/cifar.py
new file mode 100644
index 0000000..5584527
--- /dev/null
+++ b/dassl/data/datasets/ssl/cifar.py
@@ -0,0 +1,108 @@
+import math
+import random
+import os.path as osp
+
+from dassl.utils import listdir_nohidden
+
+from ..build import DATASET_REGISTRY
+from ..base_dataset import Datum, DatasetBase
+
+
+@DATASET_REGISTRY.register()
+class CIFAR10(DatasetBase):
+ """CIFAR10 for SSL.
+
+ Reference:
+ - Krizhevsky. Learning Multiple Layers of Features
+ from Tiny Images. Tech report.
+ """
+
+ dataset_dir = "cifar10"
+
+ def __init__(self, cfg):
+ root = osp.abspath(osp.expanduser(cfg.DATASET.ROOT))
+ self.dataset_dir = osp.join(root, self.dataset_dir)
+ train_dir = osp.join(self.dataset_dir, "train")
+ test_dir = osp.join(self.dataset_dir, "test")
+
+ assert cfg.DATASET.NUM_LABELED > 0
+
+ train_x, train_u, val = self._read_data_train(
+ train_dir, cfg.DATASET.NUM_LABELED, cfg.DATASET.VAL_PERCENT
+ )
+ test = self._read_data_test(test_dir)
+
+ if cfg.DATASET.ALL_AS_UNLABELED:
+ train_u = train_u + train_x
+
+ if len(val) == 0:
+ val = None
+
+ super().__init__(train_x=train_x, train_u=train_u, val=val, test=test)
+
+ def _read_data_train(self, data_dir, num_labeled, val_percent):
+ class_names = listdir_nohidden(data_dir)
+ class_names.sort()
+ num_labeled_per_class = num_labeled / len(class_names)
+ items_x, items_u, items_v = [], [], []
+
+ for label, class_name in enumerate(class_names):
+ class_dir = osp.join(data_dir, class_name)
+ imnames = listdir_nohidden(class_dir)
+
+ # Split into train and val following Oliver et al. 2018
+ # Set cfg.DATASET.VAL_PERCENT to 0 to not use val data
+ num_val = math.floor(len(imnames) * val_percent)
+ imnames_train = imnames[num_val:]
+ imnames_val = imnames[:num_val]
+
+ # Note we do shuffle after split
+ random.shuffle(imnames_train)
+
+ for i, imname in enumerate(imnames_train):
+ impath = osp.join(class_dir, imname)
+ item = Datum(impath=impath, label=label)
+
+ if (i + 1) <= num_labeled_per_class:
+ items_x.append(item)
+
+ else:
+ items_u.append(item)
+
+ for imname in imnames_val:
+ impath = osp.join(class_dir, imname)
+ item = Datum(impath=impath, label=label)
+ items_v.append(item)
+
+ return items_x, items_u, items_v
+
+ def _read_data_test(self, data_dir):
+ class_names = listdir_nohidden(data_dir)
+ class_names.sort()
+ items = []
+
+ for label, class_name in enumerate(class_names):
+ class_dir = osp.join(data_dir, class_name)
+ imnames = listdir_nohidden(class_dir)
+
+ for imname in imnames:
+ impath = osp.join(class_dir, imname)
+ item = Datum(impath=impath, label=label)
+ items.append(item)
+
+ return items
+
+
+@DATASET_REGISTRY.register()
+class CIFAR100(CIFAR10):
+ """CIFAR100 for SSL.
+
+ Reference:
+ - Krizhevsky. Learning Multiple Layers of Features
+ from Tiny Images. Tech report.
+ """
+
+ dataset_dir = "cifar100"
+
+ def __init__(self, cfg):
+ super().__init__(cfg)
diff --git a/dassl/data/datasets/ssl/stl10.py b/dassl/data/datasets/ssl/stl10.py
new file mode 100644
index 0000000..6a1f9f2
--- /dev/null
+++ b/dassl/data/datasets/ssl/stl10.py
@@ -0,0 +1,87 @@
+import numpy as np
+import os.path as osp
+
+from dassl.utils import listdir_nohidden
+
+from ..build import DATASET_REGISTRY
+from ..base_dataset import Datum, DatasetBase
+
+
+@DATASET_REGISTRY.register()
+class STL10(DatasetBase):
+ """STL-10 dataset.
+
+ Description:
+ - 10 classes: airplane, bird, car, cat, deer, dog, horse,
+ monkey, ship, truck.
+ - Images are 96x96 pixels, color.
+ - 500 training images per class, 800 test images per class.
+ - 100,000 unlabeled images for unsupervised learning.
+
+ Reference:
+ - Coates et al. An Analysis of Single Layer Networks in
+ Unsupervised Feature Learning. AISTATS 2011.
+ """
+
+ dataset_dir = "stl10"
+
+ def __init__(self, cfg):
+ root = osp.abspath(osp.expanduser(cfg.DATASET.ROOT))
+ self.dataset_dir = osp.join(root, self.dataset_dir)
+ train_dir = osp.join(self.dataset_dir, "train")
+ test_dir = osp.join(self.dataset_dir, "test")
+ unlabeled_dir = osp.join(self.dataset_dir, "unlabeled")
+ fold_file = osp.join(
+ self.dataset_dir, "stl10_binary", "fold_indices.txt"
+ )
+
+ # Only use the first five splits
+ assert 0 <= cfg.DATASET.STL10_FOLD <= 4
+
+ train_x = self._read_data_train(
+ train_dir, cfg.DATASET.STL10_FOLD, fold_file
+ )
+ train_u = self._read_data_all(unlabeled_dir)
+ test = self._read_data_all(test_dir)
+
+ if cfg.DATASET.ALL_AS_UNLABELED:
+ train_u = train_u + train_x
+
+ super().__init__(train_x=train_x, train_u=train_u, test=test)
+
+ def _read_data_train(self, data_dir, fold, fold_file):
+ imnames = listdir_nohidden(data_dir)
+ imnames.sort()
+ items = []
+
+ list_idx = list(range(len(imnames)))
+ if fold >= 0:
+ with open(fold_file, "r") as f:
+ str_idx = f.read().splitlines()[fold]
+ list_idx = np.fromstring(str_idx, dtype=np.uint8, sep=" ")
+
+ for i in list_idx:
+ imname = imnames[i]
+ impath = osp.join(data_dir, imname)
+ label = osp.splitext(imname)[0].split("_")[1]
+ label = int(label)
+ item = Datum(impath=impath, label=label)
+ items.append(item)
+
+ return items
+
+ def _read_data_all(self, data_dir):
+ imnames = listdir_nohidden(data_dir)
+ items = []
+
+ for imname in imnames:
+ impath = osp.join(data_dir, imname)
+ label = osp.splitext(imname)[0].split("_")[1]
+ if label == "none":
+ label = -1
+ else:
+ label = int(label)
+ item = Datum(impath=impath, label=label)
+ items.append(item)
+
+ return items
diff --git a/dassl/data/datasets/ssl/svhn.py b/dassl/data/datasets/ssl/svhn.py
new file mode 100644
index 0000000..15e0de5
--- /dev/null
+++ b/dassl/data/datasets/ssl/svhn.py
@@ -0,0 +1,17 @@
+from .cifar import CIFAR10
+from ..build import DATASET_REGISTRY
+
+
+@DATASET_REGISTRY.register()
+class SVHN(CIFAR10):
+ """SVHN for SSL.
+
+ Reference:
+ - Netzer et al. Reading Digits in Natural Images with
+ Unsupervised Feature Learning. NIPS-W 2011.
+ """
+
+ dataset_dir = "svhn"
+
+ def __init__(self, cfg):
+ super().__init__(cfg)
diff --git a/dassl/data/samplers.py b/dassl/data/samplers.py
new file mode 100644
index 0000000..562bfbc
--- /dev/null
+++ b/dassl/data/samplers.py
@@ -0,0 +1,205 @@
+import copy
+import numpy as np
+import random
+from collections import defaultdict
+from torch.utils.data.sampler import Sampler, RandomSampler, SequentialSampler
+
+
+class RandomDomainSampler(Sampler):
+ """Randomly samples N domains each with K images
+ to form a minibatch of size N*K.
+
+ Args:
+ data_source (list): list of Datums.
+ batch_size (int): batch size.
+ n_domain (int): number of domains to sample in a minibatch.
+ """
+
+ def __init__(self, data_source, batch_size, n_domain):
+ self.data_source = data_source
+
+ # Keep track of image indices for each domain
+ self.domain_dict = defaultdict(list)
+ for i, item in enumerate(data_source):
+ self.domain_dict[item.domain].append(i)
+ self.domains = list(self.domain_dict.keys())
+
+ # Make sure each domain has equal number of images
+ if n_domain is None or n_domain <= 0:
+ n_domain = len(self.domains)
+ assert batch_size % n_domain == 0
+ self.n_img_per_domain = batch_size // n_domain
+
+ self.batch_size = batch_size
+ # n_domain denotes number of domains sampled in a minibatch
+ self.n_domain = n_domain
+ self.length = len(list(self.__iter__()))
+
+ def __iter__(self):
+ domain_dict = copy.deepcopy(self.domain_dict)
+ final_idxs = []
+ stop_sampling = False
+
+ while not stop_sampling:
+ selected_domains = random.sample(self.domains, self.n_domain)
+
+ for domain in selected_domains:
+ idxs = domain_dict[domain]
+ selected_idxs = random.sample(idxs, self.n_img_per_domain)
+ final_idxs.extend(selected_idxs)
+
+ for idx in selected_idxs:
+ domain_dict[domain].remove(idx)
+
+ remaining = len(domain_dict[domain])
+ if remaining < self.n_img_per_domain:
+ stop_sampling = True
+
+ return iter(final_idxs)
+
+ def __len__(self):
+ return self.length
+
+
+class SeqDomainSampler(Sampler):
+ """Sequential domain sampler, which randomly samples K
+ images from each domain to form a minibatch.
+
+ Args:
+ data_source (list): list of Datums.
+ batch_size (int): batch size.
+ """
+
+ def __init__(self, data_source, batch_size):
+ self.data_source = data_source
+
+ # Keep track of image indices for each domain
+ self.domain_dict = defaultdict(list)
+ for i, item in enumerate(data_source):
+ self.domain_dict[item.domain].append(i)
+ self.domains = list(self.domain_dict.keys())
+ self.domains.sort()
+
+ # Make sure each domain has equal number of images
+ n_domain = len(self.domains)
+ assert batch_size % n_domain == 0
+ self.n_img_per_domain = batch_size // n_domain
+
+ self.batch_size = batch_size
+ # n_domain denotes number of domains sampled in a minibatch
+ self.n_domain = n_domain
+ self.length = len(list(self.__iter__()))
+
+ def __iter__(self):
+ domain_dict = copy.deepcopy(self.domain_dict)
+ final_idxs = []
+ stop_sampling = False
+
+ while not stop_sampling:
+ for domain in self.domains:
+ idxs = domain_dict[domain]
+ selected_idxs = random.sample(idxs, self.n_img_per_domain)
+ final_idxs.extend(selected_idxs)
+
+ for idx in selected_idxs:
+ domain_dict[domain].remove(idx)
+
+ remaining = len(domain_dict[domain])
+ if remaining < self.n_img_per_domain:
+ stop_sampling = True
+
+ return iter(final_idxs)
+
+ def __len__(self):
+ return self.length
+
+
+class RandomClassSampler(Sampler):
+ """Randomly samples N classes each with K instances to
+ form a minibatch of size N*K.
+
+ Modified from https://github.com/KaiyangZhou/deep-person-reid.
+
+ Args:
+ data_source (list): list of Datums.
+ batch_size (int): batch size.
+ n_ins (int): number of instances per class to sample in a minibatch.
+ """
+
+ def __init__(self, data_source, batch_size, n_ins):
+ if batch_size < n_ins:
+ raise ValueError(
+ "batch_size={} must be no less "
+ "than n_ins={}".format(batch_size, n_ins)
+ )
+
+ self.data_source = data_source
+ self.batch_size = batch_size
+ self.n_ins = n_ins
+ self.ncls_per_batch = self.batch_size // self.n_ins
+ self.index_dic = defaultdict(list)
+ for index, item in enumerate(data_source):
+ self.index_dic[item.label].append(index)
+ self.labels = list(self.index_dic.keys())
+ assert len(self.labels) >= self.ncls_per_batch
+
+ # estimate number of images in an epoch
+ self.length = len(list(self.__iter__()))
+
+ def __iter__(self):
+ batch_idxs_dict = defaultdict(list)
+
+ for label in self.labels:
+ idxs = copy.deepcopy(self.index_dic[label])
+ if len(idxs) < self.n_ins:
+ idxs = np.random.choice(idxs, size=self.n_ins, replace=True)
+ random.shuffle(idxs)
+ batch_idxs = []
+ for idx in idxs:
+ batch_idxs.append(idx)
+ if len(batch_idxs) == self.n_ins:
+ batch_idxs_dict[label].append(batch_idxs)
+ batch_idxs = []
+
+ avai_labels = copy.deepcopy(self.labels)
+ final_idxs = []
+
+ while len(avai_labels) >= self.ncls_per_batch:
+ selected_labels = random.sample(avai_labels, self.ncls_per_batch)
+ for label in selected_labels:
+ batch_idxs = batch_idxs_dict[label].pop(0)
+ final_idxs.extend(batch_idxs)
+ if len(batch_idxs_dict[label]) == 0:
+ avai_labels.remove(label)
+
+ return iter(final_idxs)
+
+ def __len__(self):
+ return self.length
+
+
+def build_sampler(
+ sampler_type,
+ cfg=None,
+ data_source=None,
+ batch_size=32,
+ n_domain=0,
+ n_ins=16
+):
+ if sampler_type == "RandomSampler":
+ return RandomSampler(data_source)
+
+ elif sampler_type == "SequentialSampler":
+ return SequentialSampler(data_source)
+
+ elif sampler_type == "RandomDomainSampler":
+ return RandomDomainSampler(data_source, batch_size, n_domain)
+
+ elif sampler_type == "SeqDomainSampler":
+ return SeqDomainSampler(data_source, batch_size)
+
+ elif sampler_type == "RandomClassSampler":
+ return RandomClassSampler(data_source, batch_size, n_ins)
+
+ else:
+ raise ValueError("Unknown sampler type: {}".format(sampler_type))
diff --git a/dassl/data/transforms/__init__.py b/dassl/data/transforms/__init__.py
new file mode 100644
index 0000000..02c05d6
--- /dev/null
+++ b/dassl/data/transforms/__init__.py
@@ -0,0 +1 @@
+from .transforms import INTERPOLATION_MODES, build_transform
diff --git a/dassl/data/transforms/__pycache__/__init__.cpython-310.pyc b/dassl/data/transforms/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000..f5a791c
Binary files /dev/null and b/dassl/data/transforms/__pycache__/__init__.cpython-310.pyc differ
diff --git a/dassl/data/transforms/__pycache__/__init__.cpython-311.pyc b/dassl/data/transforms/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000..5ae431a
Binary files /dev/null and b/dassl/data/transforms/__pycache__/__init__.cpython-311.pyc differ
diff --git a/dassl/data/transforms/__pycache__/__init__.cpython-38.pyc b/dassl/data/transforms/__pycache__/__init__.cpython-38.pyc
new file mode 100644
index 0000000..1b742a2
Binary files /dev/null and b/dassl/data/transforms/__pycache__/__init__.cpython-38.pyc differ
diff --git a/dassl/data/transforms/__pycache__/autoaugment.cpython-310.pyc b/dassl/data/transforms/__pycache__/autoaugment.cpython-310.pyc
new file mode 100644
index 0000000..0fadbc1
Binary files /dev/null and b/dassl/data/transforms/__pycache__/autoaugment.cpython-310.pyc differ
diff --git a/dassl/data/transforms/__pycache__/autoaugment.cpython-311.pyc b/dassl/data/transforms/__pycache__/autoaugment.cpython-311.pyc
new file mode 100644
index 0000000..8a90236
Binary files /dev/null and b/dassl/data/transforms/__pycache__/autoaugment.cpython-311.pyc differ
diff --git a/dassl/data/transforms/__pycache__/autoaugment.cpython-38.pyc b/dassl/data/transforms/__pycache__/autoaugment.cpython-38.pyc
new file mode 100644
index 0000000..d260f95
Binary files /dev/null and b/dassl/data/transforms/__pycache__/autoaugment.cpython-38.pyc differ
diff --git a/dassl/data/transforms/__pycache__/randaugment.cpython-310.pyc b/dassl/data/transforms/__pycache__/randaugment.cpython-310.pyc
new file mode 100644
index 0000000..7d4d102
Binary files /dev/null and b/dassl/data/transforms/__pycache__/randaugment.cpython-310.pyc differ
diff --git a/dassl/data/transforms/__pycache__/randaugment.cpython-311.pyc b/dassl/data/transforms/__pycache__/randaugment.cpython-311.pyc
new file mode 100644
index 0000000..b10f597
Binary files /dev/null and b/dassl/data/transforms/__pycache__/randaugment.cpython-311.pyc differ
diff --git a/dassl/data/transforms/__pycache__/randaugment.cpython-38.pyc b/dassl/data/transforms/__pycache__/randaugment.cpython-38.pyc
new file mode 100644
index 0000000..aa6c511
Binary files /dev/null and b/dassl/data/transforms/__pycache__/randaugment.cpython-38.pyc differ
diff --git a/dassl/data/transforms/__pycache__/transforms.cpython-310.pyc b/dassl/data/transforms/__pycache__/transforms.cpython-310.pyc
new file mode 100644
index 0000000..bc184b8
Binary files /dev/null and b/dassl/data/transforms/__pycache__/transforms.cpython-310.pyc differ
diff --git a/dassl/data/transforms/__pycache__/transforms.cpython-311.pyc b/dassl/data/transforms/__pycache__/transforms.cpython-311.pyc
new file mode 100644
index 0000000..e28a7b7
Binary files /dev/null and b/dassl/data/transforms/__pycache__/transforms.cpython-311.pyc differ
diff --git a/dassl/data/transforms/__pycache__/transforms.cpython-38.pyc b/dassl/data/transforms/__pycache__/transforms.cpython-38.pyc
new file mode 100644
index 0000000..cd72e7d
Binary files /dev/null and b/dassl/data/transforms/__pycache__/transforms.cpython-38.pyc differ
diff --git a/dassl/data/transforms/autoaugment.py b/dassl/data/transforms/autoaugment.py
new file mode 100644
index 0000000..2e14fce
--- /dev/null
+++ b/dassl/data/transforms/autoaugment.py
@@ -0,0 +1,273 @@
+"""
+Source: https://github.com/DeepVoltaire/AutoAugment
+"""
+import numpy as np
+import random
+from PIL import Image, ImageOps, ImageEnhance
+
+
+class ImageNetPolicy:
+ """Randomly choose one of the best 24 Sub-policies on ImageNet.
+
+ Example:
+ >>> policy = ImageNetPolicy()
+ >>> transformed = policy(image)
+
+ Example as a PyTorch Transform:
+ >>> transform=transforms.Compose([
+ >>> transforms.Resize(256),
+ >>> ImageNetPolicy(),
+ >>> transforms.ToTensor()])
+ """
+
+ def __init__(self, fillcolor=(128, 128, 128)):
+ self.policies = [
+ SubPolicy(0.4, "posterize", 8, 0.6, "rotate", 9, fillcolor),
+ SubPolicy(0.6, "solarize", 5, 0.6, "autocontrast", 5, fillcolor),
+ SubPolicy(0.8, "equalize", 8, 0.6, "equalize", 3, fillcolor),
+ SubPolicy(0.6, "posterize", 7, 0.6, "posterize", 6, fillcolor),
+ SubPolicy(0.4, "equalize", 7, 0.2, "solarize", 4, fillcolor),
+ SubPolicy(0.4, "equalize", 4, 0.8, "rotate", 8, fillcolor),
+ SubPolicy(0.6, "solarize", 3, 0.6, "equalize", 7, fillcolor),
+ SubPolicy(0.8, "posterize", 5, 1.0, "equalize", 2, fillcolor),
+ SubPolicy(0.2, "rotate", 3, 0.6, "solarize", 8, fillcolor),
+ SubPolicy(0.6, "equalize", 8, 0.4, "posterize", 6, fillcolor),
+ SubPolicy(0.8, "rotate", 8, 0.4, "color", 0, fillcolor),
+ SubPolicy(0.4, "rotate", 9, 0.6, "equalize", 2, fillcolor),
+ SubPolicy(0.0, "equalize", 7, 0.8, "equalize", 8, fillcolor),
+ SubPolicy(0.6, "invert", 4, 1.0, "equalize", 8, fillcolor),
+ SubPolicy(0.6, "color", 4, 1.0, "contrast", 8, fillcolor),
+ SubPolicy(0.8, "rotate", 8, 1.0, "color", 2, fillcolor),
+ SubPolicy(0.8, "color", 8, 0.8, "solarize", 7, fillcolor),
+ SubPolicy(0.4, "sharpness", 7, 0.6, "invert", 8, fillcolor),
+ SubPolicy(0.6, "shearX", 5, 1.0, "equalize", 9, fillcolor),
+ SubPolicy(0.4, "color", 0, 0.6, "equalize", 3, fillcolor),
+ SubPolicy(0.4, "equalize", 7, 0.2, "solarize", 4, fillcolor),
+ SubPolicy(0.6, "solarize", 5, 0.6, "autocontrast", 5, fillcolor),
+ SubPolicy(0.6, "invert", 4, 1.0, "equalize", 8, fillcolor),
+ SubPolicy(0.6, "color", 4, 1.0, "contrast", 8, fillcolor),
+ SubPolicy(0.8, "equalize", 8, 0.6, "equalize", 3, fillcolor),
+ ]
+
+ def __call__(self, img):
+ policy_idx = random.randint(0, len(self.policies) - 1)
+ return self.policies[policy_idx](img)
+
+ def __repr__(self):
+ return "AutoAugment ImageNet Policy"
+
+
+class CIFAR10Policy:
+ """Randomly choose one of the best 25 Sub-policies on CIFAR10.
+
+ Example:
+ >>> policy = CIFAR10Policy()
+ >>> transformed = policy(image)
+
+ Example as a PyTorch Transform:
+ >>> transform=transforms.Compose([
+ >>> transforms.Resize(256),
+ >>> CIFAR10Policy(),
+ >>> transforms.ToTensor()])
+ """
+
+ def __init__(self, fillcolor=(128, 128, 128)):
+ self.policies = [
+ SubPolicy(0.1, "invert", 7, 0.2, "contrast", 6, fillcolor),
+ SubPolicy(0.7, "rotate", 2, 0.3, "translateX", 9, fillcolor),
+ SubPolicy(0.8, "sharpness", 1, 0.9, "sharpness", 3, fillcolor),
+ SubPolicy(0.5, "shearY", 8, 0.7, "translateY", 9, fillcolor),
+ SubPolicy(0.5, "autocontrast", 8, 0.9, "equalize", 2, fillcolor),
+ SubPolicy(0.2, "shearY", 7, 0.3, "posterize", 7, fillcolor),
+ SubPolicy(0.4, "color", 3, 0.6, "brightness", 7, fillcolor),
+ SubPolicy(0.3, "sharpness", 9, 0.7, "brightness", 9, fillcolor),
+ SubPolicy(0.6, "equalize", 5, 0.5, "equalize", 1, fillcolor),
+ SubPolicy(0.6, "contrast", 7, 0.6, "sharpness", 5, fillcolor),
+ SubPolicy(0.7, "color", 7, 0.5, "translateX", 8, fillcolor),
+ SubPolicy(0.3, "equalize", 7, 0.4, "autocontrast", 8, fillcolor),
+ SubPolicy(0.4, "translateY", 3, 0.2, "sharpness", 6, fillcolor),
+ SubPolicy(0.9, "brightness", 6, 0.2, "color", 8, fillcolor),
+ SubPolicy(0.5, "solarize", 2, 0.0, "invert", 3, fillcolor),
+ SubPolicy(0.2, "equalize", 0, 0.6, "autocontrast", 0, fillcolor),
+ SubPolicy(0.2, "equalize", 8, 0.6, "equalize", 4, fillcolor),
+ SubPolicy(0.9, "color", 9, 0.6, "equalize", 6, fillcolor),
+ SubPolicy(0.8, "autocontrast", 4, 0.2, "solarize", 8, fillcolor),
+ SubPolicy(0.1, "brightness", 3, 0.7, "color", 0, fillcolor),
+ SubPolicy(0.4, "solarize", 5, 0.9, "autocontrast", 3, fillcolor),
+ SubPolicy(0.9, "translateY", 9, 0.7, "translateY", 9, fillcolor),
+ SubPolicy(0.9, "autocontrast", 2, 0.8, "solarize", 3, fillcolor),
+ SubPolicy(0.8, "equalize", 8, 0.1, "invert", 3, fillcolor),
+ SubPolicy(0.7, "translateY", 9, 0.9, "autocontrast", 1, fillcolor),
+ ]
+
+ def __call__(self, img):
+ policy_idx = random.randint(0, len(self.policies) - 1)
+ return self.policies[policy_idx](img)
+
+ def __repr__(self):
+ return "AutoAugment CIFAR10 Policy"
+
+
+class SVHNPolicy:
+ """Randomly choose one of the best 25 Sub-policies on SVHN.
+
+ Example:
+ >>> policy = SVHNPolicy()
+ >>> transformed = policy(image)
+
+ Example as a PyTorch Transform:
+ >>> transform=transforms.Compose([
+ >>> transforms.Resize(256),
+ >>> SVHNPolicy(),
+ >>> transforms.ToTensor()])
+ """
+
+ def __init__(self, fillcolor=(128, 128, 128)):
+ self.policies = [
+ SubPolicy(0.9, "shearX", 4, 0.2, "invert", 3, fillcolor),
+ SubPolicy(0.9, "shearY", 8, 0.7, "invert", 5, fillcolor),
+ SubPolicy(0.6, "equalize", 5, 0.6, "solarize", 6, fillcolor),
+ SubPolicy(0.9, "invert", 3, 0.6, "equalize", 3, fillcolor),
+ SubPolicy(0.6, "equalize", 1, 0.9, "rotate", 3, fillcolor),
+ SubPolicy(0.9, "shearX", 4, 0.8, "autocontrast", 3, fillcolor),
+ SubPolicy(0.9, "shearY", 8, 0.4, "invert", 5, fillcolor),
+ SubPolicy(0.9, "shearY", 5, 0.2, "solarize", 6, fillcolor),
+ SubPolicy(0.9, "invert", 6, 0.8, "autocontrast", 1, fillcolor),
+ SubPolicy(0.6, "equalize", 3, 0.9, "rotate", 3, fillcolor),
+ SubPolicy(0.9, "shearX", 4, 0.3, "solarize", 3, fillcolor),
+ SubPolicy(0.8, "shearY", 8, 0.7, "invert", 4, fillcolor),
+ SubPolicy(0.9, "equalize", 5, 0.6, "translateY", 6, fillcolor),
+ SubPolicy(0.9, "invert", 4, 0.6, "equalize", 7, fillcolor),
+ SubPolicy(0.3, "contrast", 3, 0.8, "rotate", 4, fillcolor),
+ SubPolicy(0.8, "invert", 5, 0.0, "translateY", 2, fillcolor),
+ SubPolicy(0.7, "shearY", 6, 0.4, "solarize", 8, fillcolor),
+ SubPolicy(0.6, "invert", 4, 0.8, "rotate", 4, fillcolor),
+ SubPolicy(0.3, "shearY", 7, 0.9, "translateX", 3, fillcolor),
+ SubPolicy(0.1, "shearX", 6, 0.6, "invert", 5, fillcolor),
+ SubPolicy(0.7, "solarize", 2, 0.6, "translateY", 7, fillcolor),
+ SubPolicy(0.8, "shearY", 4, 0.8, "invert", 8, fillcolor),
+ SubPolicy(0.7, "shearX", 9, 0.8, "translateY", 3, fillcolor),
+ SubPolicy(0.8, "shearY", 5, 0.7, "autocontrast", 3, fillcolor),
+ SubPolicy(0.7, "shearX", 2, 0.1, "invert", 5, fillcolor),
+ ]
+
+ def __call__(self, img):
+ policy_idx = random.randint(0, len(self.policies) - 1)
+ return self.policies[policy_idx](img)
+
+ def __repr__(self):
+ return "AutoAugment SVHN Policy"
+
+
+class SubPolicy(object):
+
+ def __init__(
+ self,
+ p1,
+ operation1,
+ magnitude_idx1,
+ p2,
+ operation2,
+ magnitude_idx2,
+ fillcolor=(128, 128, 128),
+ ):
+ ranges = {
+ "shearX": np.linspace(0, 0.3, 10),
+ "shearY": np.linspace(0, 0.3, 10),
+ "translateX": np.linspace(0, 150 / 331, 10),
+ "translateY": np.linspace(0, 150 / 331, 10),
+ "rotate": np.linspace(0, 30, 10),
+ "color": np.linspace(0.0, 0.9, 10),
+ "posterize": np.round(np.linspace(8, 4, 10), 0).astype(np.int),
+ "solarize": np.linspace(256, 0, 10),
+ "contrast": np.linspace(0.0, 0.9, 10),
+ "sharpness": np.linspace(0.0, 0.9, 10),
+ "brightness": np.linspace(0.0, 0.9, 10),
+ "autocontrast": [0] * 10,
+ "equalize": [0] * 10,
+ "invert": [0] * 10,
+ }
+
+ # from https://stackoverflow.com/questions/5252170/specify-image-filling-color-when-rotating-in-python-with-pil-and-setting-expand
+ def rotate_with_fill(img, magnitude):
+ rot = img.convert("RGBA").rotate(magnitude)
+ return Image.composite(
+ rot, Image.new("RGBA", rot.size, (128, ) * 4), rot
+ ).convert(img.mode)
+
+ func = {
+ "shearX":
+ lambda img, magnitude: img.transform(
+ img.size,
+ Image.AFFINE,
+ (1, magnitude * random.choice([-1, 1]), 0, 0, 1, 0),
+ Image.BICUBIC,
+ fillcolor=fillcolor,
+ ),
+ "shearY":
+ lambda img, magnitude: img.transform(
+ img.size,
+ Image.AFFINE,
+ (1, 0, 0, magnitude * random.choice([-1, 1]), 1, 0),
+ Image.BICUBIC,
+ fillcolor=fillcolor,
+ ),
+ "translateX":
+ lambda img, magnitude: img.transform(
+ img.size,
+ Image.AFFINE,
+ (
+ 1, 0, magnitude * img.size[0] * random.choice([-1, 1]), 0,
+ 1, 0
+ ),
+ fillcolor=fillcolor,
+ ),
+ "translateY":
+ lambda img, magnitude: img.transform(
+ img.size,
+ Image.AFFINE,
+ (
+ 1, 0, 0, 0, 1, magnitude * img.size[1] * random.
+ choice([-1, 1])
+ ),
+ fillcolor=fillcolor,
+ ),
+ "rotate":
+ lambda img, magnitude: rotate_with_fill(img, magnitude),
+ "color":
+ lambda img, magnitude: ImageEnhance.Color(img).
+ enhance(1 + magnitude * random.choice([-1, 1])),
+ "posterize":
+ lambda img, magnitude: ImageOps.posterize(img, magnitude),
+ "solarize":
+ lambda img, magnitude: ImageOps.solarize(img, magnitude),
+ "contrast":
+ lambda img, magnitude: ImageEnhance.Contrast(img).
+ enhance(1 + magnitude * random.choice([-1, 1])),
+ "sharpness":
+ lambda img, magnitude: ImageEnhance.Sharpness(img).
+ enhance(1 + magnitude * random.choice([-1, 1])),
+ "brightness":
+ lambda img, magnitude: ImageEnhance.Brightness(img).
+ enhance(1 + magnitude * random.choice([-1, 1])),
+ "autocontrast":
+ lambda img, magnitude: ImageOps.autocontrast(img),
+ "equalize":
+ lambda img, magnitude: ImageOps.equalize(img),
+ "invert":
+ lambda img, magnitude: ImageOps.invert(img),
+ }
+
+ self.p1 = p1
+ self.operation1 = func[operation1]
+ self.magnitude1 = ranges[operation1][magnitude_idx1]
+ self.p2 = p2
+ self.operation2 = func[operation2]
+ self.magnitude2 = ranges[operation2][magnitude_idx2]
+
+ def __call__(self, img):
+ if random.random() < self.p1:
+ img = self.operation1(img, self.magnitude1)
+ if random.random() < self.p2:
+ img = self.operation2(img, self.magnitude2)
+ return img
diff --git a/dassl/data/transforms/randaugment.py b/dassl/data/transforms/randaugment.py
new file mode 100644
index 0000000..5c39ff3
--- /dev/null
+++ b/dassl/data/transforms/randaugment.py
@@ -0,0 +1,363 @@
+"""
+Credit to
+1) https://github.com/ildoonet/pytorch-randaugment
+2) https://github.com/kakaobrain/fast-autoaugment
+"""
+import numpy as np
+import random
+import PIL
+import torch
+import PIL.ImageOps
+import PIL.ImageDraw
+import PIL.ImageEnhance
+from PIL import Image
+
+
+def ShearX(img, v):
+ assert -0.3 <= v <= 0.3
+ if random.random() > 0.5:
+ v = -v
+ return img.transform(img.size, PIL.Image.AFFINE, (1, v, 0, 0, 1, 0))
+
+
+def ShearY(img, v):
+ assert -0.3 <= v <= 0.3
+ if random.random() > 0.5:
+ v = -v
+ return img.transform(img.size, PIL.Image.AFFINE, (1, 0, 0, v, 1, 0))
+
+
+def TranslateX(img, v):
+ # [-150, 150] => percentage: [-0.45, 0.45]
+ assert -0.45 <= v <= 0.45
+ if random.random() > 0.5:
+ v = -v
+ v = v * img.size[0]
+ return img.transform(img.size, PIL.Image.AFFINE, (1, 0, v, 0, 1, 0))
+
+
+def TranslateXabs(img, v):
+ # [-150, 150] => percentage: [-0.45, 0.45]
+ assert 0 <= v
+ if random.random() > 0.5:
+ v = -v
+ return img.transform(img.size, PIL.Image.AFFINE, (1, 0, v, 0, 1, 0))
+
+
+def TranslateY(img, v):
+ # [-150, 150] => percentage: [-0.45, 0.45]
+ assert -0.45 <= v <= 0.45
+ if random.random() > 0.5:
+ v = -v
+ v = v * img.size[1]
+ return img.transform(img.size, PIL.Image.AFFINE, (1, 0, 0, 0, 1, v))
+
+
+def TranslateYabs(img, v):
+ # [-150, 150] => percentage: [-0.45, 0.45]
+ assert 0 <= v
+ if random.random() > 0.5:
+ v = -v
+ return img.transform(img.size, PIL.Image.AFFINE, (1, 0, 0, 0, 1, v))
+
+
+def Rotate(img, v):
+ assert -30 <= v <= 30
+ if random.random() > 0.5:
+ v = -v
+ return img.rotate(v)
+
+
+def AutoContrast(img, _):
+ return PIL.ImageOps.autocontrast(img)
+
+
+def Invert(img, _):
+ return PIL.ImageOps.invert(img)
+
+
+def Equalize(img, _):
+ return PIL.ImageOps.equalize(img)
+
+
+def Flip(img, _):
+ return PIL.ImageOps.mirror(img)
+
+
+def Solarize(img, v):
+ assert 0 <= v <= 256
+ return PIL.ImageOps.solarize(img, v)
+
+
+def SolarizeAdd(img, addition=0, threshold=128):
+ img_np = np.array(img).astype(np.int)
+ img_np = img_np + addition
+ img_np = np.clip(img_np, 0, 255)
+ img_np = img_np.astype(np.uint8)
+ img = Image.fromarray(img_np)
+ return PIL.ImageOps.solarize(img, threshold)
+
+
+def Posterize(img, v):
+ assert 4 <= v <= 8
+ v = int(v)
+ return PIL.ImageOps.posterize(img, v)
+
+
+def Contrast(img, v):
+ assert 0.0 <= v <= 2.0
+ return PIL.ImageEnhance.Contrast(img).enhance(v)
+
+
+def Color(img, v):
+ assert 0.0 <= v <= 2.0
+ return PIL.ImageEnhance.Color(img).enhance(v)
+
+
+def Brightness(img, v):
+ assert 0.0 <= v <= 2.0
+ return PIL.ImageEnhance.Brightness(img).enhance(v)
+
+
+def Sharpness(img, v):
+ assert 0.0 <= v <= 2.0
+ return PIL.ImageEnhance.Sharpness(img).enhance(v)
+
+
+def Cutout(img, v):
+ # [0, 60] => percentage: [0, 0.2]
+ assert 0.0 <= v <= 0.2
+ if v <= 0.0:
+ return img
+
+ v = v * img.size[0]
+ return CutoutAbs(img, v)
+
+
+def CutoutAbs(img, v):
+ # [0, 60] => percentage: [0, 0.2]
+ # assert 0 <= v <= 20
+ if v < 0:
+ return img
+ w, h = img.size
+ x0 = np.random.uniform(w)
+ y0 = np.random.uniform(h)
+
+ x0 = int(max(0, x0 - v/2.0))
+ y0 = int(max(0, y0 - v/2.0))
+ x1 = min(w, x0 + v)
+ y1 = min(h, y0 + v)
+
+ xy = (x0, y0, x1, y1)
+ color = (125, 123, 114)
+ # color = (0, 0, 0)
+ img = img.copy()
+ PIL.ImageDraw.Draw(img).rectangle(xy, color)
+ return img
+
+
+def SamplePairing(imgs):
+ # [0, 0.4]
+ def f(img1, v):
+ i = np.random.choice(len(imgs))
+ img2 = PIL.Image.fromarray(imgs[i])
+ return PIL.Image.blend(img1, img2, v)
+
+ return f
+
+
+def Identity(img, v):
+ return img
+
+
+class Lighting:
+ """Lighting noise (AlexNet - style PCA - based noise)."""
+
+ def __init__(self, alphastd, eigval, eigvec):
+ self.alphastd = alphastd
+ self.eigval = torch.Tensor(eigval)
+ self.eigvec = torch.Tensor(eigvec)
+
+ def __call__(self, img):
+ if self.alphastd == 0:
+ return img
+
+ alpha = img.new().resize_(3).normal_(0, self.alphastd)
+ rgb = (
+ self.eigvec.type_as(img).clone().mul(
+ alpha.view(1, 3).expand(3, 3)
+ ).mul(self.eigval.view(1, 3).expand(3, 3)).sum(1).squeeze()
+ )
+
+ return img.add(rgb.view(3, 1, 1).expand_as(img))
+
+
+class CutoutDefault:
+ """
+ Reference : https://github.com/quark0/darts/blob/master/cnn/utils.py
+ """
+
+ def __init__(self, length):
+ self.length = length
+
+ def __call__(self, img):
+ h, w = img.size(1), img.size(2)
+ mask = np.ones((h, w), np.float32)
+ y = np.random.randint(h)
+ x = np.random.randint(w)
+
+ y1 = np.clip(y - self.length // 2, 0, h)
+ y2 = np.clip(y + self.length // 2, 0, h)
+ x1 = np.clip(x - self.length // 2, 0, w)
+ x2 = np.clip(x + self.length // 2, 0, w)
+
+ mask[y1:y2, x1:x2] = 0.0
+ mask = torch.from_numpy(mask)
+ mask = mask.expand_as(img)
+ img *= mask
+ return img
+
+
+def randaugment_list():
+ # 16 oeprations and their ranges
+ # https://github.com/google-research/uda/blob/master/image/randaugment/policies.py#L57
+ # augs = [
+ # (Identity, 0., 1.0),
+ # (ShearX, 0., 0.3), # 0
+ # (ShearY, 0., 0.3), # 1
+ # (TranslateX, 0., 0.33), # 2
+ # (TranslateY, 0., 0.33), # 3
+ # (Rotate, 0, 30), # 4
+ # (AutoContrast, 0, 1), # 5
+ # (Invert, 0, 1), # 6
+ # (Equalize, 0, 1), # 7
+ # (Solarize, 0, 110), # 8
+ # (Posterize, 4, 8), # 9
+ # # (Contrast, 0.1, 1.9), # 10
+ # (Color, 0.1, 1.9), # 11
+ # (Brightness, 0.1, 1.9), # 12
+ # (Sharpness, 0.1, 1.9), # 13
+ # # (Cutout, 0, 0.2), # 14
+ # # (SamplePairing(imgs), 0, 0.4) # 15
+ # ]
+
+ # https://github.com/tensorflow/tpu/blob/8462d083dd89489a79e3200bcc8d4063bf362186/models/official/efficientnet/autoaugment.py#L505
+ augs = [
+ (AutoContrast, 0, 1),
+ (Equalize, 0, 1),
+ (Invert, 0, 1),
+ (Rotate, 0, 30),
+ (Posterize, 4, 8),
+ (Solarize, 0, 256),
+ (SolarizeAdd, 0, 110),
+ (Color, 0.1, 1.9),
+ (Contrast, 0.1, 1.9),
+ (Brightness, 0.1, 1.9),
+ (Sharpness, 0.1, 1.9),
+ (ShearX, 0.0, 0.3),
+ (ShearY, 0.0, 0.3),
+ (CutoutAbs, 0, 40),
+ (TranslateXabs, 0.0, 100),
+ (TranslateYabs, 0.0, 100),
+ ]
+
+ return augs
+
+
+def randaugment_list2():
+ augs = [
+ (AutoContrast, 0, 1),
+ (Brightness, 0.1, 1.9),
+ (Color, 0.1, 1.9),
+ (Contrast, 0.1, 1.9),
+ (Equalize, 0, 1),
+ (Identity, 0, 1),
+ (Invert, 0, 1),
+ (Posterize, 4, 8),
+ (Rotate, -30, 30),
+ (Sharpness, 0.1, 1.9),
+ (ShearX, -0.3, 0.3),
+ (ShearY, -0.3, 0.3),
+ (Solarize, 0, 256),
+ (TranslateX, -0.3, 0.3),
+ (TranslateY, -0.3, 0.3),
+ ]
+
+ return augs
+
+
+def fixmatch_list():
+ # https://arxiv.org/abs/2001.07685
+ augs = [
+ (AutoContrast, 0, 1),
+ (Brightness, 0.05, 0.95),
+ (Color, 0.05, 0.95),
+ (Contrast, 0.05, 0.95),
+ (Equalize, 0, 1),
+ (Identity, 0, 1),
+ (Posterize, 4, 8),
+ (Rotate, -30, 30),
+ (Sharpness, 0.05, 0.95),
+ (ShearX, -0.3, 0.3),
+ (ShearY, -0.3, 0.3),
+ (Solarize, 0, 256),
+ (TranslateX, -0.3, 0.3),
+ (TranslateY, -0.3, 0.3),
+ ]
+
+ return augs
+
+
+class RandAugment:
+
+ def __init__(self, n=2, m=10):
+ assert 0 <= m <= 30
+ self.n = n
+ self.m = m
+ self.augment_list = randaugment_list()
+
+ def __call__(self, img):
+ ops = random.choices(self.augment_list, k=self.n)
+
+ for op, minval, maxval in ops:
+ val = (self.m / 30) * (maxval-minval) + minval
+ img = op(img, val)
+
+ return img
+
+
+class RandAugment2:
+
+ def __init__(self, n=2, p=0.6):
+ self.n = n
+ self.p = p
+ self.augment_list = randaugment_list2()
+
+ def __call__(self, img):
+ ops = random.choices(self.augment_list, k=self.n)
+
+ for op, minval, maxval in ops:
+ if random.random() > self.p:
+ continue
+ m = random.random()
+ val = m * (maxval-minval) + minval
+ img = op(img, val)
+
+ return img
+
+
+class RandAugmentFixMatch:
+
+ def __init__(self, n=2):
+ self.n = n
+ self.augment_list = fixmatch_list()
+
+ def __call__(self, img):
+ ops = random.choices(self.augment_list, k=self.n)
+
+ for op, minval, maxval in ops:
+ m = random.random()
+ val = m * (maxval-minval) + minval
+ img = op(img, val)
+
+ return img
diff --git a/dassl/data/transforms/transforms.py b/dassl/data/transforms/transforms.py
new file mode 100644
index 0000000..4ea00d6
--- /dev/null
+++ b/dassl/data/transforms/transforms.py
@@ -0,0 +1,354 @@
+import numpy as np
+import random
+import torch
+import torchvision.transforms.functional as F
+from torchvision.transforms import (
+ Resize, Compose, ToTensor, Normalize, CenterCrop, RandomCrop, ColorJitter,
+ RandomApply, GaussianBlur, RandomGrayscale, RandomResizedCrop,
+ RandomHorizontalFlip
+)
+from torchvision.transforms.functional import InterpolationMode
+
+from .autoaugment import SVHNPolicy, CIFAR10Policy, ImageNetPolicy
+from .randaugment import RandAugment, RandAugment2, RandAugmentFixMatch
+
+AVAI_CHOICES = [
+ "random_flip",
+ "random_resized_crop",
+ "normalize",
+ "instance_norm",
+ "random_crop",
+ "random_translation",
+ "center_crop", # This has become a default operation during testing
+ "cutout",
+ "imagenet_policy",
+ "cifar10_policy",
+ "svhn_policy",
+ "randaugment",
+ "randaugment_fixmatch",
+ "randaugment2",
+ "gaussian_noise",
+ "colorjitter",
+ "randomgrayscale",
+ "gaussian_blur",
+]
+
+INTERPOLATION_MODES = {
+ "bilinear": InterpolationMode.BILINEAR,
+ "bicubic": InterpolationMode.BICUBIC,
+ "nearest": InterpolationMode.NEAREST,
+}
+
+
+class Random2DTranslation:
+ """Given an image of (height, width), we resize it to
+ (height*1.125, width*1.125), and then perform random cropping.
+
+ Args:
+ height (int): target image height.
+ width (int): target image width.
+ p (float, optional): probability that this operation takes place.
+ Default is 0.5.
+ interpolation (int, optional): desired interpolation. Default is
+ ``torchvision.transforms.functional.InterpolationMode.BILINEAR``
+ """
+
+ def __init__(
+ self, height, width, p=0.5, interpolation=InterpolationMode.BILINEAR
+ ):
+ self.height = height
+ self.width = width
+ self.p = p
+ self.interpolation = interpolation
+
+ def __call__(self, img):
+ if random.uniform(0, 1) > self.p:
+ return F.resize(
+ img=img,
+ size=[self.height, self.width],
+ interpolation=self.interpolation
+ )
+
+ new_width = int(round(self.width * 1.125))
+ new_height = int(round(self.height * 1.125))
+ resized_img = F.resize(
+ img=img,
+ size=[new_height, new_width],
+ interpolation=self.interpolation
+ )
+ x_maxrange = new_width - self.width
+ y_maxrange = new_height - self.height
+ x1 = int(round(random.uniform(0, x_maxrange)))
+ y1 = int(round(random.uniform(0, y_maxrange)))
+ croped_img = F.crop(
+ img=resized_img,
+ top=y1,
+ left=x1,
+ height=self.height,
+ width=self.width
+ )
+
+ return croped_img
+
+
+class InstanceNormalization:
+ """Normalize data using per-channel mean and standard deviation.
+
+ Reference:
+ - Ulyanov et al. Instance normalization: The missing in- gredient
+ for fast stylization. ArXiv 2016.
+ - Shu et al. A DIRT-T Approach to Unsupervised Domain Adaptation.
+ ICLR 2018.
+ """
+
+ def __init__(self, eps=1e-8):
+ self.eps = eps
+
+ def __call__(self, img):
+ C, H, W = img.shape
+ img_re = img.reshape(C, H * W)
+ mean = img_re.mean(1).view(C, 1, 1)
+ std = img_re.std(1).view(C, 1, 1)
+ return (img-mean) / (std + self.eps)
+
+
+class Cutout:
+ """Randomly mask out one or more patches from an image.
+
+ https://github.com/uoguelph-mlrg/Cutout
+
+ Args:
+ n_holes (int, optional): number of patches to cut out
+ of each image. Default is 1.
+ length (int, optinal): length (in pixels) of each square
+ patch. Default is 16.
+ """
+
+ def __init__(self, n_holes=1, length=16):
+ self.n_holes = n_holes
+ self.length = length
+
+ def __call__(self, img):
+ """
+ Args:
+ img (Tensor): tensor image of size (C, H, W).
+
+ Returns:
+ Tensor: image with n_holes of dimension
+ length x length cut out of it.
+ """
+ h = img.size(1)
+ w = img.size(2)
+
+ mask = np.ones((h, w), np.float32)
+
+ for n in range(self.n_holes):
+ y = np.random.randint(h)
+ x = np.random.randint(w)
+
+ y1 = np.clip(y - self.length // 2, 0, h)
+ y2 = np.clip(y + self.length // 2, 0, h)
+ x1 = np.clip(x - self.length // 2, 0, w)
+ x2 = np.clip(x + self.length // 2, 0, w)
+
+ mask[y1:y2, x1:x2] = 0.0
+
+ mask = torch.from_numpy(mask)
+ mask = mask.expand_as(img)
+ return img * mask
+
+
+class GaussianNoise:
+ """Add gaussian noise."""
+
+ def __init__(self, mean=0, std=0.15, p=0.5):
+ self.mean = mean
+ self.std = std
+ self.p = p
+
+ def __call__(self, img):
+ if random.uniform(0, 1) > self.p:
+ return img
+ noise = torch.randn(img.size()) * self.std + self.mean
+ return img + noise
+
+
+def build_transform(cfg, is_train=True, choices=None):
+ """Build transformation function.
+
+ Args:
+ cfg (CfgNode): config.
+ is_train (bool, optional): for training (True) or test (False).
+ Default is True.
+ choices (list, optional): list of strings which will overwrite
+ cfg.INPUT.TRANSFORMS if given. Default is None.
+ """
+ if cfg.INPUT.NO_TRANSFORM:
+ print("Note: no transform is applied!")
+ return None
+
+ if choices is None:
+ choices = cfg.INPUT.TRANSFORMS
+
+ for choice in choices:
+ assert choice in AVAI_CHOICES
+
+ target_size = f"{cfg.INPUT.SIZE[0]}x{cfg.INPUT.SIZE[1]}"
+
+ normalize = Normalize(mean=cfg.INPUT.PIXEL_MEAN, std=cfg.INPUT.PIXEL_STD)
+
+ if is_train:
+ return _build_transform_train(cfg, choices, target_size, normalize)
+ else:
+ return _build_transform_test(cfg, choices, target_size, normalize)
+
+
+def _build_transform_train(cfg, choices, target_size, normalize):
+ print("Building transform_train")
+ tfm_train = []
+
+ interp_mode = INTERPOLATION_MODES[cfg.INPUT.INTERPOLATION]
+ input_size = cfg.INPUT.SIZE
+
+ # Make sure the image size matches the target size
+ conditions = []
+ conditions += ["random_crop" not in choices]
+ conditions += ["random_resized_crop" not in choices]
+ if all(conditions):
+ print(f"+ resize to {target_size}")
+ tfm_train += [Resize(input_size, interpolation=interp_mode)]
+
+ if "random_translation" in choices:
+ print("+ random translation")
+ tfm_train += [Random2DTranslation(input_size[0], input_size[1])]
+
+ if "random_crop" in choices:
+ crop_padding = cfg.INPUT.CROP_PADDING
+ print(f"+ random crop (padding = {crop_padding})")
+ tfm_train += [RandomCrop(input_size, padding=crop_padding)]
+
+ if "random_resized_crop" in choices:
+ s_ = cfg.INPUT.RRCROP_SCALE
+ print(f"+ random resized crop (size={input_size}, scale={s_})")
+ tfm_train += [
+ RandomResizedCrop(input_size, scale=s_, interpolation=interp_mode)
+ ]
+
+ if "random_flip" in choices:
+ print("+ random flip")
+ tfm_train += [RandomHorizontalFlip()]
+
+ if "imagenet_policy" in choices:
+ print("+ imagenet policy")
+ tfm_train += [ImageNetPolicy()]
+
+ if "cifar10_policy" in choices:
+ print("+ cifar10 policy")
+ tfm_train += [CIFAR10Policy()]
+
+ if "svhn_policy" in choices:
+ print("+ svhn policy")
+ tfm_train += [SVHNPolicy()]
+
+ if "randaugment" in choices:
+ n_ = cfg.INPUT.RANDAUGMENT_N
+ m_ = cfg.INPUT.RANDAUGMENT_M
+ print(f"+ randaugment (n={n_}, m={m_})")
+ tfm_train += [RandAugment(n_, m_)]
+
+ if "randaugment_fixmatch" in choices:
+ n_ = cfg.INPUT.RANDAUGMENT_N
+ print(f"+ randaugment_fixmatch (n={n_})")
+ tfm_train += [RandAugmentFixMatch(n_)]
+
+ if "randaugment2" in choices:
+ n_ = cfg.INPUT.RANDAUGMENT_N
+ print(f"+ randaugment2 (n={n_})")
+ tfm_train += [RandAugment2(n_)]
+
+ if "colorjitter" in choices:
+ b_ = cfg.INPUT.COLORJITTER_B
+ c_ = cfg.INPUT.COLORJITTER_C
+ s_ = cfg.INPUT.COLORJITTER_S
+ h_ = cfg.INPUT.COLORJITTER_H
+ print(
+ f"+ color jitter (brightness={b_}, "
+ f"contrast={c_}, saturation={s_}, hue={h_})"
+ )
+ tfm_train += [
+ ColorJitter(
+ brightness=b_,
+ contrast=c_,
+ saturation=s_,
+ hue=h_,
+ )
+ ]
+
+ if "randomgrayscale" in choices:
+ print("+ random gray scale")
+ tfm_train += [RandomGrayscale(p=cfg.INPUT.RGS_P)]
+
+ if "gaussian_blur" in choices:
+ print(f"+ gaussian blur (kernel={cfg.INPUT.GB_K})")
+ gb_k, gb_p = cfg.INPUT.GB_K, cfg.INPUT.GB_P
+ tfm_train += [RandomApply([GaussianBlur(gb_k)], p=gb_p)]
+
+ print("+ to torch tensor of range [0, 1]")
+ tfm_train += [ToTensor()]
+
+ if "cutout" in choices:
+ cutout_n = cfg.INPUT.CUTOUT_N
+ cutout_len = cfg.INPUT.CUTOUT_LEN
+ print(f"+ cutout (n_holes={cutout_n}, length={cutout_len})")
+ tfm_train += [Cutout(cutout_n, cutout_len)]
+
+ if "normalize" in choices:
+ print(
+ f"+ normalization (mean={cfg.INPUT.PIXEL_MEAN}, std={cfg.INPUT.PIXEL_STD})"
+ )
+ tfm_train += [normalize]
+
+ if "gaussian_noise" in choices:
+ print(
+ f"+ gaussian noise (mean={cfg.INPUT.GN_MEAN}, std={cfg.INPUT.GN_STD})"
+ )
+ tfm_train += [GaussianNoise(cfg.INPUT.GN_MEAN, cfg.INPUT.GN_STD)]
+
+ if "instance_norm" in choices:
+ print("+ instance normalization")
+ tfm_train += [InstanceNormalization()]
+
+ tfm_train = Compose(tfm_train)
+
+ return tfm_train
+
+
+def _build_transform_test(cfg, choices, target_size, normalize):
+ print("Building transform_test")
+ tfm_test = []
+
+ interp_mode = INTERPOLATION_MODES[cfg.INPUT.INTERPOLATION]
+ input_size = cfg.INPUT.SIZE
+
+ print(f"+ resize the smaller edge to {max(input_size)}")
+ tfm_test += [Resize(max(input_size), interpolation=interp_mode)]
+
+ print(f"+ {target_size} center crop")
+ tfm_test += [CenterCrop(input_size)]
+
+ print("+ to torch tensor of range [0, 1]")
+ tfm_test += [ToTensor()]
+
+ if "normalize" in choices:
+ print(
+ f"+ normalization (mean={cfg.INPUT.PIXEL_MEAN}, std={cfg.INPUT.PIXEL_STD})"
+ )
+ tfm_test += [normalize]
+
+ if "instance_norm" in choices:
+ print("+ instance normalization")
+ tfm_test += [InstanceNormalization()]
+
+ tfm_test = Compose(tfm_test)
+
+ return tfm_test
diff --git a/dassl/engine/__init__.py b/dassl/engine/__init__.py
new file mode 100644
index 0000000..3cb3fb8
--- /dev/null
+++ b/dassl/engine/__init__.py
@@ -0,0 +1,6 @@
+from .build import TRAINER_REGISTRY, build_trainer # isort:skip
+from .trainer import TrainerX, TrainerXU, TrainerBase, SimpleTrainer, SimpleNet # isort:skip
+
+from .da import *
+from .dg import *
+from .ssl import *
diff --git a/dassl/engine/__pycache__/__init__.cpython-310.pyc b/dassl/engine/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000..e208bb2
Binary files /dev/null and b/dassl/engine/__pycache__/__init__.cpython-310.pyc differ
diff --git a/dassl/engine/__pycache__/__init__.cpython-311.pyc b/dassl/engine/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000..00684c0
Binary files /dev/null and b/dassl/engine/__pycache__/__init__.cpython-311.pyc differ
diff --git a/dassl/engine/__pycache__/__init__.cpython-38.pyc b/dassl/engine/__pycache__/__init__.cpython-38.pyc
new file mode 100644
index 0000000..f93cec5
Binary files /dev/null and b/dassl/engine/__pycache__/__init__.cpython-38.pyc differ
diff --git a/dassl/engine/__pycache__/build.cpython-310.pyc b/dassl/engine/__pycache__/build.cpython-310.pyc
new file mode 100644
index 0000000..0e90736
Binary files /dev/null and b/dassl/engine/__pycache__/build.cpython-310.pyc differ
diff --git a/dassl/engine/__pycache__/build.cpython-311.pyc b/dassl/engine/__pycache__/build.cpython-311.pyc
new file mode 100644
index 0000000..f07a3f0
Binary files /dev/null and b/dassl/engine/__pycache__/build.cpython-311.pyc differ
diff --git a/dassl/engine/__pycache__/build.cpython-38.pyc b/dassl/engine/__pycache__/build.cpython-38.pyc
new file mode 100644
index 0000000..bfa5687
Binary files /dev/null and b/dassl/engine/__pycache__/build.cpython-38.pyc differ
diff --git a/dassl/engine/__pycache__/trainer.cpython-310.pyc b/dassl/engine/__pycache__/trainer.cpython-310.pyc
new file mode 100644
index 0000000..fb5ab44
Binary files /dev/null and b/dassl/engine/__pycache__/trainer.cpython-310.pyc differ
diff --git a/dassl/engine/__pycache__/trainer.cpython-311.pyc b/dassl/engine/__pycache__/trainer.cpython-311.pyc
new file mode 100644
index 0000000..3da3e50
Binary files /dev/null and b/dassl/engine/__pycache__/trainer.cpython-311.pyc differ
diff --git a/dassl/engine/__pycache__/trainer.cpython-38.pyc b/dassl/engine/__pycache__/trainer.cpython-38.pyc
new file mode 100644
index 0000000..2451c53
Binary files /dev/null and b/dassl/engine/__pycache__/trainer.cpython-38.pyc differ
diff --git a/dassl/engine/build.py b/dassl/engine/build.py
new file mode 100644
index 0000000..456ba8d
--- /dev/null
+++ b/dassl/engine/build.py
@@ -0,0 +1,11 @@
+from dassl.utils import Registry, check_availability
+
+TRAINER_REGISTRY = Registry("TRAINER")
+
+
+def build_trainer(cfg):
+ avai_trainers = TRAINER_REGISTRY.registered_names()
+ check_availability(cfg.TRAINER.NAME, avai_trainers)
+ if cfg.VERBOSE:
+ print("Loading trainer: {}".format(cfg.TRAINER.NAME))
+ return TRAINER_REGISTRY.get(cfg.TRAINER.NAME)(cfg)
diff --git a/dassl/engine/da/__init__.py b/dassl/engine/da/__init__.py
new file mode 100644
index 0000000..910bf34
--- /dev/null
+++ b/dassl/engine/da/__init__.py
@@ -0,0 +1,10 @@
+from .se import SE
+from .mcd import MCD
+from .mme import MME
+from .adda import ADDA
+from .cdac import CDAC
+from .dael import DAEL
+from .dann import DANN
+from .adabn import AdaBN
+from .m3sda import M3SDA
+from .source_only import SourceOnly
diff --git a/dassl/engine/da/__pycache__/__init__.cpython-310.pyc b/dassl/engine/da/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000..6dd1c5b
Binary files /dev/null and b/dassl/engine/da/__pycache__/__init__.cpython-310.pyc differ
diff --git a/dassl/engine/da/__pycache__/__init__.cpython-311.pyc b/dassl/engine/da/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000..5479678
Binary files /dev/null and b/dassl/engine/da/__pycache__/__init__.cpython-311.pyc differ
diff --git a/dassl/engine/da/__pycache__/__init__.cpython-38.pyc b/dassl/engine/da/__pycache__/__init__.cpython-38.pyc
new file mode 100644
index 0000000..e288256
Binary files /dev/null and b/dassl/engine/da/__pycache__/__init__.cpython-38.pyc differ
diff --git a/dassl/engine/da/__pycache__/adabn.cpython-310.pyc b/dassl/engine/da/__pycache__/adabn.cpython-310.pyc
new file mode 100644
index 0000000..1477afb
Binary files /dev/null and b/dassl/engine/da/__pycache__/adabn.cpython-310.pyc differ
diff --git a/dassl/engine/da/__pycache__/adabn.cpython-311.pyc b/dassl/engine/da/__pycache__/adabn.cpython-311.pyc
new file mode 100644
index 0000000..18e7c96
Binary files /dev/null and b/dassl/engine/da/__pycache__/adabn.cpython-311.pyc differ
diff --git a/dassl/engine/da/__pycache__/adabn.cpython-38.pyc b/dassl/engine/da/__pycache__/adabn.cpython-38.pyc
new file mode 100644
index 0000000..20fff97
Binary files /dev/null and b/dassl/engine/da/__pycache__/adabn.cpython-38.pyc differ
diff --git a/dassl/engine/da/__pycache__/adda.cpython-310.pyc b/dassl/engine/da/__pycache__/adda.cpython-310.pyc
new file mode 100644
index 0000000..55c4757
Binary files /dev/null and b/dassl/engine/da/__pycache__/adda.cpython-310.pyc differ
diff --git a/dassl/engine/da/__pycache__/adda.cpython-311.pyc b/dassl/engine/da/__pycache__/adda.cpython-311.pyc
new file mode 100644
index 0000000..4ed988c
Binary files /dev/null and b/dassl/engine/da/__pycache__/adda.cpython-311.pyc differ
diff --git a/dassl/engine/da/__pycache__/adda.cpython-38.pyc b/dassl/engine/da/__pycache__/adda.cpython-38.pyc
new file mode 100644
index 0000000..bc41b13
Binary files /dev/null and b/dassl/engine/da/__pycache__/adda.cpython-38.pyc differ
diff --git a/dassl/engine/da/__pycache__/cdac.cpython-310.pyc b/dassl/engine/da/__pycache__/cdac.cpython-310.pyc
new file mode 100644
index 0000000..ec1551a
Binary files /dev/null and b/dassl/engine/da/__pycache__/cdac.cpython-310.pyc differ
diff --git a/dassl/engine/da/__pycache__/cdac.cpython-311.pyc b/dassl/engine/da/__pycache__/cdac.cpython-311.pyc
new file mode 100644
index 0000000..c48b257
Binary files /dev/null and b/dassl/engine/da/__pycache__/cdac.cpython-311.pyc differ
diff --git a/dassl/engine/da/__pycache__/cdac.cpython-38.pyc b/dassl/engine/da/__pycache__/cdac.cpython-38.pyc
new file mode 100644
index 0000000..48e2e52
Binary files /dev/null and b/dassl/engine/da/__pycache__/cdac.cpython-38.pyc differ
diff --git a/dassl/engine/da/__pycache__/dael.cpython-310.pyc b/dassl/engine/da/__pycache__/dael.cpython-310.pyc
new file mode 100644
index 0000000..d54daa0
Binary files /dev/null and b/dassl/engine/da/__pycache__/dael.cpython-310.pyc differ
diff --git a/dassl/engine/da/__pycache__/dael.cpython-311.pyc b/dassl/engine/da/__pycache__/dael.cpython-311.pyc
new file mode 100644
index 0000000..794db05
Binary files /dev/null and b/dassl/engine/da/__pycache__/dael.cpython-311.pyc differ
diff --git a/dassl/engine/da/__pycache__/dael.cpython-38.pyc b/dassl/engine/da/__pycache__/dael.cpython-38.pyc
new file mode 100644
index 0000000..78db289
Binary files /dev/null and b/dassl/engine/da/__pycache__/dael.cpython-38.pyc differ
diff --git a/dassl/engine/da/__pycache__/dann.cpython-310.pyc b/dassl/engine/da/__pycache__/dann.cpython-310.pyc
new file mode 100644
index 0000000..31fccb9
Binary files /dev/null and b/dassl/engine/da/__pycache__/dann.cpython-310.pyc differ
diff --git a/dassl/engine/da/__pycache__/dann.cpython-311.pyc b/dassl/engine/da/__pycache__/dann.cpython-311.pyc
new file mode 100644
index 0000000..540c99e
Binary files /dev/null and b/dassl/engine/da/__pycache__/dann.cpython-311.pyc differ
diff --git a/dassl/engine/da/__pycache__/dann.cpython-38.pyc b/dassl/engine/da/__pycache__/dann.cpython-38.pyc
new file mode 100644
index 0000000..bcd740a
Binary files /dev/null and b/dassl/engine/da/__pycache__/dann.cpython-38.pyc differ
diff --git a/dassl/engine/da/__pycache__/m3sda.cpython-310.pyc b/dassl/engine/da/__pycache__/m3sda.cpython-310.pyc
new file mode 100644
index 0000000..8d90eab
Binary files /dev/null and b/dassl/engine/da/__pycache__/m3sda.cpython-310.pyc differ
diff --git a/dassl/engine/da/__pycache__/m3sda.cpython-311.pyc b/dassl/engine/da/__pycache__/m3sda.cpython-311.pyc
new file mode 100644
index 0000000..eade75a
Binary files /dev/null and b/dassl/engine/da/__pycache__/m3sda.cpython-311.pyc differ
diff --git a/dassl/engine/da/__pycache__/m3sda.cpython-38.pyc b/dassl/engine/da/__pycache__/m3sda.cpython-38.pyc
new file mode 100644
index 0000000..ad7c072
Binary files /dev/null and b/dassl/engine/da/__pycache__/m3sda.cpython-38.pyc differ
diff --git a/dassl/engine/da/__pycache__/mcd.cpython-310.pyc b/dassl/engine/da/__pycache__/mcd.cpython-310.pyc
new file mode 100644
index 0000000..5bf361c
Binary files /dev/null and b/dassl/engine/da/__pycache__/mcd.cpython-310.pyc differ
diff --git a/dassl/engine/da/__pycache__/mcd.cpython-311.pyc b/dassl/engine/da/__pycache__/mcd.cpython-311.pyc
new file mode 100644
index 0000000..7e29902
Binary files /dev/null and b/dassl/engine/da/__pycache__/mcd.cpython-311.pyc differ
diff --git a/dassl/engine/da/__pycache__/mcd.cpython-38.pyc b/dassl/engine/da/__pycache__/mcd.cpython-38.pyc
new file mode 100644
index 0000000..70e5ed4
Binary files /dev/null and b/dassl/engine/da/__pycache__/mcd.cpython-38.pyc differ
diff --git a/dassl/engine/da/__pycache__/mme.cpython-310.pyc b/dassl/engine/da/__pycache__/mme.cpython-310.pyc
new file mode 100644
index 0000000..3b2f2a1
Binary files /dev/null and b/dassl/engine/da/__pycache__/mme.cpython-310.pyc differ
diff --git a/dassl/engine/da/__pycache__/mme.cpython-311.pyc b/dassl/engine/da/__pycache__/mme.cpython-311.pyc
new file mode 100644
index 0000000..4ab68c9
Binary files /dev/null and b/dassl/engine/da/__pycache__/mme.cpython-311.pyc differ
diff --git a/dassl/engine/da/__pycache__/mme.cpython-38.pyc b/dassl/engine/da/__pycache__/mme.cpython-38.pyc
new file mode 100644
index 0000000..df39d9f
Binary files /dev/null and b/dassl/engine/da/__pycache__/mme.cpython-38.pyc differ
diff --git a/dassl/engine/da/__pycache__/se.cpython-310.pyc b/dassl/engine/da/__pycache__/se.cpython-310.pyc
new file mode 100644
index 0000000..696abbd
Binary files /dev/null and b/dassl/engine/da/__pycache__/se.cpython-310.pyc differ
diff --git a/dassl/engine/da/__pycache__/se.cpython-311.pyc b/dassl/engine/da/__pycache__/se.cpython-311.pyc
new file mode 100644
index 0000000..af15c3a
Binary files /dev/null and b/dassl/engine/da/__pycache__/se.cpython-311.pyc differ
diff --git a/dassl/engine/da/__pycache__/se.cpython-38.pyc b/dassl/engine/da/__pycache__/se.cpython-38.pyc
new file mode 100644
index 0000000..d382cef
Binary files /dev/null and b/dassl/engine/da/__pycache__/se.cpython-38.pyc differ
diff --git a/dassl/engine/da/__pycache__/source_only.cpython-310.pyc b/dassl/engine/da/__pycache__/source_only.cpython-310.pyc
new file mode 100644
index 0000000..a4de383
Binary files /dev/null and b/dassl/engine/da/__pycache__/source_only.cpython-310.pyc differ
diff --git a/dassl/engine/da/__pycache__/source_only.cpython-311.pyc b/dassl/engine/da/__pycache__/source_only.cpython-311.pyc
new file mode 100644
index 0000000..281850c
Binary files /dev/null and b/dassl/engine/da/__pycache__/source_only.cpython-311.pyc differ
diff --git a/dassl/engine/da/__pycache__/source_only.cpython-38.pyc b/dassl/engine/da/__pycache__/source_only.cpython-38.pyc
new file mode 100644
index 0000000..b630dcd
Binary files /dev/null and b/dassl/engine/da/__pycache__/source_only.cpython-38.pyc differ
diff --git a/dassl/engine/da/adabn.py b/dassl/engine/da/adabn.py
new file mode 100644
index 0000000..116d8a2
--- /dev/null
+++ b/dassl/engine/da/adabn.py
@@ -0,0 +1,38 @@
+import torch
+
+from dassl.utils import check_isfile
+from dassl.engine import TRAINER_REGISTRY, TrainerXU
+
+
+@TRAINER_REGISTRY.register()
+class AdaBN(TrainerXU):
+ """Adaptive Batch Normalization.
+
+ https://arxiv.org/abs/1603.04779.
+ """
+
+ def __init__(self, cfg):
+ super().__init__(cfg)
+ self.done_reset_bn_stats = False
+
+ def check_cfg(self, cfg):
+ assert check_isfile(
+ cfg.MODEL.INIT_WEIGHTS
+ ), "The weights of source model must be provided"
+
+ def before_epoch(self):
+ if not self.done_reset_bn_stats:
+ for m in self.model.modules():
+ classname = m.__class__.__name__
+ if classname.find("BatchNorm") != -1:
+ m.reset_running_stats()
+
+ self.done_reset_bn_stats = True
+
+ def forward_backward(self, batch_x, batch_u):
+ input_u = batch_u["img"].to(self.device)
+
+ with torch.no_grad():
+ self.model(input_u)
+
+ return None
diff --git a/dassl/engine/da/adda.py b/dassl/engine/da/adda.py
new file mode 100644
index 0000000..a9018e7
--- /dev/null
+++ b/dassl/engine/da/adda.py
@@ -0,0 +1,85 @@
+import copy
+import torch
+import torch.nn as nn
+
+from dassl.optim import build_optimizer, build_lr_scheduler
+from dassl.utils import check_isfile, count_num_param, open_specified_layers
+from dassl.engine import TRAINER_REGISTRY, TrainerXU
+from dassl.modeling import build_head
+
+
+@TRAINER_REGISTRY.register()
+class ADDA(TrainerXU):
+ """Adversarial Discriminative Domain Adaptation.
+
+ https://arxiv.org/abs/1702.05464.
+ """
+
+ def __init__(self, cfg):
+ super().__init__(cfg)
+ self.open_layers = ["backbone"]
+ if isinstance(self.model.head, nn.Module):
+ self.open_layers.append("head")
+
+ self.source_model = copy.deepcopy(self.model)
+ self.source_model.eval()
+ for param in self.source_model.parameters():
+ param.requires_grad_(False)
+
+ self.build_critic()
+
+ self.bce = nn.BCEWithLogitsLoss()
+
+ def check_cfg(self, cfg):
+ assert check_isfile(
+ cfg.MODEL.INIT_WEIGHTS
+ ), "The weights of source model must be provided"
+
+ def build_critic(self):
+ cfg = self.cfg
+
+ print("Building critic network")
+ fdim = self.model.fdim
+ critic_body = build_head(
+ "mlp",
+ verbose=cfg.VERBOSE,
+ in_features=fdim,
+ hidden_layers=[fdim, fdim // 2],
+ activation="leaky_relu",
+ )
+ self.critic = nn.Sequential(critic_body, nn.Linear(fdim // 2, 1))
+ print("# params: {:,}".format(count_num_param(self.critic)))
+ self.critic.to(self.device)
+ self.optim_c = build_optimizer(self.critic, cfg.OPTIM)
+ self.sched_c = build_lr_scheduler(self.optim_c, cfg.OPTIM)
+ self.register_model("critic", self.critic, self.optim_c, self.sched_c)
+
+ def forward_backward(self, batch_x, batch_u):
+ open_specified_layers(self.model, self.open_layers)
+ input_x, _, input_u = self.parse_batch_train(batch_x, batch_u)
+ domain_x = torch.ones(input_x.shape[0], 1).to(self.device)
+ domain_u = torch.zeros(input_u.shape[0], 1).to(self.device)
+
+ _, feat_x = self.source_model(input_x, return_feature=True)
+ _, feat_u = self.model(input_u, return_feature=True)
+
+ logit_xd = self.critic(feat_x)
+ logit_ud = self.critic(feat_u.detach())
+
+ loss_critic = self.bce(logit_xd, domain_x)
+ loss_critic += self.bce(logit_ud, domain_u)
+ self.model_backward_and_update(loss_critic, "critic")
+
+ logit_ud = self.critic(feat_u)
+ loss_model = self.bce(logit_ud, 1 - domain_u)
+ self.model_backward_and_update(loss_model, "model")
+
+ loss_summary = {
+ "loss_critic": loss_critic.item(),
+ "loss_model": loss_model.item(),
+ }
+
+ if (self.batch_idx + 1) == self.num_batches:
+ self.update_lr()
+
+ return loss_summary
diff --git a/dassl/engine/da/cdac.py b/dassl/engine/da/cdac.py
new file mode 100644
index 0000000..ed84659
--- /dev/null
+++ b/dassl/engine/da/cdac.py
@@ -0,0 +1,275 @@
+import numpy as np
+from functools import partial
+import torch
+import torch.nn as nn
+from torch.nn import functional as F
+from torch.optim.lr_scheduler import LambdaLR
+
+from dassl.data import DataManager
+from dassl.optim import build_optimizer
+from dassl.utils import count_num_param
+from dassl.engine import TRAINER_REGISTRY, TrainerXU
+from dassl.metrics import compute_accuracy
+from dassl.modeling.ops import ReverseGrad
+from dassl.engine.trainer import SimpleNet
+from dassl.data.transforms.transforms import build_transform
+
+
+def custom_scheduler(iter, max_iter=None, alpha=10, beta=0.75, init_lr=0.001):
+ """Custom LR Annealing
+
+ https://arxiv.org/pdf/1409.7495.pdf
+ """
+ if max_iter is None:
+ return init_lr
+ return (1 + float(iter / max_iter) * alpha)**(-1.0 * beta)
+
+
+class AAC(nn.Module):
+
+ def forward(self, sim_mat, prob_u, prob_us):
+
+ P = prob_u.matmul(prob_us.t())
+
+ loss = -(
+ sim_mat * torch.log(P + 1e-7) +
+ (1.-sim_mat) * torch.log(1. - P + 1e-7)
+ )
+ return loss.mean()
+
+
+class Prototypes(nn.Module):
+
+ def __init__(self, fdim, num_classes, temp=0.05):
+ super().__init__()
+ self.prototypes = nn.Linear(fdim, num_classes, bias=False)
+ self.temp = temp
+ self.revgrad = ReverseGrad()
+
+ def forward(self, x, reverse=False):
+ if reverse:
+ x = self.revgrad(x)
+ x = F.normalize(x, p=2, dim=1)
+ out = self.prototypes(x)
+ out = out / self.temp
+ return out
+
+
+@TRAINER_REGISTRY.register()
+class CDAC(TrainerXU):
+ """Cross Domain Adaptive Clustering.
+
+ https://arxiv.org/pdf/2104.09415.pdf
+ """
+
+ def __init__(self, cfg):
+ self.rampup_coef = cfg.TRAINER.CDAC.RAMPUP_COEF
+ self.rampup_iters = cfg.TRAINER.CDAC.RAMPUP_ITRS
+ self.lr_multi = cfg.TRAINER.CDAC.CLASS_LR_MULTI
+ self.topk = cfg.TRAINER.CDAC.TOPK_MATCH
+ self.p_thresh = cfg.TRAINER.CDAC.P_THRESH
+ self.aac_criterion = AAC()
+ super().__init__(cfg)
+
+ def check_cfg(self, cfg):
+ assert len(
+ cfg.TRAINER.CDAC.STRONG_TRANSFORMS
+ ) > 0, "Strong augmentations are necessary to run CDAC"
+ assert cfg.DATALOADER.K_TRANSFORMS == 2, "CDAC needs two strong augmentations of the same image."
+
+ def build_data_loader(self):
+
+ cfg = self.cfg
+ tfm_train = build_transform(cfg, is_train=True)
+ custom_tfm_train = [tfm_train]
+ choices = cfg.TRAINER.CDAC.STRONG_TRANSFORMS
+ tfm_train_strong = build_transform(cfg, is_train=True, choices=choices)
+ custom_tfm_train += [tfm_train_strong]
+ self.dm = DataManager(self.cfg, custom_tfm_train=custom_tfm_train)
+ self.train_loader_x = self.dm.train_loader_x
+ self.train_loader_u = self.dm.train_loader_u
+ self.val_loader = self.dm.val_loader
+ self.test_loader = self.dm.test_loader
+ self.num_classes = self.dm.num_classes
+ self.lab2cname = self.dm.lab2cname
+
+ def build_model(self):
+ cfg = self.cfg
+
+ # Custom LR Scheduler for CDAC
+ if self.cfg.TRAIN.COUNT_ITER == "train_x":
+ self.num_batches = len(self.train_loader_x)
+ elif self.cfg.TRAIN.COUNT_ITER == "train_u":
+ self.num_batches = len(self.len_train_loader_u)
+ elif self.cfg.TRAIN.COUNT_ITER == "smaller_one":
+ self.num_batches = min(
+ len(self.train_loader_x), len(self.train_loader_u)
+ )
+ self.max_iter = self.max_epoch * self.num_batches
+ print("Max Iterations: %d" % self.max_iter)
+
+ print("Building F")
+ self.F = SimpleNet(cfg, cfg.MODEL, 0)
+ self.F.to(self.device)
+ print("# params: {:,}".format(count_num_param(self.F)))
+ self.optim_F = build_optimizer(self.F, cfg.OPTIM)
+ custom_lr_F = partial(
+ custom_scheduler, max_iter=self.max_iter, init_lr=cfg.OPTIM.LR
+ )
+ self.sched_F = LambdaLR(self.optim_F, custom_lr_F)
+ self.register_model("F", self.F, self.optim_F, self.sched_F)
+
+ print("Building C")
+ self.C = Prototypes(self.F.fdim, self.num_classes)
+ self.C.to(self.device)
+ print("# params: {:,}".format(count_num_param(self.C)))
+ self.optim_C = build_optimizer(self.C, cfg.OPTIM)
+
+ # Multiply the learning rate of C by lr_multi
+ for group_param in self.optim_C.param_groups:
+ group_param['lr'] *= self.lr_multi
+ custom_lr_C = partial(
+ custom_scheduler,
+ max_iter=self.max_iter,
+ init_lr=cfg.OPTIM.LR * self.lr_multi
+ )
+ self.sched_C = LambdaLR(self.optim_C, custom_lr_C)
+ self.register_model("C", self.C, self.optim_C, self.sched_C)
+
+ def assess_y_pred_quality(self, y_pred, y_true, mask):
+ n_masked_correct = (y_pred.eq(y_true).float() * mask).sum()
+ acc_thre = n_masked_correct / (mask.sum() + 1e-5)
+ acc_raw = y_pred.eq(y_true).sum() / y_pred.numel() # raw accuracy
+ keep_rate = mask.sum() / mask.numel()
+ output = {
+ "acc_thre": acc_thre,
+ "acc_raw": acc_raw,
+ "keep_rate": keep_rate
+ }
+ return output
+
+ def forward_backward(self, batch_x, batch_u):
+
+ current_itr = self.epoch * self.num_batches + self.batch_idx
+
+ input_x, label_x, input_u, input_us, input_us2, label_u = self.parse_batch_train(
+ batch_x, batch_u
+ )
+
+ # Paper Reference Eq. 2 - Supervised Loss
+
+ feat_x = self.F(input_x)
+ logit_x = self.C(feat_x)
+ loss_x = F.cross_entropy(logit_x, label_x)
+
+ self.model_backward_and_update(loss_x)
+
+ feat_u = self.F(input_u)
+ feat_us = self.F(input_us)
+ feat_us2 = self.F(input_us2)
+
+ # Paper Reference Eq.3 - Adversarial Adaptive Loss
+ logit_u = self.C(feat_u, reverse=True)
+ logit_us = self.C(feat_us, reverse=True)
+ prob_u, prob_us = F.softmax(logit_u, dim=1), F.softmax(logit_us, dim=1)
+
+ # Get similarity matrix s_ij
+ sim_mat = self.get_similarity_matrix(feat_u, self.topk, self.device)
+
+ aac_loss = (-1. * self.aac_criterion(sim_mat, prob_u, prob_us))
+
+ # Paper Reference Eq. 4 - Pseudo label Loss
+ logit_u = self.C(feat_u)
+ logit_us = self.C(feat_us)
+ logit_us2 = self.C(feat_us2)
+ prob_u, prob_us, prob_us2 = F.softmax(
+ logit_u, dim=1
+ ), F.softmax(
+ logit_us, dim=1
+ ), F.softmax(
+ logit_us2, dim=1
+ )
+ prob_u = prob_u.detach()
+ max_probs, max_idx = torch.max(prob_u, dim=-1)
+ mask = max_probs.ge(self.p_thresh).float()
+ p_u_stats = self.assess_y_pred_quality(max_idx, label_u, mask)
+
+ pl_loss = (
+ F.cross_entropy(logit_us2, max_idx, reduction='none') * mask
+ ).mean()
+
+ # Paper Reference Eq. 8 - Consistency Loss
+ cons_multi = self.sigmoid_rampup(
+ current_itr=current_itr, rampup_itr=self.rampup_iters
+ ) * self.rampup_coef
+ cons_loss = cons_multi * F.mse_loss(prob_us, prob_us2)
+
+ loss_u = aac_loss + pl_loss + cons_loss
+
+ self.model_backward_and_update(loss_u)
+
+ loss_summary = {
+ "loss_x": loss_x.item(),
+ "acc_x": compute_accuracy(logit_x, label_x)[0].item(),
+ "loss_u": loss_u.item(),
+ "aac_loss": aac_loss.item(),
+ "pl_loss": pl_loss.item(),
+ "cons_loss": cons_loss.item(),
+ "p_u_pred_acc": p_u_stats["acc_raw"],
+ "p_u_pred_acc_thre": p_u_stats["acc_thre"],
+ "p_u_pred_keep": p_u_stats["keep_rate"]
+ }
+
+ # Update LR after every iteration as mentioned in the paper
+
+ self.update_lr()
+
+ return loss_summary
+
+ def parse_batch_train(self, batch_x, batch_u):
+
+ input_x = batch_x["img"][0]
+ label_x = batch_x["label"]
+
+ input_u = batch_u["img"][0]
+ input_us = batch_u["img2"][0]
+ input_us2 = batch_u["img2"][1]
+ label_u = batch_u["label"]
+
+ input_x = input_x.to(self.device)
+ label_x = label_x.to(self.device)
+
+ input_u = input_u.to(self.device)
+ input_us = input_us.to(self.device)
+ input_us2 = input_us2.to(self.device)
+ label_u = label_u.to(self.device)
+
+ return input_x, label_x, input_u, input_us, input_us2, label_u
+
+ def model_inference(self, input):
+ return self.C(self.F(input))
+
+ @staticmethod
+ def get_similarity_matrix(feat, topk, device):
+
+ feat_d = feat.detach()
+
+ feat_d = torch.sort(
+ torch.argsort(feat_d, dim=1, descending=True)[:, :topk], dim=1
+ )[0]
+ sim_mat = torch.zeros((feat_d.shape[0], feat_d.shape[0])).to(device)
+ for row in range(feat_d.shape[0]):
+ sim_mat[row, torch.all(feat_d == feat_d[row, :], dim=1)] = 1
+ return sim_mat
+
+ @staticmethod
+ def sigmoid_rampup(current_itr, rampup_itr):
+ """Exponential Rampup
+ https://arxiv.org/abs/1610.02242
+ """
+ if rampup_itr == 0:
+ return 1.0
+ else:
+ var = np.clip(current_itr, 0.0, rampup_itr)
+ phase = 1.0 - var/rampup_itr
+ return float(np.exp(-5.0 * phase * phase))
diff --git a/dassl/engine/da/dael.py b/dassl/engine/da/dael.py
new file mode 100644
index 0000000..458df7d
--- /dev/null
+++ b/dassl/engine/da/dael.py
@@ -0,0 +1,210 @@
+import torch
+import torch.nn as nn
+
+from dassl.data import DataManager
+from dassl.optim import build_optimizer, build_lr_scheduler
+from dassl.utils import count_num_param
+from dassl.engine import TRAINER_REGISTRY, TrainerXU
+from dassl.metrics import compute_accuracy
+from dassl.engine.trainer import SimpleNet
+from dassl.data.transforms import build_transform
+from dassl.modeling.ops.utils import create_onehot
+
+
+class Experts(nn.Module):
+
+ def __init__(self, n_source, fdim, num_classes):
+ super().__init__()
+ self.linears = nn.ModuleList(
+ [nn.Linear(fdim, num_classes) for _ in range(n_source)]
+ )
+ self.softmax = nn.Softmax(dim=1)
+
+ def forward(self, i, x):
+ x = self.linears[i](x)
+ x = self.softmax(x)
+ return x
+
+
+@TRAINER_REGISTRY.register()
+class DAEL(TrainerXU):
+ """Domain Adaptive Ensemble Learning.
+
+ https://arxiv.org/abs/2003.07325.
+ """
+
+ def __init__(self, cfg):
+ super().__init__(cfg)
+ n_domain = cfg.DATALOADER.TRAIN_X.N_DOMAIN
+ batch_size = cfg.DATALOADER.TRAIN_X.BATCH_SIZE
+ if n_domain <= 0:
+ n_domain = self.num_source_domains
+ self.split_batch = batch_size // n_domain
+ self.n_domain = n_domain
+
+ self.weight_u = cfg.TRAINER.DAEL.WEIGHT_U
+ self.conf_thre = cfg.TRAINER.DAEL.CONF_THRE
+
+ def check_cfg(self, cfg):
+ assert cfg.DATALOADER.TRAIN_X.SAMPLER == "RandomDomainSampler"
+ assert not cfg.DATALOADER.TRAIN_U.SAME_AS_X
+ assert len(cfg.TRAINER.DAEL.STRONG_TRANSFORMS) > 0
+
+ def build_data_loader(self):
+ cfg = self.cfg
+ tfm_train = build_transform(cfg, is_train=True)
+ custom_tfm_train = [tfm_train]
+ choices = cfg.TRAINER.DAEL.STRONG_TRANSFORMS
+ tfm_train_strong = build_transform(cfg, is_train=True, choices=choices)
+ custom_tfm_train += [tfm_train_strong]
+ dm = DataManager(self.cfg, custom_tfm_train=custom_tfm_train)
+ self.train_loader_x = dm.train_loader_x
+ self.train_loader_u = dm.train_loader_u
+ self.val_loader = dm.val_loader
+ self.test_loader = dm.test_loader
+ self.num_classes = dm.num_classes
+ self.num_source_domains = dm.num_source_domains
+ self.lab2cname = dm.lab2cname
+
+ def build_model(self):
+ cfg = self.cfg
+
+ print("Building F")
+ self.F = SimpleNet(cfg, cfg.MODEL, 0)
+ self.F.to(self.device)
+ print("# params: {:,}".format(count_num_param(self.F)))
+ self.optim_F = build_optimizer(self.F, cfg.OPTIM)
+ self.sched_F = build_lr_scheduler(self.optim_F, cfg.OPTIM)
+ self.register_model("F", self.F, self.optim_F, self.sched_F)
+ fdim = self.F.fdim
+
+ print("Building E")
+ self.E = Experts(self.num_source_domains, fdim, self.num_classes)
+ self.E.to(self.device)
+ print("# params: {:,}".format(count_num_param(self.E)))
+ self.optim_E = build_optimizer(self.E, cfg.OPTIM)
+ self.sched_E = build_lr_scheduler(self.optim_E, cfg.OPTIM)
+ self.register_model("E", self.E, self.optim_E, self.sched_E)
+
+ def forward_backward(self, batch_x, batch_u):
+ parsed_data = self.parse_batch_train(batch_x, batch_u)
+ input_x, input_x2, label_x, domain_x, input_u, input_u2 = parsed_data
+
+ input_x = torch.split(input_x, self.split_batch, 0)
+ input_x2 = torch.split(input_x2, self.split_batch, 0)
+ label_x = torch.split(label_x, self.split_batch, 0)
+ domain_x = torch.split(domain_x, self.split_batch, 0)
+ domain_x = [d[0].item() for d in domain_x]
+
+ # Generate pseudo label
+ with torch.no_grad():
+ feat_u = self.F(input_u)
+ pred_u = []
+ for k in range(self.num_source_domains):
+ pred_uk = self.E(k, feat_u)
+ pred_uk = pred_uk.unsqueeze(1)
+ pred_u.append(pred_uk)
+ pred_u = torch.cat(pred_u, 1) # (B, K, C)
+ # Get the highest probability and index (label) for each expert
+ experts_max_p, experts_max_idx = pred_u.max(2) # (B, K)
+ # Get the most confident expert
+ max_expert_p, max_expert_idx = experts_max_p.max(1) # (B)
+ pseudo_label_u = []
+ for i, experts_label in zip(max_expert_idx, experts_max_idx):
+ pseudo_label_u.append(experts_label[i])
+ pseudo_label_u = torch.stack(pseudo_label_u, 0)
+ pseudo_label_u = create_onehot(pseudo_label_u, self.num_classes)
+ pseudo_label_u = pseudo_label_u.to(self.device)
+ label_u_mask = (max_expert_p >= self.conf_thre).float()
+
+ loss_x = 0
+ loss_cr = 0
+ acc_x = 0
+
+ feat_x = [self.F(x) for x in input_x]
+ feat_x2 = [self.F(x) for x in input_x2]
+ feat_u2 = self.F(input_u2)
+
+ for feat_xi, feat_x2i, label_xi, i in zip(
+ feat_x, feat_x2, label_x, domain_x
+ ):
+ cr_s = [j for j in domain_x if j != i]
+
+ # Learning expert
+ pred_xi = self.E(i, feat_xi)
+ loss_x += (-label_xi * torch.log(pred_xi + 1e-5)).sum(1).mean()
+ expert_label_xi = pred_xi.detach()
+ acc_x += compute_accuracy(pred_xi.detach(),
+ label_xi.max(1)[1])[0].item()
+
+ # Consistency regularization
+ cr_pred = []
+ for j in cr_s:
+ pred_j = self.E(j, feat_x2i)
+ pred_j = pred_j.unsqueeze(1)
+ cr_pred.append(pred_j)
+ cr_pred = torch.cat(cr_pred, 1)
+ cr_pred = cr_pred.mean(1)
+ loss_cr += ((cr_pred - expert_label_xi)**2).sum(1).mean()
+
+ loss_x /= self.n_domain
+ loss_cr /= self.n_domain
+ acc_x /= self.n_domain
+
+ # Unsupervised loss
+ pred_u = []
+ for k in range(self.num_source_domains):
+ pred_uk = self.E(k, feat_u2)
+ pred_uk = pred_uk.unsqueeze(1)
+ pred_u.append(pred_uk)
+ pred_u = torch.cat(pred_u, 1)
+ pred_u = pred_u.mean(1)
+ l_u = (-pseudo_label_u * torch.log(pred_u + 1e-5)).sum(1)
+ loss_u = (l_u * label_u_mask).mean()
+
+ loss = 0
+ loss += loss_x
+ loss += loss_cr
+ loss += loss_u * self.weight_u
+ self.model_backward_and_update(loss)
+
+ loss_summary = {
+ "loss_x": loss_x.item(),
+ "acc_x": acc_x,
+ "loss_cr": loss_cr.item(),
+ "loss_u": loss_u.item(),
+ }
+
+ if (self.batch_idx + 1) == self.num_batches:
+ self.update_lr()
+
+ return loss_summary
+
+ def parse_batch_train(self, batch_x, batch_u):
+ input_x = batch_x["img"]
+ input_x2 = batch_x["img2"]
+ label_x = batch_x["label"]
+ domain_x = batch_x["domain"]
+ input_u = batch_u["img"]
+ input_u2 = batch_u["img2"]
+
+ label_x = create_onehot(label_x, self.num_classes)
+
+ input_x = input_x.to(self.device)
+ input_x2 = input_x2.to(self.device)
+ label_x = label_x.to(self.device)
+ input_u = input_u.to(self.device)
+ input_u2 = input_u2.to(self.device)
+
+ return input_x, input_x2, label_x, domain_x, input_u, input_u2
+
+ def model_inference(self, input):
+ f = self.F(input)
+ p = []
+ for k in range(self.num_source_domains):
+ p_k = self.E(k, f)
+ p_k = p_k.unsqueeze(1)
+ p.append(p_k)
+ p = torch.cat(p, 1)
+ p = p.mean(1)
+ return p
diff --git a/dassl/engine/da/dann.py b/dassl/engine/da/dann.py
new file mode 100644
index 0000000..64bb3f7
--- /dev/null
+++ b/dassl/engine/da/dann.py
@@ -0,0 +1,78 @@
+import numpy as np
+import torch
+import torch.nn as nn
+
+from dassl.optim import build_optimizer, build_lr_scheduler
+from dassl.utils import count_num_param
+from dassl.engine import TRAINER_REGISTRY, TrainerXU
+from dassl.metrics import compute_accuracy
+from dassl.modeling import build_head
+from dassl.modeling.ops import ReverseGrad
+
+
+@TRAINER_REGISTRY.register()
+class DANN(TrainerXU):
+ """Domain-Adversarial Neural Networks.
+
+ https://arxiv.org/abs/1505.07818.
+ """
+
+ def __init__(self, cfg):
+ super().__init__(cfg)
+ self.build_critic()
+ self.ce = nn.CrossEntropyLoss()
+ self.bce = nn.BCEWithLogitsLoss()
+
+ def build_critic(self):
+ cfg = self.cfg
+
+ print("Building critic network")
+ fdim = self.model.fdim
+ critic_body = build_head(
+ "mlp",
+ verbose=cfg.VERBOSE,
+ in_features=fdim,
+ hidden_layers=[fdim, fdim],
+ activation="leaky_relu",
+ )
+ self.critic = nn.Sequential(critic_body, nn.Linear(fdim, 1))
+ print("# params: {:,}".format(count_num_param(self.critic)))
+ self.critic.to(self.device)
+ self.optim_c = build_optimizer(self.critic, cfg.OPTIM)
+ self.sched_c = build_lr_scheduler(self.optim_c, cfg.OPTIM)
+ self.register_model("critic", self.critic, self.optim_c, self.sched_c)
+ self.revgrad = ReverseGrad()
+
+ def forward_backward(self, batch_x, batch_u):
+ input_x, label_x, input_u = self.parse_batch_train(batch_x, batch_u)
+ domain_x = torch.ones(input_x.shape[0], 1).to(self.device)
+ domain_u = torch.zeros(input_u.shape[0], 1).to(self.device)
+
+ global_step = self.batch_idx + self.epoch * self.num_batches
+ progress = global_step / (self.max_epoch * self.num_batches)
+ lmda = 2 / (1 + np.exp(-10 * progress)) - 1
+
+ logit_x, feat_x = self.model(input_x, return_feature=True)
+ _, feat_u = self.model(input_u, return_feature=True)
+
+ loss_x = self.ce(logit_x, label_x)
+
+ feat_x = self.revgrad(feat_x, grad_scaling=lmda)
+ feat_u = self.revgrad(feat_u, grad_scaling=lmda)
+ output_xd = self.critic(feat_x)
+ output_ud = self.critic(feat_u)
+ loss_d = self.bce(output_xd, domain_x) + self.bce(output_ud, domain_u)
+
+ loss = loss_x + loss_d
+ self.model_backward_and_update(loss)
+
+ loss_summary = {
+ "loss_x": loss_x.item(),
+ "acc_x": compute_accuracy(logit_x, label_x)[0].item(),
+ "loss_d": loss_d.item(),
+ }
+
+ if (self.batch_idx + 1) == self.num_batches:
+ self.update_lr()
+
+ return loss_summary
diff --git a/dassl/engine/da/m3sda.py b/dassl/engine/da/m3sda.py
new file mode 100644
index 0000000..59b5673
--- /dev/null
+++ b/dassl/engine/da/m3sda.py
@@ -0,0 +1,208 @@
+import torch
+import torch.nn as nn
+from torch.nn import functional as F
+
+from dassl.optim import build_optimizer, build_lr_scheduler
+from dassl.utils import count_num_param
+from dassl.engine import TRAINER_REGISTRY, TrainerXU
+from dassl.engine.trainer import SimpleNet
+
+
+class PairClassifiers(nn.Module):
+
+ def __init__(self, fdim, num_classes):
+ super().__init__()
+ self.c1 = nn.Linear(fdim, num_classes)
+ self.c2 = nn.Linear(fdim, num_classes)
+
+ def forward(self, x):
+ z1 = self.c1(x)
+ if not self.training:
+ return z1
+ z2 = self.c2(x)
+ return z1, z2
+
+
+@TRAINER_REGISTRY.register()
+class M3SDA(TrainerXU):
+ """Moment Matching for Multi-Source Domain Adaptation.
+
+ https://arxiv.org/abs/1812.01754.
+ """
+
+ def __init__(self, cfg):
+ super().__init__(cfg)
+ n_domain = cfg.DATALOADER.TRAIN_X.N_DOMAIN
+ batch_size = cfg.DATALOADER.TRAIN_X.BATCH_SIZE
+ if n_domain <= 0:
+ n_domain = self.num_source_domains
+ self.split_batch = batch_size // n_domain
+ self.n_domain = n_domain
+
+ self.n_step_F = cfg.TRAINER.M3SDA.N_STEP_F
+ self.lmda = cfg.TRAINER.M3SDA.LMDA
+
+ def check_cfg(self, cfg):
+ assert cfg.DATALOADER.TRAIN_X.SAMPLER == "RandomDomainSampler"
+ assert not cfg.DATALOADER.TRAIN_U.SAME_AS_X
+
+ def build_model(self):
+ cfg = self.cfg
+
+ print("Building F")
+ self.F = SimpleNet(cfg, cfg.MODEL, 0)
+ self.F.to(self.device)
+ print("# params: {:,}".format(count_num_param(self.F)))
+ self.optim_F = build_optimizer(self.F, cfg.OPTIM)
+ self.sched_F = build_lr_scheduler(self.optim_F, cfg.OPTIM)
+ self.register_model("F", self.F, self.optim_F, self.sched_F)
+ fdim = self.F.fdim
+
+ print("Building C")
+ self.C = nn.ModuleList(
+ [
+ PairClassifiers(fdim, self.num_classes)
+ for _ in range(self.num_source_domains)
+ ]
+ )
+ self.C.to(self.device)
+ print("# params: {:,}".format(count_num_param(self.C)))
+ self.optim_C = build_optimizer(self.C, cfg.OPTIM)
+ self.sched_C = build_lr_scheduler(self.optim_C, cfg.OPTIM)
+ self.register_model("C", self.C, self.optim_C, self.sched_C)
+
+ def forward_backward(self, batch_x, batch_u):
+ parsed = self.parse_batch_train(batch_x, batch_u)
+ input_x, label_x, domain_x, input_u = parsed
+
+ input_x = torch.split(input_x, self.split_batch, 0)
+ label_x = torch.split(label_x, self.split_batch, 0)
+ domain_x = torch.split(domain_x, self.split_batch, 0)
+ domain_x = [d[0].item() for d in domain_x]
+
+ # Step A
+ loss_x = 0
+ feat_x = []
+
+ for x, y, d in zip(input_x, label_x, domain_x):
+ f = self.F(x)
+ z1, z2 = self.C[d](f)
+ loss_x += F.cross_entropy(z1, y) + F.cross_entropy(z2, y)
+
+ feat_x.append(f)
+
+ loss_x /= self.n_domain
+
+ feat_u = self.F(input_u)
+ loss_msda = self.moment_distance(feat_x, feat_u)
+
+ loss_step_A = loss_x + loss_msda * self.lmda
+ self.model_backward_and_update(loss_step_A)
+
+ # Step B
+ with torch.no_grad():
+ feat_u = self.F(input_u)
+
+ loss_x, loss_dis = 0, 0
+
+ for x, y, d in zip(input_x, label_x, domain_x):
+ with torch.no_grad():
+ f = self.F(x)
+ z1, z2 = self.C[d](f)
+ loss_x += F.cross_entropy(z1, y) + F.cross_entropy(z2, y)
+
+ z1, z2 = self.C[d](feat_u)
+ p1 = F.softmax(z1, 1)
+ p2 = F.softmax(z2, 1)
+ loss_dis += self.discrepancy(p1, p2)
+
+ loss_x /= self.n_domain
+ loss_dis /= self.n_domain
+
+ loss_step_B = loss_x - loss_dis
+ self.model_backward_and_update(loss_step_B, "C")
+
+ # Step C
+ for _ in range(self.n_step_F):
+ feat_u = self.F(input_u)
+
+ loss_dis = 0
+
+ for d in domain_x:
+ z1, z2 = self.C[d](feat_u)
+ p1 = F.softmax(z1, 1)
+ p2 = F.softmax(z2, 1)
+ loss_dis += self.discrepancy(p1, p2)
+
+ loss_dis /= self.n_domain
+ loss_step_C = loss_dis
+
+ self.model_backward_and_update(loss_step_C, "F")
+
+ loss_summary = {
+ "loss_step_A": loss_step_A.item(),
+ "loss_step_B": loss_step_B.item(),
+ "loss_step_C": loss_step_C.item(),
+ }
+
+ if (self.batch_idx + 1) == self.num_batches:
+ self.update_lr()
+
+ return loss_summary
+
+ def moment_distance(self, x, u):
+ # x (list): a list of feature matrix.
+ # u (torch.Tensor): feature matrix.
+ x_mean = [xi.mean(0) for xi in x]
+ u_mean = u.mean(0)
+ dist1 = self.pairwise_distance(x_mean, u_mean)
+
+ x_var = [xi.var(0) for xi in x]
+ u_var = u.var(0)
+ dist2 = self.pairwise_distance(x_var, u_var)
+
+ return (dist1+dist2) / 2
+
+ def pairwise_distance(self, x, u):
+ # x (list): a list of feature vector.
+ # u (torch.Tensor): feature vector.
+ dist = 0
+ count = 0
+
+ for xi in x:
+ dist += self.euclidean(xi, u)
+ count += 1
+
+ for i in range(len(x) - 1):
+ for j in range(i + 1, len(x)):
+ dist += self.euclidean(x[i], x[j])
+ count += 1
+
+ return dist / count
+
+ def euclidean(self, input1, input2):
+ return ((input1 - input2)**2).sum().sqrt()
+
+ def discrepancy(self, y1, y2):
+ return (y1 - y2).abs().mean()
+
+ def parse_batch_train(self, batch_x, batch_u):
+ input_x = batch_x["img"]
+ label_x = batch_x["label"]
+ domain_x = batch_x["domain"]
+ input_u = batch_u["img"]
+
+ input_x = input_x.to(self.device)
+ label_x = label_x.to(self.device)
+ input_u = input_u.to(self.device)
+
+ return input_x, label_x, domain_x, input_u
+
+ def model_inference(self, input):
+ f = self.F(input)
+ p = 0
+ for C_i in self.C:
+ z = C_i(f)
+ p += F.softmax(z, 1)
+ p = p / len(self.C)
+ return p
diff --git a/dassl/engine/da/mcd.py b/dassl/engine/da/mcd.py
new file mode 100644
index 0000000..174a2e0
--- /dev/null
+++ b/dassl/engine/da/mcd.py
@@ -0,0 +1,105 @@
+import torch
+import torch.nn as nn
+from torch.nn import functional as F
+
+from dassl.optim import build_optimizer, build_lr_scheduler
+from dassl.utils import count_num_param
+from dassl.engine import TRAINER_REGISTRY, TrainerXU
+from dassl.engine.trainer import SimpleNet
+
+
+@TRAINER_REGISTRY.register()
+class MCD(TrainerXU):
+ """Maximum Classifier Discrepancy.
+
+ https://arxiv.org/abs/1712.02560.
+ """
+
+ def __init__(self, cfg):
+ super().__init__(cfg)
+ self.n_step_F = cfg.TRAINER.MCD.N_STEP_F
+
+ def build_model(self):
+ cfg = self.cfg
+
+ print("Building F")
+ self.F = SimpleNet(cfg, cfg.MODEL, 0)
+ self.F.to(self.device)
+ print("# params: {:,}".format(count_num_param(self.F)))
+ self.optim_F = build_optimizer(self.F, cfg.OPTIM)
+ self.sched_F = build_lr_scheduler(self.optim_F, cfg.OPTIM)
+ self.register_model("F", self.F, self.optim_F, self.sched_F)
+ fdim = self.F.fdim
+
+ print("Building C1")
+ self.C1 = nn.Linear(fdim, self.num_classes)
+ self.C1.to(self.device)
+ print("# params: {:,}".format(count_num_param(self.C1)))
+ self.optim_C1 = build_optimizer(self.C1, cfg.OPTIM)
+ self.sched_C1 = build_lr_scheduler(self.optim_C1, cfg.OPTIM)
+ self.register_model("C1", self.C1, self.optim_C1, self.sched_C1)
+
+ print("Building C2")
+ self.C2 = nn.Linear(fdim, self.num_classes)
+ self.C2.to(self.device)
+ print("# params: {:,}".format(count_num_param(self.C2)))
+ self.optim_C2 = build_optimizer(self.C2, cfg.OPTIM)
+ self.sched_C2 = build_lr_scheduler(self.optim_C2, cfg.OPTIM)
+ self.register_model("C2", self.C2, self.optim_C2, self.sched_C2)
+
+ def forward_backward(self, batch_x, batch_u):
+ parsed = self.parse_batch_train(batch_x, batch_u)
+ input_x, label_x, input_u = parsed
+
+ # Step A
+ feat_x = self.F(input_x)
+ logit_x1 = self.C1(feat_x)
+ logit_x2 = self.C2(feat_x)
+ loss_x1 = F.cross_entropy(logit_x1, label_x)
+ loss_x2 = F.cross_entropy(logit_x2, label_x)
+ loss_step_A = loss_x1 + loss_x2
+ self.model_backward_and_update(loss_step_A)
+
+ # Step B
+ with torch.no_grad():
+ feat_x = self.F(input_x)
+ logit_x1 = self.C1(feat_x)
+ logit_x2 = self.C2(feat_x)
+ loss_x1 = F.cross_entropy(logit_x1, label_x)
+ loss_x2 = F.cross_entropy(logit_x2, label_x)
+ loss_x = loss_x1 + loss_x2
+
+ with torch.no_grad():
+ feat_u = self.F(input_u)
+ pred_u1 = F.softmax(self.C1(feat_u), 1)
+ pred_u2 = F.softmax(self.C2(feat_u), 1)
+ loss_dis = self.discrepancy(pred_u1, pred_u2)
+
+ loss_step_B = loss_x - loss_dis
+ self.model_backward_and_update(loss_step_B, ["C1", "C2"])
+
+ # Step C
+ for _ in range(self.n_step_F):
+ feat_u = self.F(input_u)
+ pred_u1 = F.softmax(self.C1(feat_u), 1)
+ pred_u2 = F.softmax(self.C2(feat_u), 1)
+ loss_step_C = self.discrepancy(pred_u1, pred_u2)
+ self.model_backward_and_update(loss_step_C, "F")
+
+ loss_summary = {
+ "loss_step_A": loss_step_A.item(),
+ "loss_step_B": loss_step_B.item(),
+ "loss_step_C": loss_step_C.item(),
+ }
+
+ if (self.batch_idx + 1) == self.num_batches:
+ self.update_lr()
+
+ return loss_summary
+
+ def discrepancy(self, y1, y2):
+ return (y1 - y2).abs().mean()
+
+ def model_inference(self, input):
+ feat = self.F(input)
+ return self.C1(feat)
diff --git a/dassl/engine/da/mme.py b/dassl/engine/da/mme.py
new file mode 100644
index 0000000..fd7775c
--- /dev/null
+++ b/dassl/engine/da/mme.py
@@ -0,0 +1,86 @@
+import torch
+import torch.nn as nn
+from torch.nn import functional as F
+
+from dassl.optim import build_optimizer, build_lr_scheduler
+from dassl.utils import count_num_param
+from dassl.engine import TRAINER_REGISTRY, TrainerXU
+from dassl.metrics import compute_accuracy
+from dassl.modeling.ops import ReverseGrad
+from dassl.engine.trainer import SimpleNet
+
+
+class Prototypes(nn.Module):
+
+ def __init__(self, fdim, num_classes, temp=0.05):
+ super().__init__()
+ self.prototypes = nn.Linear(fdim, num_classes, bias=False)
+ self.temp = temp
+
+ def forward(self, x):
+ x = F.normalize(x, p=2, dim=1)
+ out = self.prototypes(x)
+ out = out / self.temp
+ return out
+
+
+@TRAINER_REGISTRY.register()
+class MME(TrainerXU):
+ """Minimax Entropy.
+
+ https://arxiv.org/abs/1904.06487.
+ """
+
+ def __init__(self, cfg):
+ super().__init__(cfg)
+ self.lmda = cfg.TRAINER.MME.LMDA
+
+ def build_model(self):
+ cfg = self.cfg
+
+ print("Building F")
+ self.F = SimpleNet(cfg, cfg.MODEL, 0)
+ self.F.to(self.device)
+ print("# params: {:,}".format(count_num_param(self.F)))
+ self.optim_F = build_optimizer(self.F, cfg.OPTIM)
+ self.sched_F = build_lr_scheduler(self.optim_F, cfg.OPTIM)
+ self.register_model("F", self.F, self.optim_F, self.sched_F)
+
+ print("Building C")
+ self.C = Prototypes(self.F.fdim, self.num_classes)
+ self.C.to(self.device)
+ print("# params: {:,}".format(count_num_param(self.C)))
+ self.optim_C = build_optimizer(self.C, cfg.OPTIM)
+ self.sched_C = build_lr_scheduler(self.optim_C, cfg.OPTIM)
+ self.register_model("C", self.C, self.optim_C, self.sched_C)
+
+ self.revgrad = ReverseGrad()
+
+ def forward_backward(self, batch_x, batch_u):
+ input_x, label_x, input_u = self.parse_batch_train(batch_x, batch_u)
+
+ feat_x = self.F(input_x)
+ logit_x = self.C(feat_x)
+ loss_x = F.cross_entropy(logit_x, label_x)
+ self.model_backward_and_update(loss_x)
+
+ feat_u = self.F(input_u)
+ feat_u = self.revgrad(feat_u)
+ logit_u = self.C(feat_u)
+ prob_u = F.softmax(logit_u, 1)
+ loss_u = -(-prob_u * torch.log(prob_u + 1e-5)).sum(1).mean()
+ self.model_backward_and_update(loss_u * self.lmda)
+
+ loss_summary = {
+ "loss_x": loss_x.item(),
+ "acc_x": compute_accuracy(logit_x, label_x)[0].item(),
+ "loss_u": loss_u.item(),
+ }
+
+ if (self.batch_idx + 1) == self.num_batches:
+ self.update_lr()
+
+ return loss_summary
+
+ def model_inference(self, input):
+ return self.C(self.F(input))
diff --git a/dassl/engine/da/se.py b/dassl/engine/da/se.py
new file mode 100644
index 0000000..b0f498a
--- /dev/null
+++ b/dassl/engine/da/se.py
@@ -0,0 +1,78 @@
+import copy
+from torch.nn import functional as F
+
+from dassl.engine import TRAINER_REGISTRY, TrainerXU
+from dassl.metrics import compute_accuracy
+from dassl.modeling.ops.utils import sigmoid_rampup, ema_model_update
+
+
+@TRAINER_REGISTRY.register()
+class SE(TrainerXU):
+ """Self-ensembling for visual domain adaptation.
+
+ https://arxiv.org/abs/1706.05208.
+ """
+
+ def __init__(self, cfg):
+ super().__init__(cfg)
+ self.ema_alpha = cfg.TRAINER.SE.EMA_ALPHA
+ self.conf_thre = cfg.TRAINER.SE.CONF_THRE
+ self.rampup = cfg.TRAINER.SE.RAMPUP
+
+ self.teacher = copy.deepcopy(self.model)
+ self.teacher.train()
+ for param in self.teacher.parameters():
+ param.requires_grad_(False)
+
+ def check_cfg(self, cfg):
+ assert cfg.DATALOADER.K_TRANSFORMS == 2
+
+ def forward_backward(self, batch_x, batch_u):
+ global_step = self.batch_idx + self.epoch * self.num_batches
+ parsed = self.parse_batch_train(batch_x, batch_u)
+ input_x, label_x, input_u1, input_u2 = parsed
+
+ logit_x = self.model(input_x)
+ loss_x = F.cross_entropy(logit_x, label_x)
+
+ prob_u = F.softmax(self.model(input_u1), 1)
+ t_prob_u = F.softmax(self.teacher(input_u2), 1)
+ loss_u = ((prob_u - t_prob_u)**2).sum(1)
+
+ if self.conf_thre:
+ max_prob = t_prob_u.max(1)[0]
+ mask = (max_prob > self.conf_thre).float()
+ loss_u = (loss_u * mask).mean()
+ else:
+ weight_u = sigmoid_rampup(global_step, self.rampup)
+ loss_u = loss_u.mean() * weight_u
+
+ loss = loss_x + loss_u
+ self.model_backward_and_update(loss)
+
+ ema_alpha = min(1 - 1 / (global_step+1), self.ema_alpha)
+ ema_model_update(self.model, self.teacher, ema_alpha)
+
+ loss_summary = {
+ "loss_x": loss_x.item(),
+ "acc_x": compute_accuracy(logit_x, label_x)[0].item(),
+ "loss_u": loss_u.item(),
+ }
+
+ if (self.batch_idx + 1) == self.num_batches:
+ self.update_lr()
+
+ return loss_summary
+
+ def parse_batch_train(self, batch_x, batch_u):
+ input_x = batch_x["img"][0]
+ label_x = batch_x["label"]
+ input_u = batch_u["img"]
+ input_u1, input_u2 = input_u
+
+ input_x = input_x.to(self.device)
+ label_x = label_x.to(self.device)
+ input_u1 = input_u1.to(self.device)
+ input_u2 = input_u2.to(self.device)
+
+ return input_x, label_x, input_u1, input_u2
diff --git a/dassl/engine/da/source_only.py b/dassl/engine/da/source_only.py
new file mode 100644
index 0000000..2e7d9a6
--- /dev/null
+++ b/dassl/engine/da/source_only.py
@@ -0,0 +1,34 @@
+from torch.nn import functional as F
+
+from dassl.engine import TRAINER_REGISTRY, TrainerXU
+from dassl.metrics import compute_accuracy
+
+
+@TRAINER_REGISTRY.register()
+class SourceOnly(TrainerXU):
+ """Baseline model for domain adaptation, which is
+ trained using source data only.
+ """
+
+ def forward_backward(self, batch_x, batch_u):
+ input, label = self.parse_batch_train(batch_x, batch_u)
+ output = self.model(input)
+ loss = F.cross_entropy(output, label)
+ self.model_backward_and_update(loss)
+
+ loss_summary = {
+ "loss": loss.item(),
+ "acc": compute_accuracy(output, label)[0].item(),
+ }
+
+ if (self.batch_idx + 1) == self.num_batches:
+ self.update_lr()
+
+ return loss_summary
+
+ def parse_batch_train(self, batch_x, batch_u):
+ input = batch_x["img"]
+ label = batch_x["label"]
+ input = input.to(self.device)
+ label = label.to(self.device)
+ return input, label
diff --git a/dassl/engine/dg/__init__.py b/dassl/engine/dg/__init__.py
new file mode 100644
index 0000000..23146a4
--- /dev/null
+++ b/dassl/engine/dg/__init__.py
@@ -0,0 +1,5 @@
+from .ddaig import DDAIG
+from .daeldg import DAELDG
+from .vanilla import Vanilla
+from .crossgrad import CrossGrad
+from .domain_mix import DomainMix
diff --git a/dassl/engine/dg/__pycache__/__init__.cpython-310.pyc b/dassl/engine/dg/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000..10c9584
Binary files /dev/null and b/dassl/engine/dg/__pycache__/__init__.cpython-310.pyc differ
diff --git a/dassl/engine/dg/__pycache__/__init__.cpython-311.pyc b/dassl/engine/dg/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000..d35ab77
Binary files /dev/null and b/dassl/engine/dg/__pycache__/__init__.cpython-311.pyc differ
diff --git a/dassl/engine/dg/__pycache__/__init__.cpython-38.pyc b/dassl/engine/dg/__pycache__/__init__.cpython-38.pyc
new file mode 100644
index 0000000..4150be9
Binary files /dev/null and b/dassl/engine/dg/__pycache__/__init__.cpython-38.pyc differ
diff --git a/dassl/engine/dg/__pycache__/crossgrad.cpython-310.pyc b/dassl/engine/dg/__pycache__/crossgrad.cpython-310.pyc
new file mode 100644
index 0000000..859fada
Binary files /dev/null and b/dassl/engine/dg/__pycache__/crossgrad.cpython-310.pyc differ
diff --git a/dassl/engine/dg/__pycache__/crossgrad.cpython-311.pyc b/dassl/engine/dg/__pycache__/crossgrad.cpython-311.pyc
new file mode 100644
index 0000000..3efb82e
Binary files /dev/null and b/dassl/engine/dg/__pycache__/crossgrad.cpython-311.pyc differ
diff --git a/dassl/engine/dg/__pycache__/crossgrad.cpython-38.pyc b/dassl/engine/dg/__pycache__/crossgrad.cpython-38.pyc
new file mode 100644
index 0000000..fb02f0f
Binary files /dev/null and b/dassl/engine/dg/__pycache__/crossgrad.cpython-38.pyc differ
diff --git a/dassl/engine/dg/__pycache__/daeldg.cpython-310.pyc b/dassl/engine/dg/__pycache__/daeldg.cpython-310.pyc
new file mode 100644
index 0000000..3c4929f
Binary files /dev/null and b/dassl/engine/dg/__pycache__/daeldg.cpython-310.pyc differ
diff --git a/dassl/engine/dg/__pycache__/daeldg.cpython-311.pyc b/dassl/engine/dg/__pycache__/daeldg.cpython-311.pyc
new file mode 100644
index 0000000..082663e
Binary files /dev/null and b/dassl/engine/dg/__pycache__/daeldg.cpython-311.pyc differ
diff --git a/dassl/engine/dg/__pycache__/daeldg.cpython-38.pyc b/dassl/engine/dg/__pycache__/daeldg.cpython-38.pyc
new file mode 100644
index 0000000..4eb313c
Binary files /dev/null and b/dassl/engine/dg/__pycache__/daeldg.cpython-38.pyc differ
diff --git a/dassl/engine/dg/__pycache__/ddaig.cpython-310.pyc b/dassl/engine/dg/__pycache__/ddaig.cpython-310.pyc
new file mode 100644
index 0000000..707858d
Binary files /dev/null and b/dassl/engine/dg/__pycache__/ddaig.cpython-310.pyc differ
diff --git a/dassl/engine/dg/__pycache__/ddaig.cpython-311.pyc b/dassl/engine/dg/__pycache__/ddaig.cpython-311.pyc
new file mode 100644
index 0000000..77b89f0
Binary files /dev/null and b/dassl/engine/dg/__pycache__/ddaig.cpython-311.pyc differ
diff --git a/dassl/engine/dg/__pycache__/ddaig.cpython-38.pyc b/dassl/engine/dg/__pycache__/ddaig.cpython-38.pyc
new file mode 100644
index 0000000..1e7cda6
Binary files /dev/null and b/dassl/engine/dg/__pycache__/ddaig.cpython-38.pyc differ
diff --git a/dassl/engine/dg/__pycache__/domain_mix.cpython-310.pyc b/dassl/engine/dg/__pycache__/domain_mix.cpython-310.pyc
new file mode 100644
index 0000000..773298c
Binary files /dev/null and b/dassl/engine/dg/__pycache__/domain_mix.cpython-310.pyc differ
diff --git a/dassl/engine/dg/__pycache__/domain_mix.cpython-311.pyc b/dassl/engine/dg/__pycache__/domain_mix.cpython-311.pyc
new file mode 100644
index 0000000..5ea51e7
Binary files /dev/null and b/dassl/engine/dg/__pycache__/domain_mix.cpython-311.pyc differ
diff --git a/dassl/engine/dg/__pycache__/domain_mix.cpython-38.pyc b/dassl/engine/dg/__pycache__/domain_mix.cpython-38.pyc
new file mode 100644
index 0000000..ae12258
Binary files /dev/null and b/dassl/engine/dg/__pycache__/domain_mix.cpython-38.pyc differ
diff --git a/dassl/engine/dg/__pycache__/vanilla.cpython-310.pyc b/dassl/engine/dg/__pycache__/vanilla.cpython-310.pyc
new file mode 100644
index 0000000..f2ffbdb
Binary files /dev/null and b/dassl/engine/dg/__pycache__/vanilla.cpython-310.pyc differ
diff --git a/dassl/engine/dg/__pycache__/vanilla.cpython-311.pyc b/dassl/engine/dg/__pycache__/vanilla.cpython-311.pyc
new file mode 100644
index 0000000..97ece86
Binary files /dev/null and b/dassl/engine/dg/__pycache__/vanilla.cpython-311.pyc differ
diff --git a/dassl/engine/dg/__pycache__/vanilla.cpython-38.pyc b/dassl/engine/dg/__pycache__/vanilla.cpython-38.pyc
new file mode 100644
index 0000000..f8f1295
Binary files /dev/null and b/dassl/engine/dg/__pycache__/vanilla.cpython-38.pyc differ
diff --git a/dassl/engine/dg/crossgrad.py b/dassl/engine/dg/crossgrad.py
new file mode 100644
index 0000000..ad9a6bd
--- /dev/null
+++ b/dassl/engine/dg/crossgrad.py
@@ -0,0 +1,83 @@
+import torch
+from torch.nn import functional as F
+
+from dassl.optim import build_optimizer, build_lr_scheduler
+from dassl.utils import count_num_param
+from dassl.engine import TRAINER_REGISTRY, TrainerX
+from dassl.engine.trainer import SimpleNet
+
+
+@TRAINER_REGISTRY.register()
+class CrossGrad(TrainerX):
+ """Cross-gradient training.
+
+ https://arxiv.org/abs/1804.10745.
+ """
+
+ def __init__(self, cfg):
+ super().__init__(cfg)
+ self.eps_f = cfg.TRAINER.CROSSGRAD.EPS_F
+ self.eps_d = cfg.TRAINER.CROSSGRAD.EPS_D
+ self.alpha_f = cfg.TRAINER.CROSSGRAD.ALPHA_F
+ self.alpha_d = cfg.TRAINER.CROSSGRAD.ALPHA_D
+
+ def build_model(self):
+ cfg = self.cfg
+
+ print("Building F")
+ self.F = SimpleNet(cfg, cfg.MODEL, self.num_classes)
+ self.F.to(self.device)
+ print("# params: {:,}".format(count_num_param(self.F)))
+ self.optim_F = build_optimizer(self.F, cfg.OPTIM)
+ self.sched_F = build_lr_scheduler(self.optim_F, cfg.OPTIM)
+ self.register_model("F", self.F, self.optim_F, self.sched_F)
+
+ print("Building D")
+ self.D = SimpleNet(cfg, cfg.MODEL, self.num_source_domains)
+ self.D.to(self.device)
+ print("# params: {:,}".format(count_num_param(self.D)))
+ self.optim_D = build_optimizer(self.D, cfg.OPTIM)
+ self.sched_D = build_lr_scheduler(self.optim_D, cfg.OPTIM)
+ self.register_model("D", self.D, self.optim_D, self.sched_D)
+
+ def forward_backward(self, batch):
+ input, label, domain = self.parse_batch_train(batch)
+
+ input.requires_grad = True
+
+ # Compute domain perturbation
+ loss_d = F.cross_entropy(self.D(input), domain)
+ loss_d.backward()
+ grad_d = torch.clamp(input.grad.data, min=-0.1, max=0.1)
+ input_d = input.data + self.eps_f * grad_d
+
+ # Compute label perturbation
+ input.grad.data.zero_()
+ loss_f = F.cross_entropy(self.F(input), label)
+ loss_f.backward()
+ grad_f = torch.clamp(input.grad.data, min=-0.1, max=0.1)
+ input_f = input.data + self.eps_d * grad_f
+
+ input = input.detach()
+
+ # Update label net
+ loss_f1 = F.cross_entropy(self.F(input), label)
+ loss_f2 = F.cross_entropy(self.F(input_d), label)
+ loss_f = (1 - self.alpha_f) * loss_f1 + self.alpha_f * loss_f2
+ self.model_backward_and_update(loss_f, "F")
+
+ # Update domain net
+ loss_d1 = F.cross_entropy(self.D(input), domain)
+ loss_d2 = F.cross_entropy(self.D(input_f), domain)
+ loss_d = (1 - self.alpha_d) * loss_d1 + self.alpha_d * loss_d2
+ self.model_backward_and_update(loss_d, "D")
+
+ loss_summary = {"loss_f": loss_f.item(), "loss_d": loss_d.item()}
+
+ if (self.batch_idx + 1) == self.num_batches:
+ self.update_lr()
+
+ return loss_summary
+
+ def model_inference(self, input):
+ return self.F(input)
diff --git a/dassl/engine/dg/daeldg.py b/dassl/engine/dg/daeldg.py
new file mode 100644
index 0000000..8d6d11c
--- /dev/null
+++ b/dassl/engine/dg/daeldg.py
@@ -0,0 +1,168 @@
+import torch
+import torch.nn as nn
+
+from dassl.data import DataManager
+from dassl.optim import build_optimizer, build_lr_scheduler
+from dassl.utils import count_num_param
+from dassl.engine import TRAINER_REGISTRY, TrainerX
+from dassl.metrics import compute_accuracy
+from dassl.engine.trainer import SimpleNet
+from dassl.data.transforms import build_transform
+from dassl.modeling.ops.utils import create_onehot
+
+
+class Experts(nn.Module):
+
+ def __init__(self, n_source, fdim, num_classes):
+ super().__init__()
+ self.linears = nn.ModuleList(
+ [nn.Linear(fdim, num_classes) for _ in range(n_source)]
+ )
+ self.softmax = nn.Softmax(dim=1)
+
+ def forward(self, i, x):
+ x = self.linears[i](x)
+ x = self.softmax(x)
+ return x
+
+
+@TRAINER_REGISTRY.register()
+class DAELDG(TrainerX):
+ """Domain Adaptive Ensemble Learning.
+
+ DG version: only use labeled source data.
+
+ https://arxiv.org/abs/2003.07325.
+ """
+
+ def __init__(self, cfg):
+ super().__init__(cfg)
+ n_domain = cfg.DATALOADER.TRAIN_X.N_DOMAIN
+ batch_size = cfg.DATALOADER.TRAIN_X.BATCH_SIZE
+ if n_domain <= 0:
+ n_domain = self.num_source_domains
+ self.split_batch = batch_size // n_domain
+ self.n_domain = n_domain
+ self.conf_thre = cfg.TRAINER.DAELDG.CONF_THRE
+
+ def check_cfg(self, cfg):
+ assert cfg.DATALOADER.TRAIN_X.SAMPLER == "RandomDomainSampler"
+ assert len(cfg.TRAINER.DAELDG.STRONG_TRANSFORMS) > 0
+
+ def build_data_loader(self):
+ cfg = self.cfg
+ tfm_train = build_transform(cfg, is_train=True)
+ custom_tfm_train = [tfm_train]
+ choices = cfg.TRAINER.DAELDG.STRONG_TRANSFORMS
+ tfm_train_strong = build_transform(cfg, is_train=True, choices=choices)
+ custom_tfm_train += [tfm_train_strong]
+ dm = DataManager(self.cfg, custom_tfm_train=custom_tfm_train)
+ self.train_loader_x = dm.train_loader_x
+ self.train_loader_u = dm.train_loader_u
+ self.val_loader = dm.val_loader
+ self.test_loader = dm.test_loader
+ self.num_classes = dm.num_classes
+ self.num_source_domains = dm.num_source_domains
+ self.lab2cname = dm.lab2cname
+
+ def build_model(self):
+ cfg = self.cfg
+
+ print("Building F")
+ self.F = SimpleNet(cfg, cfg.MODEL, 0)
+ self.F.to(self.device)
+ print("# params: {:,}".format(count_num_param(self.F)))
+ self.optim_F = build_optimizer(self.F, cfg.OPTIM)
+ self.sched_F = build_lr_scheduler(self.optim_F, cfg.OPTIM)
+ self.register_model("F", self.F, self.optim_F, self.sched_F)
+ fdim = self.F.fdim
+
+ print("Building E")
+ self.E = Experts(self.num_source_domains, fdim, self.num_classes)
+ self.E.to(self.device)
+ print("# params: {:,}".format(count_num_param(self.E)))
+ self.optim_E = build_optimizer(self.E, cfg.OPTIM)
+ self.sched_E = build_lr_scheduler(self.optim_E, cfg.OPTIM)
+ self.register_model("E", self.E, self.optim_E, self.sched_E)
+
+ def forward_backward(self, batch):
+ parsed_data = self.parse_batch_train(batch)
+ input, input2, label, domain = parsed_data
+
+ input = torch.split(input, self.split_batch, 0)
+ input2 = torch.split(input2, self.split_batch, 0)
+ label = torch.split(label, self.split_batch, 0)
+ domain = torch.split(domain, self.split_batch, 0)
+ domain = [d[0].item() for d in domain]
+
+ loss_x = 0
+ loss_cr = 0
+ acc = 0
+
+ feat = [self.F(x) for x in input]
+ feat2 = [self.F(x) for x in input2]
+
+ for feat_i, feat2_i, label_i, i in zip(feat, feat2, label, domain):
+ cr_s = [j for j in domain if j != i]
+
+ # Learning expert
+ pred_i = self.E(i, feat_i)
+ loss_x += (-label_i * torch.log(pred_i + 1e-5)).sum(1).mean()
+ expert_label_i = pred_i.detach()
+ acc += compute_accuracy(pred_i.detach(),
+ label_i.max(1)[1])[0].item()
+
+ # Consistency regularization
+ cr_pred = []
+ for j in cr_s:
+ pred_j = self.E(j, feat2_i)
+ pred_j = pred_j.unsqueeze(1)
+ cr_pred.append(pred_j)
+ cr_pred = torch.cat(cr_pred, 1)
+ cr_pred = cr_pred.mean(1)
+ loss_cr += ((cr_pred - expert_label_i)**2).sum(1).mean()
+
+ loss_x /= self.n_domain
+ loss_cr /= self.n_domain
+ acc /= self.n_domain
+
+ loss = 0
+ loss += loss_x
+ loss += loss_cr
+ self.model_backward_and_update(loss)
+
+ loss_summary = {
+ "loss_x": loss_x.item(),
+ "acc": acc,
+ "loss_cr": loss_cr.item()
+ }
+
+ if (self.batch_idx + 1) == self.num_batches:
+ self.update_lr()
+
+ return loss_summary
+
+ def parse_batch_train(self, batch):
+ input = batch["img"]
+ input2 = batch["img2"]
+ label = batch["label"]
+ domain = batch["domain"]
+
+ label = create_onehot(label, self.num_classes)
+
+ input = input.to(self.device)
+ input2 = input2.to(self.device)
+ label = label.to(self.device)
+
+ return input, input2, label, domain
+
+ def model_inference(self, input):
+ f = self.F(input)
+ p = []
+ for k in range(self.num_source_domains):
+ p_k = self.E(k, f)
+ p_k = p_k.unsqueeze(1)
+ p.append(p_k)
+ p = torch.cat(p, 1)
+ p = p.mean(1)
+ return p
diff --git a/dassl/engine/dg/ddaig.py b/dassl/engine/dg/ddaig.py
new file mode 100644
index 0000000..b7fbd97
--- /dev/null
+++ b/dassl/engine/dg/ddaig.py
@@ -0,0 +1,107 @@
+import torch
+from torch.nn import functional as F
+
+from dassl.optim import build_optimizer, build_lr_scheduler
+from dassl.utils import count_num_param
+from dassl.engine import TRAINER_REGISTRY, TrainerX
+from dassl.modeling import build_network
+from dassl.engine.trainer import SimpleNet
+
+
+@TRAINER_REGISTRY.register()
+class DDAIG(TrainerX):
+ """Deep Domain-Adversarial Image Generation.
+
+ https://arxiv.org/abs/2003.06054.
+ """
+
+ def __init__(self, cfg):
+ super().__init__(cfg)
+ self.lmda = cfg.TRAINER.DDAIG.LMDA
+ self.clamp = cfg.TRAINER.DDAIG.CLAMP
+ self.clamp_min = cfg.TRAINER.DDAIG.CLAMP_MIN
+ self.clamp_max = cfg.TRAINER.DDAIG.CLAMP_MAX
+ self.warmup = cfg.TRAINER.DDAIG.WARMUP
+ self.alpha = cfg.TRAINER.DDAIG.ALPHA
+
+ def build_model(self):
+ cfg = self.cfg
+
+ print("Building F")
+ self.F = SimpleNet(cfg, cfg.MODEL, self.num_classes)
+ self.F.to(self.device)
+ print("# params: {:,}".format(count_num_param(self.F)))
+ self.optim_F = build_optimizer(self.F, cfg.OPTIM)
+ self.sched_F = build_lr_scheduler(self.optim_F, cfg.OPTIM)
+ self.register_model("F", self.F, self.optim_F, self.sched_F)
+
+ print("Building D")
+ self.D = SimpleNet(cfg, cfg.MODEL, self.num_source_domains)
+ self.D.to(self.device)
+ print("# params: {:,}".format(count_num_param(self.D)))
+ self.optim_D = build_optimizer(self.D, cfg.OPTIM)
+ self.sched_D = build_lr_scheduler(self.optim_D, cfg.OPTIM)
+ self.register_model("D", self.D, self.optim_D, self.sched_D)
+
+ print("Building G")
+ self.G = build_network(cfg.TRAINER.DDAIG.G_ARCH, verbose=cfg.VERBOSE)
+ self.G.to(self.device)
+ print("# params: {:,}".format(count_num_param(self.G)))
+ self.optim_G = build_optimizer(self.G, cfg.OPTIM)
+ self.sched_G = build_lr_scheduler(self.optim_G, cfg.OPTIM)
+ self.register_model("G", self.G, self.optim_G, self.sched_G)
+
+ def forward_backward(self, batch):
+ input, label, domain = self.parse_batch_train(batch)
+
+ #############
+ # Update G
+ #############
+ input_p = self.G(input, lmda=self.lmda)
+ if self.clamp:
+ input_p = torch.clamp(
+ input_p, min=self.clamp_min, max=self.clamp_max
+ )
+ loss_g = 0
+ # Minimize label loss
+ loss_g += F.cross_entropy(self.F(input_p), label)
+ # Maximize domain loss
+ loss_g -= F.cross_entropy(self.D(input_p), domain)
+ self.model_backward_and_update(loss_g, "G")
+
+ # Perturb data with new G
+ with torch.no_grad():
+ input_p = self.G(input, lmda=self.lmda)
+ if self.clamp:
+ input_p = torch.clamp(
+ input_p, min=self.clamp_min, max=self.clamp_max
+ )
+
+ #############
+ # Update F
+ #############
+ loss_f = F.cross_entropy(self.F(input), label)
+ if (self.epoch + 1) > self.warmup:
+ loss_fp = F.cross_entropy(self.F(input_p), label)
+ loss_f = (1.0 - self.alpha) * loss_f + self.alpha * loss_fp
+ self.model_backward_and_update(loss_f, "F")
+
+ #############
+ # Update D
+ #############
+ loss_d = F.cross_entropy(self.D(input), domain)
+ self.model_backward_and_update(loss_d, "D")
+
+ loss_summary = {
+ "loss_g": loss_g.item(),
+ "loss_f": loss_f.item(),
+ "loss_d": loss_d.item(),
+ }
+
+ if (self.batch_idx + 1) == self.num_batches:
+ self.update_lr()
+
+ return loss_summary
+
+ def model_inference(self, input):
+ return self.F(input)
diff --git a/dassl/engine/dg/domain_mix.py b/dassl/engine/dg/domain_mix.py
new file mode 100644
index 0000000..654f270
--- /dev/null
+++ b/dassl/engine/dg/domain_mix.py
@@ -0,0 +1,81 @@
+import torch
+from torch.nn import functional as F
+
+from dassl.engine import TRAINER_REGISTRY, TrainerX
+from dassl.metrics import compute_accuracy
+
+__all__ = ["DomainMix"]
+
+
+@TRAINER_REGISTRY.register()
+class DomainMix(TrainerX):
+ """DomainMix.
+
+ Dynamic Domain Generalization.
+
+ https://github.com/MetaVisionLab/DDG
+ """
+
+ def __init__(self, cfg):
+ super(DomainMix, self).__init__(cfg)
+ self.mix_type = cfg.TRAINER.DOMAINMIX.TYPE
+ self.alpha = cfg.TRAINER.DOMAINMIX.ALPHA
+ self.beta = cfg.TRAINER.DOMAINMIX.BETA
+ self.dist_beta = torch.distributions.Beta(self.alpha, self.beta)
+
+ def forward_backward(self, batch):
+ images, label_a, label_b, lam = self.parse_batch_train(batch)
+ output = self.model(images)
+ loss = lam * F.cross_entropy(
+ output, label_a
+ ) + (1-lam) * F.cross_entropy(output, label_b)
+ self.model_backward_and_update(loss)
+
+ loss_summary = {
+ "loss": loss.item(),
+ "acc": compute_accuracy(output, label_a)[0].item()
+ }
+
+ if (self.batch_idx + 1) == self.num_batches:
+ self.update_lr()
+
+ return loss_summary
+
+ def parse_batch_train(self, batch):
+ images = batch["img"]
+ target = batch["label"]
+ domain = batch["domain"]
+ images = images.to(self.device)
+ target = target.to(self.device)
+ domain = domain.to(self.device)
+ images, target_a, target_b, lam = self.domain_mix(
+ images, target, domain
+ )
+ return images, target_a, target_b, lam
+
+ def domain_mix(self, x, target, domain):
+ lam = (
+ self.dist_beta.rsample((1, ))
+ if self.alpha > 0 else torch.tensor(1)
+ ).to(x.device)
+
+ # random shuffle
+ perm = torch.randperm(x.size(0), dtype=torch.int64, device=x.device)
+ if self.mix_type == "crossdomain":
+ domain_list = torch.unique(domain)
+ if len(domain_list) > 1:
+ for idx in domain_list:
+ cnt_a = torch.sum(domain == idx)
+ idx_b = (domain != idx).nonzero().squeeze(-1)
+ cnt_b = idx_b.shape[0]
+ perm_b = torch.ones(cnt_b).multinomial(
+ num_samples=cnt_a, replacement=bool(cnt_a > cnt_b)
+ )
+ perm[domain == idx] = idx_b[perm_b]
+ elif self.mix_type != "random":
+ raise NotImplementedError(
+ f"Chooses {'random', 'crossdomain'}, but got {self.mix_type}."
+ )
+ mixed_x = lam*x + (1-lam) * x[perm, :]
+ target_a, target_b = target, target[perm]
+ return mixed_x, target_a, target_b, lam
diff --git a/dassl/engine/dg/vanilla.py b/dassl/engine/dg/vanilla.py
new file mode 100644
index 0000000..e35f30a
--- /dev/null
+++ b/dassl/engine/dg/vanilla.py
@@ -0,0 +1,35 @@
+from torch.nn import functional as F
+
+from dassl.engine import TRAINER_REGISTRY, TrainerX
+from dassl.metrics import compute_accuracy
+
+
+@TRAINER_REGISTRY.register()
+class Vanilla(TrainerX):
+ """Vanilla model.
+
+ A.k.a. Empirical Risk Minimization, or ERM.
+ """
+
+ def forward_backward(self, batch):
+ input, target = self.parse_batch_train(batch)
+ output = self.model(input)
+ loss = F.cross_entropy(output, target)
+ self.model_backward_and_update(loss)
+
+ loss_summary = {
+ "loss": loss.item(),
+ "acc": compute_accuracy(output, target)[0].item(),
+ }
+
+ if (self.batch_idx + 1) == self.num_batches:
+ self.update_lr()
+
+ return loss_summary
+
+ def parse_batch_train(self, batch):
+ input = batch["img"]
+ target = batch["label"]
+ input = input.to(self.device)
+ target = target.to(self.device)
+ return input, target
diff --git a/dassl/engine/ssl/__init__.py b/dassl/engine/ssl/__init__.py
new file mode 100644
index 0000000..46fa781
--- /dev/null
+++ b/dassl/engine/ssl/__init__.py
@@ -0,0 +1,5 @@
+from .entmin import EntMin
+from .fixmatch import FixMatch
+from .mixmatch import MixMatch
+from .mean_teacher import MeanTeacher
+from .sup_baseline import SupBaseline
diff --git a/dassl/engine/ssl/__pycache__/__init__.cpython-310.pyc b/dassl/engine/ssl/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000..6a2f283
Binary files /dev/null and b/dassl/engine/ssl/__pycache__/__init__.cpython-310.pyc differ
diff --git a/dassl/engine/ssl/__pycache__/__init__.cpython-311.pyc b/dassl/engine/ssl/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000..06a39e3
Binary files /dev/null and b/dassl/engine/ssl/__pycache__/__init__.cpython-311.pyc differ
diff --git a/dassl/engine/ssl/__pycache__/__init__.cpython-38.pyc b/dassl/engine/ssl/__pycache__/__init__.cpython-38.pyc
new file mode 100644
index 0000000..312f81c
Binary files /dev/null and b/dassl/engine/ssl/__pycache__/__init__.cpython-38.pyc differ
diff --git a/dassl/engine/ssl/__pycache__/entmin.cpython-310.pyc b/dassl/engine/ssl/__pycache__/entmin.cpython-310.pyc
new file mode 100644
index 0000000..07a53d7
Binary files /dev/null and b/dassl/engine/ssl/__pycache__/entmin.cpython-310.pyc differ
diff --git a/dassl/engine/ssl/__pycache__/entmin.cpython-311.pyc b/dassl/engine/ssl/__pycache__/entmin.cpython-311.pyc
new file mode 100644
index 0000000..5081d50
Binary files /dev/null and b/dassl/engine/ssl/__pycache__/entmin.cpython-311.pyc differ
diff --git a/dassl/engine/ssl/__pycache__/entmin.cpython-38.pyc b/dassl/engine/ssl/__pycache__/entmin.cpython-38.pyc
new file mode 100644
index 0000000..7954459
Binary files /dev/null and b/dassl/engine/ssl/__pycache__/entmin.cpython-38.pyc differ
diff --git a/dassl/engine/ssl/__pycache__/fixmatch.cpython-310.pyc b/dassl/engine/ssl/__pycache__/fixmatch.cpython-310.pyc
new file mode 100644
index 0000000..f65008e
Binary files /dev/null and b/dassl/engine/ssl/__pycache__/fixmatch.cpython-310.pyc differ
diff --git a/dassl/engine/ssl/__pycache__/fixmatch.cpython-311.pyc b/dassl/engine/ssl/__pycache__/fixmatch.cpython-311.pyc
new file mode 100644
index 0000000..129e1fc
Binary files /dev/null and b/dassl/engine/ssl/__pycache__/fixmatch.cpython-311.pyc differ
diff --git a/dassl/engine/ssl/__pycache__/fixmatch.cpython-38.pyc b/dassl/engine/ssl/__pycache__/fixmatch.cpython-38.pyc
new file mode 100644
index 0000000..3f1108a
Binary files /dev/null and b/dassl/engine/ssl/__pycache__/fixmatch.cpython-38.pyc differ
diff --git a/dassl/engine/ssl/__pycache__/mean_teacher.cpython-310.pyc b/dassl/engine/ssl/__pycache__/mean_teacher.cpython-310.pyc
new file mode 100644
index 0000000..85b9cc4
Binary files /dev/null and b/dassl/engine/ssl/__pycache__/mean_teacher.cpython-310.pyc differ
diff --git a/dassl/engine/ssl/__pycache__/mean_teacher.cpython-311.pyc b/dassl/engine/ssl/__pycache__/mean_teacher.cpython-311.pyc
new file mode 100644
index 0000000..85a66b6
Binary files /dev/null and b/dassl/engine/ssl/__pycache__/mean_teacher.cpython-311.pyc differ
diff --git a/dassl/engine/ssl/__pycache__/mean_teacher.cpython-38.pyc b/dassl/engine/ssl/__pycache__/mean_teacher.cpython-38.pyc
new file mode 100644
index 0000000..25bf6a3
Binary files /dev/null and b/dassl/engine/ssl/__pycache__/mean_teacher.cpython-38.pyc differ
diff --git a/dassl/engine/ssl/__pycache__/mixmatch.cpython-310.pyc b/dassl/engine/ssl/__pycache__/mixmatch.cpython-310.pyc
new file mode 100644
index 0000000..ddc7de2
Binary files /dev/null and b/dassl/engine/ssl/__pycache__/mixmatch.cpython-310.pyc differ
diff --git a/dassl/engine/ssl/__pycache__/mixmatch.cpython-311.pyc b/dassl/engine/ssl/__pycache__/mixmatch.cpython-311.pyc
new file mode 100644
index 0000000..a9acf60
Binary files /dev/null and b/dassl/engine/ssl/__pycache__/mixmatch.cpython-311.pyc differ
diff --git a/dassl/engine/ssl/__pycache__/mixmatch.cpython-38.pyc b/dassl/engine/ssl/__pycache__/mixmatch.cpython-38.pyc
new file mode 100644
index 0000000..01f1aba
Binary files /dev/null and b/dassl/engine/ssl/__pycache__/mixmatch.cpython-38.pyc differ
diff --git a/dassl/engine/ssl/__pycache__/sup_baseline.cpython-310.pyc b/dassl/engine/ssl/__pycache__/sup_baseline.cpython-310.pyc
new file mode 100644
index 0000000..e18eca0
Binary files /dev/null and b/dassl/engine/ssl/__pycache__/sup_baseline.cpython-310.pyc differ
diff --git a/dassl/engine/ssl/__pycache__/sup_baseline.cpython-311.pyc b/dassl/engine/ssl/__pycache__/sup_baseline.cpython-311.pyc
new file mode 100644
index 0000000..7d1d4a9
Binary files /dev/null and b/dassl/engine/ssl/__pycache__/sup_baseline.cpython-311.pyc differ
diff --git a/dassl/engine/ssl/__pycache__/sup_baseline.cpython-38.pyc b/dassl/engine/ssl/__pycache__/sup_baseline.cpython-38.pyc
new file mode 100644
index 0000000..3d142d2
Binary files /dev/null and b/dassl/engine/ssl/__pycache__/sup_baseline.cpython-38.pyc differ
diff --git a/dassl/engine/ssl/entmin.py b/dassl/engine/ssl/entmin.py
new file mode 100644
index 0000000..a17186a
--- /dev/null
+++ b/dassl/engine/ssl/entmin.py
@@ -0,0 +1,41 @@
+import torch
+from torch.nn import functional as F
+
+from dassl.engine import TRAINER_REGISTRY, TrainerXU
+from dassl.metrics import compute_accuracy
+
+
+@TRAINER_REGISTRY.register()
+class EntMin(TrainerXU):
+ """Entropy Minimization.
+
+ http://papers.nips.cc/paper/2740-semi-supervised-learning-by-entropy-minimization.pdf.
+ """
+
+ def __init__(self, cfg):
+ super().__init__(cfg)
+ self.lmda = cfg.TRAINER.ENTMIN.LMDA
+
+ def forward_backward(self, batch_x, batch_u):
+ input_x, label_x, input_u = self.parse_batch_train(batch_x, batch_u)
+
+ output_x = self.model(input_x)
+ loss_x = F.cross_entropy(output_x, label_x)
+
+ output_u = F.softmax(self.model(input_u), 1)
+ loss_u = (-output_u * torch.log(output_u + 1e-5)).sum(1).mean()
+
+ loss = loss_x + loss_u * self.lmda
+
+ self.model_backward_and_update(loss)
+
+ loss_summary = {
+ "loss_x": loss_x.item(),
+ "acc_x": compute_accuracy(output_x, label_x)[0].item(),
+ "loss_u": loss_u.item(),
+ }
+
+ if (self.batch_idx + 1) == self.num_batches:
+ self.update_lr()
+
+ return loss_summary
diff --git a/dassl/engine/ssl/fixmatch.py b/dassl/engine/ssl/fixmatch.py
new file mode 100644
index 0000000..be6001f
--- /dev/null
+++ b/dassl/engine/ssl/fixmatch.py
@@ -0,0 +1,112 @@
+import torch
+from torch.nn import functional as F
+
+from dassl.data import DataManager
+from dassl.engine import TRAINER_REGISTRY, TrainerXU
+from dassl.metrics import compute_accuracy
+from dassl.data.transforms import build_transform
+
+
+@TRAINER_REGISTRY.register()
+class FixMatch(TrainerXU):
+ """FixMatch: Simplifying Semi-Supervised Learning with
+ Consistency and Confidence.
+
+ https://arxiv.org/abs/2001.07685.
+ """
+
+ def __init__(self, cfg):
+ super().__init__(cfg)
+ self.weight_u = cfg.TRAINER.FIXMATCH.WEIGHT_U
+ self.conf_thre = cfg.TRAINER.FIXMATCH.CONF_THRE
+
+ def check_cfg(self, cfg):
+ assert len(cfg.TRAINER.FIXMATCH.STRONG_TRANSFORMS) > 0
+
+ def build_data_loader(self):
+ cfg = self.cfg
+ tfm_train = build_transform(cfg, is_train=True)
+ custom_tfm_train = [tfm_train]
+ choices = cfg.TRAINER.FIXMATCH.STRONG_TRANSFORMS
+ tfm_train_strong = build_transform(cfg, is_train=True, choices=choices)
+ custom_tfm_train += [tfm_train_strong]
+ self.dm = DataManager(self.cfg, custom_tfm_train=custom_tfm_train)
+ self.train_loader_x = self.dm.train_loader_x
+ self.train_loader_u = self.dm.train_loader_u
+ self.val_loader = self.dm.val_loader
+ self.test_loader = self.dm.test_loader
+ self.num_classes = self.dm.num_classes
+
+ def assess_y_pred_quality(self, y_pred, y_true, mask):
+ n_masked_correct = (y_pred.eq(y_true).float() * mask).sum()
+ acc_thre = n_masked_correct / (mask.sum() + 1e-5)
+ acc_raw = y_pred.eq(y_true).sum() / y_pred.numel() # raw accuracy
+ keep_rate = mask.sum() / mask.numel()
+ output = {
+ "acc_thre": acc_thre,
+ "acc_raw": acc_raw,
+ "keep_rate": keep_rate
+ }
+ return output
+
+ def forward_backward(self, batch_x, batch_u):
+ parsed_data = self.parse_batch_train(batch_x, batch_u)
+ input_x, input_x2, label_x, input_u, input_u2, label_u = parsed_data
+ input_u = torch.cat([input_x, input_u], 0)
+ input_u2 = torch.cat([input_x2, input_u2], 0)
+ n_x = input_x.size(0)
+
+ # Generate pseudo labels
+ with torch.no_grad():
+ output_u = F.softmax(self.model(input_u), 1)
+ max_prob, label_u_pred = output_u.max(1)
+ mask_u = (max_prob >= self.conf_thre).float()
+
+ # Evaluate pseudo labels' accuracy
+ y_u_pred_stats = self.assess_y_pred_quality(
+ label_u_pred[n_x:], label_u, mask_u[n_x:]
+ )
+
+ # Supervised loss
+ output_x = self.model(input_x)
+ loss_x = F.cross_entropy(output_x, label_x)
+
+ # Unsupervised loss
+ output_u = self.model(input_u2)
+ loss_u = F.cross_entropy(output_u, label_u_pred, reduction="none")
+ loss_u = (loss_u * mask_u).mean()
+
+ loss = loss_x + loss_u * self.weight_u
+ self.model_backward_and_update(loss)
+
+ loss_summary = {
+ "loss_x": loss_x.item(),
+ "acc_x": compute_accuracy(output_x, label_x)[0].item(),
+ "loss_u": loss_u.item(),
+ "y_u_pred_acc_raw": y_u_pred_stats["acc_raw"],
+ "y_u_pred_acc_thre": y_u_pred_stats["acc_thre"],
+ "y_u_pred_keep": y_u_pred_stats["keep_rate"],
+ }
+
+ if (self.batch_idx + 1) == self.num_batches:
+ self.update_lr()
+
+ return loss_summary
+
+ def parse_batch_train(self, batch_x, batch_u):
+ input_x = batch_x["img"]
+ input_x2 = batch_x["img2"]
+ label_x = batch_x["label"]
+ input_u = batch_u["img"]
+ input_u2 = batch_u["img2"]
+ # label_u is used only for evaluating pseudo labels' accuracy
+ label_u = batch_u["label"]
+
+ input_x = input_x.to(self.device)
+ input_x2 = input_x2.to(self.device)
+ label_x = label_x.to(self.device)
+ input_u = input_u.to(self.device)
+ input_u2 = input_u2.to(self.device)
+ label_u = label_u.to(self.device)
+
+ return input_x, input_x2, label_x, input_u, input_u2, label_u
diff --git a/dassl/engine/ssl/mean_teacher.py b/dassl/engine/ssl/mean_teacher.py
new file mode 100644
index 0000000..054dc49
--- /dev/null
+++ b/dassl/engine/ssl/mean_teacher.py
@@ -0,0 +1,54 @@
+import copy
+from torch.nn import functional as F
+
+from dassl.engine import TRAINER_REGISTRY, TrainerXU
+from dassl.metrics import compute_accuracy
+from dassl.modeling.ops.utils import sigmoid_rampup, ema_model_update
+
+
+@TRAINER_REGISTRY.register()
+class MeanTeacher(TrainerXU):
+ """Mean teacher.
+
+ https://arxiv.org/abs/1703.01780.
+ """
+
+ def __init__(self, cfg):
+ super().__init__(cfg)
+ self.weight_u = cfg.TRAINER.MEANTEACHER.WEIGHT_U
+ self.ema_alpha = cfg.TRAINER.MEANTEACHER.EMA_ALPHA
+ self.rampup = cfg.TRAINER.MEANTEACHER.RAMPUP
+
+ self.teacher = copy.deepcopy(self.model)
+ self.teacher.train()
+ for param in self.teacher.parameters():
+ param.requires_grad_(False)
+
+ def forward_backward(self, batch_x, batch_u):
+ input_x, label_x, input_u = self.parse_batch_train(batch_x, batch_u)
+
+ logit_x = self.model(input_x)
+ loss_x = F.cross_entropy(logit_x, label_x)
+
+ target_u = F.softmax(self.teacher(input_u), 1)
+ prob_u = F.softmax(self.model(input_u), 1)
+ loss_u = ((prob_u - target_u)**2).sum(1).mean()
+
+ weight_u = self.weight_u * sigmoid_rampup(self.epoch, self.rampup)
+ loss = loss_x + loss_u*weight_u
+ self.model_backward_and_update(loss)
+
+ global_step = self.batch_idx + self.epoch * self.num_batches
+ ema_alpha = min(1 - 1 / (global_step+1), self.ema_alpha)
+ ema_model_update(self.model, self.teacher, ema_alpha)
+
+ loss_summary = {
+ "loss_x": loss_x.item(),
+ "acc_x": compute_accuracy(logit_x, label_x)[0].item(),
+ "loss_u": loss_u.item(),
+ }
+
+ if (self.batch_idx + 1) == self.num_batches:
+ self.update_lr()
+
+ return loss_summary
diff --git a/dassl/engine/ssl/mixmatch.py b/dassl/engine/ssl/mixmatch.py
new file mode 100644
index 0000000..6bb24e1
--- /dev/null
+++ b/dassl/engine/ssl/mixmatch.py
@@ -0,0 +1,98 @@
+import torch
+from torch.nn import functional as F
+
+from dassl.engine import TRAINER_REGISTRY, TrainerXU
+from dassl.modeling.ops import mixup
+from dassl.modeling.ops.utils import (
+ sharpen_prob, create_onehot, linear_rampup, shuffle_index
+)
+
+
+@TRAINER_REGISTRY.register()
+class MixMatch(TrainerXU):
+ """MixMatch: A Holistic Approach to Semi-Supervised Learning.
+
+ https://arxiv.org/abs/1905.02249.
+ """
+
+ def __init__(self, cfg):
+ super().__init__(cfg)
+ self.weight_u = cfg.TRAINER.MIXMATCH.WEIGHT_U
+ self.temp = cfg.TRAINER.MIXMATCH.TEMP
+ self.beta = cfg.TRAINER.MIXMATCH.MIXUP_BETA
+ self.rampup = cfg.TRAINER.MIXMATCH.RAMPUP
+
+ def check_cfg(self, cfg):
+ assert cfg.DATALOADER.K_TRANSFORMS > 1
+
+ def forward_backward(self, batch_x, batch_u):
+ input_x, label_x, input_u = self.parse_batch_train(batch_x, batch_u)
+ num_x = input_x.shape[0]
+
+ global_step = self.batch_idx + self.epoch * self.num_batches
+ weight_u = self.weight_u * linear_rampup(global_step, self.rampup)
+
+ # Generate pseudo-label for unlabeled data
+ with torch.no_grad():
+ output_u = 0
+ for input_ui in input_u:
+ output_ui = F.softmax(self.model(input_ui), 1)
+ output_u += output_ui
+ output_u /= len(input_u)
+ label_u = sharpen_prob(output_u, self.temp)
+ label_u = [label_u] * len(input_u)
+ label_u = torch.cat(label_u, 0)
+ input_u = torch.cat(input_u, 0)
+
+ # Combine and shuffle labeled and unlabeled data
+ input_xu = torch.cat([input_x, input_u], 0)
+ label_xu = torch.cat([label_x, label_u], 0)
+ input_xu, label_xu = shuffle_index(input_xu, label_xu)
+
+ # Mixup
+ input_x, label_x = mixup(
+ input_x,
+ input_xu[:num_x],
+ label_x,
+ label_xu[:num_x],
+ self.beta,
+ preserve_order=True,
+ )
+
+ input_u, label_u = mixup(
+ input_u,
+ input_xu[num_x:],
+ label_u,
+ label_xu[num_x:],
+ self.beta,
+ preserve_order=True,
+ )
+
+ # Compute losses
+ output_x = F.softmax(self.model(input_x), 1)
+ loss_x = (-label_x * torch.log(output_x + 1e-5)).sum(1).mean()
+
+ output_u = F.softmax(self.model(input_u), 1)
+ loss_u = ((label_u - output_u)**2).mean()
+
+ loss = loss_x + loss_u*weight_u
+ self.model_backward_and_update(loss)
+
+ loss_summary = {"loss_x": loss_x.item(), "loss_u": loss_u.item()}
+
+ if (self.batch_idx + 1) == self.num_batches:
+ self.update_lr()
+
+ return loss_summary
+
+ def parse_batch_train(self, batch_x, batch_u):
+ input_x = batch_x["img"][0]
+ label_x = batch_x["label"]
+ label_x = create_onehot(label_x, self.num_classes)
+ input_u = batch_u["img"]
+
+ input_x = input_x.to(self.device)
+ label_x = label_x.to(self.device)
+ input_u = [input_ui.to(self.device) for input_ui in input_u]
+
+ return input_x, label_x, input_u
diff --git a/dassl/engine/ssl/sup_baseline.py b/dassl/engine/ssl/sup_baseline.py
new file mode 100644
index 0000000..b2f5228
--- /dev/null
+++ b/dassl/engine/ssl/sup_baseline.py
@@ -0,0 +1,32 @@
+from torch.nn import functional as F
+
+from dassl.engine import TRAINER_REGISTRY, TrainerXU
+from dassl.metrics import compute_accuracy
+
+
+@TRAINER_REGISTRY.register()
+class SupBaseline(TrainerXU):
+ """Supervised Baseline."""
+
+ def forward_backward(self, batch_x, batch_u):
+ input, label = self.parse_batch_train(batch_x, batch_u)
+ output = self.model(input)
+ loss = F.cross_entropy(output, label)
+ self.model_backward_and_update(loss)
+
+ loss_summary = {
+ "loss": loss.item(),
+ "acc": compute_accuracy(output, label)[0].item(),
+ }
+
+ if (self.batch_idx + 1) == self.num_batches:
+ self.update_lr()
+
+ return loss_summary
+
+ def parse_batch_train(self, batch_x, batch_u):
+ input = batch_x["img"]
+ label = batch_x["label"]
+ input = input.to(self.device)
+ label = label.to(self.device)
+ return input, label
diff --git a/dassl/engine/trainer.py b/dassl/engine/trainer.py
new file mode 100644
index 0000000..548957a
--- /dev/null
+++ b/dassl/engine/trainer.py
@@ -0,0 +1,643 @@
+import time
+import numpy as np
+import os.path as osp
+import datetime
+from collections import OrderedDict
+import torch
+import torch.nn as nn
+from tqdm import tqdm
+from torch.utils.tensorboard import SummaryWriter
+
+from dassl.data import DataManager
+from dassl.optim import build_optimizer, build_lr_scheduler
+from dassl.utils import (
+ MetricMeter, AverageMeter, tolist_if_not, count_num_param, load_checkpoint,
+ save_checkpoint, mkdir_if_missing, resume_from_checkpoint,
+ load_pretrained_weights
+)
+from dassl.modeling import build_head, build_backbone
+from dassl.evaluation import build_evaluator
+
+
+class SimpleNet(nn.Module):
+ """A simple neural network composed of a CNN backbone
+ and optionally a head such as mlp for classification.
+ """
+
+ def __init__(self, cfg, model_cfg, num_classes, **kwargs):
+ super().__init__()
+ self.backbone = build_backbone(
+ model_cfg.BACKBONE.NAME,
+ verbose=cfg.VERBOSE,
+ pretrained=model_cfg.BACKBONE.PRETRAINED,
+ **kwargs,
+ )
+ fdim = self.backbone.out_features
+
+ self.head = None
+ if model_cfg.HEAD.NAME and model_cfg.HEAD.HIDDEN_LAYERS:
+ self.head = build_head(
+ model_cfg.HEAD.NAME,
+ verbose=cfg.VERBOSE,
+ in_features=fdim,
+ hidden_layers=model_cfg.HEAD.HIDDEN_LAYERS,
+ activation=model_cfg.HEAD.ACTIVATION,
+ bn=model_cfg.HEAD.BN,
+ dropout=model_cfg.HEAD.DROPOUT,
+ **kwargs,
+ )
+ fdim = self.head.out_features
+
+ self.classifier = None
+ if num_classes > 0:
+ self.classifier = nn.Linear(fdim, num_classes)
+
+ self._fdim = fdim
+
+ @property
+ def fdim(self):
+ return self._fdim
+
+ def forward(self, x, return_feature=False):
+ f = self.backbone(x)
+ if self.head is not None:
+ f = self.head(f)
+
+ if self.classifier is None:
+ return f
+
+ y = self.classifier(f)
+
+ if return_feature:
+ return y, f
+
+ return y
+
+
+class TrainerBase:
+ """Base class for iterative trainer."""
+
+ def __init__(self):
+ self._models = OrderedDict()
+ self._optims = OrderedDict()
+ self._scheds = OrderedDict()
+ self._writer = None
+
+ def register_model(self, name="model", model=None, optim=None, sched=None):
+ if self.__dict__.get("_models") is None:
+ raise AttributeError(
+ "Cannot assign model before super().__init__() call"
+ )
+
+ if self.__dict__.get("_optims") is None:
+ raise AttributeError(
+ "Cannot assign optim before super().__init__() call"
+ )
+
+ if self.__dict__.get("_scheds") is None:
+ raise AttributeError(
+ "Cannot assign sched before super().__init__() call"
+ )
+
+ # assert name not in self._models, "Found duplicate model names"
+
+ self._models[name] = model
+ self._optims[name] = optim
+ self._scheds[name] = sched
+
+ def get_model_names(self, names=None):
+ names_real = list(self._models.keys())
+ if names is not None:
+ names = tolist_if_not(names)
+ for name in names:
+ assert name in names_real
+ return names
+ else:
+ return names_real
+
+ def save_model(
+ self, epoch, directory, is_best=False, val_result=None, model_name=""
+ ):
+ names = self.get_model_names()
+
+ for name in names:
+ model_dict = self._models[name].state_dict()
+
+ optim_dict = None
+ if self._optims[name] is not None:
+ optim_dict = self._optims[name].state_dict()
+
+ sched_dict = None
+ if self._scheds[name] is not None:
+ sched_dict = self._scheds[name].state_dict()
+
+ save_checkpoint(
+ {
+ "state_dict": model_dict,
+ "epoch": epoch + 1,
+ "optimizer": optim_dict,
+ "scheduler": sched_dict,
+ "val_result": val_result
+ },
+ osp.join(directory, name),
+ is_best=is_best,
+ model_name=model_name,
+ )
+
+ def resume_model_if_exist(self, directory):
+ names = self.get_model_names()
+ file_missing = False
+
+ for name in names:
+ path = osp.join(directory, name)
+ if not osp.exists(path):
+ file_missing = True
+ break
+
+ if file_missing:
+ print("No checkpoint found, train from scratch")
+ return 0
+
+ print(f"Found checkpoint at {directory} (will resume training)")
+
+ for name in names:
+ path = osp.join(directory, name)
+ start_epoch = resume_from_checkpoint(
+ path, self._models[name], self._optims[name],
+ self._scheds[name]
+ )
+
+ return start_epoch
+
+ def load_model(self, directory, epoch=None):
+ if not directory:
+ print(
+ "Note that load_model() is skipped as no pretrained "
+ "model is given (ignore this if it's done on purpose)"
+ )
+ return
+
+ names = self.get_model_names()
+
+ # By default, the best model is loaded
+ model_file = "model-best.pth.tar"
+
+ if epoch is not None:
+ model_file = "model.pth.tar-" + str(epoch)
+
+ for name in names:
+ model_path = osp.join(directory, name, model_file)
+
+ if not osp.exists(model_path):
+ raise FileNotFoundError(f"No model at {model_path}")
+
+ checkpoint = load_checkpoint(model_path)
+ state_dict = checkpoint["state_dict"]
+ epoch = checkpoint["epoch"]
+ val_result = checkpoint["val_result"]
+ print(
+ f"Load {model_path} to {name} (epoch={epoch}, val_result={val_result:.1f})"
+ )
+ self._models[name].load_state_dict(state_dict)
+
+ def set_model_mode(self, mode="train", names=None):
+ names = self.get_model_names(names)
+
+ for name in names:
+ if mode == "train":
+ self._models[name].train()
+ elif mode in ["test", "eval"]:
+ self._models[name].eval()
+ else:
+ raise KeyError
+
+ def update_lr(self, names=None):
+ names = self.get_model_names(names)
+
+ for name in names:
+ if self._scheds[name] is not None:
+ self._scheds[name].step()
+
+ def detect_anomaly(self, loss):
+ if not torch.isfinite(loss).all():
+ raise FloatingPointError("Loss is infinite or NaN!")
+
+ def init_writer(self, log_dir):
+ if self.__dict__.get("_writer") is None or self._writer is None:
+ print(f"Initialize tensorboard (log_dir={log_dir})")
+ self._writer = SummaryWriter(log_dir=log_dir)
+
+ def close_writer(self):
+ if self._writer is not None:
+ self._writer.close()
+
+ def write_scalar(self, tag, scalar_value, global_step=None):
+ if self._writer is None:
+ # Do nothing if writer is not initialized
+ # Note that writer is only used when training is needed
+ pass
+ else:
+ self._writer.add_scalar(tag, scalar_value, global_step)
+
+ def train(self, start_epoch, max_epoch):
+ """Generic training loops."""
+ self.start_epoch = start_epoch
+ self.max_epoch = max_epoch
+
+ self.before_train()
+ for self.epoch in range(self.start_epoch, self.max_epoch):
+ self.before_epoch()
+ self.run_epoch()
+ self.after_epoch()
+ self.after_train()
+
+ def before_train(self):
+ pass
+
+ def after_train(self):
+ pass
+
+ def before_epoch(self):
+ pass
+
+ def after_epoch(self):
+ pass
+
+ def run_epoch(self):
+ raise NotImplementedError
+
+ def test(self):
+ raise NotImplementedError
+
+ def parse_batch_train(self, batch):
+ raise NotImplementedError
+
+ def parse_batch_test(self, batch):
+ raise NotImplementedError
+
+ def forward_backward(self, batch):
+ raise NotImplementedError
+
+ def model_inference(self, input):
+ raise NotImplementedError
+
+ def model_zero_grad(self, names=None):
+ names = self.get_model_names(names)
+ for name in names:
+ if self._optims[name] is not None:
+ self._optims[name].zero_grad()
+
+ def model_backward(self, loss):
+ self.detect_anomaly(loss)
+ loss.backward()
+
+ def model_update(self, names=None):
+ names = self.get_model_names(names)
+ for name in names:
+ if self._optims[name] is not None:
+ self._optims[name].step()
+
+ def model_backward_and_update(self, loss, names=None):
+ self.model_zero_grad(names)
+ self.model_backward(loss)
+ self.model_update(names)
+
+
+class SimpleTrainer(TrainerBase):
+ """A simple trainer class implementing generic functions."""
+
+ def __init__(self, cfg):
+ super().__init__()
+ self.check_cfg(cfg)
+
+ if torch.cuda.is_available() and cfg.USE_CUDA:
+ self.device = torch.device("cuda")
+ else:
+ self.device = torch.device("cpu")
+
+ # Save as attributes some frequently used variables
+ self.start_epoch = self.epoch = 0
+ self.max_epoch = cfg.OPTIM.MAX_EPOCH
+ self.output_dir = cfg.OUTPUT_DIR
+
+ self.cfg = cfg
+ self.build_data_loader()
+ # self.build_model()
+ self.evaluator = build_evaluator(cfg, lab2cname=self.lab2cname)
+ self.best_result = -np.inf
+
+ def check_cfg(self, cfg):
+ """Check whether some variables are set correctly for
+ the trainer (optional).
+
+ For example, a trainer might require a particular sampler
+ for training such as 'RandomDomainSampler', so it is good
+ to do the checking:
+
+ assert cfg.DATALOADER.SAMPLER_TRAIN == 'RandomDomainSampler'
+ """
+ pass
+
+ def build_data_loader(self):
+ """Create essential data-related attributes.
+
+ A re-implementation of this method must create the
+ same attributes (self.dm is optional).
+ """
+ dm = DataManager(self.cfg)
+
+ self.train_loader_x = dm.train_loader_x
+ self.train_loader_u = dm.train_loader_u # optional, can be None
+ self.val_loader = dm.val_loader # optional, can be None
+ self.test_loader = dm.test_loader
+
+ self.num_classes = dm.num_classes
+ self.num_source_domains = dm.num_source_domains
+ self.lab2cname = dm.lab2cname # dict {label: classname}
+
+ self.dm = dm
+
+ def build_model(self):
+ """Build and register model.
+
+ The default builds a classification model along with its
+ optimizer and scheduler.
+
+ Custom trainers can re-implement this method if necessary.
+ """
+ cfg = self.cfg
+
+ print("Building model")
+ self.model = SimpleNet(cfg, cfg.MODEL, self.num_classes)
+ if cfg.MODEL.INIT_WEIGHTS:
+ load_pretrained_weights(self.model, cfg.MODEL.INIT_WEIGHTS)
+ self.model.to(self.device)
+ print(f"# params: {count_num_param(self.model):,}")
+ self.optim = build_optimizer(self.model, cfg.OPTIM)
+ self.sched = build_lr_scheduler(self.optim, cfg.OPTIM)
+ self.register_model("model", self.model, self.optim, self.sched)
+
+ device_count = torch.cuda.device_count()
+ if device_count > 1:
+ print(f"Detected {device_count} GPUs (use nn.DataParallel)")
+ self.model = nn.DataParallel(self.model)
+
+ def train(self):
+ super().train(self.start_epoch, self.max_epoch)
+
+ def before_train(self):
+ # directory = self.cfg.OUTPUT_DIR
+ # if self.cfg.RESUME:
+ # directory = self.cfg.RESUME
+ # self.start_epoch = self.resume_model_if_exist(directory)
+
+ # Initialize summary writer
+ # writer_dir = osp.join(self.output_dir, "tensorboard")
+ # mkdir_if_missing(writer_dir)
+ # self.init_writer(writer_dir)
+ print("INITIALIZE the weights")
+ self.build_model()
+ # Remember the starting time (for computing the elapsed time)
+ self.time_start = time.time()
+
+ def after_train(self):
+ print("Finish training")
+
+ do_test = not self.cfg.TEST.NO_TEST
+ if do_test:
+ if self.cfg.TEST.FINAL_MODEL == "best_val":
+ print("Deploy the model with the best val performance")
+ self.load_model(self.output_dir)
+ else:
+ print("Deploy the last-epoch model")
+ self.test()
+
+ # Show elapsed time
+ elapsed = round(time.time() - self.time_start)
+ elapsed = str(datetime.timedelta(seconds=elapsed))
+ print(f"Elapsed: {elapsed}")
+
+ # Close writer
+ self.close_writer()
+
+ def after_epoch(self):
+ last_epoch = (self.epoch + 1) == self.max_epoch
+ do_test = not self.cfg.TEST.NO_TEST
+ meet_checkpoint_freq = (
+ (self.epoch + 1) % self.cfg.TRAIN.CHECKPOINT_FREQ == 0
+ if self.cfg.TRAIN.CHECKPOINT_FREQ > 0 else False
+ )
+
+ if do_test and self.cfg.TEST.FINAL_MODEL == "best_val":
+ curr_result = self.test(split="val")
+ is_best = curr_result > self.best_result
+ if is_best:
+ self.best_result = curr_result
+ self.save_model(
+ self.epoch,
+ self.output_dir,
+ val_result=curr_result,
+ model_name="model-best.pth.tar"
+ )
+
+ if meet_checkpoint_freq or last_epoch:
+ self.save_model(self.epoch, self.output_dir)
+
+ @torch.no_grad()
+ def test(self, split=None, text_features=None):
+ """A generic testing pipeline."""
+ self.set_model_mode("eval")
+ self.evaluator.reset()
+
+ if split is None:
+ split = self.cfg.TEST.SPLIT
+
+ if split == "val" and self.val_loader is not None:
+ data_loader = self.val_loader
+ else:
+ split = "test" # in case val_loader is None
+ data_loader = self.test_loader
+
+ print(f"Evaluate on the *{split}* set")
+
+ for batch_idx, batch in enumerate(tqdm(data_loader)):
+ input, label = self.parse_batch_test(batch)
+ output = self.model_inference(input, text_features)
+ self.evaluator.process(output, label)
+
+ results = self.evaluator.evaluate()
+
+ for k, v in results.items():
+ tag = f"{split}/{k}"
+ self.write_scalar(tag, v, self.epoch)
+
+ return list(results.values())[0]
+
+ def model_inference(self, input, text_features):
+ if text_features is not None:
+ return self.model.forward_with_customized_text_feature(input, text_features)
+ else:
+ return self.model(input)
+
+
+ def parse_batch_test(self, batch):
+ input = batch["img"]
+ label = batch["label"]
+
+ input = input.to(self.device)
+ label = label.to(self.device)
+
+ return input, label
+
+ def get_current_lr(self, names=None):
+ names = self.get_model_names(names)
+ name = names[0]
+ return self._optims[name].param_groups[0]["lr"]
+
+
+class TrainerXU(SimpleTrainer):
+ """A base trainer using both labeled and unlabeled data.
+
+ In the context of domain adaptation, labeled and unlabeled data
+ come from source and target domains respectively.
+
+ When it comes to semi-supervised learning, all data comes from the
+ same domain.
+ """
+
+ def run_epoch(self):
+ self.set_model_mode("train")
+ losses = MetricMeter()
+ batch_time = AverageMeter()
+ data_time = AverageMeter()
+
+ # Decide to iterate over labeled or unlabeled dataset
+ len_train_loader_x = len(self.train_loader_x)
+ len_train_loader_u = len(self.train_loader_u)
+ if self.cfg.TRAIN.COUNT_ITER == "train_x":
+ self.num_batches = len_train_loader_x
+ elif self.cfg.TRAIN.COUNT_ITER == "train_u":
+ self.num_batches = len_train_loader_u
+ elif self.cfg.TRAIN.COUNT_ITER == "smaller_one":
+ self.num_batches = min(len_train_loader_x, len_train_loader_u)
+ else:
+ raise ValueError
+
+ train_loader_x_iter = iter(self.train_loader_x)
+ train_loader_u_iter = iter(self.train_loader_u)
+
+ end = time.time()
+ for self.batch_idx in range(self.num_batches):
+ try:
+ batch_x = next(train_loader_x_iter)
+ except StopIteration:
+ train_loader_x_iter = iter(self.train_loader_x)
+ batch_x = next(train_loader_x_iter)
+
+ try:
+ batch_u = next(train_loader_u_iter)
+ except StopIteration:
+ train_loader_u_iter = iter(self.train_loader_u)
+ batch_u = next(train_loader_u_iter)
+
+ data_time.update(time.time() - end)
+ loss_summary = self.forward_backward(batch_x, batch_u)
+ batch_time.update(time.time() - end)
+ losses.update(loss_summary)
+
+ meet_freq = (self.batch_idx + 1) % self.cfg.TRAIN.PRINT_FREQ == 0
+ only_few_batches = self.num_batches < self.cfg.TRAIN.PRINT_FREQ
+ if meet_freq or only_few_batches:
+ nb_remain = 0
+ nb_remain += self.num_batches - self.batch_idx - 1
+ nb_remain += (
+ self.max_epoch - self.epoch - 1
+ ) * self.num_batches
+ eta_seconds = batch_time.avg * nb_remain
+ eta = str(datetime.timedelta(seconds=int(eta_seconds)))
+
+ info = []
+ info += [f"epoch [{self.epoch + 1}/{self.max_epoch}]"]
+ info += [f"batch [{self.batch_idx + 1}/{self.num_batches}]"]
+ info += [f"time {batch_time.val:.3f} ({batch_time.avg:.3f})"]
+ info += [f"data {data_time.val:.3f} ({data_time.avg:.3f})"]
+ info += [f"{losses}"]
+ info += [f"lr {self.get_current_lr():.4e}"]
+ info += [f"eta {eta}"]
+ print(" ".join(info))
+
+ n_iter = self.epoch * self.num_batches + self.batch_idx
+ for name, meter in losses.meters.items():
+ self.write_scalar("train/" + name, meter.avg, n_iter)
+ self.write_scalar("train/lr", self.get_current_lr(), n_iter)
+
+ end = time.time()
+
+ def parse_batch_train(self, batch_x, batch_u):
+ input_x = batch_x["img"]
+ label_x = batch_x["label"]
+ input_u = batch_u["img"]
+
+ input_x = input_x.to(self.device)
+ label_x = label_x.to(self.device)
+ input_u = input_u.to(self.device)
+
+ return input_x, label_x, input_u
+
+
+class TrainerX(SimpleTrainer):
+ """A base trainer using labeled data only."""
+
+ def run_epoch(self):
+ self.set_model_mode("train")
+ losses = MetricMeter()
+ batch_time = AverageMeter()
+ data_time = AverageMeter()
+ self.num_batches = len(self.train_loader_x)
+
+ end = time.time()
+ for self.batch_idx, batch in enumerate(self.train_loader_x):
+ data_time.update(time.time() - end)
+ loss_summary = self.forward_backward(batch)
+ batch_time.update(time.time() - end)
+ losses.update(loss_summary)
+
+ meet_freq = (self.batch_idx + 1) % self.cfg.TRAIN.PRINT_FREQ == 0
+ only_few_batches = self.num_batches < self.cfg.TRAIN.PRINT_FREQ
+ if meet_freq or only_few_batches:
+ nb_remain = 0
+ nb_remain += self.num_batches - self.batch_idx - 1
+ nb_remain += (
+ self.max_epoch - self.epoch - 1
+ ) * self.num_batches
+ eta_seconds = batch_time.avg * nb_remain
+ eta = str(datetime.timedelta(seconds=int(eta_seconds)))
+
+ info = []
+ info += [f"epoch [{self.epoch + 1}/{self.max_epoch}]"]
+ info += [f"batch [{self.batch_idx + 1}/{self.num_batches}]"]
+ info += [f"time {batch_time.val:.3f} ({batch_time.avg:.3f})"]
+ info += [f"data {data_time.val:.3f} ({data_time.avg:.3f})"]
+ info += [f"{losses}"]
+ info += [f"lr {self.get_current_lr():.4e}"]
+ info += [f"eta {eta}"]
+ print(" ".join(info))
+
+ n_iter = self.epoch * self.num_batches + self.batch_idx
+ for name, meter in losses.meters.items():
+ self.write_scalar("train/" + name, meter.avg, n_iter)
+ self.write_scalar("train/lr", self.get_current_lr(), n_iter)
+
+ end = time.time()
+ return losses
+
+ def parse_batch_train(self, batch):
+ input = batch["img"]
+ label = batch["label"]
+ domain = batch["domain"]
+
+ input = input.to(self.device)
+ label = label.to(self.device)
+ domain = domain.to(self.device)
+
+ return input, label, domain
diff --git a/dassl/evaluation/__init__.py b/dassl/evaluation/__init__.py
new file mode 100644
index 0000000..59a024f
--- /dev/null
+++ b/dassl/evaluation/__init__.py
@@ -0,0 +1,3 @@
+from .build import build_evaluator, EVALUATOR_REGISTRY # isort:skip
+
+from .evaluator import EvaluatorBase, Classification
diff --git a/dassl/evaluation/__pycache__/__init__.cpython-310.pyc b/dassl/evaluation/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000..968aa53
Binary files /dev/null and b/dassl/evaluation/__pycache__/__init__.cpython-310.pyc differ
diff --git a/dassl/evaluation/__pycache__/__init__.cpython-311.pyc b/dassl/evaluation/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000..c020166
Binary files /dev/null and b/dassl/evaluation/__pycache__/__init__.cpython-311.pyc differ
diff --git a/dassl/evaluation/__pycache__/__init__.cpython-38.pyc b/dassl/evaluation/__pycache__/__init__.cpython-38.pyc
new file mode 100644
index 0000000..1d7c576
Binary files /dev/null and b/dassl/evaluation/__pycache__/__init__.cpython-38.pyc differ
diff --git a/dassl/evaluation/__pycache__/build.cpython-310.pyc b/dassl/evaluation/__pycache__/build.cpython-310.pyc
new file mode 100644
index 0000000..95c2e69
Binary files /dev/null and b/dassl/evaluation/__pycache__/build.cpython-310.pyc differ
diff --git a/dassl/evaluation/__pycache__/build.cpython-311.pyc b/dassl/evaluation/__pycache__/build.cpython-311.pyc
new file mode 100644
index 0000000..962e4ab
Binary files /dev/null and b/dassl/evaluation/__pycache__/build.cpython-311.pyc differ
diff --git a/dassl/evaluation/__pycache__/build.cpython-38.pyc b/dassl/evaluation/__pycache__/build.cpython-38.pyc
new file mode 100644
index 0000000..d1bdf47
Binary files /dev/null and b/dassl/evaluation/__pycache__/build.cpython-38.pyc differ
diff --git a/dassl/evaluation/__pycache__/evaluator.cpython-310.pyc b/dassl/evaluation/__pycache__/evaluator.cpython-310.pyc
new file mode 100644
index 0000000..0dafff2
Binary files /dev/null and b/dassl/evaluation/__pycache__/evaluator.cpython-310.pyc differ
diff --git a/dassl/evaluation/__pycache__/evaluator.cpython-311.pyc b/dassl/evaluation/__pycache__/evaluator.cpython-311.pyc
new file mode 100644
index 0000000..4803886
Binary files /dev/null and b/dassl/evaluation/__pycache__/evaluator.cpython-311.pyc differ
diff --git a/dassl/evaluation/__pycache__/evaluator.cpython-38.pyc b/dassl/evaluation/__pycache__/evaluator.cpython-38.pyc
new file mode 100644
index 0000000..2c313e2
Binary files /dev/null and b/dassl/evaluation/__pycache__/evaluator.cpython-38.pyc differ
diff --git a/dassl/evaluation/build.py b/dassl/evaluation/build.py
new file mode 100644
index 0000000..3132a3f
--- /dev/null
+++ b/dassl/evaluation/build.py
@@ -0,0 +1,11 @@
+from dassl.utils import Registry, check_availability
+
+EVALUATOR_REGISTRY = Registry("EVALUATOR")
+
+
+def build_evaluator(cfg, **kwargs):
+ avai_evaluators = EVALUATOR_REGISTRY.registered_names()
+ check_availability(cfg.TEST.EVALUATOR, avai_evaluators)
+ if cfg.VERBOSE:
+ print("Loading evaluator: {}".format(cfg.TEST.EVALUATOR))
+ return EVALUATOR_REGISTRY.get(cfg.TEST.EVALUATOR)(cfg, **kwargs)
diff --git a/dassl/evaluation/evaluator.py b/dassl/evaluation/evaluator.py
new file mode 100644
index 0000000..eef3797
--- /dev/null
+++ b/dassl/evaluation/evaluator.py
@@ -0,0 +1,125 @@
+import numpy as np
+import os.path as osp
+from collections import OrderedDict, defaultdict
+import torch
+from sklearn.metrics import f1_score, confusion_matrix
+
+from .build import EVALUATOR_REGISTRY
+
+
+class EvaluatorBase:
+ """Base evaluator."""
+
+ def __init__(self, cfg):
+ self.cfg = cfg
+
+ def reset(self):
+ raise NotImplementedError
+
+ def process(self, mo, gt):
+ raise NotImplementedError
+
+ def evaluate(self):
+ raise NotImplementedError
+
+
+@EVALUATOR_REGISTRY.register()
+class Classification(EvaluatorBase):
+ """Evaluator for classification."""
+
+ def __init__(self, cfg, lab2cname=None, **kwargs):
+ super().__init__(cfg)
+ self._lab2cname = lab2cname
+ self._correct = 0
+ self._total = 0
+ self._per_class_res = None
+ self._y_true = []
+ self._y_pred = []
+ if cfg.TEST.PER_CLASS_RESULT:
+ assert lab2cname is not None
+ self._per_class_res = defaultdict(list)
+
+ def reset(self):
+ self._correct = 0
+ self._total = 0
+ self._y_true = []
+ self._y_pred = []
+ if self._per_class_res is not None:
+ self._per_class_res = defaultdict(list)
+
+ def process(self, mo, gt):
+ # mo (torch.Tensor): model output [batch, num_classes]
+ # gt (torch.LongTensor): ground truth [batch]
+ pred = mo.max(1)[1]
+ matches = pred.eq(gt).float()
+ self._correct += int(matches.sum().item())
+ self._total += gt.shape[0]
+
+ self._y_true.extend(gt.data.cpu().numpy().tolist())
+ self._y_pred.extend(pred.data.cpu().numpy().tolist())
+
+ if self._per_class_res is not None:
+ for i, label in enumerate(gt):
+ label = label.item()
+ matches_i = int(matches[i].item())
+ self._per_class_res[label].append(matches_i)
+
+ def evaluate(self):
+ results = OrderedDict()
+ acc = 100.0 * self._correct / self._total
+ err = 100.0 - acc
+ macro_f1 = 100.0 * f1_score(
+ self._y_true,
+ self._y_pred,
+ average="macro",
+ labels=np.unique(self._y_true)
+ )
+
+ # The first value will be returned by trainer.test()
+ results["accuracy"] = acc
+ results["error_rate"] = err
+ results["macro_f1"] = macro_f1
+
+ print(
+ "=> result\n"
+ f"* total: {self._total:,}\n"
+ f"* correct: {self._correct:,}\n"
+ f"* accuracy: {acc:.1f}%\n"
+ f"* error: {err:.1f}%\n"
+ f"* macro_f1: {macro_f1:.1f}%"
+ )
+
+ if self._per_class_res is not None:
+ labels = list(self._per_class_res.keys())
+ labels.sort()
+
+ print("=> per-class result")
+ accs = []
+
+ for label in labels:
+ classname = self._lab2cname[label]
+ res = self._per_class_res[label]
+ correct = sum(res)
+ total = len(res)
+ acc = 100.0 * correct / total
+ accs.append(acc)
+ print(
+ f"* class: {label} ({classname})\t"
+ f"total: {total:,}\t"
+ f"correct: {correct:,}\t"
+ f"acc: {acc:.1f}%"
+ )
+ mean_acc = np.mean(accs)
+ print(f"* average: {mean_acc:.1f}%")
+
+ results["perclass_accuracy"] = mean_acc
+
+ if self.cfg.TEST.COMPUTE_CMAT:
+ cmat = confusion_matrix(
+ self._y_true, self._y_pred, normalize="true"
+ )
+ save_path = osp.join(self.cfg.OUTPUT_DIR, "cmat.pt")
+ torch.save(cmat, save_path)
+ print(f"Confusion matrix is saved to {save_path}")
+
+ return results
diff --git a/dassl/metrics/__init__.py b/dassl/metrics/__init__.py
new file mode 100644
index 0000000..c2b37de
--- /dev/null
+++ b/dassl/metrics/__init__.py
@@ -0,0 +1,4 @@
+from .accuracy import compute_accuracy
+from .distance import (
+ cosine_distance, compute_distance_matrix, euclidean_squared_distance
+)
diff --git a/dassl/metrics/__pycache__/__init__.cpython-310.pyc b/dassl/metrics/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000..c74433d
Binary files /dev/null and b/dassl/metrics/__pycache__/__init__.cpython-310.pyc differ
diff --git a/dassl/metrics/__pycache__/__init__.cpython-311.pyc b/dassl/metrics/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000..167445b
Binary files /dev/null and b/dassl/metrics/__pycache__/__init__.cpython-311.pyc differ
diff --git a/dassl/metrics/__pycache__/__init__.cpython-38.pyc b/dassl/metrics/__pycache__/__init__.cpython-38.pyc
new file mode 100644
index 0000000..a3fe759
Binary files /dev/null and b/dassl/metrics/__pycache__/__init__.cpython-38.pyc differ
diff --git a/dassl/metrics/__pycache__/accuracy.cpython-310.pyc b/dassl/metrics/__pycache__/accuracy.cpython-310.pyc
new file mode 100644
index 0000000..ca60ea6
Binary files /dev/null and b/dassl/metrics/__pycache__/accuracy.cpython-310.pyc differ
diff --git a/dassl/metrics/__pycache__/accuracy.cpython-311.pyc b/dassl/metrics/__pycache__/accuracy.cpython-311.pyc
new file mode 100644
index 0000000..c109c81
Binary files /dev/null and b/dassl/metrics/__pycache__/accuracy.cpython-311.pyc differ
diff --git a/dassl/metrics/__pycache__/accuracy.cpython-38.pyc b/dassl/metrics/__pycache__/accuracy.cpython-38.pyc
new file mode 100644
index 0000000..51203f0
Binary files /dev/null and b/dassl/metrics/__pycache__/accuracy.cpython-38.pyc differ
diff --git a/dassl/metrics/__pycache__/distance.cpython-310.pyc b/dassl/metrics/__pycache__/distance.cpython-310.pyc
new file mode 100644
index 0000000..0024130
Binary files /dev/null and b/dassl/metrics/__pycache__/distance.cpython-310.pyc differ
diff --git a/dassl/metrics/__pycache__/distance.cpython-311.pyc b/dassl/metrics/__pycache__/distance.cpython-311.pyc
new file mode 100644
index 0000000..1da9347
Binary files /dev/null and b/dassl/metrics/__pycache__/distance.cpython-311.pyc differ
diff --git a/dassl/metrics/__pycache__/distance.cpython-38.pyc b/dassl/metrics/__pycache__/distance.cpython-38.pyc
new file mode 100644
index 0000000..2ca0cd2
Binary files /dev/null and b/dassl/metrics/__pycache__/distance.cpython-38.pyc differ
diff --git a/dassl/metrics/accuracy.py b/dassl/metrics/accuracy.py
new file mode 100644
index 0000000..a8ed0ae
--- /dev/null
+++ b/dassl/metrics/accuracy.py
@@ -0,0 +1,30 @@
+def compute_accuracy(output, target, topk=(1, )):
+ """Computes the accuracy over the k top predictions for
+ the specified values of k.
+
+ Args:
+ output (torch.Tensor): prediction matrix with shape (batch_size, num_classes).
+ target (torch.LongTensor): ground truth labels with shape (batch_size).
+ topk (tuple, optional): accuracy at top-k will be computed. For example,
+ topk=(1, 5) means accuracy at top-1 and top-5 will be computed.
+
+ Returns:
+ list: accuracy at top-k.
+ """
+ maxk = max(topk)
+ batch_size = target.size(0)
+
+ if isinstance(output, (tuple, list)):
+ output = output[0]
+
+ _, pred = output.topk(maxk, 1, True, True)
+ pred = pred.t()
+ correct = pred.eq(target.view(1, -1).expand_as(pred))
+
+ res = []
+ for k in topk:
+ correct_k = correct[:k].view(-1).float().sum(0, keepdim=True)
+ acc = correct_k.mul_(100.0 / batch_size)
+ res.append(acc)
+
+ return res
diff --git a/dassl/metrics/distance.py b/dassl/metrics/distance.py
new file mode 100644
index 0000000..8056815
--- /dev/null
+++ b/dassl/metrics/distance.py
@@ -0,0 +1,77 @@
+"""
+Source: https://github.com/KaiyangZhou/deep-person-reid
+"""
+import torch
+from torch.nn import functional as F
+
+
+def compute_distance_matrix(input1, input2, metric="euclidean"):
+ """A wrapper function for computing distance matrix.
+
+ Each input matrix has the shape (n_data, feature_dim).
+
+ Args:
+ input1 (torch.Tensor): 2-D feature matrix.
+ input2 (torch.Tensor): 2-D feature matrix.
+ metric (str, optional): "euclidean" or "cosine".
+ Default is "euclidean".
+
+ Returns:
+ torch.Tensor: distance matrix.
+ """
+ # check input
+ assert isinstance(input1, torch.Tensor)
+ assert isinstance(input2, torch.Tensor)
+ assert input1.dim() == 2, "Expected 2-D tensor, but got {}-D".format(
+ input1.dim()
+ )
+ assert input2.dim() == 2, "Expected 2-D tensor, but got {}-D".format(
+ input2.dim()
+ )
+ assert input1.size(1) == input2.size(1)
+
+ if metric == "euclidean":
+ distmat = euclidean_squared_distance(input1, input2)
+ elif metric == "cosine":
+ distmat = cosine_distance(input1, input2)
+ else:
+ raise ValueError(
+ "Unknown distance metric: {}. "
+ 'Please choose either "euclidean" or "cosine"'.format(metric)
+ )
+
+ return distmat
+
+
+def euclidean_squared_distance(input1, input2):
+ """Computes euclidean squared distance.
+
+ Args:
+ input1 (torch.Tensor): 2-D feature matrix.
+ input2 (torch.Tensor): 2-D feature matrix.
+
+ Returns:
+ torch.Tensor: distance matrix.
+ """
+ m, n = input1.size(0), input2.size(0)
+ mat1 = torch.pow(input1, 2).sum(dim=1, keepdim=True).expand(m, n)
+ mat2 = torch.pow(input2, 2).sum(dim=1, keepdim=True).expand(n, m).t()
+ distmat = mat1 + mat2
+ distmat.addmm_(1, -2, input1, input2.t())
+ return distmat
+
+
+def cosine_distance(input1, input2):
+ """Computes cosine distance.
+
+ Args:
+ input1 (torch.Tensor): 2-D feature matrix.
+ input2 (torch.Tensor): 2-D feature matrix.
+
+ Returns:
+ torch.Tensor: distance matrix.
+ """
+ input1_normed = F.normalize(input1, p=2, dim=1)
+ input2_normed = F.normalize(input2, p=2, dim=1)
+ distmat = 1 - torch.mm(input1_normed, input2_normed.t())
+ return distmat
diff --git a/dassl/modeling/__init__.py b/dassl/modeling/__init__.py
new file mode 100644
index 0000000..88466b9
--- /dev/null
+++ b/dassl/modeling/__init__.py
@@ -0,0 +1,3 @@
+from .head import HEAD_REGISTRY, build_head
+from .network import NETWORK_REGISTRY, build_network
+from .backbone import BACKBONE_REGISTRY, Backbone, build_backbone
diff --git a/dassl/modeling/__pycache__/__init__.cpython-310.pyc b/dassl/modeling/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000..ad725e7
Binary files /dev/null and b/dassl/modeling/__pycache__/__init__.cpython-310.pyc differ
diff --git a/dassl/modeling/__pycache__/__init__.cpython-311.pyc b/dassl/modeling/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000..b744b03
Binary files /dev/null and b/dassl/modeling/__pycache__/__init__.cpython-311.pyc differ
diff --git a/dassl/modeling/__pycache__/__init__.cpython-38.pyc b/dassl/modeling/__pycache__/__init__.cpython-38.pyc
new file mode 100644
index 0000000..d8d25a4
Binary files /dev/null and b/dassl/modeling/__pycache__/__init__.cpython-38.pyc differ
diff --git a/dassl/modeling/backbone/__init__.py b/dassl/modeling/backbone/__init__.py
new file mode 100644
index 0000000..8e6dc68
--- /dev/null
+++ b/dassl/modeling/backbone/__init__.py
@@ -0,0 +1,23 @@
+from .build import build_backbone, BACKBONE_REGISTRY # isort:skip
+from .backbone import Backbone # isort:skip
+
+from .vgg import vgg16
+from .resnet import (
+ resnet18, resnet34, resnet50, resnet101, resnet152, resnet18_ms_l1,
+ resnet50_ms_l1, resnet18_ms_l12, resnet50_ms_l12, resnet101_ms_l1,
+ resnet18_ms_l123, resnet50_ms_l123, resnet101_ms_l12, resnet101_ms_l123,
+ resnet18_efdmix_l1, resnet50_efdmix_l1, resnet18_efdmix_l12,
+ resnet50_efdmix_l12, resnet101_efdmix_l1, resnet18_efdmix_l123,
+ resnet50_efdmix_l123, resnet101_efdmix_l12, resnet101_efdmix_l123
+)
+from .alexnet import alexnet
+from .wide_resnet import wide_resnet_16_4, wide_resnet_28_2
+from .cnn_digitsdg import cnn_digitsdg
+from .efficientnet import (
+ efficientnet_b0, efficientnet_b1, efficientnet_b2, efficientnet_b3,
+ efficientnet_b4, efficientnet_b5, efficientnet_b6, efficientnet_b7
+)
+from .resnet_dynamic import *
+from .cnn_digitsingle import cnn_digitsingle
+from .preact_resnet18 import preact_resnet18
+from .cnn_digit5_m3sda import cnn_digit5_m3sda
diff --git a/dassl/modeling/backbone/__pycache__/__init__.cpython-310.pyc b/dassl/modeling/backbone/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000..c4484d5
Binary files /dev/null and b/dassl/modeling/backbone/__pycache__/__init__.cpython-310.pyc differ
diff --git a/dassl/modeling/backbone/__pycache__/__init__.cpython-311.pyc b/dassl/modeling/backbone/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000..9dc9c76
Binary files /dev/null and b/dassl/modeling/backbone/__pycache__/__init__.cpython-311.pyc differ
diff --git a/dassl/modeling/backbone/__pycache__/__init__.cpython-38.pyc b/dassl/modeling/backbone/__pycache__/__init__.cpython-38.pyc
new file mode 100644
index 0000000..b781daa
Binary files /dev/null and b/dassl/modeling/backbone/__pycache__/__init__.cpython-38.pyc differ
diff --git a/dassl/modeling/backbone/__pycache__/alexnet.cpython-310.pyc b/dassl/modeling/backbone/__pycache__/alexnet.cpython-310.pyc
new file mode 100644
index 0000000..bda385b
Binary files /dev/null and b/dassl/modeling/backbone/__pycache__/alexnet.cpython-310.pyc differ
diff --git a/dassl/modeling/backbone/__pycache__/alexnet.cpython-311.pyc b/dassl/modeling/backbone/__pycache__/alexnet.cpython-311.pyc
new file mode 100644
index 0000000..00ccfde
Binary files /dev/null and b/dassl/modeling/backbone/__pycache__/alexnet.cpython-311.pyc differ
diff --git a/dassl/modeling/backbone/__pycache__/alexnet.cpython-38.pyc b/dassl/modeling/backbone/__pycache__/alexnet.cpython-38.pyc
new file mode 100644
index 0000000..e5ce508
Binary files /dev/null and b/dassl/modeling/backbone/__pycache__/alexnet.cpython-38.pyc differ
diff --git a/dassl/modeling/backbone/__pycache__/backbone.cpython-310.pyc b/dassl/modeling/backbone/__pycache__/backbone.cpython-310.pyc
new file mode 100644
index 0000000..3b307e0
Binary files /dev/null and b/dassl/modeling/backbone/__pycache__/backbone.cpython-310.pyc differ
diff --git a/dassl/modeling/backbone/__pycache__/backbone.cpython-311.pyc b/dassl/modeling/backbone/__pycache__/backbone.cpython-311.pyc
new file mode 100644
index 0000000..f9a70d1
Binary files /dev/null and b/dassl/modeling/backbone/__pycache__/backbone.cpython-311.pyc differ
diff --git a/dassl/modeling/backbone/__pycache__/backbone.cpython-38.pyc b/dassl/modeling/backbone/__pycache__/backbone.cpython-38.pyc
new file mode 100644
index 0000000..1d542d0
Binary files /dev/null and b/dassl/modeling/backbone/__pycache__/backbone.cpython-38.pyc differ
diff --git a/dassl/modeling/backbone/__pycache__/build.cpython-310.pyc b/dassl/modeling/backbone/__pycache__/build.cpython-310.pyc
new file mode 100644
index 0000000..a7755d8
Binary files /dev/null and b/dassl/modeling/backbone/__pycache__/build.cpython-310.pyc differ
diff --git a/dassl/modeling/backbone/__pycache__/build.cpython-311.pyc b/dassl/modeling/backbone/__pycache__/build.cpython-311.pyc
new file mode 100644
index 0000000..4818f6c
Binary files /dev/null and b/dassl/modeling/backbone/__pycache__/build.cpython-311.pyc differ
diff --git a/dassl/modeling/backbone/__pycache__/build.cpython-38.pyc b/dassl/modeling/backbone/__pycache__/build.cpython-38.pyc
new file mode 100644
index 0000000..4b7c9e0
Binary files /dev/null and b/dassl/modeling/backbone/__pycache__/build.cpython-38.pyc differ
diff --git a/dassl/modeling/backbone/__pycache__/cnn_digit5_m3sda.cpython-310.pyc b/dassl/modeling/backbone/__pycache__/cnn_digit5_m3sda.cpython-310.pyc
new file mode 100644
index 0000000..95cef53
Binary files /dev/null and b/dassl/modeling/backbone/__pycache__/cnn_digit5_m3sda.cpython-310.pyc differ
diff --git a/dassl/modeling/backbone/__pycache__/cnn_digit5_m3sda.cpython-311.pyc b/dassl/modeling/backbone/__pycache__/cnn_digit5_m3sda.cpython-311.pyc
new file mode 100644
index 0000000..f65a45a
Binary files /dev/null and b/dassl/modeling/backbone/__pycache__/cnn_digit5_m3sda.cpython-311.pyc differ
diff --git a/dassl/modeling/backbone/__pycache__/cnn_digit5_m3sda.cpython-38.pyc b/dassl/modeling/backbone/__pycache__/cnn_digit5_m3sda.cpython-38.pyc
new file mode 100644
index 0000000..17fc5b7
Binary files /dev/null and b/dassl/modeling/backbone/__pycache__/cnn_digit5_m3sda.cpython-38.pyc differ
diff --git a/dassl/modeling/backbone/__pycache__/cnn_digitsdg.cpython-310.pyc b/dassl/modeling/backbone/__pycache__/cnn_digitsdg.cpython-310.pyc
new file mode 100644
index 0000000..006aff6
Binary files /dev/null and b/dassl/modeling/backbone/__pycache__/cnn_digitsdg.cpython-310.pyc differ
diff --git a/dassl/modeling/backbone/__pycache__/cnn_digitsdg.cpython-311.pyc b/dassl/modeling/backbone/__pycache__/cnn_digitsdg.cpython-311.pyc
new file mode 100644
index 0000000..00864ee
Binary files /dev/null and b/dassl/modeling/backbone/__pycache__/cnn_digitsdg.cpython-311.pyc differ
diff --git a/dassl/modeling/backbone/__pycache__/cnn_digitsdg.cpython-38.pyc b/dassl/modeling/backbone/__pycache__/cnn_digitsdg.cpython-38.pyc
new file mode 100644
index 0000000..d4e17f0
Binary files /dev/null and b/dassl/modeling/backbone/__pycache__/cnn_digitsdg.cpython-38.pyc differ
diff --git a/dassl/modeling/backbone/__pycache__/cnn_digitsingle.cpython-310.pyc b/dassl/modeling/backbone/__pycache__/cnn_digitsingle.cpython-310.pyc
new file mode 100644
index 0000000..7f0892a
Binary files /dev/null and b/dassl/modeling/backbone/__pycache__/cnn_digitsingle.cpython-310.pyc differ
diff --git a/dassl/modeling/backbone/__pycache__/cnn_digitsingle.cpython-311.pyc b/dassl/modeling/backbone/__pycache__/cnn_digitsingle.cpython-311.pyc
new file mode 100644
index 0000000..e15a38e
Binary files /dev/null and b/dassl/modeling/backbone/__pycache__/cnn_digitsingle.cpython-311.pyc differ
diff --git a/dassl/modeling/backbone/__pycache__/cnn_digitsingle.cpython-38.pyc b/dassl/modeling/backbone/__pycache__/cnn_digitsingle.cpython-38.pyc
new file mode 100644
index 0000000..38292b6
Binary files /dev/null and b/dassl/modeling/backbone/__pycache__/cnn_digitsingle.cpython-38.pyc differ
diff --git a/dassl/modeling/backbone/__pycache__/preact_resnet18.cpython-310.pyc b/dassl/modeling/backbone/__pycache__/preact_resnet18.cpython-310.pyc
new file mode 100644
index 0000000..f436de5
Binary files /dev/null and b/dassl/modeling/backbone/__pycache__/preact_resnet18.cpython-310.pyc differ
diff --git a/dassl/modeling/backbone/__pycache__/preact_resnet18.cpython-311.pyc b/dassl/modeling/backbone/__pycache__/preact_resnet18.cpython-311.pyc
new file mode 100644
index 0000000..9562a2f
Binary files /dev/null and b/dassl/modeling/backbone/__pycache__/preact_resnet18.cpython-311.pyc differ
diff --git a/dassl/modeling/backbone/__pycache__/preact_resnet18.cpython-38.pyc b/dassl/modeling/backbone/__pycache__/preact_resnet18.cpython-38.pyc
new file mode 100644
index 0000000..725b069
Binary files /dev/null and b/dassl/modeling/backbone/__pycache__/preact_resnet18.cpython-38.pyc differ
diff --git a/dassl/modeling/backbone/__pycache__/resnet.cpython-310.pyc b/dassl/modeling/backbone/__pycache__/resnet.cpython-310.pyc
new file mode 100644
index 0000000..44a86e5
Binary files /dev/null and b/dassl/modeling/backbone/__pycache__/resnet.cpython-310.pyc differ
diff --git a/dassl/modeling/backbone/__pycache__/resnet.cpython-311.pyc b/dassl/modeling/backbone/__pycache__/resnet.cpython-311.pyc
new file mode 100644
index 0000000..c1d7d46
Binary files /dev/null and b/dassl/modeling/backbone/__pycache__/resnet.cpython-311.pyc differ
diff --git a/dassl/modeling/backbone/__pycache__/resnet.cpython-38.pyc b/dassl/modeling/backbone/__pycache__/resnet.cpython-38.pyc
new file mode 100644
index 0000000..c283c0d
Binary files /dev/null and b/dassl/modeling/backbone/__pycache__/resnet.cpython-38.pyc differ
diff --git a/dassl/modeling/backbone/__pycache__/resnet_dynamic.cpython-310.pyc b/dassl/modeling/backbone/__pycache__/resnet_dynamic.cpython-310.pyc
new file mode 100644
index 0000000..6173ffe
Binary files /dev/null and b/dassl/modeling/backbone/__pycache__/resnet_dynamic.cpython-310.pyc differ
diff --git a/dassl/modeling/backbone/__pycache__/resnet_dynamic.cpython-311.pyc b/dassl/modeling/backbone/__pycache__/resnet_dynamic.cpython-311.pyc
new file mode 100644
index 0000000..e56bef3
Binary files /dev/null and b/dassl/modeling/backbone/__pycache__/resnet_dynamic.cpython-311.pyc differ
diff --git a/dassl/modeling/backbone/__pycache__/resnet_dynamic.cpython-38.pyc b/dassl/modeling/backbone/__pycache__/resnet_dynamic.cpython-38.pyc
new file mode 100644
index 0000000..40143a0
Binary files /dev/null and b/dassl/modeling/backbone/__pycache__/resnet_dynamic.cpython-38.pyc differ
diff --git a/dassl/modeling/backbone/__pycache__/vgg.cpython-310.pyc b/dassl/modeling/backbone/__pycache__/vgg.cpython-310.pyc
new file mode 100644
index 0000000..c468de0
Binary files /dev/null and b/dassl/modeling/backbone/__pycache__/vgg.cpython-310.pyc differ
diff --git a/dassl/modeling/backbone/__pycache__/vgg.cpython-311.pyc b/dassl/modeling/backbone/__pycache__/vgg.cpython-311.pyc
new file mode 100644
index 0000000..9016f61
Binary files /dev/null and b/dassl/modeling/backbone/__pycache__/vgg.cpython-311.pyc differ
diff --git a/dassl/modeling/backbone/__pycache__/vgg.cpython-38.pyc b/dassl/modeling/backbone/__pycache__/vgg.cpython-38.pyc
new file mode 100644
index 0000000..084b191
Binary files /dev/null and b/dassl/modeling/backbone/__pycache__/vgg.cpython-38.pyc differ
diff --git a/dassl/modeling/backbone/__pycache__/wide_resnet.cpython-310.pyc b/dassl/modeling/backbone/__pycache__/wide_resnet.cpython-310.pyc
new file mode 100644
index 0000000..da87c48
Binary files /dev/null and b/dassl/modeling/backbone/__pycache__/wide_resnet.cpython-310.pyc differ
diff --git a/dassl/modeling/backbone/__pycache__/wide_resnet.cpython-311.pyc b/dassl/modeling/backbone/__pycache__/wide_resnet.cpython-311.pyc
new file mode 100644
index 0000000..49b8ed3
Binary files /dev/null and b/dassl/modeling/backbone/__pycache__/wide_resnet.cpython-311.pyc differ
diff --git a/dassl/modeling/backbone/__pycache__/wide_resnet.cpython-38.pyc b/dassl/modeling/backbone/__pycache__/wide_resnet.cpython-38.pyc
new file mode 100644
index 0000000..3a9fbbb
Binary files /dev/null and b/dassl/modeling/backbone/__pycache__/wide_resnet.cpython-38.pyc differ
diff --git a/dassl/modeling/backbone/alexnet.py b/dassl/modeling/backbone/alexnet.py
new file mode 100644
index 0000000..2daff24
--- /dev/null
+++ b/dassl/modeling/backbone/alexnet.py
@@ -0,0 +1,64 @@
+import torch
+import torch.nn as nn
+import torch.utils.model_zoo as model_zoo
+
+from .build import BACKBONE_REGISTRY
+from .backbone import Backbone
+
+model_urls = {
+ "alexnet": "https://download.pytorch.org/models/alexnet-owt-4df8aa71.pth",
+}
+
+
+class AlexNet(Backbone):
+
+ def __init__(self):
+ super().__init__()
+ self.features = nn.Sequential(
+ nn.Conv2d(3, 64, kernel_size=11, stride=4, padding=2),
+ nn.ReLU(inplace=True),
+ nn.MaxPool2d(kernel_size=3, stride=2),
+ nn.Conv2d(64, 192, kernel_size=5, padding=2),
+ nn.ReLU(inplace=True),
+ nn.MaxPool2d(kernel_size=3, stride=2),
+ nn.Conv2d(192, 384, kernel_size=3, padding=1),
+ nn.ReLU(inplace=True),
+ nn.Conv2d(384, 256, kernel_size=3, padding=1),
+ nn.ReLU(inplace=True),
+ nn.Conv2d(256, 256, kernel_size=3, padding=1),
+ nn.ReLU(inplace=True),
+ nn.MaxPool2d(kernel_size=3, stride=2),
+ )
+ self.avgpool = nn.AdaptiveAvgPool2d((6, 6))
+ # Note that self.classifier outputs features rather than logits
+ self.classifier = nn.Sequential(
+ nn.Dropout(),
+ nn.Linear(256 * 6 * 6, 4096),
+ nn.ReLU(inplace=True),
+ nn.Dropout(),
+ nn.Linear(4096, 4096),
+ nn.ReLU(inplace=True),
+ )
+
+ self._out_features = 4096
+
+ def forward(self, x):
+ x = self.features(x)
+ x = self.avgpool(x)
+ x = torch.flatten(x, 1)
+ return self.classifier(x)
+
+
+def init_pretrained_weights(model, model_url):
+ pretrain_dict = model_zoo.load_url(model_url)
+ model.load_state_dict(pretrain_dict, strict=False)
+
+
+@BACKBONE_REGISTRY.register()
+def alexnet(pretrained=True, **kwargs):
+ model = AlexNet()
+
+ if pretrained:
+ init_pretrained_weights(model, model_urls["alexnet"])
+
+ return model
diff --git a/dassl/modeling/backbone/backbone.py b/dassl/modeling/backbone/backbone.py
new file mode 100644
index 0000000..b544d94
--- /dev/null
+++ b/dassl/modeling/backbone/backbone.py
@@ -0,0 +1,17 @@
+import torch.nn as nn
+
+
+class Backbone(nn.Module):
+
+ def __init__(self):
+ super().__init__()
+
+ def forward(self):
+ pass
+
+ @property
+ def out_features(self):
+ """Output feature dimension."""
+ if self.__dict__.get("_out_features") is None:
+ return None
+ return self._out_features
diff --git a/dassl/modeling/backbone/build.py b/dassl/modeling/backbone/build.py
new file mode 100644
index 0000000..61f4e4f
--- /dev/null
+++ b/dassl/modeling/backbone/build.py
@@ -0,0 +1,11 @@
+from dassl.utils import Registry, check_availability
+
+BACKBONE_REGISTRY = Registry("BACKBONE")
+
+
+def build_backbone(name, verbose=True, **kwargs):
+ avai_backbones = BACKBONE_REGISTRY.registered_names()
+ check_availability(name, avai_backbones)
+ if verbose:
+ print("Backbone: {}".format(name))
+ return BACKBONE_REGISTRY.get(name)(**kwargs)
diff --git a/dassl/modeling/backbone/cnn_digit5_m3sda.py b/dassl/modeling/backbone/cnn_digit5_m3sda.py
new file mode 100644
index 0000000..deabded
--- /dev/null
+++ b/dassl/modeling/backbone/cnn_digit5_m3sda.py
@@ -0,0 +1,58 @@
+"""
+Reference
+
+https://github.com/VisionLearningGroup/VisionLearningGroup.github.io/tree/master/M3SDA
+"""
+import torch.nn as nn
+from torch.nn import functional as F
+
+from .build import BACKBONE_REGISTRY
+from .backbone import Backbone
+
+
+class FeatureExtractor(Backbone):
+
+ def __init__(self):
+ super().__init__()
+ self.conv1 = nn.Conv2d(3, 64, kernel_size=5, stride=1, padding=2)
+ self.bn1 = nn.BatchNorm2d(64)
+ self.conv2 = nn.Conv2d(64, 64, kernel_size=5, stride=1, padding=2)
+ self.bn2 = nn.BatchNorm2d(64)
+ self.conv3 = nn.Conv2d(64, 128, kernel_size=5, stride=1, padding=2)
+ self.bn3 = nn.BatchNorm2d(128)
+ self.fc1 = nn.Linear(8192, 3072)
+ self.bn1_fc = nn.BatchNorm1d(3072)
+ self.fc2 = nn.Linear(3072, 2048)
+ self.bn2_fc = nn.BatchNorm1d(2048)
+
+ self._out_features = 2048
+
+ def _check_input(self, x):
+ H, W = x.shape[2:]
+ assert (
+ H == 32 and W == 32
+ ), "Input to network must be 32x32, " "but got {}x{}".format(H, W)
+
+ def forward(self, x):
+ self._check_input(x)
+ x = F.relu(self.bn1(self.conv1(x)))
+ x = F.max_pool2d(x, stride=2, kernel_size=3, padding=1)
+ x = F.relu(self.bn2(self.conv2(x)))
+ x = F.max_pool2d(x, stride=2, kernel_size=3, padding=1)
+ x = F.relu(self.bn3(self.conv3(x)))
+ x = x.view(x.size(0), 8192)
+ x = F.relu(self.bn1_fc(self.fc1(x)))
+ x = F.dropout(x, training=self.training)
+ x = F.relu(self.bn2_fc(self.fc2(x)))
+ return x
+
+
+@BACKBONE_REGISTRY.register()
+def cnn_digit5_m3sda(**kwargs):
+ """
+ This architecture was used for the Digit-5 dataset in:
+
+ - Peng et al. Moment Matching for Multi-Source
+ Domain Adaptation. ICCV 2019.
+ """
+ return FeatureExtractor()
diff --git a/dassl/modeling/backbone/cnn_digitsdg.py b/dassl/modeling/backbone/cnn_digitsdg.py
new file mode 100644
index 0000000..c68044f
--- /dev/null
+++ b/dassl/modeling/backbone/cnn_digitsdg.py
@@ -0,0 +1,61 @@
+import torch.nn as nn
+from torch.nn import functional as F
+
+from dassl.utils import init_network_weights
+
+from .build import BACKBONE_REGISTRY
+from .backbone import Backbone
+
+
+class Convolution(nn.Module):
+
+ def __init__(self, c_in, c_out):
+ super().__init__()
+ self.conv = nn.Conv2d(c_in, c_out, 3, stride=1, padding=1)
+ self.relu = nn.ReLU(True)
+
+ def forward(self, x):
+ return self.relu(self.conv(x))
+
+
+class ConvNet(Backbone):
+
+ def __init__(self, c_hidden=64):
+ super().__init__()
+ self.conv1 = Convolution(3, c_hidden)
+ self.conv2 = Convolution(c_hidden, c_hidden)
+ self.conv3 = Convolution(c_hidden, c_hidden)
+ self.conv4 = Convolution(c_hidden, c_hidden)
+
+ self._out_features = 2**2 * c_hidden
+
+ def _check_input(self, x):
+ H, W = x.shape[2:]
+ assert (
+ H == 32 and W == 32
+ ), "Input to network must be 32x32, " "but got {}x{}".format(H, W)
+
+ def forward(self, x):
+ self._check_input(x)
+ x = self.conv1(x)
+ x = F.max_pool2d(x, 2)
+ x = self.conv2(x)
+ x = F.max_pool2d(x, 2)
+ x = self.conv3(x)
+ x = F.max_pool2d(x, 2)
+ x = self.conv4(x)
+ x = F.max_pool2d(x, 2)
+ return x.view(x.size(0), -1)
+
+
+@BACKBONE_REGISTRY.register()
+def cnn_digitsdg(**kwargs):
+ """
+ This architecture was used for DigitsDG dataset in:
+
+ - Zhou et al. Deep Domain-Adversarial Image Generation
+ for Domain Generalisation. AAAI 2020.
+ """
+ model = ConvNet(c_hidden=64)
+ init_network_weights(model, init_type="kaiming")
+ return model
diff --git a/dassl/modeling/backbone/cnn_digitsingle.py b/dassl/modeling/backbone/cnn_digitsingle.py
new file mode 100644
index 0000000..0c5101c
--- /dev/null
+++ b/dassl/modeling/backbone/cnn_digitsingle.py
@@ -0,0 +1,56 @@
+"""
+This model is built based on
+https://github.com/ricvolpi/generalize-unseen-domains/blob/master/model.py
+"""
+import torch.nn as nn
+from torch.nn import functional as F
+
+from dassl.utils import init_network_weights
+
+from .build import BACKBONE_REGISTRY
+from .backbone import Backbone
+
+
+class CNN(Backbone):
+
+ def __init__(self):
+ super().__init__()
+ self.conv1 = nn.Conv2d(3, 64, 5)
+ self.conv2 = nn.Conv2d(64, 128, 5)
+ self.fc3 = nn.Linear(5 * 5 * 128, 1024)
+ self.fc4 = nn.Linear(1024, 1024)
+
+ self._out_features = 1024
+
+ def _check_input(self, x):
+ H, W = x.shape[2:]
+ assert (
+ H == 32 and W == 32
+ ), "Input to network must be 32x32, " "but got {}x{}".format(H, W)
+
+ def forward(self, x):
+ self._check_input(x)
+ x = self.conv1(x)
+ x = F.relu(x)
+ x = F.max_pool2d(x, 2)
+
+ x = self.conv2(x)
+ x = F.relu(x)
+ x = F.max_pool2d(x, 2)
+
+ x = x.view(x.size(0), -1)
+
+ x = self.fc3(x)
+ x = F.relu(x)
+
+ x = self.fc4(x)
+ x = F.relu(x)
+
+ return x
+
+
+@BACKBONE_REGISTRY.register()
+def cnn_digitsingle(**kwargs):
+ model = CNN()
+ init_network_weights(model, init_type="kaiming")
+ return model
diff --git a/dassl/modeling/backbone/efficientnet/__init__.py b/dassl/modeling/backbone/efficientnet/__init__.py
new file mode 100644
index 0000000..20ee433
--- /dev/null
+++ b/dassl/modeling/backbone/efficientnet/__init__.py
@@ -0,0 +1,12 @@
+"""
+Source: https://github.com/lukemelas/EfficientNet-PyTorch.
+"""
+__version__ = "0.6.4"
+from .model import (
+ EfficientNet, efficientnet_b0, efficientnet_b1, efficientnet_b2,
+ efficientnet_b3, efficientnet_b4, efficientnet_b5, efficientnet_b6,
+ efficientnet_b7
+)
+from .utils import (
+ BlockArgs, BlockDecoder, GlobalParams, efficientnet, get_model_params
+)
diff --git a/dassl/modeling/backbone/efficientnet/__pycache__/__init__.cpython-310.pyc b/dassl/modeling/backbone/efficientnet/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000..c0dd457
Binary files /dev/null and b/dassl/modeling/backbone/efficientnet/__pycache__/__init__.cpython-310.pyc differ
diff --git a/dassl/modeling/backbone/efficientnet/__pycache__/__init__.cpython-311.pyc b/dassl/modeling/backbone/efficientnet/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000..48b6570
Binary files /dev/null and b/dassl/modeling/backbone/efficientnet/__pycache__/__init__.cpython-311.pyc differ
diff --git a/dassl/modeling/backbone/efficientnet/__pycache__/__init__.cpython-38.pyc b/dassl/modeling/backbone/efficientnet/__pycache__/__init__.cpython-38.pyc
new file mode 100644
index 0000000..9ba3948
Binary files /dev/null and b/dassl/modeling/backbone/efficientnet/__pycache__/__init__.cpython-38.pyc differ
diff --git a/dassl/modeling/backbone/efficientnet/__pycache__/model.cpython-310.pyc b/dassl/modeling/backbone/efficientnet/__pycache__/model.cpython-310.pyc
new file mode 100644
index 0000000..cc0a818
Binary files /dev/null and b/dassl/modeling/backbone/efficientnet/__pycache__/model.cpython-310.pyc differ
diff --git a/dassl/modeling/backbone/efficientnet/__pycache__/model.cpython-311.pyc b/dassl/modeling/backbone/efficientnet/__pycache__/model.cpython-311.pyc
new file mode 100644
index 0000000..fa8d79a
Binary files /dev/null and b/dassl/modeling/backbone/efficientnet/__pycache__/model.cpython-311.pyc differ
diff --git a/dassl/modeling/backbone/efficientnet/__pycache__/model.cpython-38.pyc b/dassl/modeling/backbone/efficientnet/__pycache__/model.cpython-38.pyc
new file mode 100644
index 0000000..24dba10
Binary files /dev/null and b/dassl/modeling/backbone/efficientnet/__pycache__/model.cpython-38.pyc differ
diff --git a/dassl/modeling/backbone/efficientnet/__pycache__/utils.cpython-310.pyc b/dassl/modeling/backbone/efficientnet/__pycache__/utils.cpython-310.pyc
new file mode 100644
index 0000000..c3c7378
Binary files /dev/null and b/dassl/modeling/backbone/efficientnet/__pycache__/utils.cpython-310.pyc differ
diff --git a/dassl/modeling/backbone/efficientnet/__pycache__/utils.cpython-311.pyc b/dassl/modeling/backbone/efficientnet/__pycache__/utils.cpython-311.pyc
new file mode 100644
index 0000000..9c649d9
Binary files /dev/null and b/dassl/modeling/backbone/efficientnet/__pycache__/utils.cpython-311.pyc differ
diff --git a/dassl/modeling/backbone/efficientnet/__pycache__/utils.cpython-38.pyc b/dassl/modeling/backbone/efficientnet/__pycache__/utils.cpython-38.pyc
new file mode 100644
index 0000000..1f1ad77
Binary files /dev/null and b/dassl/modeling/backbone/efficientnet/__pycache__/utils.cpython-38.pyc differ
diff --git a/dassl/modeling/backbone/efficientnet/model.py b/dassl/modeling/backbone/efficientnet/model.py
new file mode 100755
index 0000000..ed01261
--- /dev/null
+++ b/dassl/modeling/backbone/efficientnet/model.py
@@ -0,0 +1,371 @@
+import torch
+from torch import nn
+from torch.nn import functional as F
+
+from .utils import (
+ Swish, MemoryEfficientSwish, drop_connect, round_filters, round_repeats,
+ get_model_params, efficientnet_params, get_same_padding_conv2d,
+ load_pretrained_weights, calculate_output_image_size
+)
+from ..build import BACKBONE_REGISTRY
+from ..backbone import Backbone
+
+
+class MBConvBlock(nn.Module):
+ """
+ Mobile Inverted Residual Bottleneck Block
+
+ Args:
+ block_args (namedtuple): BlockArgs, see above
+ global_params (namedtuple): GlobalParam, see above
+
+ Attributes:
+ has_se (bool): Whether the block contains a Squeeze and Excitation layer.
+ """
+
+ def __init__(self, block_args, global_params, image_size=None):
+ super().__init__()
+ self._block_args = block_args
+ self._bn_mom = 1 - global_params.batch_norm_momentum
+ self._bn_eps = global_params.batch_norm_epsilon
+ self.has_se = (self._block_args.se_ratio is
+ not None) and (0 < self._block_args.se_ratio <= 1)
+ self.id_skip = block_args.id_skip # skip connection and drop connect
+
+ # Expansion phase
+ inp = self._block_args.input_filters # number of input channels
+ oup = (
+ self._block_args.input_filters * self._block_args.expand_ratio
+ ) # number of output channels
+ if self._block_args.expand_ratio != 1:
+ Conv2d = get_same_padding_conv2d(image_size=image_size)
+ self._expand_conv = Conv2d(
+ in_channels=inp, out_channels=oup, kernel_size=1, bias=False
+ )
+ self._bn0 = nn.BatchNorm2d(
+ num_features=oup, momentum=self._bn_mom, eps=self._bn_eps
+ )
+ # image_size = calculate_output_image_size(image_size, 1) <-- this would do nothing
+
+ # Depthwise convolution phase
+ k = self._block_args.kernel_size
+ s = self._block_args.stride
+ Conv2d = get_same_padding_conv2d(image_size=image_size)
+ self._depthwise_conv = Conv2d(
+ in_channels=oup,
+ out_channels=oup,
+ groups=oup, # groups makes it depthwise
+ kernel_size=k,
+ stride=s,
+ bias=False,
+ )
+ self._bn1 = nn.BatchNorm2d(
+ num_features=oup, momentum=self._bn_mom, eps=self._bn_eps
+ )
+ image_size = calculate_output_image_size(image_size, s)
+
+ # Squeeze and Excitation layer, if desired
+ if self.has_se:
+ Conv2d = get_same_padding_conv2d(image_size=(1, 1))
+ num_squeezed_channels = max(
+ 1,
+ int(
+ self._block_args.input_filters * self._block_args.se_ratio
+ )
+ )
+ self._se_reduce = Conv2d(
+ in_channels=oup,
+ out_channels=num_squeezed_channels,
+ kernel_size=1
+ )
+ self._se_expand = Conv2d(
+ in_channels=num_squeezed_channels,
+ out_channels=oup,
+ kernel_size=1
+ )
+
+ # Output phase
+ final_oup = self._block_args.output_filters
+ Conv2d = get_same_padding_conv2d(image_size=image_size)
+ self._project_conv = Conv2d(
+ in_channels=oup, out_channels=final_oup, kernel_size=1, bias=False
+ )
+ self._bn2 = nn.BatchNorm2d(
+ num_features=final_oup, momentum=self._bn_mom, eps=self._bn_eps
+ )
+ self._swish = MemoryEfficientSwish()
+
+ def forward(self, inputs, drop_connect_rate=None):
+ """
+ :param inputs: input tensor
+ :param drop_connect_rate: drop connect rate (float, between 0 and 1)
+ :return: output of block
+ """
+
+ # Expansion and Depthwise Convolution
+ x = inputs
+ if self._block_args.expand_ratio != 1:
+ x = self._swish(self._bn0(self._expand_conv(inputs)))
+ x = self._swish(self._bn1(self._depthwise_conv(x)))
+
+ # Squeeze and Excitation
+ if self.has_se:
+ x_squeezed = F.adaptive_avg_pool2d(x, 1)
+ x_squeezed = self._se_expand(
+ self._swish(self._se_reduce(x_squeezed))
+ )
+ x = torch.sigmoid(x_squeezed) * x
+
+ x = self._bn2(self._project_conv(x))
+
+ # Skip connection and drop connect
+ input_filters, output_filters = (
+ self._block_args.input_filters,
+ self._block_args.output_filters,
+ )
+ if (
+ self.id_skip and self._block_args.stride == 1
+ and input_filters == output_filters
+ ):
+ if drop_connect_rate:
+ x = drop_connect(
+ x, p=drop_connect_rate, training=self.training
+ )
+ x = x + inputs # skip connection
+ return x
+
+ def set_swish(self, memory_efficient=True):
+ """Sets swish function as memory efficient (for training) or standard (for export)"""
+ self._swish = MemoryEfficientSwish() if memory_efficient else Swish()
+
+
+class EfficientNet(Backbone):
+ """
+ An EfficientNet model. Most easily loaded with the .from_name or .from_pretrained methods
+
+ Args:
+ blocks_args (list): A list of BlockArgs to construct blocks
+ global_params (namedtuple): A set of GlobalParams shared between blocks
+
+ Example:
+ model = EfficientNet.from_pretrained('efficientnet-b0')
+
+ """
+
+ def __init__(self, blocks_args=None, global_params=None):
+ super().__init__()
+ assert isinstance(blocks_args, list), "blocks_args should be a list"
+ assert len(blocks_args) > 0, "block args must be greater than 0"
+ self._global_params = global_params
+ self._blocks_args = blocks_args
+
+ # Batch norm parameters
+ bn_mom = 1 - self._global_params.batch_norm_momentum
+ bn_eps = self._global_params.batch_norm_epsilon
+
+ # Get stem static or dynamic convolution depending on image size
+ image_size = global_params.image_size
+ Conv2d = get_same_padding_conv2d(image_size=global_params.image_size)
+
+ # Stem
+ in_channels = 3 # rgb
+ out_channels = round_filters(
+ 32, self._global_params
+ ) # number of output channels
+ self._conv_stem = Conv2d(
+ in_channels, out_channels, kernel_size=3, stride=2, bias=False
+ )
+ self._bn0 = nn.BatchNorm2d(
+ num_features=out_channels, momentum=bn_mom, eps=bn_eps
+ )
+ image_size = calculate_output_image_size(image_size, 2)
+
+ # Build blocks
+ self._blocks = nn.ModuleList([])
+ for block_args in self._blocks_args:
+
+ # Update block input and output filters based on depth multiplier.
+ block_args = block_args._replace(
+ input_filters=round_filters(
+ block_args.input_filters, self._global_params
+ ),
+ output_filters=round_filters(
+ block_args.output_filters, self._global_params
+ ),
+ num_repeat=round_repeats(
+ block_args.num_repeat, self._global_params
+ ),
+ )
+
+ # The first block needs to take care of stride and filter size increase.
+ self._blocks.append(
+ MBConvBlock(
+ block_args, self._global_params, image_size=image_size
+ )
+ )
+ image_size = calculate_output_image_size(
+ image_size, block_args.stride
+ )
+ if block_args.num_repeat > 1:
+ block_args = block_args._replace(
+ input_filters=block_args.output_filters, stride=1
+ )
+ for _ in range(block_args.num_repeat - 1):
+ self._blocks.append(
+ MBConvBlock(
+ block_args, self._global_params, image_size=image_size
+ )
+ )
+ # image_size = calculate_output_image_size(image_size, block_args.stride) # ?
+
+ # Head
+ in_channels = block_args.output_filters # output of final block
+ out_channels = round_filters(1280, self._global_params)
+ Conv2d = get_same_padding_conv2d(image_size=image_size)
+ self._conv_head = Conv2d(
+ in_channels, out_channels, kernel_size=1, bias=False
+ )
+ self._bn1 = nn.BatchNorm2d(
+ num_features=out_channels, momentum=bn_mom, eps=bn_eps
+ )
+
+ # Final linear layer
+ self._avg_pooling = nn.AdaptiveAvgPool2d(1)
+ self._dropout = nn.Dropout(self._global_params.dropout_rate)
+ # self._fc = nn.Linear(out_channels, self._global_params.num_classes)
+ self._swish = MemoryEfficientSwish()
+
+ self._out_features = out_channels
+
+ def set_swish(self, memory_efficient=True):
+ """Sets swish function as memory efficient (for training) or standard (for export)"""
+ self._swish = MemoryEfficientSwish() if memory_efficient else Swish()
+ for block in self._blocks:
+ block.set_swish(memory_efficient)
+
+ def extract_features(self, inputs):
+ """Returns output of the final convolution layer"""
+
+ # Stem
+ x = self._swish(self._bn0(self._conv_stem(inputs)))
+
+ # Blocks
+ for idx, block in enumerate(self._blocks):
+ drop_connect_rate = self._global_params.drop_connect_rate
+ if drop_connect_rate:
+ drop_connect_rate *= float(idx) / len(self._blocks)
+ x = block(x, drop_connect_rate=drop_connect_rate)
+
+ # Head
+ x = self._swish(self._bn1(self._conv_head(x)))
+
+ return x
+
+ def forward(self, inputs):
+ """
+ Calls extract_features to extract features, applies
+ final linear layer, and returns logits.
+ """
+ bs = inputs.size(0)
+ # Convolution layers
+ x = self.extract_features(inputs)
+
+ # Pooling and final linear layer
+ x = self._avg_pooling(x)
+ x = x.view(bs, -1)
+ x = self._dropout(x)
+ # x = self._fc(x)
+ return x
+
+ @classmethod
+ def from_name(cls, model_name, override_params=None):
+ cls._check_model_name_is_valid(model_name)
+ blocks_args, global_params = get_model_params(
+ model_name, override_params
+ )
+ return cls(blocks_args, global_params)
+
+ @classmethod
+ def from_pretrained(
+ cls, model_name, advprop=False, num_classes=1000, in_channels=3
+ ):
+ model = cls.from_name(
+ model_name, override_params={"num_classes": num_classes}
+ )
+ load_pretrained_weights(
+ model, model_name, load_fc=(num_classes == 1000), advprop=advprop
+ )
+ model._change_in_channels(in_channels)
+ return model
+
+ @classmethod
+ def get_image_size(cls, model_name):
+ cls._check_model_name_is_valid(model_name)
+ _, _, res, _ = efficientnet_params(model_name)
+ return res
+
+ @classmethod
+ def _check_model_name_is_valid(cls, model_name):
+ """Validates model name."""
+ valid_models = ["efficientnet-b" + str(i) for i in range(9)]
+ if model_name not in valid_models:
+ raise ValueError(
+ "model_name should be one of: " + ", ".join(valid_models)
+ )
+
+ def _change_in_channels(model, in_channels):
+ if in_channels != 3:
+ Conv2d = get_same_padding_conv2d(
+ image_size=model._global_params.image_size
+ )
+ out_channels = round_filters(32, model._global_params)
+ model._conv_stem = Conv2d(
+ in_channels, out_channels, kernel_size=3, stride=2, bias=False
+ )
+
+
+def build_efficientnet(name, pretrained):
+ if pretrained:
+ return EfficientNet.from_pretrained("efficientnet-{}".format(name))
+ else:
+ return EfficientNet.from_name("efficientnet-{}".format(name))
+
+
+@BACKBONE_REGISTRY.register()
+def efficientnet_b0(pretrained=True, **kwargs):
+ return build_efficientnet("b0", pretrained)
+
+
+@BACKBONE_REGISTRY.register()
+def efficientnet_b1(pretrained=True, **kwargs):
+ return build_efficientnet("b1", pretrained)
+
+
+@BACKBONE_REGISTRY.register()
+def efficientnet_b2(pretrained=True, **kwargs):
+ return build_efficientnet("b2", pretrained)
+
+
+@BACKBONE_REGISTRY.register()
+def efficientnet_b3(pretrained=True, **kwargs):
+ return build_efficientnet("b3", pretrained)
+
+
+@BACKBONE_REGISTRY.register()
+def efficientnet_b4(pretrained=True, **kwargs):
+ return build_efficientnet("b4", pretrained)
+
+
+@BACKBONE_REGISTRY.register()
+def efficientnet_b5(pretrained=True, **kwargs):
+ return build_efficientnet("b5", pretrained)
+
+
+@BACKBONE_REGISTRY.register()
+def efficientnet_b6(pretrained=True, **kwargs):
+ return build_efficientnet("b6", pretrained)
+
+
+@BACKBONE_REGISTRY.register()
+def efficientnet_b7(pretrained=True, **kwargs):
+ return build_efficientnet("b7", pretrained)
diff --git a/dassl/modeling/backbone/efficientnet/utils.py b/dassl/modeling/backbone/efficientnet/utils.py
new file mode 100755
index 0000000..a420506
--- /dev/null
+++ b/dassl/modeling/backbone/efficientnet/utils.py
@@ -0,0 +1,477 @@
+"""
+This file contains helper functions for building the model and for loading model parameters.
+These helper functions are built to mirror those in the official TensorFlow implementation.
+"""
+
+import re
+import math
+import collections
+from functools import partial
+import torch
+from torch import nn
+from torch.nn import functional as F
+from torch.utils import model_zoo
+
+########################################################################
+############### HELPERS FUNCTIONS FOR MODEL ARCHITECTURE ###############
+########################################################################
+
+# Parameters for the entire model (stem, all blocks, and head)
+GlobalParams = collections.namedtuple(
+ "GlobalParams",
+ [
+ "batch_norm_momentum",
+ "batch_norm_epsilon",
+ "dropout_rate",
+ "num_classes",
+ "width_coefficient",
+ "depth_coefficient",
+ "depth_divisor",
+ "min_depth",
+ "drop_connect_rate",
+ "image_size",
+ ],
+)
+
+# Parameters for an individual model block
+BlockArgs = collections.namedtuple(
+ "BlockArgs",
+ [
+ "kernel_size",
+ "num_repeat",
+ "input_filters",
+ "output_filters",
+ "expand_ratio",
+ "id_skip",
+ "stride",
+ "se_ratio",
+ ],
+)
+
+# Change namedtuple defaults
+GlobalParams.__new__.__defaults__ = (None, ) * len(GlobalParams._fields)
+BlockArgs.__new__.__defaults__ = (None, ) * len(BlockArgs._fields)
+
+
+class SwishImplementation(torch.autograd.Function):
+
+ @staticmethod
+ def forward(ctx, i):
+ result = i * torch.sigmoid(i)
+ ctx.save_for_backward(i)
+ return result
+
+ @staticmethod
+ def backward(ctx, grad_output):
+ i = ctx.saved_variables[0]
+ sigmoid_i = torch.sigmoid(i)
+ return grad_output * (sigmoid_i * (1 + i * (1-sigmoid_i)))
+
+
+class MemoryEfficientSwish(nn.Module):
+
+ def forward(self, x):
+ return SwishImplementation.apply(x)
+
+
+class Swish(nn.Module):
+
+ def forward(self, x):
+ return x * torch.sigmoid(x)
+
+
+def round_filters(filters, global_params):
+ """Calculate and round number of filters based on depth multiplier."""
+ multiplier = global_params.width_coefficient
+ if not multiplier:
+ return filters
+ divisor = global_params.depth_divisor
+ min_depth = global_params.min_depth
+ filters *= multiplier
+ min_depth = min_depth or divisor
+ new_filters = max(min_depth, int(filters + divisor/2) // divisor * divisor)
+ if new_filters < 0.9 * filters: # prevent rounding by more than 10%
+ new_filters += divisor
+ return int(new_filters)
+
+
+def round_repeats(repeats, global_params):
+ """Round number of filters based on depth multiplier."""
+ multiplier = global_params.depth_coefficient
+ if not multiplier:
+ return repeats
+ return int(math.ceil(multiplier * repeats))
+
+
+def drop_connect(inputs, p, training):
+ """Drop connect."""
+ if not training:
+ return inputs
+ batch_size = inputs.shape[0]
+ keep_prob = 1 - p
+ random_tensor = keep_prob
+ random_tensor += torch.rand(
+ [batch_size, 1, 1, 1], dtype=inputs.dtype, device=inputs.device
+ )
+ binary_tensor = torch.floor(random_tensor)
+ output = inputs / keep_prob * binary_tensor
+ return output
+
+
+def get_same_padding_conv2d(image_size=None):
+ """Chooses static padding if you have specified an image size, and dynamic padding otherwise.
+ Static padding is necessary for ONNX exporting of models."""
+ if image_size is None:
+ return Conv2dDynamicSamePadding
+ else:
+ return partial(Conv2dStaticSamePadding, image_size=image_size)
+
+
+def get_width_and_height_from_size(x):
+ """Obtains width and height from a int or tuple"""
+ if isinstance(x, int):
+ return x, x
+ if isinstance(x, list) or isinstance(x, tuple):
+ return x
+ else:
+ raise TypeError()
+
+
+def calculate_output_image_size(input_image_size, stride):
+ """
+ Calculates the output image size when using Conv2dSamePadding with a stride.
+ Necessary for static padding. Thanks to mannatsingh for pointing this out.
+ """
+ if input_image_size is None:
+ return None
+ image_height, image_width = get_width_and_height_from_size(
+ input_image_size
+ )
+ stride = stride if isinstance(stride, int) else stride[0]
+ image_height = int(math.ceil(image_height / stride))
+ image_width = int(math.ceil(image_width / stride))
+ return [image_height, image_width]
+
+
+class Conv2dDynamicSamePadding(nn.Conv2d):
+ """2D Convolutions like TensorFlow, for a dynamic image size"""
+
+ def __init__(
+ self,
+ in_channels,
+ out_channels,
+ kernel_size,
+ stride=1,
+ dilation=1,
+ groups=1,
+ bias=True,
+ ):
+ super().__init__(
+ in_channels, out_channels, kernel_size, stride, 0, dilation,
+ groups, bias
+ )
+ self.stride = self.stride if len(self.stride
+ ) == 2 else [self.stride[0]] * 2
+
+ def forward(self, x):
+ ih, iw = x.size()[-2:]
+ kh, kw = self.weight.size()[-2:]
+ sh, sw = self.stride
+ oh, ow = math.ceil(ih / sh), math.ceil(iw / sw)
+ pad_h = max(
+ (oh-1) * self.stride[0] + (kh-1) * self.dilation[0] + 1 - ih, 0
+ )
+ pad_w = max(
+ (ow-1) * self.stride[1] + (kw-1) * self.dilation[1] + 1 - iw, 0
+ )
+ if pad_h > 0 or pad_w > 0:
+ x = F.pad(
+ x,
+ [pad_w // 2, pad_w - pad_w//2, pad_h // 2, pad_h - pad_h//2]
+ )
+ return F.conv2d(
+ x,
+ self.weight,
+ self.bias,
+ self.stride,
+ self.padding,
+ self.dilation,
+ self.groups,
+ )
+
+
+class Conv2dStaticSamePadding(nn.Conv2d):
+ """2D Convolutions like TensorFlow, for a fixed image size"""
+
+ def __init__(
+ self,
+ in_channels,
+ out_channels,
+ kernel_size,
+ image_size=None,
+ **kwargs
+ ):
+ super().__init__(in_channels, out_channels, kernel_size, **kwargs)
+ self.stride = self.stride if len(self.stride
+ ) == 2 else [self.stride[0]] * 2
+
+ # Calculate padding based on image size and save it
+ assert image_size is not None
+ ih, iw = (image_size,
+ image_size) if isinstance(image_size, int) else image_size
+ kh, kw = self.weight.size()[-2:]
+ sh, sw = self.stride
+ oh, ow = math.ceil(ih / sh), math.ceil(iw / sw)
+ pad_h = max(
+ (oh-1) * self.stride[0] + (kh-1) * self.dilation[0] + 1 - ih, 0
+ )
+ pad_w = max(
+ (ow-1) * self.stride[1] + (kw-1) * self.dilation[1] + 1 - iw, 0
+ )
+ if pad_h > 0 or pad_w > 0:
+ self.static_padding = nn.ZeroPad2d(
+ (pad_w // 2, pad_w - pad_w//2, pad_h // 2, pad_h - pad_h//2)
+ )
+ else:
+ self.static_padding = Identity()
+
+ def forward(self, x):
+ x = self.static_padding(x)
+ x = F.conv2d(
+ x,
+ self.weight,
+ self.bias,
+ self.stride,
+ self.padding,
+ self.dilation,
+ self.groups,
+ )
+ return x
+
+
+class Identity(nn.Module):
+
+ def __init__(self, ):
+ super(Identity, self).__init__()
+
+ def forward(self, input):
+ return input
+
+
+########################################################################
+############## HELPERS FUNCTIONS FOR LOADING MODEL PARAMS ##############
+########################################################################
+
+
+def efficientnet_params(model_name):
+ """Map EfficientNet model name to parameter coefficients."""
+ params_dict = {
+ # Coefficients: width,depth,res,dropout
+ "efficientnet-b0": (1.0, 1.0, 224, 0.2),
+ "efficientnet-b1": (1.0, 1.1, 240, 0.2),
+ "efficientnet-b2": (1.1, 1.2, 260, 0.3),
+ "efficientnet-b3": (1.2, 1.4, 300, 0.3),
+ "efficientnet-b4": (1.4, 1.8, 380, 0.4),
+ "efficientnet-b5": (1.6, 2.2, 456, 0.4),
+ "efficientnet-b6": (1.8, 2.6, 528, 0.5),
+ "efficientnet-b7": (2.0, 3.1, 600, 0.5),
+ "efficientnet-b8": (2.2, 3.6, 672, 0.5),
+ "efficientnet-l2": (4.3, 5.3, 800, 0.5),
+ }
+ return params_dict[model_name]
+
+
+class BlockDecoder(object):
+ """Block Decoder for readability, straight from the official TensorFlow repository"""
+
+ @staticmethod
+ def _decode_block_string(block_string):
+ """Gets a block through a string notation of arguments."""
+ assert isinstance(block_string, str)
+
+ ops = block_string.split("_")
+ options = {}
+ for op in ops:
+ splits = re.split(r"(\d.*)", op)
+ if len(splits) >= 2:
+ key, value = splits[:2]
+ options[key] = value
+
+ # Check stride
+ assert ("s" in options and len(options["s"]) == 1) or (
+ len(options["s"]) == 2 and options["s"][0] == options["s"][1]
+ )
+
+ return BlockArgs(
+ kernel_size=int(options["k"]),
+ num_repeat=int(options["r"]),
+ input_filters=int(options["i"]),
+ output_filters=int(options["o"]),
+ expand_ratio=int(options["e"]),
+ id_skip=("noskip" not in block_string),
+ se_ratio=float(options["se"]) if "se" in options else None,
+ stride=[int(options["s"][0])],
+ )
+
+ @staticmethod
+ def _encode_block_string(block):
+ """Encodes a block to a string."""
+ args = [
+ "r%d" % block.num_repeat,
+ "k%d" % block.kernel_size,
+ "s%d%d" % (block.strides[0], block.strides[1]),
+ "e%s" % block.expand_ratio,
+ "i%d" % block.input_filters,
+ "o%d" % block.output_filters,
+ ]
+ if 0 < block.se_ratio <= 1:
+ args.append("se%s" % block.se_ratio)
+ if block.id_skip is False:
+ args.append("noskip")
+ return "_".join(args)
+
+ @staticmethod
+ def decode(string_list):
+ """
+ Decodes a list of string notations to specify blocks inside the network.
+
+ :param string_list: a list of strings, each string is a notation of block
+ :return: a list of BlockArgs namedtuples of block args
+ """
+ assert isinstance(string_list, list)
+ blocks_args = []
+ for block_string in string_list:
+ blocks_args.append(BlockDecoder._decode_block_string(block_string))
+ return blocks_args
+
+ @staticmethod
+ def encode(blocks_args):
+ """
+ Encodes a list of BlockArgs to a list of strings.
+
+ :param blocks_args: a list of BlockArgs namedtuples of block args
+ :return: a list of strings, each string is a notation of block
+ """
+ block_strings = []
+ for block in blocks_args:
+ block_strings.append(BlockDecoder._encode_block_string(block))
+ return block_strings
+
+
+def efficientnet(
+ width_coefficient=None,
+ depth_coefficient=None,
+ dropout_rate=0.2,
+ drop_connect_rate=0.2,
+ image_size=None,
+ num_classes=1000,
+):
+ """Creates a efficientnet model."""
+
+ blocks_args = [
+ "r1_k3_s11_e1_i32_o16_se0.25",
+ "r2_k3_s22_e6_i16_o24_se0.25",
+ "r2_k5_s22_e6_i24_o40_se0.25",
+ "r3_k3_s22_e6_i40_o80_se0.25",
+ "r3_k5_s11_e6_i80_o112_se0.25",
+ "r4_k5_s22_e6_i112_o192_se0.25",
+ "r1_k3_s11_e6_i192_o320_se0.25",
+ ]
+ blocks_args = BlockDecoder.decode(blocks_args)
+
+ global_params = GlobalParams(
+ batch_norm_momentum=0.99,
+ batch_norm_epsilon=1e-3,
+ dropout_rate=dropout_rate,
+ drop_connect_rate=drop_connect_rate,
+ # data_format='channels_last', # removed, this is always true in PyTorch
+ num_classes=num_classes,
+ width_coefficient=width_coefficient,
+ depth_coefficient=depth_coefficient,
+ depth_divisor=8,
+ min_depth=None,
+ image_size=image_size,
+ )
+
+ return blocks_args, global_params
+
+
+def get_model_params(model_name, override_params):
+ """Get the block args and global params for a given model"""
+ if model_name.startswith("efficientnet"):
+ w, d, s, p = efficientnet_params(model_name)
+ # note: all models have drop connect rate = 0.2
+ blocks_args, global_params = efficientnet(
+ width_coefficient=w,
+ depth_coefficient=d,
+ dropout_rate=p,
+ image_size=s
+ )
+ else:
+ raise NotImplementedError(
+ "model name is not pre-defined: %s" % model_name
+ )
+ if override_params:
+ # ValueError will be raised here if override_params has fields not included in global_params.
+ global_params = global_params._replace(**override_params)
+ return blocks_args, global_params
+
+
+url_map = {
+ "efficientnet-b0":
+ "https://github.com/lukemelas/EfficientNet-PyTorch/releases/download/1.0/efficientnet-b0-355c32eb.pth",
+ "efficientnet-b1":
+ "https://github.com/lukemelas/EfficientNet-PyTorch/releases/download/1.0/efficientnet-b1-f1951068.pth",
+ "efficientnet-b2":
+ "https://github.com/lukemelas/EfficientNet-PyTorch/releases/download/1.0/efficientnet-b2-8bb594d6.pth",
+ "efficientnet-b3":
+ "https://github.com/lukemelas/EfficientNet-PyTorch/releases/download/1.0/efficientnet-b3-5fb5a3c3.pth",
+ "efficientnet-b4":
+ "https://github.com/lukemelas/EfficientNet-PyTorch/releases/download/1.0/efficientnet-b4-6ed6700e.pth",
+ "efficientnet-b5":
+ "https://github.com/lukemelas/EfficientNet-PyTorch/releases/download/1.0/efficientnet-b5-b6417697.pth",
+ "efficientnet-b6":
+ "https://github.com/lukemelas/EfficientNet-PyTorch/releases/download/1.0/efficientnet-b6-c76e70fd.pth",
+ "efficientnet-b7":
+ "https://github.com/lukemelas/EfficientNet-PyTorch/releases/download/1.0/efficientnet-b7-dcc49843.pth",
+}
+
+url_map_advprop = {
+ "efficientnet-b0":
+ "https://github.com/lukemelas/EfficientNet-PyTorch/releases/download/1.0/adv-efficientnet-b0-b64d5a18.pth",
+ "efficientnet-b1":
+ "https://github.com/lukemelas/EfficientNet-PyTorch/releases/download/1.0/adv-efficientnet-b1-0f3ce85a.pth",
+ "efficientnet-b2":
+ "https://github.com/lukemelas/EfficientNet-PyTorch/releases/download/1.0/adv-efficientnet-b2-6e9d97e5.pth",
+ "efficientnet-b3":
+ "https://github.com/lukemelas/EfficientNet-PyTorch/releases/download/1.0/adv-efficientnet-b3-cdd7c0f4.pth",
+ "efficientnet-b4":
+ "https://github.com/lukemelas/EfficientNet-PyTorch/releases/download/1.0/adv-efficientnet-b4-44fb3a87.pth",
+ "efficientnet-b5":
+ "https://github.com/lukemelas/EfficientNet-PyTorch/releases/download/1.0/adv-efficientnet-b5-86493f6b.pth",
+ "efficientnet-b6":
+ "https://github.com/lukemelas/EfficientNet-PyTorch/releases/download/1.0/adv-efficientnet-b6-ac80338e.pth",
+ "efficientnet-b7":
+ "https://github.com/lukemelas/EfficientNet-PyTorch/releases/download/1.0/adv-efficientnet-b7-4652b6dd.pth",
+ "efficientnet-b8":
+ "https://github.com/lukemelas/EfficientNet-PyTorch/releases/download/1.0/adv-efficientnet-b8-22a8fe65.pth",
+}
+
+
+def load_pretrained_weights(model, model_name, load_fc=True, advprop=False):
+ """Loads pretrained weights, and downloads if loading for the first time."""
+ # AutoAugment or Advprop (different preprocessing)
+ url_map_ = url_map_advprop if advprop else url_map
+ state_dict = model_zoo.load_url(url_map_[model_name])
+ model.load_state_dict(state_dict, strict=False)
+ """
+ if load_fc:
+ model.load_state_dict(state_dict)
+ else:
+ state_dict.pop('_fc.weight')
+ state_dict.pop('_fc.bias')
+ res = model.load_state_dict(state_dict, strict=False)
+ assert set(res.missing_keys) == set(['_fc.weight', '_fc.bias']), 'issue loading pretrained weights'
+
+ print('Loaded pretrained weights for {}'.format(model_name))
+ """
diff --git a/dassl/modeling/backbone/preact_resnet18.py b/dassl/modeling/backbone/preact_resnet18.py
new file mode 100644
index 0000000..8c07089
--- /dev/null
+++ b/dassl/modeling/backbone/preact_resnet18.py
@@ -0,0 +1,135 @@
+import torch.nn as nn
+import torch.nn.functional as F
+
+from .build import BACKBONE_REGISTRY
+from .backbone import Backbone
+
+
+class PreActBlock(nn.Module):
+ expansion = 1
+
+ def __init__(self, in_planes, planes, stride=1):
+ super().__init__()
+ self.bn1 = nn.BatchNorm2d(in_planes)
+ self.conv1 = nn.Conv2d(
+ in_planes,
+ planes,
+ kernel_size=3,
+ stride=stride,
+ padding=1,
+ bias=False
+ )
+ self.bn2 = nn.BatchNorm2d(planes)
+ self.conv2 = nn.Conv2d(
+ planes, planes, kernel_size=3, stride=1, padding=1, bias=False
+ )
+
+ if stride != 1 or in_planes != self.expansion * planes:
+ self.shortcut = nn.Sequential(
+ nn.Conv2d(
+ in_planes,
+ self.expansion * planes,
+ kernel_size=1,
+ stride=stride,
+ bias=False,
+ )
+ )
+
+ def forward(self, x):
+ out = F.relu(self.bn1(x))
+ shortcut = self.shortcut(out) if hasattr(self, "shortcut") else x
+ out = self.conv1(out)
+ out = self.conv2(F.relu(self.bn2(out)))
+ out += shortcut
+ return out
+
+
+class PreActBottleneck(nn.Module):
+ expansion = 4
+
+ def __init__(self, in_planes, planes, stride=1):
+ super().__init__()
+ self.bn1 = nn.BatchNorm2d(in_planes)
+ self.conv1 = nn.Conv2d(in_planes, planes, kernel_size=1, bias=False)
+ self.bn2 = nn.BatchNorm2d(planes)
+ self.conv2 = nn.Conv2d(
+ planes,
+ planes,
+ kernel_size=3,
+ stride=stride,
+ padding=1,
+ bias=False
+ )
+ self.bn3 = nn.BatchNorm2d(planes)
+ self.conv3 = nn.Conv2d(
+ planes, self.expansion * planes, kernel_size=1, bias=False
+ )
+
+ if stride != 1 or in_planes != self.expansion * planes:
+ self.shortcut = nn.Sequential(
+ nn.Conv2d(
+ in_planes,
+ self.expansion * planes,
+ kernel_size=1,
+ stride=stride,
+ bias=False,
+ )
+ )
+
+ def forward(self, x):
+ out = F.relu(self.bn1(x))
+ shortcut = self.shortcut(out) if hasattr(self, "shortcut") else x
+ out = self.conv1(out)
+ out = self.conv2(F.relu(self.bn2(out)))
+ out = self.conv3(F.relu(self.bn3(out)))
+ out += shortcut
+ return out
+
+
+class PreActResNet(Backbone):
+
+ def __init__(self, block, num_blocks):
+ super().__init__()
+ self.in_planes = 64
+
+ self.conv1 = nn.Conv2d(
+ 3, 64, kernel_size=3, stride=1, padding=1, bias=False
+ )
+ self.layer1 = self._make_layer(block, 64, num_blocks[0], stride=1)
+ self.layer2 = self._make_layer(block, 128, num_blocks[1], stride=2)
+ self.layer3 = self._make_layer(block, 256, num_blocks[2], stride=2)
+ self.layer4 = self._make_layer(block, 512, num_blocks[3], stride=2)
+
+ self._out_features = 512 * block.expansion
+
+ def _make_layer(self, block, planes, num_blocks, stride):
+ strides = [stride] + [1] * (num_blocks-1)
+ layers = []
+ for stride in strides:
+ layers.append(block(self.in_planes, planes, stride))
+ self.in_planes = planes * block.expansion
+ return nn.Sequential(*layers)
+
+ def forward(self, x):
+ out = self.conv1(x)
+ out = self.layer1(out)
+ out = self.layer2(out)
+ out = self.layer3(out)
+ out = self.layer4(out)
+ out = F.avg_pool2d(out, 4)
+ out = out.view(out.size(0), -1)
+ return out
+
+
+"""
+Preact-ResNet18 was used for the CIFAR10 and
+SVHN datasets (both are SSL tasks) in
+
+- Wang et al. Semi-Supervised Learning by
+Augmented Distribution Alignment. ICCV 2019.
+"""
+
+
+@BACKBONE_REGISTRY.register()
+def preact_resnet18(**kwargs):
+ return PreActResNet(PreActBlock, [2, 2, 2, 2])
diff --git a/dassl/modeling/backbone/resnet.py b/dassl/modeling/backbone/resnet.py
new file mode 100644
index 0000000..60b9a8c
--- /dev/null
+++ b/dassl/modeling/backbone/resnet.py
@@ -0,0 +1,591 @@
+import torch.nn as nn
+import torch.utils.model_zoo as model_zoo
+
+from .build import BACKBONE_REGISTRY
+from .backbone import Backbone
+
+model_urls = {
+ "resnet18": "https://download.pytorch.org/models/resnet18-5c106cde.pth",
+ "resnet34": "https://download.pytorch.org/models/resnet34-333f7ec4.pth",
+ "resnet50": "https://download.pytorch.org/models/resnet50-19c8e357.pth",
+ "resnet101": "https://download.pytorch.org/models/resnet101-5d3b4d8f.pth",
+ "resnet152": "https://download.pytorch.org/models/resnet152-b121ed2d.pth",
+}
+
+
+def conv3x3(in_planes, out_planes, stride=1):
+ """3x3 convolution with padding"""
+ return nn.Conv2d(
+ in_planes,
+ out_planes,
+ kernel_size=3,
+ stride=stride,
+ padding=1,
+ bias=False
+ )
+
+
+class BasicBlock(nn.Module):
+ expansion = 1
+
+ def __init__(self, inplanes, planes, stride=1, downsample=None):
+ super().__init__()
+ self.conv1 = conv3x3(inplanes, planes, stride)
+ self.bn1 = nn.BatchNorm2d(planes)
+ self.relu = nn.ReLU(inplace=True)
+ self.conv2 = conv3x3(planes, planes)
+ self.bn2 = nn.BatchNorm2d(planes)
+ self.downsample = downsample
+ self.stride = stride
+
+ def forward(self, x):
+ residual = x
+
+ out = self.conv1(x)
+ out = self.bn1(out)
+ out = self.relu(out)
+
+ out = self.conv2(out)
+ out = self.bn2(out)
+
+ if self.downsample is not None:
+ residual = self.downsample(x)
+
+ out += residual
+ out = self.relu(out)
+
+ return out
+
+
+class Bottleneck(nn.Module):
+ expansion = 4
+
+ def __init__(self, inplanes, planes, stride=1, downsample=None):
+ super().__init__()
+ self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=1, bias=False)
+ self.bn1 = nn.BatchNorm2d(planes)
+ self.conv2 = nn.Conv2d(
+ planes,
+ planes,
+ kernel_size=3,
+ stride=stride,
+ padding=1,
+ bias=False
+ )
+ self.bn2 = nn.BatchNorm2d(planes)
+ self.conv3 = nn.Conv2d(
+ planes, planes * self.expansion, kernel_size=1, bias=False
+ )
+ self.bn3 = nn.BatchNorm2d(planes * self.expansion)
+ self.relu = nn.ReLU(inplace=True)
+ self.downsample = downsample
+ self.stride = stride
+
+ def forward(self, x):
+ residual = x
+
+ out = self.conv1(x)
+ out = self.bn1(out)
+ out = self.relu(out)
+
+ out = self.conv2(out)
+ out = self.bn2(out)
+ out = self.relu(out)
+
+ out = self.conv3(out)
+ out = self.bn3(out)
+
+ if self.downsample is not None:
+ residual = self.downsample(x)
+
+ out += residual
+ out = self.relu(out)
+
+ return out
+
+
+class ResNet(Backbone):
+
+ def __init__(
+ self,
+ block,
+ layers,
+ ms_class=None,
+ ms_layers=[],
+ ms_p=0.5,
+ ms_a=0.1,
+ **kwargs
+ ):
+ self.inplanes = 64
+ super().__init__()
+
+ # backbone network
+ self.conv1 = nn.Conv2d(
+ 3, 64, kernel_size=7, stride=2, padding=3, bias=False
+ )
+ self.bn1 = nn.BatchNorm2d(64)
+ self.relu = nn.ReLU(inplace=True)
+ self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
+ self.layer1 = self._make_layer(block, 64, layers[0])
+ self.layer2 = self._make_layer(block, 128, layers[1], stride=2)
+ self.layer3 = self._make_layer(block, 256, layers[2], stride=2)
+ self.layer4 = self._make_layer(block, 512, layers[3], stride=2)
+ self.global_avgpool = nn.AdaptiveAvgPool2d(1)
+
+ self._out_features = 512 * block.expansion
+
+ self.mixstyle = None
+ if ms_layers:
+ self.mixstyle = ms_class(p=ms_p, alpha=ms_a)
+ for layer_name in ms_layers:
+ assert layer_name in ["layer1", "layer2", "layer3"]
+ print(
+ f"Insert {self.mixstyle.__class__.__name__} after {ms_layers}"
+ )
+ self.ms_layers = ms_layers
+
+ self._init_params()
+
+ def _make_layer(self, block, planes, blocks, stride=1):
+ downsample = None
+ if stride != 1 or self.inplanes != planes * block.expansion:
+ downsample = nn.Sequential(
+ nn.Conv2d(
+ self.inplanes,
+ planes * block.expansion,
+ kernel_size=1,
+ stride=stride,
+ bias=False,
+ ),
+ nn.BatchNorm2d(planes * block.expansion),
+ )
+
+ layers = []
+ layers.append(block(self.inplanes, planes, stride, downsample))
+ self.inplanes = planes * block.expansion
+ for i in range(1, blocks):
+ layers.append(block(self.inplanes, planes))
+
+ return nn.Sequential(*layers)
+
+ def _init_params(self):
+ for m in self.modules():
+ if isinstance(m, nn.Conv2d):
+ nn.init.kaiming_normal_(
+ m.weight, mode="fan_out", nonlinearity="relu"
+ )
+ if m.bias is not None:
+ nn.init.constant_(m.bias, 0)
+ elif isinstance(m, nn.BatchNorm2d):
+ nn.init.constant_(m.weight, 1)
+ nn.init.constant_(m.bias, 0)
+ elif isinstance(m, nn.BatchNorm1d):
+ nn.init.constant_(m.weight, 1)
+ nn.init.constant_(m.bias, 0)
+ elif isinstance(m, nn.Linear):
+ nn.init.normal_(m.weight, 0, 0.01)
+ if m.bias is not None:
+ nn.init.constant_(m.bias, 0)
+
+ def featuremaps(self, x):
+ x = self.conv1(x)
+ x = self.bn1(x)
+ x = self.relu(x)
+ x = self.maxpool(x)
+ x = self.layer1(x)
+ if "layer1" in self.ms_layers:
+ x = self.mixstyle(x)
+ x = self.layer2(x)
+ if "layer2" in self.ms_layers:
+ x = self.mixstyle(x)
+ x = self.layer3(x)
+ if "layer3" in self.ms_layers:
+ x = self.mixstyle(x)
+ return self.layer4(x)
+
+ def forward(self, x):
+ f = self.featuremaps(x)
+ v = self.global_avgpool(f)
+ return v.view(v.size(0), -1)
+
+
+def init_pretrained_weights(model, model_url):
+ pretrain_dict = model_zoo.load_url(model_url)
+ model.load_state_dict(pretrain_dict, strict=False)
+
+
+"""
+Residual network configurations:
+--
+resnet18: block=BasicBlock, layers=[2, 2, 2, 2]
+resnet34: block=BasicBlock, layers=[3, 4, 6, 3]
+resnet50: block=Bottleneck, layers=[3, 4, 6, 3]
+resnet101: block=Bottleneck, layers=[3, 4, 23, 3]
+resnet152: block=Bottleneck, layers=[3, 8, 36, 3]
+"""
+
+
+@BACKBONE_REGISTRY.register()
+def resnet18(pretrained=True, **kwargs):
+ model = ResNet(block=BasicBlock, layers=[2, 2, 2, 2])
+
+ if pretrained:
+ init_pretrained_weights(model, model_urls["resnet18"])
+
+ return model
+
+
+@BACKBONE_REGISTRY.register()
+def resnet34(pretrained=True, **kwargs):
+ model = ResNet(block=BasicBlock, layers=[3, 4, 6, 3])
+
+ if pretrained:
+ init_pretrained_weights(model, model_urls["resnet34"])
+
+ return model
+
+
+@BACKBONE_REGISTRY.register()
+def resnet50(pretrained=True, **kwargs):
+ model = ResNet(block=Bottleneck, layers=[3, 4, 6, 3])
+
+ if pretrained:
+ init_pretrained_weights(model, model_urls["resnet50"])
+
+ return model
+
+
+@BACKBONE_REGISTRY.register()
+def resnet101(pretrained=True, **kwargs):
+ model = ResNet(block=Bottleneck, layers=[3, 4, 23, 3])
+
+ if pretrained:
+ init_pretrained_weights(model, model_urls["resnet101"])
+
+ return model
+
+
+@BACKBONE_REGISTRY.register()
+def resnet152(pretrained=True, **kwargs):
+ model = ResNet(block=Bottleneck, layers=[3, 8, 36, 3])
+
+ if pretrained:
+ init_pretrained_weights(model, model_urls["resnet152"])
+
+ return model
+
+
+"""
+Residual networks with mixstyle
+"""
+
+
+@BACKBONE_REGISTRY.register()
+def resnet18_ms_l123(pretrained=True, **kwargs):
+ from dassl.modeling.ops import MixStyle
+
+ model = ResNet(
+ block=BasicBlock,
+ layers=[2, 2, 2, 2],
+ ms_class=MixStyle,
+ ms_layers=["layer1", "layer2", "layer3"],
+ )
+
+ if pretrained:
+ init_pretrained_weights(model, model_urls["resnet18"])
+
+ return model
+
+
+@BACKBONE_REGISTRY.register()
+def resnet18_ms_l12(pretrained=True, **kwargs):
+ from dassl.modeling.ops import MixStyle
+
+ model = ResNet(
+ block=BasicBlock,
+ layers=[2, 2, 2, 2],
+ ms_class=MixStyle,
+ ms_layers=["layer1", "layer2"],
+ )
+
+ if pretrained:
+ init_pretrained_weights(model, model_urls["resnet18"])
+
+ return model
+
+
+@BACKBONE_REGISTRY.register()
+def resnet18_ms_l1(pretrained=True, **kwargs):
+ from dassl.modeling.ops import MixStyle
+
+ model = ResNet(
+ block=BasicBlock,
+ layers=[2, 2, 2, 2],
+ ms_class=MixStyle,
+ ms_layers=["layer1"]
+ )
+
+ if pretrained:
+ init_pretrained_weights(model, model_urls["resnet18"])
+
+ return model
+
+
+@BACKBONE_REGISTRY.register()
+def resnet50_ms_l123(pretrained=True, **kwargs):
+ from dassl.modeling.ops import MixStyle
+
+ model = ResNet(
+ block=Bottleneck,
+ layers=[3, 4, 6, 3],
+ ms_class=MixStyle,
+ ms_layers=["layer1", "layer2", "layer3"],
+ )
+
+ if pretrained:
+ init_pretrained_weights(model, model_urls["resnet50"])
+
+ return model
+
+
+@BACKBONE_REGISTRY.register()
+def resnet50_ms_l12(pretrained=True, **kwargs):
+ from dassl.modeling.ops import MixStyle
+
+ model = ResNet(
+ block=Bottleneck,
+ layers=[3, 4, 6, 3],
+ ms_class=MixStyle,
+ ms_layers=["layer1", "layer2"],
+ )
+
+ if pretrained:
+ init_pretrained_weights(model, model_urls["resnet50"])
+
+ return model
+
+
+@BACKBONE_REGISTRY.register()
+def resnet50_ms_l1(pretrained=True, **kwargs):
+ from dassl.modeling.ops import MixStyle
+
+ model = ResNet(
+ block=Bottleneck,
+ layers=[3, 4, 6, 3],
+ ms_class=MixStyle,
+ ms_layers=["layer1"]
+ )
+
+ if pretrained:
+ init_pretrained_weights(model, model_urls["resnet50"])
+
+ return model
+
+
+@BACKBONE_REGISTRY.register()
+def resnet101_ms_l123(pretrained=True, **kwargs):
+ from dassl.modeling.ops import MixStyle
+
+ model = ResNet(
+ block=Bottleneck,
+ layers=[3, 4, 23, 3],
+ ms_class=MixStyle,
+ ms_layers=["layer1", "layer2", "layer3"],
+ )
+
+ if pretrained:
+ init_pretrained_weights(model, model_urls["resnet101"])
+
+ return model
+
+
+@BACKBONE_REGISTRY.register()
+def resnet101_ms_l12(pretrained=True, **kwargs):
+ from dassl.modeling.ops import MixStyle
+
+ model = ResNet(
+ block=Bottleneck,
+ layers=[3, 4, 23, 3],
+ ms_class=MixStyle,
+ ms_layers=["layer1", "layer2"],
+ )
+
+ if pretrained:
+ init_pretrained_weights(model, model_urls["resnet101"])
+
+ return model
+
+
+@BACKBONE_REGISTRY.register()
+def resnet101_ms_l1(pretrained=True, **kwargs):
+ from dassl.modeling.ops import MixStyle
+
+ model = ResNet(
+ block=Bottleneck,
+ layers=[3, 4, 23, 3],
+ ms_class=MixStyle,
+ ms_layers=["layer1"]
+ )
+
+ if pretrained:
+ init_pretrained_weights(model, model_urls["resnet101"])
+
+ return model
+
+
+"""
+Residual networks with efdmix
+"""
+
+
+@BACKBONE_REGISTRY.register()
+def resnet18_efdmix_l123(pretrained=True, **kwargs):
+ from dassl.modeling.ops import EFDMix
+
+ model = ResNet(
+ block=BasicBlock,
+ layers=[2, 2, 2, 2],
+ ms_class=EFDMix,
+ ms_layers=["layer1", "layer2", "layer3"],
+ )
+
+ if pretrained:
+ init_pretrained_weights(model, model_urls["resnet18"])
+
+ return model
+
+
+@BACKBONE_REGISTRY.register()
+def resnet18_efdmix_l12(pretrained=True, **kwargs):
+ from dassl.modeling.ops import EFDMix
+
+ model = ResNet(
+ block=BasicBlock,
+ layers=[2, 2, 2, 2],
+ ms_class=EFDMix,
+ ms_layers=["layer1", "layer2"],
+ )
+
+ if pretrained:
+ init_pretrained_weights(model, model_urls["resnet18"])
+
+ return model
+
+
+@BACKBONE_REGISTRY.register()
+def resnet18_efdmix_l1(pretrained=True, **kwargs):
+ from dassl.modeling.ops import EFDMix
+
+ model = ResNet(
+ block=BasicBlock,
+ layers=[2, 2, 2, 2],
+ ms_class=EFDMix,
+ ms_layers=["layer1"]
+ )
+
+ if pretrained:
+ init_pretrained_weights(model, model_urls["resnet18"])
+
+ return model
+
+
+@BACKBONE_REGISTRY.register()
+def resnet50_efdmix_l123(pretrained=True, **kwargs):
+ from dassl.modeling.ops import EFDMix
+
+ model = ResNet(
+ block=Bottleneck,
+ layers=[3, 4, 6, 3],
+ ms_class=EFDMix,
+ ms_layers=["layer1", "layer2", "layer3"],
+ )
+
+ if pretrained:
+ init_pretrained_weights(model, model_urls["resnet50"])
+
+ return model
+
+
+@BACKBONE_REGISTRY.register()
+def resnet50_efdmix_l12(pretrained=True, **kwargs):
+ from dassl.modeling.ops import EFDMix
+
+ model = ResNet(
+ block=Bottleneck,
+ layers=[3, 4, 6, 3],
+ ms_class=EFDMix,
+ ms_layers=["layer1", "layer2"],
+ )
+
+ if pretrained:
+ init_pretrained_weights(model, model_urls["resnet50"])
+
+ return model
+
+
+@BACKBONE_REGISTRY.register()
+def resnet50_efdmix_l1(pretrained=True, **kwargs):
+ from dassl.modeling.ops import EFDMix
+
+ model = ResNet(
+ block=Bottleneck,
+ layers=[3, 4, 6, 3],
+ ms_class=EFDMix,
+ ms_layers=["layer1"]
+ )
+
+ if pretrained:
+ init_pretrained_weights(model, model_urls["resnet50"])
+
+ return model
+
+
+@BACKBONE_REGISTRY.register()
+def resnet101_efdmix_l123(pretrained=True, **kwargs):
+ from dassl.modeling.ops import EFDMix
+
+ model = ResNet(
+ block=Bottleneck,
+ layers=[3, 4, 23, 3],
+ ms_class=EFDMix,
+ ms_layers=["layer1", "layer2", "layer3"],
+ )
+
+ if pretrained:
+ init_pretrained_weights(model, model_urls["resnet101"])
+
+ return model
+
+
+@BACKBONE_REGISTRY.register()
+def resnet101_efdmix_l12(pretrained=True, **kwargs):
+ from dassl.modeling.ops import EFDMix
+
+ model = ResNet(
+ block=Bottleneck,
+ layers=[3, 4, 23, 3],
+ ms_class=EFDMix,
+ ms_layers=["layer1", "layer2"],
+ )
+
+ if pretrained:
+ init_pretrained_weights(model, model_urls["resnet101"])
+
+ return model
+
+
+@BACKBONE_REGISTRY.register()
+def resnet101_efdmix_l1(pretrained=True, **kwargs):
+ from dassl.modeling.ops import EFDMix
+
+ model = ResNet(
+ block=Bottleneck,
+ layers=[3, 4, 23, 3],
+ ms_class=EFDMix,
+ ms_layers=["layer1"]
+ )
+
+ if pretrained:
+ init_pretrained_weights(model, model_urls["resnet101"])
+
+ return model
diff --git a/dassl/modeling/backbone/resnet_dynamic.py b/dassl/modeling/backbone/resnet_dynamic.py
new file mode 100644
index 0000000..c4e08de
--- /dev/null
+++ b/dassl/modeling/backbone/resnet_dynamic.py
@@ -0,0 +1,734 @@
+"""
+Dynamic ResNet from `"Dynamic Domain Generalization" `_.
+"""
+
+from typing import Any, List, Type, Union, Callable, Optional
+from collections import OrderedDict
+import torch
+import torch.nn as nn
+from torch import Tensor
+from torch.hub import load_state_dict_from_url
+
+from dassl.modeling.ops import MixStyle, Conv2dDynamic
+
+from .build import BACKBONE_REGISTRY
+from .backbone import Backbone
+
+__all__ = [
+ "resnet18_dynamic", "resnet50_dynamic", "resnet101_dynamic",
+ "resnet18_dynamic_ms_l123", "resnet18_dynamic_ms_l12",
+ "resnet18_dynamic_ms_l1", "resnet50_dynamic_ms_l123",
+ "resnet50_dynamic_ms_l12", "resnet50_dynamic_ms_l1",
+ "resnet101_dynamic_ms_l123", "resnet101_dynamic_ms_l12",
+ "resnet101_dynamic_ms_l1"
+]
+
+model_urls = {
+ "resnet18_dynamic":
+ "https://csip.fzu.edu.cn/files/models/resnet18_dynamic-074db766.pth",
+ "resnet50_dynamic":
+ "https://csip.fzu.edu.cn/files/models/resnet50_dynamic-2c3b0201.pth",
+ "resnet101_dynamic":
+ "https://csip.fzu.edu.cn/files/models/resnet101_dynamic-c5f15780.pth",
+}
+
+
+def conv3x3(
+ in_planes: int,
+ out_planes: int,
+ stride: int = 1,
+ groups: int = 1,
+ dilation: int = 1
+) -> nn.Conv2d:
+ """3x3 convolution with padding"""
+ return nn.Conv2d(
+ in_planes,
+ out_planes,
+ kernel_size=3,
+ stride=stride,
+ padding=dilation,
+ groups=groups,
+ bias=False,
+ dilation=dilation
+ )
+
+
+def conv3x3_dynamic(
+ in_planes: int,
+ out_planes: int,
+ stride: int = 1,
+ attention_in_channels: int = None
+) -> Conv2dDynamic:
+ """3x3 convolution with padding"""
+ return Conv2dDynamic(
+ in_planes,
+ out_planes,
+ kernel_size=3,
+ stride=stride,
+ padding=1,
+ bias=False,
+ attention_in_channels=attention_in_channels
+ )
+
+
+def conv1x1(in_planes: int, out_planes: int, stride: int = 1) -> nn.Conv2d:
+ """1x1 convolution"""
+ return nn.Conv2d(
+ in_planes, out_planes, kernel_size=1, stride=stride, bias=False
+ )
+
+
+def load_state_dict(
+ model: nn.Module,
+ state_dict: "OrderedDict[str, Tensor]",
+ allowed_missing_keys: List = None
+):
+ r"""Copies parameters and buffers from :attr:`state_dict` into
+ this module and its descendants. If :attr:`strict` is ``True``, then
+ the keys of :attr:`state_dict` must exactly match the keys returned
+ by this module's :meth:`~torch.nn.Module.state_dict` function.
+
+ Args:
+ model (torch.nn.Module): a torch.nn.Module object where state_dict load for.
+ state_dict (dict): a dict containing parameters and
+ persistent buffers.
+ allowed_missing_keys (List, optional): not raise `RuntimeError` if missing_keys
+ equal to allowed_missing_keys.
+
+ Returns:
+ ``NamedTuple`` with ``missing_keys`` and ``unexpected_keys`` fields:
+ * **missing_keys** is a list of str containing the missing keys
+ * **unexpected_keys** is a list of str containing the unexpected keys
+
+ Note:
+ If a parameter or buffer is registered as ``None`` and its corresponding key
+ exists in :attr:`state_dict`, :meth:`load_state_dict` will raise a
+ ``RuntimeError``.
+ """
+ missing_keys, unexpected_keys = model.load_state_dict(
+ state_dict, strict=allowed_missing_keys is None
+ )
+
+ msgs: List[str] = []
+ raise_error = False
+ if len(unexpected_keys) > 0:
+ raise_error = True
+ msgs.insert(
+ 0, "Unexpected key(s) in state_dict: {}. ".format(
+ ", ".join("'{}'".format(k) for k in unexpected_keys)
+ )
+ )
+ if len(missing_keys) > 0:
+ if allowed_missing_keys is None or sorted(missing_keys) != sorted(
+ allowed_missing_keys
+ ):
+ raise_error = True
+ msgs.insert(
+ 0, "Missing key(s) in state_dict: {}. ".format(
+ ", ".join("'{}'".format(k) for k in missing_keys)
+ )
+ )
+ if raise_error:
+ raise RuntimeError(
+ "Error(s) in loading state_dict for {}:\n\t{}".format(
+ model.__class__.__name__, "\n\t".join(msgs)
+ )
+ )
+ if len(msgs) > 0:
+ print(
+ "\nInfo(s) in loading state_dict for {}:\n\t{}".format(
+ model.__class__.__name__, "\n\t".join(msgs)
+ )
+ )
+
+
+class BasicBlock(nn.Module):
+ expansion: int = 1
+
+ def __init__(
+ self,
+ inplanes: int,
+ planes: int,
+ stride: int = 1,
+ downsample: Optional[nn.Module] = None,
+ groups: int = 1,
+ base_width: int = 64,
+ dilation: int = 1,
+ norm_layer: Optional[Callable[..., nn.Module]] = None
+ ) -> None:
+ super(BasicBlock, self).__init__()
+ if norm_layer is None:
+ norm_layer = nn.BatchNorm2d
+ if groups != 1 or base_width != 64:
+ raise ValueError(
+ "BasicBlock only supports groups=1 and base_width=64"
+ )
+ if dilation > 1:
+ raise NotImplementedError(
+ "Dilation > 1 not supported in BasicBlock"
+ )
+ # Both self.conv1 and self.downsample layers downsample the input when stride != 1
+ self.conv1 = conv3x3(inplanes, planes, stride)
+ self.bn1 = norm_layer(planes)
+ self.relu = nn.ReLU(inplace=True)
+ self.conv2 = conv3x3(planes, planes)
+ self.bn2 = norm_layer(planes)
+ self.downsample = downsample
+ self.stride = stride
+
+ def forward(self, x: Tensor) -> Tensor:
+ identity = x
+
+ out = self.conv1(x)
+ out = self.bn1(out)
+ out = self.relu(out)
+
+ out = self.conv2(out)
+ out = self.bn2(out)
+
+ if self.downsample is not None:
+ identity = self.downsample(x)
+
+ out += identity
+ out = self.relu(out)
+
+ return out
+
+
+class Bottleneck(nn.Module):
+ # Bottleneck in torchvision places the stride for downsampling at 3x3 convolution(self.conv2)
+ # while original implementation places the stride at the first 1x1 convolution(self.conv1)
+ # according to "Deep residual learning for image recognition"https://arxiv.org/abs/1512.03385.
+ # This variant is also known as ResNet V1.5 and improves accuracy according to
+ # https://ngc.nvidia.com/catalog/model-scripts/nvidia:resnet_50_v1_5_for_pytorch.
+
+ expansion: int = 4
+
+ def __init__(
+ self,
+ inplanes: int,
+ planes: int,
+ stride: int = 1,
+ downsample: Optional[nn.Module] = None,
+ groups: int = 1,
+ base_width: int = 64,
+ dilation: int = 1,
+ norm_layer: Optional[Callable[..., nn.Module]] = None
+ ) -> None:
+ super(Bottleneck, self).__init__()
+ if norm_layer is None:
+ norm_layer = nn.BatchNorm2d
+ width = int(planes * (base_width/64.)) * groups
+ # Both self.conv2 and self.downsample layers downsample the input when stride != 1
+ self.conv1 = conv1x1(inplanes, width)
+ self.bn1 = norm_layer(width)
+ self.conv2 = conv3x3(width, width, stride, groups, dilation)
+ self.bn2 = norm_layer(width)
+ self.conv3 = conv1x1(width, planes * self.expansion)
+ self.bn3 = norm_layer(planes * self.expansion)
+ self.relu = nn.ReLU(inplace=True)
+ self.downsample = downsample
+ self.stride = stride
+
+ def forward(self, x: Tensor) -> Tensor:
+ identity = x
+
+ out = self.conv1(x)
+ out = self.bn1(out)
+ out = self.relu(out)
+
+ out = self.conv2(out)
+ out = self.bn2(out)
+ out = self.relu(out)
+
+ out = self.conv3(out)
+ out = self.bn3(out)
+
+ if self.downsample is not None:
+ identity = self.downsample(x)
+
+ out += identity
+ out = self.relu(out)
+
+ return out
+
+
+class BasicBlockDynamic(nn.Module):
+ expansion: int = 1
+
+ def __init__(
+ self,
+ inplanes: int,
+ planes: int,
+ stride: int = 1,
+ downsample: Optional[nn.Module] = None,
+ groups: int = 1,
+ base_width: int = 64,
+ dilation: int = 1,
+ norm_layer: Optional[Callable[..., nn.Module]] = None
+ ) -> None:
+ super(BasicBlockDynamic, self).__init__()
+ if norm_layer is None:
+ norm_layer = nn.BatchNorm2d
+ if groups != 1 or base_width != 64:
+ raise ValueError(
+ "BasicBlock only supports groups=1 and base_width=64"
+ )
+ if dilation > 1:
+ raise NotImplementedError(
+ "Dilation > 1 not supported in BasicBlock"
+ )
+ # Both self.conv1 and self.downsample layers downsample the input when stride != 1
+ self.conv1 = conv3x3_dynamic(
+ inplanes, planes, stride, attention_in_channels=inplanes
+ )
+ self.bn1 = norm_layer(planes)
+ self.relu = nn.ReLU(inplace=True)
+ self.conv2 = conv3x3_dynamic(
+ planes, planes, attention_in_channels=inplanes
+ )
+ self.bn2 = norm_layer(planes)
+ self.downsample = downsample
+ self.stride = stride
+
+ def forward(self, x: Tensor) -> Tensor:
+ identity = x
+
+ out = self.conv1(x, attention_x=x)
+ out = self.bn1(out)
+ out = self.relu(out)
+
+ out = self.conv2(out, attention_x=x)
+ out = self.bn2(out)
+
+ if self.downsample is not None:
+ identity = self.downsample(x)
+
+ out += identity
+ out = self.relu(out)
+
+ return out
+
+
+class BottleneckDynamic(nn.Module):
+ # Bottleneck in torchvision places the stride for downsampling at 3x3 convolution(self.conv2)
+ # while original implementation places the stride at the first 1x1 convolution(self.conv1)
+ # according to "Deep residual learning for image recognition"https://arxiv.org/abs/1512.03385.
+ # This variant is also known as ResNet V1.5 and improves accuracy according to
+ # https://ngc.nvidia.com/catalog/model-scripts/nvidia:resnet_50_v1_5_for_pytorch.
+
+ expansion: int = 4
+
+ def __init__(
+ self,
+ inplanes: int,
+ planes: int,
+ stride: int = 1,
+ downsample: Optional[nn.Module] = None,
+ groups: int = 1,
+ base_width: int = 64,
+ dilation: int = 1,
+ norm_layer: Optional[Callable[..., nn.Module]] = None
+ ) -> None:
+ super(BottleneckDynamic, self).__init__()
+ if groups != 1:
+ raise ValueError("BottleneckDynamic only supports groups=1")
+ if dilation > 1:
+ raise NotImplementedError(
+ "Dilation > 1 not supported in BottleneckDynamic"
+ )
+ if norm_layer is None:
+ norm_layer = nn.BatchNorm2d
+ width = int(planes * (base_width/64.)) * groups
+ # Both self.conv2 and self.downsample layers downsample the input when stride != 1
+ self.conv1 = conv1x1(inplanes, width)
+ self.bn1 = norm_layer(width)
+ self.conv2 = conv3x3_dynamic(
+ width, width, stride, attention_in_channels=inplanes
+ )
+ self.bn2 = norm_layer(width)
+ self.conv3 = conv1x1(width, planes * self.expansion)
+ self.bn3 = norm_layer(planes * self.expansion)
+ self.relu = nn.ReLU(inplace=True)
+ self.downsample = downsample
+ self.stride = stride
+
+ def forward(self, x: Tensor) -> Tensor:
+ identity = x
+
+ out = self.conv1(x)
+ out = self.bn1(out)
+ out = self.relu(out)
+
+ out = self.conv2(out, attention_x=x)
+ out = self.bn2(out)
+ out = self.relu(out)
+
+ out = self.conv3(out)
+ out = self.bn3(out)
+
+ if self.downsample is not None:
+ identity = self.downsample(x)
+
+ out += identity
+ out = self.relu(out)
+
+ return out
+
+
+class ResNet(Backbone):
+
+ def __init__(
+ self,
+ block: Type[Union[BasicBlock, Bottleneck, BasicBlockDynamic,
+ BottleneckDynamic]],
+ layers: List[int],
+ has_fc: bool = True,
+ num_classes: int = 1000,
+ zero_init_residual: bool = False,
+ groups: int = 1,
+ width_per_group: int = 64,
+ replace_stride_with_dilation: Optional[List[bool]] = None,
+ norm_layer: Optional[Callable[..., nn.Module]] = None,
+ ms_class=None,
+ ms_layers=None,
+ ms_p=0.5,
+ ms_a=0.1
+ ) -> None:
+ super(ResNet, self).__init__()
+ if norm_layer is None:
+ norm_layer = nn.BatchNorm2d
+ self._norm_layer = norm_layer
+
+ self.inplanes = 64
+ self.dilation = 1
+ if replace_stride_with_dilation is None:
+ # each element in the tuple indicates if we should replace
+ # the 2x2 stride with a dilated convolution instead
+ replace_stride_with_dilation = [False, False, False]
+ if len(replace_stride_with_dilation) != 3:
+ raise ValueError(
+ "replace_stride_with_dilation should be None "
+ "or a 3-element tuple, got {}".
+ format(replace_stride_with_dilation)
+ )
+ self.groups = groups
+ self.base_width = width_per_group
+ self.conv1 = nn.Conv2d(
+ 3, self.inplanes, kernel_size=7, stride=2, padding=3, bias=False
+ )
+ self.bn1 = norm_layer(self.inplanes)
+ self.relu = nn.ReLU(inplace=True)
+ self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
+ self.layer1 = self._make_layer(block, 64, layers[0])
+ self.layer2 = self._make_layer(
+ block,
+ 128,
+ layers[1],
+ stride=2,
+ dilate=replace_stride_with_dilation[0]
+ )
+ self.layer3 = self._make_layer(
+ block,
+ 256,
+ layers[2],
+ stride=2,
+ dilate=replace_stride_with_dilation[1]
+ )
+ self.layer4 = self._make_layer(
+ block,
+ 512,
+ layers[3],
+ stride=2,
+ dilate=replace_stride_with_dilation[2]
+ )
+ self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
+
+ self.has_fc = has_fc
+ self._out_features = 512 * block.expansion
+ if has_fc:
+ self.fc = nn.Linear(self.out_features, num_classes)
+ self._out_features = num_classes
+
+ if ms_class is not None and ms_layers is not None:
+ self.ms_class = ms_class(p=ms_p, alpha=ms_a)
+ for layer in ms_layers:
+ assert layer in ["layer1", "layer2", "layer3"]
+ self.ms_layers = ms_layers
+ else:
+ self.ms_class = None
+ self.ms_layers = []
+
+ for m in self.modules():
+ if isinstance(m, nn.Conv2d):
+ nn.init.kaiming_normal_(
+ m.weight, mode="fan_out", nonlinearity="relu"
+ )
+ elif isinstance(m, (nn.BatchNorm2d, nn.GroupNorm)):
+ nn.init.constant_(m.weight, 1)
+ nn.init.constant_(m.bias, 0)
+
+ # Zero-initialize the last BN in each residual branch,
+ # so that the residual branch starts with zeros, and each residual block behaves like an identity.
+ # This improves the model by 0.2~0.3% according to https://arxiv.org/abs/1706.02677
+ if zero_init_residual:
+ for m in self.modules():
+ if isinstance(m, Bottleneck):
+ nn.init.constant_(m.bn3.weight, 0)
+ elif isinstance(m, BasicBlock):
+ nn.init.constant_(m.bn2.weight, 0)
+
+ def _make_layer(
+ self,
+ block: Type[Union[BasicBlock, Bottleneck]],
+ planes: int,
+ blocks: int,
+ stride: int = 1,
+ dilate: bool = False
+ ) -> nn.Sequential:
+ norm_layer = self._norm_layer
+ downsample = None
+ previous_dilation = self.dilation
+ if dilate:
+ self.dilation *= stride
+ stride = 1
+ if stride != 1 or self.inplanes != planes * block.expansion:
+ downsample = nn.Sequential(
+ conv1x1(self.inplanes, planes * block.expansion, stride),
+ norm_layer(planes * block.expansion),
+ )
+
+ layers = []
+ layers.append(
+ block(
+ self.inplanes, planes, stride, downsample, self.groups,
+ self.base_width, previous_dilation, norm_layer
+ )
+ )
+ self.inplanes = planes * block.expansion
+ for _ in range(1, blocks):
+ layers.append(
+ block(
+ self.inplanes,
+ planes,
+ groups=self.groups,
+ base_width=self.base_width,
+ dilation=self.dilation,
+ norm_layer=norm_layer
+ )
+ )
+
+ return nn.Sequential(*layers)
+
+ def _forward_impl(self, x: Tensor) -> Tensor:
+ # See note [TorchScript super()]
+ x = self.conv1(x)
+ x = self.bn1(x)
+ x = self.relu(x)
+ x = self.maxpool(x)
+
+ x = self.layer1(x)
+ if "layer1" in self.ms_layers:
+ x = self.ms_class(x)
+ x = self.layer2(x)
+ if "layer2" in self.ms_layers:
+ x = self.ms_class(x)
+ x = self.layer3(x)
+ if "layer3" in self.ms_layers:
+ x = self.ms_class(x)
+ x = self.layer4(x)
+
+ x = self.avgpool(x)
+ x = torch.flatten(x, 1)
+ if self.has_fc:
+ x = self.fc(x)
+
+ return x
+
+ def forward(self, x: Tensor) -> Tensor:
+ return self._forward_impl(x)
+
+
+def _resnet(
+ arch: str, block: Type[Union[BasicBlock, Bottleneck, BasicBlockDynamic,
+ BottleneckDynamic]], layers: List[int],
+ pretrained: bool, progress: bool, **kwargs: Any
+) -> ResNet:
+ model = ResNet(block, layers, **kwargs)
+ if pretrained:
+ state_dict = load_state_dict_from_url(
+ model_urls[arch], progress=progress
+ )
+ # remove useless keys from sate_dict 1. no fc; 2. out_features != 1000.
+ removed_keys = model.has_fc is False or (
+ model.has_fc is True and model.out_features != 1000
+ )
+ removed_keys = ["fc.weight", "fc.bias"] if removed_keys else []
+ for key in removed_keys:
+ state_dict.pop(key)
+ # if has fc, then allow missing key, else strict load state_dict.
+ allowed_missing_keys = removed_keys if model.has_fc else None
+ load_state_dict(model, state_dict, allowed_missing_keys)
+ return model
+
+
+@BACKBONE_REGISTRY.register()
+def resnet18_dynamic(pretrained=True, **kwargs) -> ResNet:
+ model = _resnet(
+ "resnet18_dynamic",
+ BasicBlockDynamic, [2, 2, 2, 2],
+ pretrained=pretrained,
+ progress=True,
+ has_fc=False
+ )
+ return model
+
+
+@BACKBONE_REGISTRY.register()
+def resnet50_dynamic(pretrained=True, **kwargs) -> ResNet:
+ model = _resnet(
+ "resnet50_dynamic",
+ BottleneckDynamic, [3, 4, 6, 3],
+ pretrained=pretrained,
+ progress=True,
+ has_fc=False
+ )
+ return model
+
+
+@BACKBONE_REGISTRY.register()
+def resnet101_dynamic(pretrained=True, **kwargs) -> ResNet:
+ model = _resnet(
+ "resnet101_dynamic",
+ BottleneckDynamic, [3, 4, 23, 3],
+ pretrained=pretrained,
+ progress=True,
+ has_fc=False
+ )
+ return model
+
+
+@BACKBONE_REGISTRY.register()
+def resnet18_dynamic_ms_l123(pretrained=True, **kwargs) -> ResNet:
+ model = _resnet(
+ "resnet18_dynamic",
+ BasicBlockDynamic, [2, 2, 2, 2],
+ pretrained=pretrained,
+ progress=True,
+ has_fc=False,
+ ms_class=MixStyle,
+ ms_layers=["layer1", "layer2", "layer3"]
+ )
+ return model
+
+
+@BACKBONE_REGISTRY.register()
+def resnet18_dynamic_ms_l12(pretrained=True, **kwargs) -> ResNet:
+ model = _resnet(
+ "resnet18_dynamic",
+ BasicBlockDynamic, [2, 2, 2, 2],
+ pretrained=pretrained,
+ progress=True,
+ has_fc=False,
+ ms_class=MixStyle,
+ ms_layers=["layer1", "layer2"]
+ )
+ return model
+
+
+@BACKBONE_REGISTRY.register()
+def resnet18_dynamic_ms_l1(pretrained=True, **kwargs) -> ResNet:
+ model = _resnet(
+ "resnet18_dynamic",
+ BasicBlockDynamic, [2, 2, 2, 2],
+ pretrained=pretrained,
+ progress=True,
+ has_fc=False,
+ ms_class=MixStyle,
+ ms_layers=["layer1"]
+ )
+ return model
+
+
+@BACKBONE_REGISTRY.register()
+def resnet50_dynamic_ms_l123(pretrained=True, **kwargs) -> ResNet:
+ model = _resnet(
+ "resnet50_dynamic",
+ BottleneckDynamic, [3, 4, 6, 3],
+ pretrained=pretrained,
+ progress=True,
+ has_fc=False,
+ ms_class=MixStyle,
+ ms_layers=["layer1", "layer2", "layer3"]
+ )
+ return model
+
+
+@BACKBONE_REGISTRY.register()
+def resnet50_dynamic_ms_l12(pretrained=True, **kwargs) -> ResNet:
+ model = _resnet(
+ "resnet50_dynamic",
+ BottleneckDynamic, [3, 4, 6, 3],
+ pretrained=pretrained,
+ progress=True,
+ has_fc=False,
+ ms_class=MixStyle,
+ ms_layers=["layer1", "layer2"]
+ )
+ return model
+
+
+@BACKBONE_REGISTRY.register()
+def resnet50_dynamic_ms_l1(pretrained=True, **kwargs) -> ResNet:
+ model = _resnet(
+ "resnet50_dynamic",
+ BottleneckDynamic, [3, 4, 6, 3],
+ pretrained=pretrained,
+ progress=True,
+ has_fc=False,
+ ms_class=MixStyle,
+ ms_layers=["layer1"]
+ )
+ return model
+
+
+@BACKBONE_REGISTRY.register()
+def resnet101_dynamic_ms_l123(pretrained=True, **kwargs) -> ResNet:
+ model = _resnet(
+ "resnet101_dynamic",
+ BottleneckDynamic, [3, 4, 23, 3],
+ pretrained=pretrained,
+ progress=True,
+ has_fc=False,
+ ms_class=MixStyle,
+ ms_layers=["layer1", "layer2", "layer3"]
+ )
+ return model
+
+
+@BACKBONE_REGISTRY.register()
+def resnet101_dynamic_ms_l12(pretrained=True, **kwargs) -> ResNet:
+ model = _resnet(
+ "resnet101_dynamic",
+ BottleneckDynamic, [3, 4, 23, 3],
+ pretrained=pretrained,
+ progress=True,
+ has_fc=False,
+ ms_class=MixStyle,
+ ms_layers=["layer1", "layer2"]
+ )
+ return model
+
+
+@BACKBONE_REGISTRY.register()
+def resnet101_dynamic_ms_l1(pretrained=True, **kwargs) -> ResNet:
+ model = _resnet(
+ "resnet101_dynamic",
+ BottleneckDynamic, [3, 4, 23, 3],
+ pretrained=pretrained,
+ progress=True,
+ has_fc=False,
+ ms_class=MixStyle,
+ ms_layers=["layer1"]
+ )
+ return model
diff --git a/dassl/modeling/backbone/vgg.py b/dassl/modeling/backbone/vgg.py
new file mode 100644
index 0000000..3f91491
--- /dev/null
+++ b/dassl/modeling/backbone/vgg.py
@@ -0,0 +1,147 @@
+import torch
+import torch.nn as nn
+
+from .build import BACKBONE_REGISTRY
+from .backbone import Backbone
+
+try:
+ from torch.hub import load_state_dict_from_url
+except ImportError:
+ from torch.utils.model_zoo import load_url as load_state_dict_from_url
+
+model_urls = {
+ "vgg11": "https://download.pytorch.org/models/vgg11-bbd30ac9.pth",
+ "vgg13": "https://download.pytorch.org/models/vgg13-c768596a.pth",
+ "vgg16": "https://download.pytorch.org/models/vgg16-397923af.pth",
+ "vgg19": "https://download.pytorch.org/models/vgg19-dcbb9e9d.pth",
+ "vgg11_bn": "https://download.pytorch.org/models/vgg11_bn-6002323d.pth",
+ "vgg13_bn": "https://download.pytorch.org/models/vgg13_bn-abd245e5.pth",
+ "vgg16_bn": "https://download.pytorch.org/models/vgg16_bn-6c64b313.pth",
+ "vgg19_bn": "https://download.pytorch.org/models/vgg19_bn-c79401a0.pth",
+}
+
+
+class VGG(Backbone):
+
+ def __init__(self, features, init_weights=True):
+ super().__init__()
+ self.features = features
+ self.avgpool = nn.AdaptiveAvgPool2d((7, 7))
+ # Note that self.classifier outputs features rather than logits
+ self.classifier = nn.Sequential(
+ nn.Linear(512 * 7 * 7, 4096),
+ nn.ReLU(True),
+ nn.Dropout(),
+ nn.Linear(4096, 4096),
+ nn.ReLU(True),
+ nn.Dropout(),
+ )
+
+ self._out_features = 4096
+
+ if init_weights:
+ self._initialize_weights()
+
+ def forward(self, x):
+ x = self.features(x)
+ x = self.avgpool(x)
+ x = torch.flatten(x, 1)
+ return self.classifier(x)
+
+ def _initialize_weights(self):
+ for m in self.modules():
+ if isinstance(m, nn.Conv2d):
+ nn.init.kaiming_normal_(
+ m.weight, mode="fan_out", nonlinearity="relu"
+ )
+ if m.bias is not None:
+ nn.init.constant_(m.bias, 0)
+ elif isinstance(m, nn.BatchNorm2d):
+ nn.init.constant_(m.weight, 1)
+ nn.init.constant_(m.bias, 0)
+ elif isinstance(m, nn.Linear):
+ nn.init.normal_(m.weight, 0, 0.01)
+ nn.init.constant_(m.bias, 0)
+
+
+def make_layers(cfg, batch_norm=False):
+ layers = []
+ in_channels = 3
+ for v in cfg:
+ if v == "M":
+ layers += [nn.MaxPool2d(kernel_size=2, stride=2)]
+ else:
+ conv2d = nn.Conv2d(in_channels, v, kernel_size=3, padding=1)
+ if batch_norm:
+ layers += [conv2d, nn.BatchNorm2d(v), nn.ReLU(inplace=True)]
+ else:
+ layers += [conv2d, nn.ReLU(inplace=True)]
+ in_channels = v
+ return nn.Sequential(*layers)
+
+
+cfgs = {
+ "A": [64, "M", 128, "M", 256, 256, "M", 512, 512, "M", 512, 512, "M"],
+ "B":
+ [64, 64, "M", 128, 128, "M", 256, 256, "M", 512, 512, "M", 512, 512, "M"],
+ "D": [
+ 64,
+ 64,
+ "M",
+ 128,
+ 128,
+ "M",
+ 256,
+ 256,
+ 256,
+ "M",
+ 512,
+ 512,
+ 512,
+ "M",
+ 512,
+ 512,
+ 512,
+ "M",
+ ],
+ "E": [
+ 64,
+ 64,
+ "M",
+ 128,
+ 128,
+ "M",
+ 256,
+ 256,
+ 256,
+ 256,
+ "M",
+ 512,
+ 512,
+ 512,
+ 512,
+ "M",
+ 512,
+ 512,
+ 512,
+ 512,
+ "M",
+ ],
+}
+
+
+def _vgg(arch, cfg, batch_norm, pretrained):
+ init_weights = False if pretrained else True
+ model = VGG(
+ make_layers(cfgs[cfg], batch_norm=batch_norm),
+ init_weights=init_weights
+ )
+ if pretrained:
+ state_dict = load_state_dict_from_url(model_urls[arch], progress=True)
+ model.load_state_dict(state_dict, strict=False)
+ return model
+
+
+@BACKBONE_REGISTRY.register()
+def vgg16(pretrained=True, **kwargs):
+ return _vgg("vgg16", "D", False, pretrained)
diff --git a/dassl/modeling/backbone/wide_resnet.py b/dassl/modeling/backbone/wide_resnet.py
new file mode 100644
index 0000000..88ea949
--- /dev/null
+++ b/dassl/modeling/backbone/wide_resnet.py
@@ -0,0 +1,150 @@
+"""
+Modified from https://github.com/xternalz/WideResNet-pytorch
+"""
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+
+from .build import BACKBONE_REGISTRY
+from .backbone import Backbone
+
+
+class BasicBlock(nn.Module):
+
+ def __init__(self, in_planes, out_planes, stride, dropRate=0.0):
+ super().__init__()
+ self.bn1 = nn.BatchNorm2d(in_planes)
+ self.relu1 = nn.LeakyReLU(0.01, inplace=True)
+ self.conv1 = nn.Conv2d(
+ in_planes,
+ out_planes,
+ kernel_size=3,
+ stride=stride,
+ padding=1,
+ bias=False
+ )
+ self.bn2 = nn.BatchNorm2d(out_planes)
+ self.relu2 = nn.LeakyReLU(0.01, inplace=True)
+ self.conv2 = nn.Conv2d(
+ out_planes,
+ out_planes,
+ kernel_size=3,
+ stride=1,
+ padding=1,
+ bias=False
+ )
+ self.droprate = dropRate
+ self.equalInOut = in_planes == out_planes
+ self.convShortcut = (
+ (not self.equalInOut) and nn.Conv2d(
+ in_planes,
+ out_planes,
+ kernel_size=1,
+ stride=stride,
+ padding=0,
+ bias=False,
+ ) or None
+ )
+
+ def forward(self, x):
+ if not self.equalInOut:
+ x = self.relu1(self.bn1(x))
+ else:
+ out = self.relu1(self.bn1(x))
+ out = self.relu2(self.bn2(self.conv1(out if self.equalInOut else x)))
+ if self.droprate > 0:
+ out = F.dropout(out, p=self.droprate, training=self.training)
+ out = self.conv2(out)
+ return torch.add(x if self.equalInOut else self.convShortcut(x), out)
+
+
+class NetworkBlock(nn.Module):
+
+ def __init__(
+ self, nb_layers, in_planes, out_planes, block, stride, dropRate=0.0
+ ):
+ super().__init__()
+ self.layer = self._make_layer(
+ block, in_planes, out_planes, nb_layers, stride, dropRate
+ )
+
+ def _make_layer(
+ self, block, in_planes, out_planes, nb_layers, stride, dropRate
+ ):
+ layers = []
+ for i in range(int(nb_layers)):
+ layers.append(
+ block(
+ i == 0 and in_planes or out_planes,
+ out_planes,
+ i == 0 and stride or 1,
+ dropRate,
+ )
+ )
+ return nn.Sequential(*layers)
+
+ def forward(self, x):
+ return self.layer(x)
+
+
+class WideResNet(Backbone):
+
+ def __init__(self, depth, widen_factor, dropRate=0.0):
+ super().__init__()
+ nChannels = [
+ 16, 16 * widen_factor, 32 * widen_factor, 64 * widen_factor
+ ]
+ assert (depth-4) % 6 == 0
+ n = (depth-4) / 6
+ block = BasicBlock
+ # 1st conv before any network block
+ self.conv1 = nn.Conv2d(
+ 3, nChannels[0], kernel_size=3, stride=1, padding=1, bias=False
+ )
+ # 1st block
+ self.block1 = NetworkBlock(
+ n, nChannels[0], nChannels[1], block, 1, dropRate
+ )
+ # 2nd block
+ self.block2 = NetworkBlock(
+ n, nChannels[1], nChannels[2], block, 2, dropRate
+ )
+ # 3rd block
+ self.block3 = NetworkBlock(
+ n, nChannels[2], nChannels[3], block, 2, dropRate
+ )
+ # global average pooling and classifier
+ self.bn1 = nn.BatchNorm2d(nChannels[3])
+ self.relu = nn.LeakyReLU(0.01, inplace=True)
+
+ self._out_features = nChannels[3]
+
+ for m in self.modules():
+ if isinstance(m, nn.Conv2d):
+ nn.init.kaiming_normal_(
+ m.weight, mode="fan_out", nonlinearity="relu"
+ )
+ elif isinstance(m, nn.BatchNorm2d):
+ m.weight.data.fill_(1)
+ m.bias.data.zero_()
+ elif isinstance(m, nn.Linear):
+ m.bias.data.zero_()
+
+ def forward(self, x):
+ out = self.conv1(x)
+ out = self.block1(out)
+ out = self.block2(out)
+ out = self.block3(out)
+ out = self.relu(self.bn1(out))
+ out = F.adaptive_avg_pool2d(out, 1)
+ return out.view(out.size(0), -1)
+
+
+@BACKBONE_REGISTRY.register()
+def wide_resnet_28_2(**kwargs):
+ return WideResNet(28, 2)
+
+
+@BACKBONE_REGISTRY.register()
+def wide_resnet_16_4(**kwargs):
+ return WideResNet(16, 4)
diff --git a/dassl/modeling/head/__init__.py b/dassl/modeling/head/__init__.py
new file mode 100644
index 0000000..e76fb8c
--- /dev/null
+++ b/dassl/modeling/head/__init__.py
@@ -0,0 +1,3 @@
+from .build import build_head, HEAD_REGISTRY # isort:skip
+
+from .mlp import mlp
diff --git a/dassl/modeling/head/__pycache__/__init__.cpython-310.pyc b/dassl/modeling/head/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000..9f53335
Binary files /dev/null and b/dassl/modeling/head/__pycache__/__init__.cpython-310.pyc differ
diff --git a/dassl/modeling/head/__pycache__/__init__.cpython-311.pyc b/dassl/modeling/head/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000..2ffa441
Binary files /dev/null and b/dassl/modeling/head/__pycache__/__init__.cpython-311.pyc differ
diff --git a/dassl/modeling/head/__pycache__/__init__.cpython-38.pyc b/dassl/modeling/head/__pycache__/__init__.cpython-38.pyc
new file mode 100644
index 0000000..eb4a821
Binary files /dev/null and b/dassl/modeling/head/__pycache__/__init__.cpython-38.pyc differ
diff --git a/dassl/modeling/head/__pycache__/build.cpython-310.pyc b/dassl/modeling/head/__pycache__/build.cpython-310.pyc
new file mode 100644
index 0000000..85b6f5c
Binary files /dev/null and b/dassl/modeling/head/__pycache__/build.cpython-310.pyc differ
diff --git a/dassl/modeling/head/__pycache__/build.cpython-311.pyc b/dassl/modeling/head/__pycache__/build.cpython-311.pyc
new file mode 100644
index 0000000..3e46996
Binary files /dev/null and b/dassl/modeling/head/__pycache__/build.cpython-311.pyc differ
diff --git a/dassl/modeling/head/__pycache__/build.cpython-38.pyc b/dassl/modeling/head/__pycache__/build.cpython-38.pyc
new file mode 100644
index 0000000..e1bd9b8
Binary files /dev/null and b/dassl/modeling/head/__pycache__/build.cpython-38.pyc differ
diff --git a/dassl/modeling/head/__pycache__/mlp.cpython-310.pyc b/dassl/modeling/head/__pycache__/mlp.cpython-310.pyc
new file mode 100644
index 0000000..3741797
Binary files /dev/null and b/dassl/modeling/head/__pycache__/mlp.cpython-310.pyc differ
diff --git a/dassl/modeling/head/__pycache__/mlp.cpython-311.pyc b/dassl/modeling/head/__pycache__/mlp.cpython-311.pyc
new file mode 100644
index 0000000..00ca504
Binary files /dev/null and b/dassl/modeling/head/__pycache__/mlp.cpython-311.pyc differ
diff --git a/dassl/modeling/head/__pycache__/mlp.cpython-38.pyc b/dassl/modeling/head/__pycache__/mlp.cpython-38.pyc
new file mode 100644
index 0000000..204270a
Binary files /dev/null and b/dassl/modeling/head/__pycache__/mlp.cpython-38.pyc differ
diff --git a/dassl/modeling/head/build.py b/dassl/modeling/head/build.py
new file mode 100644
index 0000000..730437b
--- /dev/null
+++ b/dassl/modeling/head/build.py
@@ -0,0 +1,11 @@
+from dassl.utils import Registry, check_availability
+
+HEAD_REGISTRY = Registry("HEAD")
+
+
+def build_head(name, verbose=True, **kwargs):
+ avai_heads = HEAD_REGISTRY.registered_names()
+ check_availability(name, avai_heads)
+ if verbose:
+ print("Head: {}".format(name))
+ return HEAD_REGISTRY.get(name)(**kwargs)
diff --git a/dassl/modeling/head/mlp.py b/dassl/modeling/head/mlp.py
new file mode 100644
index 0000000..89aae50
--- /dev/null
+++ b/dassl/modeling/head/mlp.py
@@ -0,0 +1,50 @@
+import functools
+import torch.nn as nn
+
+from .build import HEAD_REGISTRY
+
+
+class MLP(nn.Module):
+
+ def __init__(
+ self,
+ in_features=2048,
+ hidden_layers=[],
+ activation="relu",
+ bn=True,
+ dropout=0.0,
+ ):
+ super().__init__()
+ if isinstance(hidden_layers, int):
+ hidden_layers = [hidden_layers]
+
+ assert len(hidden_layers) > 0
+ self.out_features = hidden_layers[-1]
+
+ mlp = []
+
+ if activation == "relu":
+ act_fn = functools.partial(nn.ReLU, inplace=True)
+ elif activation == "leaky_relu":
+ act_fn = functools.partial(nn.LeakyReLU, inplace=True)
+ else:
+ raise NotImplementedError
+
+ for hidden_dim in hidden_layers:
+ mlp += [nn.Linear(in_features, hidden_dim)]
+ if bn:
+ mlp += [nn.BatchNorm1d(hidden_dim)]
+ mlp += [act_fn()]
+ if dropout > 0:
+ mlp += [nn.Dropout(dropout)]
+ in_features = hidden_dim
+
+ self.mlp = nn.Sequential(*mlp)
+
+ def forward(self, x):
+ return self.mlp(x)
+
+
+@HEAD_REGISTRY.register()
+def mlp(**kwargs):
+ return MLP(**kwargs)
diff --git a/dassl/modeling/network/__init__.py b/dassl/modeling/network/__init__.py
new file mode 100644
index 0000000..a6fcc63
--- /dev/null
+++ b/dassl/modeling/network/__init__.py
@@ -0,0 +1,5 @@
+from .build import build_network, NETWORK_REGISTRY # isort:skip
+
+from .ddaig_fcn import (
+ fcn_3x32_gctx, fcn_3x64_gctx, fcn_3x32_gctx_stn, fcn_3x64_gctx_stn
+)
diff --git a/dassl/modeling/network/__pycache__/__init__.cpython-310.pyc b/dassl/modeling/network/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000..ac754c1
Binary files /dev/null and b/dassl/modeling/network/__pycache__/__init__.cpython-310.pyc differ
diff --git a/dassl/modeling/network/__pycache__/__init__.cpython-311.pyc b/dassl/modeling/network/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000..7d2feab
Binary files /dev/null and b/dassl/modeling/network/__pycache__/__init__.cpython-311.pyc differ
diff --git a/dassl/modeling/network/__pycache__/__init__.cpython-38.pyc b/dassl/modeling/network/__pycache__/__init__.cpython-38.pyc
new file mode 100644
index 0000000..46475cc
Binary files /dev/null and b/dassl/modeling/network/__pycache__/__init__.cpython-38.pyc differ
diff --git a/dassl/modeling/network/__pycache__/build.cpython-310.pyc b/dassl/modeling/network/__pycache__/build.cpython-310.pyc
new file mode 100644
index 0000000..6237980
Binary files /dev/null and b/dassl/modeling/network/__pycache__/build.cpython-310.pyc differ
diff --git a/dassl/modeling/network/__pycache__/build.cpython-311.pyc b/dassl/modeling/network/__pycache__/build.cpython-311.pyc
new file mode 100644
index 0000000..e916525
Binary files /dev/null and b/dassl/modeling/network/__pycache__/build.cpython-311.pyc differ
diff --git a/dassl/modeling/network/__pycache__/build.cpython-38.pyc b/dassl/modeling/network/__pycache__/build.cpython-38.pyc
new file mode 100644
index 0000000..d44db6f
Binary files /dev/null and b/dassl/modeling/network/__pycache__/build.cpython-38.pyc differ
diff --git a/dassl/modeling/network/__pycache__/ddaig_fcn.cpython-310.pyc b/dassl/modeling/network/__pycache__/ddaig_fcn.cpython-310.pyc
new file mode 100644
index 0000000..5ccc18d
Binary files /dev/null and b/dassl/modeling/network/__pycache__/ddaig_fcn.cpython-310.pyc differ
diff --git a/dassl/modeling/network/__pycache__/ddaig_fcn.cpython-311.pyc b/dassl/modeling/network/__pycache__/ddaig_fcn.cpython-311.pyc
new file mode 100644
index 0000000..f5cd7bd
Binary files /dev/null and b/dassl/modeling/network/__pycache__/ddaig_fcn.cpython-311.pyc differ
diff --git a/dassl/modeling/network/__pycache__/ddaig_fcn.cpython-38.pyc b/dassl/modeling/network/__pycache__/ddaig_fcn.cpython-38.pyc
new file mode 100644
index 0000000..7a84b65
Binary files /dev/null and b/dassl/modeling/network/__pycache__/ddaig_fcn.cpython-38.pyc differ
diff --git a/dassl/modeling/network/build.py b/dassl/modeling/network/build.py
new file mode 100644
index 0000000..e615314
--- /dev/null
+++ b/dassl/modeling/network/build.py
@@ -0,0 +1,11 @@
+from dassl.utils import Registry, check_availability
+
+NETWORK_REGISTRY = Registry("NETWORK")
+
+
+def build_network(name, verbose=True, **kwargs):
+ avai_models = NETWORK_REGISTRY.registered_names()
+ check_availability(name, avai_models)
+ if verbose:
+ print("Network: {}".format(name))
+ return NETWORK_REGISTRY.get(name)(**kwargs)
diff --git a/dassl/modeling/network/ddaig_fcn.py b/dassl/modeling/network/ddaig_fcn.py
new file mode 100644
index 0000000..17e3bdd
--- /dev/null
+++ b/dassl/modeling/network/ddaig_fcn.py
@@ -0,0 +1,329 @@
+"""
+Credit to: https://github.com/junyanz/pytorch-CycleGAN-and-pix2pix
+"""
+import functools
+import torch
+import torch.nn as nn
+from torch.nn import functional as F
+
+from .build import NETWORK_REGISTRY
+
+
+def init_network_weights(model, init_type="normal", gain=0.02):
+
+ def _init_func(m):
+ classname = m.__class__.__name__
+ if hasattr(m, "weight") and (
+ classname.find("Conv") != -1 or classname.find("Linear") != -1
+ ):
+ if init_type == "normal":
+ nn.init.normal_(m.weight.data, 0.0, gain)
+ elif init_type == "xavier":
+ nn.init.xavier_normal_(m.weight.data, gain=gain)
+ elif init_type == "kaiming":
+ nn.init.kaiming_normal_(m.weight.data, a=0, mode="fan_in")
+ elif init_type == "orthogonal":
+ nn.init.orthogonal_(m.weight.data, gain=gain)
+ else:
+ raise NotImplementedError(
+ "initialization method {} is not implemented".
+ format(init_type)
+ )
+ if hasattr(m, "bias") and m.bias is not None:
+ nn.init.constant_(m.bias.data, 0.0)
+ elif classname.find("BatchNorm2d") != -1:
+ nn.init.constant_(m.weight.data, 1.0)
+ nn.init.constant_(m.bias.data, 0.0)
+ elif classname.find("InstanceNorm2d") != -1:
+ if m.weight is not None and m.bias is not None:
+ nn.init.constant_(m.weight.data, 1.0)
+ nn.init.constant_(m.bias.data, 0.0)
+
+ model.apply(_init_func)
+
+
+def get_norm_layer(norm_type="instance"):
+ if norm_type == "batch":
+ norm_layer = functools.partial(nn.BatchNorm2d, affine=True)
+ elif norm_type == "instance":
+ norm_layer = functools.partial(
+ nn.InstanceNorm2d, affine=False, track_running_stats=False
+ )
+ elif norm_type == "none":
+ norm_layer = None
+ else:
+ raise NotImplementedError(
+ "normalization layer [%s] is not found" % norm_type
+ )
+ return norm_layer
+
+
+class ResnetBlock(nn.Module):
+
+ def __init__(self, dim, padding_type, norm_layer, use_dropout, use_bias):
+ super().__init__()
+ self.conv_block = self.build_conv_block(
+ dim, padding_type, norm_layer, use_dropout, use_bias
+ )
+
+ def build_conv_block(
+ self, dim, padding_type, norm_layer, use_dropout, use_bias
+ ):
+ conv_block = []
+ p = 0
+ if padding_type == "reflect":
+ conv_block += [nn.ReflectionPad2d(1)]
+ elif padding_type == "replicate":
+ conv_block += [nn.ReplicationPad2d(1)]
+ elif padding_type == "zero":
+ p = 1
+ else:
+ raise NotImplementedError(
+ "padding [%s] is not implemented" % padding_type
+ )
+
+ conv_block += [
+ nn.Conv2d(dim, dim, kernel_size=3, padding=p, bias=use_bias),
+ norm_layer(dim),
+ nn.ReLU(True),
+ ]
+ if use_dropout:
+ conv_block += [nn.Dropout(0.5)]
+
+ p = 0
+ if padding_type == "reflect":
+ conv_block += [nn.ReflectionPad2d(1)]
+ elif padding_type == "replicate":
+ conv_block += [nn.ReplicationPad2d(1)]
+ elif padding_type == "zero":
+ p = 1
+ else:
+ raise NotImplementedError(
+ "padding [%s] is not implemented" % padding_type
+ )
+ conv_block += [
+ nn.Conv2d(dim, dim, kernel_size=3, padding=p, bias=use_bias),
+ norm_layer(dim),
+ ]
+
+ return nn.Sequential(*conv_block)
+
+ def forward(self, x):
+ return x + self.conv_block(x)
+
+
+class LocNet(nn.Module):
+ """Localization network."""
+
+ def __init__(
+ self,
+ input_nc,
+ nc=32,
+ n_blocks=3,
+ use_dropout=False,
+ padding_type="zero",
+ image_size=32,
+ ):
+ super().__init__()
+
+ backbone = []
+ backbone += [
+ nn.Conv2d(
+ input_nc, nc, kernel_size=3, stride=2, padding=1, bias=False
+ )
+ ]
+ backbone += [nn.BatchNorm2d(nc)]
+ backbone += [nn.ReLU(True)]
+ for _ in range(n_blocks):
+ backbone += [
+ ResnetBlock(
+ nc,
+ padding_type=padding_type,
+ norm_layer=nn.BatchNorm2d,
+ use_dropout=use_dropout,
+ use_bias=False,
+ )
+ ]
+ backbone += [nn.MaxPool2d(2, stride=2)]
+ self.backbone = nn.Sequential(*backbone)
+ reduced_imsize = int(image_size * 0.5**(n_blocks + 1))
+ self.fc_loc = nn.Linear(nc * reduced_imsize**2, 2 * 2)
+
+ def forward(self, x):
+ x = self.backbone(x)
+ x = x.view(x.size(0), -1)
+ x = self.fc_loc(x)
+ x = torch.tanh(x)
+ x = x.view(-1, 2, 2)
+ theta = x.data.new_zeros(x.size(0), 2, 3)
+ theta[:, :, :2] = x
+ return theta
+
+
+class FCN(nn.Module):
+ """Fully convolutional network."""
+
+ def __init__(
+ self,
+ input_nc,
+ output_nc,
+ nc=32,
+ n_blocks=3,
+ norm_layer=nn.BatchNorm2d,
+ use_dropout=False,
+ padding_type="reflect",
+ gctx=True,
+ stn=False,
+ image_size=32,
+ ):
+ super().__init__()
+
+ backbone = []
+
+ p = 0
+ if padding_type == "reflect":
+ backbone += [nn.ReflectionPad2d(1)]
+ elif padding_type == "replicate":
+ backbone += [nn.ReplicationPad2d(1)]
+ elif padding_type == "zero":
+ p = 1
+ else:
+ raise NotImplementedError
+ backbone += [
+ nn.Conv2d(
+ input_nc, nc, kernel_size=3, stride=1, padding=p, bias=False
+ )
+ ]
+ backbone += [norm_layer(nc)]
+ backbone += [nn.ReLU(True)]
+
+ for _ in range(n_blocks):
+ backbone += [
+ ResnetBlock(
+ nc,
+ padding_type=padding_type,
+ norm_layer=norm_layer,
+ use_dropout=use_dropout,
+ use_bias=False,
+ )
+ ]
+ self.backbone = nn.Sequential(*backbone)
+
+ # global context fusion layer
+ self.gctx_fusion = None
+ if gctx:
+ self.gctx_fusion = nn.Sequential(
+ nn.Conv2d(
+ 2 * nc, nc, kernel_size=1, stride=1, padding=0, bias=False
+ ),
+ norm_layer(nc),
+ nn.ReLU(True),
+ )
+
+ self.regress = nn.Sequential(
+ nn.Conv2d(
+ nc, output_nc, kernel_size=1, stride=1, padding=0, bias=True
+ ),
+ nn.Tanh(),
+ )
+
+ self.locnet = None
+ if stn:
+ self.locnet = LocNet(
+ input_nc, nc=nc, n_blocks=n_blocks, image_size=image_size
+ )
+
+ def init_loc_layer(self):
+ """Initialize the weights/bias with identity transformation."""
+ if self.locnet is not None:
+ self.locnet.fc_loc.weight.data.zero_()
+ self.locnet.fc_loc.bias.data.copy_(
+ torch.tensor([1, 0, 0, 1], dtype=torch.float)
+ )
+
+ def stn(self, x):
+ """Spatial transformer network."""
+ theta = self.locnet(x)
+ grid = F.affine_grid(theta, x.size())
+ return F.grid_sample(x, grid), theta
+
+ def forward(self, x, lmda=1.0, return_p=False, return_stn_output=False):
+ """
+ Args:
+ x (torch.Tensor): input mini-batch.
+ lmda (float): multiplier for perturbation.
+ return_p (bool): return perturbation.
+ return_stn_output (bool): return the output of stn.
+ """
+ theta = None
+ if self.locnet is not None:
+ x, theta = self.stn(x)
+ input = x
+
+ x = self.backbone(x)
+ if self.gctx_fusion is not None:
+ c = F.adaptive_avg_pool2d(x, (1, 1))
+ c = c.expand_as(x)
+ x = torch.cat([x, c], 1)
+ x = self.gctx_fusion(x)
+
+ p = self.regress(x)
+ x_p = input + lmda*p
+
+ if return_stn_output:
+ return x_p, p, input
+
+ if return_p:
+ return x_p, p
+
+ return x_p
+
+
+@NETWORK_REGISTRY.register()
+def fcn_3x32_gctx(**kwargs):
+ norm_layer = get_norm_layer(norm_type="instance")
+ net = FCN(3, 3, nc=32, n_blocks=3, norm_layer=norm_layer)
+ init_network_weights(net, init_type="normal", gain=0.02)
+ return net
+
+
+@NETWORK_REGISTRY.register()
+def fcn_3x64_gctx(**kwargs):
+ norm_layer = get_norm_layer(norm_type="instance")
+ net = FCN(3, 3, nc=64, n_blocks=3, norm_layer=norm_layer)
+ init_network_weights(net, init_type="normal", gain=0.02)
+ return net
+
+
+@NETWORK_REGISTRY.register()
+def fcn_3x32_gctx_stn(image_size=32, **kwargs):
+ norm_layer = get_norm_layer(norm_type="instance")
+ net = FCN(
+ 3,
+ 3,
+ nc=32,
+ n_blocks=3,
+ norm_layer=norm_layer,
+ stn=True,
+ image_size=image_size
+ )
+ init_network_weights(net, init_type="normal", gain=0.02)
+ net.init_loc_layer()
+ return net
+
+
+@NETWORK_REGISTRY.register()
+def fcn_3x64_gctx_stn(image_size=224, **kwargs):
+ norm_layer = get_norm_layer(norm_type="instance")
+ net = FCN(
+ 3,
+ 3,
+ nc=64,
+ n_blocks=3,
+ norm_layer=norm_layer,
+ stn=True,
+ image_size=image_size
+ )
+ init_network_weights(net, init_type="normal", gain=0.02)
+ net.init_loc_layer()
+ return net
diff --git a/dassl/modeling/ops/__init__.py b/dassl/modeling/ops/__init__.py
new file mode 100644
index 0000000..44d0640
--- /dev/null
+++ b/dassl/modeling/ops/__init__.py
@@ -0,0 +1,18 @@
+from .mmd import MaximumMeanDiscrepancy
+from .conv import *
+from .dsbn import DSBN1d, DSBN2d
+from .mixup import mixup
+from .efdmix import (
+ EFDMix, random_efdmix, activate_efdmix, run_with_efdmix, deactivate_efdmix,
+ crossdomain_efdmix, run_without_efdmix
+)
+from .mixstyle import (
+ MixStyle, random_mixstyle, activate_mixstyle, run_with_mixstyle,
+ deactivate_mixstyle, crossdomain_mixstyle, run_without_mixstyle
+)
+from .attention import *
+from .transnorm import TransNorm1d, TransNorm2d
+from .sequential2 import Sequential2
+from .reverse_grad import ReverseGrad
+from .cross_entropy import cross_entropy
+from .optimal_transport import SinkhornDivergence, MinibatchEnergyDistance
diff --git a/dassl/modeling/ops/__pycache__/__init__.cpython-310.pyc b/dassl/modeling/ops/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000..4c75624
Binary files /dev/null and b/dassl/modeling/ops/__pycache__/__init__.cpython-310.pyc differ
diff --git a/dassl/modeling/ops/__pycache__/__init__.cpython-311.pyc b/dassl/modeling/ops/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000..928b758
Binary files /dev/null and b/dassl/modeling/ops/__pycache__/__init__.cpython-311.pyc differ
diff --git a/dassl/modeling/ops/__pycache__/__init__.cpython-38.pyc b/dassl/modeling/ops/__pycache__/__init__.cpython-38.pyc
new file mode 100644
index 0000000..d92b0bb
Binary files /dev/null and b/dassl/modeling/ops/__pycache__/__init__.cpython-38.pyc differ
diff --git a/dassl/modeling/ops/__pycache__/attention.cpython-310.pyc b/dassl/modeling/ops/__pycache__/attention.cpython-310.pyc
new file mode 100644
index 0000000..f39a9e2
Binary files /dev/null and b/dassl/modeling/ops/__pycache__/attention.cpython-310.pyc differ
diff --git a/dassl/modeling/ops/__pycache__/attention.cpython-311.pyc b/dassl/modeling/ops/__pycache__/attention.cpython-311.pyc
new file mode 100644
index 0000000..a5ee26d
Binary files /dev/null and b/dassl/modeling/ops/__pycache__/attention.cpython-311.pyc differ
diff --git a/dassl/modeling/ops/__pycache__/attention.cpython-38.pyc b/dassl/modeling/ops/__pycache__/attention.cpython-38.pyc
new file mode 100644
index 0000000..bd6eafb
Binary files /dev/null and b/dassl/modeling/ops/__pycache__/attention.cpython-38.pyc differ
diff --git a/dassl/modeling/ops/__pycache__/conv.cpython-310.pyc b/dassl/modeling/ops/__pycache__/conv.cpython-310.pyc
new file mode 100644
index 0000000..81fa761
Binary files /dev/null and b/dassl/modeling/ops/__pycache__/conv.cpython-310.pyc differ
diff --git a/dassl/modeling/ops/__pycache__/conv.cpython-311.pyc b/dassl/modeling/ops/__pycache__/conv.cpython-311.pyc
new file mode 100644
index 0000000..ea7d4fd
Binary files /dev/null and b/dassl/modeling/ops/__pycache__/conv.cpython-311.pyc differ
diff --git a/dassl/modeling/ops/__pycache__/conv.cpython-38.pyc b/dassl/modeling/ops/__pycache__/conv.cpython-38.pyc
new file mode 100644
index 0000000..9b7dbe4
Binary files /dev/null and b/dassl/modeling/ops/__pycache__/conv.cpython-38.pyc differ
diff --git a/dassl/modeling/ops/__pycache__/cross_entropy.cpython-310.pyc b/dassl/modeling/ops/__pycache__/cross_entropy.cpython-310.pyc
new file mode 100644
index 0000000..372e9c0
Binary files /dev/null and b/dassl/modeling/ops/__pycache__/cross_entropy.cpython-310.pyc differ
diff --git a/dassl/modeling/ops/__pycache__/cross_entropy.cpython-311.pyc b/dassl/modeling/ops/__pycache__/cross_entropy.cpython-311.pyc
new file mode 100644
index 0000000..8412a72
Binary files /dev/null and b/dassl/modeling/ops/__pycache__/cross_entropy.cpython-311.pyc differ
diff --git a/dassl/modeling/ops/__pycache__/cross_entropy.cpython-38.pyc b/dassl/modeling/ops/__pycache__/cross_entropy.cpython-38.pyc
new file mode 100644
index 0000000..88fb92f
Binary files /dev/null and b/dassl/modeling/ops/__pycache__/cross_entropy.cpython-38.pyc differ
diff --git a/dassl/modeling/ops/__pycache__/dsbn.cpython-310.pyc b/dassl/modeling/ops/__pycache__/dsbn.cpython-310.pyc
new file mode 100644
index 0000000..67977dc
Binary files /dev/null and b/dassl/modeling/ops/__pycache__/dsbn.cpython-310.pyc differ
diff --git a/dassl/modeling/ops/__pycache__/dsbn.cpython-311.pyc b/dassl/modeling/ops/__pycache__/dsbn.cpython-311.pyc
new file mode 100644
index 0000000..ef78381
Binary files /dev/null and b/dassl/modeling/ops/__pycache__/dsbn.cpython-311.pyc differ
diff --git a/dassl/modeling/ops/__pycache__/dsbn.cpython-38.pyc b/dassl/modeling/ops/__pycache__/dsbn.cpython-38.pyc
new file mode 100644
index 0000000..e36ce23
Binary files /dev/null and b/dassl/modeling/ops/__pycache__/dsbn.cpython-38.pyc differ
diff --git a/dassl/modeling/ops/__pycache__/efdmix.cpython-310.pyc b/dassl/modeling/ops/__pycache__/efdmix.cpython-310.pyc
new file mode 100644
index 0000000..7574747
Binary files /dev/null and b/dassl/modeling/ops/__pycache__/efdmix.cpython-310.pyc differ
diff --git a/dassl/modeling/ops/__pycache__/efdmix.cpython-311.pyc b/dassl/modeling/ops/__pycache__/efdmix.cpython-311.pyc
new file mode 100644
index 0000000..6df84fd
Binary files /dev/null and b/dassl/modeling/ops/__pycache__/efdmix.cpython-311.pyc differ
diff --git a/dassl/modeling/ops/__pycache__/efdmix.cpython-38.pyc b/dassl/modeling/ops/__pycache__/efdmix.cpython-38.pyc
new file mode 100644
index 0000000..da2cfee
Binary files /dev/null and b/dassl/modeling/ops/__pycache__/efdmix.cpython-38.pyc differ
diff --git a/dassl/modeling/ops/__pycache__/mixstyle.cpython-310.pyc b/dassl/modeling/ops/__pycache__/mixstyle.cpython-310.pyc
new file mode 100644
index 0000000..e445da4
Binary files /dev/null and b/dassl/modeling/ops/__pycache__/mixstyle.cpython-310.pyc differ
diff --git a/dassl/modeling/ops/__pycache__/mixstyle.cpython-311.pyc b/dassl/modeling/ops/__pycache__/mixstyle.cpython-311.pyc
new file mode 100644
index 0000000..1300587
Binary files /dev/null and b/dassl/modeling/ops/__pycache__/mixstyle.cpython-311.pyc differ
diff --git a/dassl/modeling/ops/__pycache__/mixstyle.cpython-38.pyc b/dassl/modeling/ops/__pycache__/mixstyle.cpython-38.pyc
new file mode 100644
index 0000000..1295738
Binary files /dev/null and b/dassl/modeling/ops/__pycache__/mixstyle.cpython-38.pyc differ
diff --git a/dassl/modeling/ops/__pycache__/mixup.cpython-310.pyc b/dassl/modeling/ops/__pycache__/mixup.cpython-310.pyc
new file mode 100644
index 0000000..260829c
Binary files /dev/null and b/dassl/modeling/ops/__pycache__/mixup.cpython-310.pyc differ
diff --git a/dassl/modeling/ops/__pycache__/mixup.cpython-311.pyc b/dassl/modeling/ops/__pycache__/mixup.cpython-311.pyc
new file mode 100644
index 0000000..905e616
Binary files /dev/null and b/dassl/modeling/ops/__pycache__/mixup.cpython-311.pyc differ
diff --git a/dassl/modeling/ops/__pycache__/mixup.cpython-38.pyc b/dassl/modeling/ops/__pycache__/mixup.cpython-38.pyc
new file mode 100644
index 0000000..38ac5cf
Binary files /dev/null and b/dassl/modeling/ops/__pycache__/mixup.cpython-38.pyc differ
diff --git a/dassl/modeling/ops/__pycache__/mmd.cpython-310.pyc b/dassl/modeling/ops/__pycache__/mmd.cpython-310.pyc
new file mode 100644
index 0000000..5d5d5ff
Binary files /dev/null and b/dassl/modeling/ops/__pycache__/mmd.cpython-310.pyc differ
diff --git a/dassl/modeling/ops/__pycache__/mmd.cpython-311.pyc b/dassl/modeling/ops/__pycache__/mmd.cpython-311.pyc
new file mode 100644
index 0000000..1f2197f
Binary files /dev/null and b/dassl/modeling/ops/__pycache__/mmd.cpython-311.pyc differ
diff --git a/dassl/modeling/ops/__pycache__/mmd.cpython-38.pyc b/dassl/modeling/ops/__pycache__/mmd.cpython-38.pyc
new file mode 100644
index 0000000..58d5ef3
Binary files /dev/null and b/dassl/modeling/ops/__pycache__/mmd.cpython-38.pyc differ
diff --git a/dassl/modeling/ops/__pycache__/optimal_transport.cpython-310.pyc b/dassl/modeling/ops/__pycache__/optimal_transport.cpython-310.pyc
new file mode 100644
index 0000000..59ce897
Binary files /dev/null and b/dassl/modeling/ops/__pycache__/optimal_transport.cpython-310.pyc differ
diff --git a/dassl/modeling/ops/__pycache__/optimal_transport.cpython-311.pyc b/dassl/modeling/ops/__pycache__/optimal_transport.cpython-311.pyc
new file mode 100644
index 0000000..9bfc7f6
Binary files /dev/null and b/dassl/modeling/ops/__pycache__/optimal_transport.cpython-311.pyc differ
diff --git a/dassl/modeling/ops/__pycache__/optimal_transport.cpython-38.pyc b/dassl/modeling/ops/__pycache__/optimal_transport.cpython-38.pyc
new file mode 100644
index 0000000..d49c6fb
Binary files /dev/null and b/dassl/modeling/ops/__pycache__/optimal_transport.cpython-38.pyc differ
diff --git a/dassl/modeling/ops/__pycache__/reverse_grad.cpython-310.pyc b/dassl/modeling/ops/__pycache__/reverse_grad.cpython-310.pyc
new file mode 100644
index 0000000..628003d
Binary files /dev/null and b/dassl/modeling/ops/__pycache__/reverse_grad.cpython-310.pyc differ
diff --git a/dassl/modeling/ops/__pycache__/reverse_grad.cpython-311.pyc b/dassl/modeling/ops/__pycache__/reverse_grad.cpython-311.pyc
new file mode 100644
index 0000000..4ac30a6
Binary files /dev/null and b/dassl/modeling/ops/__pycache__/reverse_grad.cpython-311.pyc differ
diff --git a/dassl/modeling/ops/__pycache__/reverse_grad.cpython-38.pyc b/dassl/modeling/ops/__pycache__/reverse_grad.cpython-38.pyc
new file mode 100644
index 0000000..1cc383e
Binary files /dev/null and b/dassl/modeling/ops/__pycache__/reverse_grad.cpython-38.pyc differ
diff --git a/dassl/modeling/ops/__pycache__/sequential2.cpython-310.pyc b/dassl/modeling/ops/__pycache__/sequential2.cpython-310.pyc
new file mode 100644
index 0000000..df251fd
Binary files /dev/null and b/dassl/modeling/ops/__pycache__/sequential2.cpython-310.pyc differ
diff --git a/dassl/modeling/ops/__pycache__/sequential2.cpython-311.pyc b/dassl/modeling/ops/__pycache__/sequential2.cpython-311.pyc
new file mode 100644
index 0000000..5ef5c86
Binary files /dev/null and b/dassl/modeling/ops/__pycache__/sequential2.cpython-311.pyc differ
diff --git a/dassl/modeling/ops/__pycache__/sequential2.cpython-38.pyc b/dassl/modeling/ops/__pycache__/sequential2.cpython-38.pyc
new file mode 100644
index 0000000..cba847c
Binary files /dev/null and b/dassl/modeling/ops/__pycache__/sequential2.cpython-38.pyc differ
diff --git a/dassl/modeling/ops/__pycache__/transnorm.cpython-310.pyc b/dassl/modeling/ops/__pycache__/transnorm.cpython-310.pyc
new file mode 100644
index 0000000..4cacd55
Binary files /dev/null and b/dassl/modeling/ops/__pycache__/transnorm.cpython-310.pyc differ
diff --git a/dassl/modeling/ops/__pycache__/transnorm.cpython-311.pyc b/dassl/modeling/ops/__pycache__/transnorm.cpython-311.pyc
new file mode 100644
index 0000000..1734581
Binary files /dev/null and b/dassl/modeling/ops/__pycache__/transnorm.cpython-311.pyc differ
diff --git a/dassl/modeling/ops/__pycache__/transnorm.cpython-38.pyc b/dassl/modeling/ops/__pycache__/transnorm.cpython-38.pyc
new file mode 100644
index 0000000..ef259ba
Binary files /dev/null and b/dassl/modeling/ops/__pycache__/transnorm.cpython-38.pyc differ
diff --git a/dassl/modeling/ops/__pycache__/utils.cpython-310.pyc b/dassl/modeling/ops/__pycache__/utils.cpython-310.pyc
new file mode 100644
index 0000000..f31d7c4
Binary files /dev/null and b/dassl/modeling/ops/__pycache__/utils.cpython-310.pyc differ
diff --git a/dassl/modeling/ops/__pycache__/utils.cpython-311.pyc b/dassl/modeling/ops/__pycache__/utils.cpython-311.pyc
new file mode 100644
index 0000000..b3c4680
Binary files /dev/null and b/dassl/modeling/ops/__pycache__/utils.cpython-311.pyc differ
diff --git a/dassl/modeling/ops/__pycache__/utils.cpython-38.pyc b/dassl/modeling/ops/__pycache__/utils.cpython-38.pyc
new file mode 100644
index 0000000..5ab44c1
Binary files /dev/null and b/dassl/modeling/ops/__pycache__/utils.cpython-38.pyc differ
diff --git a/dassl/modeling/ops/attention.py b/dassl/modeling/ops/attention.py
new file mode 100644
index 0000000..16ddcda
--- /dev/null
+++ b/dassl/modeling/ops/attention.py
@@ -0,0 +1,31 @@
+import torch.nn as nn
+from torch.nn import functional as F
+
+__all__ = ["Attention"]
+
+
+class Attention(nn.Module):
+ """Attention from `"Dynamic Domain Generalization" `_.
+ """
+
+ def __init__(
+ self,
+ in_channels: int,
+ out_features: int,
+ squeeze=None,
+ bias: bool = True
+ ):
+ super(Attention, self).__init__()
+ self.squeeze = squeeze if squeeze else in_channels // 16
+ assert self.squeeze > 0
+ self.avg_pool = nn.AdaptiveAvgPool2d(1)
+ self.fc1 = nn.Linear(in_channels, self.squeeze, bias=bias)
+ self.fc2 = nn.Linear(self.squeeze, out_features, bias=bias)
+ self.sf = nn.Softmax(dim=-1)
+
+ def forward(self, x):
+ x = self.avg_pool(x).view(x.shape[:-2])
+ x = self.fc1(x)
+ x = F.relu(x, inplace=True)
+ x = self.fc2(x)
+ return self.sf(x)
diff --git a/dassl/modeling/ops/conv.py b/dassl/modeling/ops/conv.py
new file mode 100644
index 0000000..fcee716
--- /dev/null
+++ b/dassl/modeling/ops/conv.py
@@ -0,0 +1,95 @@
+import torch.nn as nn
+
+from .attention import Attention
+
+__all__ = ["Conv2dDynamic"]
+
+
+class Conv2dDynamic(nn.Module):
+ """Conv2dDynamic from `"Dynamic Domain Generalization" `_.
+ """
+
+ def __init__(
+ self,
+ in_channels: int,
+ out_channels: int,
+ kernel_size: int,
+ stride: int,
+ padding: int,
+ bias: bool = True,
+ squeeze: int = None,
+ attention_in_channels: int = None
+ ) -> None:
+ super(Conv2dDynamic, self).__init__()
+
+ if kernel_size // 2 != padding:
+ # Only when this condition is met, we can ensure that different
+ # kernel_size can obtain feature maps of consistent size.
+ # Let I, K, S, P, O: O = (I + 2P - K) // S + 1, if P = K // 2, then O = (I - K % 2) // S + 1
+ # This means that the output of two different Ks with the same parity can be made the same by adjusting P.
+ raise ValueError("`padding` must be equal to `kernel_size // 2`.")
+ if kernel_size % 2 == 0:
+ raise ValueError(
+ "Kernel_size must be odd now because the templates we used are odd (kernel_size=1)."
+ )
+
+ self.conv = nn.Conv2d(
+ in_channels,
+ out_channels,
+ kernel_size=kernel_size,
+ stride=stride,
+ padding=padding,
+ bias=bias
+ )
+ self.kernel_templates = nn.ModuleDict()
+ self.kernel_templates["conv_nn"] = nn.Conv2d(
+ in_channels,
+ out_channels,
+ kernel_size=kernel_size,
+ stride=stride,
+ padding=padding,
+ groups=min(in_channels, out_channels),
+ bias=bias
+ )
+ self.kernel_templates["conv_11"] = nn.Conv2d(
+ in_channels,
+ out_channels,
+ kernel_size=1,
+ stride=stride,
+ padding=0,
+ bias=bias
+ )
+ self.kernel_templates["conv_n1"] = nn.Conv2d(
+ in_channels,
+ out_channels,
+ kernel_size=(kernel_size, 1),
+ stride=stride,
+ padding=(padding, 0),
+ bias=bias
+ )
+ self.kernel_templates["conv_1n"] = nn.Conv2d(
+ in_channels,
+ out_channels,
+ kernel_size=(1, kernel_size),
+ stride=stride,
+ padding=(0, padding),
+ bias=bias
+ )
+ self.attention = Attention(
+ attention_in_channels if attention_in_channels else in_channels,
+ 4,
+ squeeze,
+ bias=bias
+ )
+
+ def forward(self, x, attention_x=None):
+ attention_x = x if attention_x is None else attention_x
+ y = self.attention(attention_x)
+
+ out = self.conv(x)
+
+ for i, template in enumerate(self.kernel_templates):
+ out += self.kernel_templates[template](x) * y[:,
+ i].view(-1, 1, 1, 1)
+
+ return out
diff --git a/dassl/modeling/ops/cross_entropy.py b/dassl/modeling/ops/cross_entropy.py
new file mode 100644
index 0000000..21723b0
--- /dev/null
+++ b/dassl/modeling/ops/cross_entropy.py
@@ -0,0 +1,30 @@
+import torch
+from torch.nn import functional as F
+
+
+def cross_entropy(input, target, label_smooth=0, reduction="mean"):
+ """Cross entropy loss.
+
+ Args:
+ input (torch.Tensor): logit matrix with shape of (batch, num_classes).
+ target (torch.LongTensor): int label matrix.
+ label_smooth (float, optional): label smoothing hyper-parameter.
+ Default is 0.
+ reduction (str, optional): how the losses for a mini-batch
+ will be aggregated. Default is 'mean'.
+ """
+ num_classes = input.shape[1]
+ log_prob = F.log_softmax(input, dim=1)
+ zeros = torch.zeros(log_prob.size())
+ target = zeros.scatter_(1, target.unsqueeze(1).data.cpu(), 1)
+ target = target.type_as(input)
+ target = (1-label_smooth) * target + label_smooth/num_classes
+ loss = (-target * log_prob).sum(1)
+ if reduction == "mean":
+ return loss.mean()
+ elif reduction == "sum":
+ return loss.sum()
+ elif reduction == "none":
+ return loss
+ else:
+ raise ValueError
diff --git a/dassl/modeling/ops/dsbn.py b/dassl/modeling/ops/dsbn.py
new file mode 100644
index 0000000..e3ee355
--- /dev/null
+++ b/dassl/modeling/ops/dsbn.py
@@ -0,0 +1,45 @@
+import torch.nn as nn
+
+
+class _DSBN(nn.Module):
+ """Domain Specific Batch Normalization.
+
+ Args:
+ num_features (int): number of features.
+ n_domain (int): number of domains.
+ bn_type (str): type of bn. Choices are ['1d', '2d'].
+ """
+
+ def __init__(self, num_features, n_domain, bn_type):
+ super().__init__()
+ if bn_type == "1d":
+ BN = nn.BatchNorm1d
+ elif bn_type == "2d":
+ BN = nn.BatchNorm2d
+ else:
+ raise ValueError
+
+ self.bn = nn.ModuleList(BN(num_features) for _ in range(n_domain))
+
+ self.valid_domain_idxs = list(range(n_domain))
+ self.n_domain = n_domain
+ self.domain_idx = 0
+
+ def select_bn(self, domain_idx=0):
+ assert domain_idx in self.valid_domain_idxs
+ self.domain_idx = domain_idx
+
+ def forward(self, x):
+ return self.bn[self.domain_idx](x)
+
+
+class DSBN1d(_DSBN):
+
+ def __init__(self, num_features, n_domain):
+ super().__init__(num_features, n_domain, "1d")
+
+
+class DSBN2d(_DSBN):
+
+ def __init__(self, num_features, n_domain):
+ super().__init__(num_features, n_domain, "2d")
diff --git a/dassl/modeling/ops/efdmix.py b/dassl/modeling/ops/efdmix.py
new file mode 100644
index 0000000..af58815
--- /dev/null
+++ b/dassl/modeling/ops/efdmix.py
@@ -0,0 +1,118 @@
+import random
+from contextlib import contextmanager
+import torch
+import torch.nn as nn
+
+
+def deactivate_efdmix(m):
+ if type(m) == EFDMix:
+ m.set_activation_status(False)
+
+
+def activate_efdmix(m):
+ if type(m) == EFDMix:
+ m.set_activation_status(True)
+
+
+def random_efdmix(m):
+ if type(m) == EFDMix:
+ m.update_mix_method("random")
+
+
+def crossdomain_efdmix(m):
+ if type(m) == EFDMix:
+ m.update_mix_method("crossdomain")
+
+
+@contextmanager
+def run_without_efdmix(model):
+ # Assume MixStyle was initially activated
+ try:
+ model.apply(deactivate_efdmix)
+ yield
+ finally:
+ model.apply(activate_efdmix)
+
+
+@contextmanager
+def run_with_efdmix(model, mix=None):
+ # Assume MixStyle was initially deactivated
+ if mix == "random":
+ model.apply(random_efdmix)
+
+ elif mix == "crossdomain":
+ model.apply(crossdomain_efdmix)
+
+ try:
+ model.apply(activate_efdmix)
+ yield
+ finally:
+ model.apply(deactivate_efdmix)
+
+
+class EFDMix(nn.Module):
+ """EFDMix.
+
+ Reference:
+ Zhang et al. Exact Feature Distribution Matching for Arbitrary Style Transfer and Domain Generalization. CVPR 2022.
+ """
+
+ def __init__(self, p=0.5, alpha=0.1, eps=1e-6, mix="random"):
+ """
+ Args:
+ p (float): probability of using MixStyle.
+ alpha (float): parameter of the Beta distribution.
+ eps (float): scaling parameter to avoid numerical issues.
+ mix (str): how to mix.
+ """
+ super().__init__()
+ self.p = p
+ self.beta = torch.distributions.Beta(alpha, alpha)
+ self.eps = eps
+ self.alpha = alpha
+ self.mix = mix
+ self._activated = True
+
+ def __repr__(self):
+ return (
+ f"MixStyle(p={self.p}, alpha={self.alpha}, eps={self.eps}, mix={self.mix})"
+ )
+
+ def set_activation_status(self, status=True):
+ self._activated = status
+
+ def update_mix_method(self, mix="random"):
+ self.mix = mix
+
+ def forward(self, x):
+ if not self.training or not self._activated:
+ return x
+
+ if random.random() > self.p:
+ return x
+
+ B, C, W, H = x.size(0), x.size(1), x.size(2), x.size(3)
+ x_view = x.view(B, C, -1)
+ value_x, index_x = torch.sort(x_view) # sort inputs
+ lmda = self.beta.sample((B, 1, 1))
+ lmda = lmda.to(x.device)
+
+ if self.mix == "random":
+ # random shuffle
+ perm = torch.randperm(B)
+
+ elif self.mix == "crossdomain":
+ # split into two halves and swap the order
+ perm = torch.arange(B - 1, -1, -1) # inverse index
+ perm_b, perm_a = perm.chunk(2)
+ perm_b = perm_b[torch.randperm(perm_b.shape[0])]
+ perm_a = perm_a[torch.randperm(perm_a.shape[0])]
+ perm = torch.cat([perm_b, perm_a], 0)
+
+ else:
+ raise NotImplementedError
+
+ inverse_index = index_x.argsort(-1)
+ x_view_copy = value_x[perm].gather(-1, inverse_index)
+ new_x = x_view + (x_view_copy - x_view.detach()) * (1-lmda)
+ return new_x.view(B, C, W, H)
diff --git a/dassl/modeling/ops/mixstyle.py b/dassl/modeling/ops/mixstyle.py
new file mode 100644
index 0000000..34f47a8
--- /dev/null
+++ b/dassl/modeling/ops/mixstyle.py
@@ -0,0 +1,124 @@
+import random
+from contextlib import contextmanager
+import torch
+import torch.nn as nn
+
+
+def deactivate_mixstyle(m):
+ if type(m) == MixStyle:
+ m.set_activation_status(False)
+
+
+def activate_mixstyle(m):
+ if type(m) == MixStyle:
+ m.set_activation_status(True)
+
+
+def random_mixstyle(m):
+ if type(m) == MixStyle:
+ m.update_mix_method("random")
+
+
+def crossdomain_mixstyle(m):
+ if type(m) == MixStyle:
+ m.update_mix_method("crossdomain")
+
+
+@contextmanager
+def run_without_mixstyle(model):
+ # Assume MixStyle was initially activated
+ try:
+ model.apply(deactivate_mixstyle)
+ yield
+ finally:
+ model.apply(activate_mixstyle)
+
+
+@contextmanager
+def run_with_mixstyle(model, mix=None):
+ # Assume MixStyle was initially deactivated
+ if mix == "random":
+ model.apply(random_mixstyle)
+
+ elif mix == "crossdomain":
+ model.apply(crossdomain_mixstyle)
+
+ try:
+ model.apply(activate_mixstyle)
+ yield
+ finally:
+ model.apply(deactivate_mixstyle)
+
+
+class MixStyle(nn.Module):
+ """MixStyle.
+
+ Reference:
+ Zhou et al. Domain Generalization with MixStyle. ICLR 2021.
+ """
+
+ def __init__(self, p=0.5, alpha=0.1, eps=1e-6, mix="random"):
+ """
+ Args:
+ p (float): probability of using MixStyle.
+ alpha (float): parameter of the Beta distribution.
+ eps (float): scaling parameter to avoid numerical issues.
+ mix (str): how to mix.
+ """
+ super().__init__()
+ self.p = p
+ self.beta = torch.distributions.Beta(alpha, alpha)
+ self.eps = eps
+ self.alpha = alpha
+ self.mix = mix
+ self._activated = True
+
+ def __repr__(self):
+ return (
+ f"MixStyle(p={self.p}, alpha={self.alpha}, eps={self.eps}, mix={self.mix})"
+ )
+
+ def set_activation_status(self, status=True):
+ self._activated = status
+
+ def update_mix_method(self, mix="random"):
+ self.mix = mix
+
+ def forward(self, x):
+ if not self.training or not self._activated:
+ return x
+
+ if random.random() > self.p:
+ return x
+
+ B = x.size(0)
+
+ mu = x.mean(dim=[2, 3], keepdim=True)
+ var = x.var(dim=[2, 3], keepdim=True)
+ sig = (var + self.eps).sqrt()
+ mu, sig = mu.detach(), sig.detach()
+ x_normed = (x-mu) / sig
+
+ lmda = self.beta.sample((B, 1, 1, 1))
+ lmda = lmda.to(x.device)
+
+ if self.mix == "random":
+ # random shuffle
+ perm = torch.randperm(B)
+
+ elif self.mix == "crossdomain":
+ # split into two halves and swap the order
+ perm = torch.arange(B - 1, -1, -1) # inverse index
+ perm_b, perm_a = perm.chunk(2)
+ perm_b = perm_b[torch.randperm(perm_b.shape[0])]
+ perm_a = perm_a[torch.randperm(perm_a.shape[0])]
+ perm = torch.cat([perm_b, perm_a], 0)
+
+ else:
+ raise NotImplementedError
+
+ mu2, sig2 = mu[perm], sig[perm]
+ mu_mix = mu*lmda + mu2 * (1-lmda)
+ sig_mix = sig*lmda + sig2 * (1-lmda)
+
+ return x_normed*sig_mix + mu_mix
diff --git a/dassl/modeling/ops/mixup.py b/dassl/modeling/ops/mixup.py
new file mode 100644
index 0000000..5844074
--- /dev/null
+++ b/dassl/modeling/ops/mixup.py
@@ -0,0 +1,23 @@
+import torch
+
+
+def mixup(x1, x2, y1, y2, beta, preserve_order=False):
+ """Mixup.
+
+ Args:
+ x1 (torch.Tensor): data with shape of (b, c, h, w).
+ x2 (torch.Tensor): data with shape of (b, c, h, w).
+ y1 (torch.Tensor): label with shape of (b, n).
+ y2 (torch.Tensor): label with shape of (b, n).
+ beta (float): hyper-parameter for Beta sampling.
+ preserve_order (bool): apply lmda=max(lmda, 1-lmda).
+ Default is False.
+ """
+ lmda = torch.distributions.Beta(beta, beta).sample([x1.shape[0], 1, 1, 1])
+ if preserve_order:
+ lmda = torch.max(lmda, 1 - lmda)
+ lmda = lmda.to(x1.device)
+ xmix = x1*lmda + x2 * (1-lmda)
+ lmda = lmda[:, :, 0, 0]
+ ymix = y1*lmda + y2 * (1-lmda)
+ return xmix, ymix
diff --git a/dassl/modeling/ops/mmd.py b/dassl/modeling/ops/mmd.py
new file mode 100644
index 0000000..a23fa57
--- /dev/null
+++ b/dassl/modeling/ops/mmd.py
@@ -0,0 +1,91 @@
+import torch
+import torch.nn as nn
+from torch.nn import functional as F
+
+
+class MaximumMeanDiscrepancy(nn.Module):
+
+ def __init__(self, kernel_type="rbf", normalize=False):
+ super().__init__()
+ self.kernel_type = kernel_type
+ self.normalize = normalize
+
+ def forward(self, x, y):
+ # x, y: two batches of data with shape (batch, dim)
+ # MMD^2(x, y) = k(x, x') - 2k(x, y) + k(y, y')
+ if self.normalize:
+ x = F.normalize(x, dim=1)
+ y = F.normalize(y, dim=1)
+ if self.kernel_type == "linear":
+ return self.linear_mmd(x, y)
+ elif self.kernel_type == "poly":
+ return self.poly_mmd(x, y)
+ elif self.kernel_type == "rbf":
+ return self.rbf_mmd(x, y)
+ else:
+ raise NotImplementedError
+
+ def linear_mmd(self, x, y):
+ # k(x, y) = x^T y
+ k_xx = self.remove_self_distance(torch.mm(x, x.t()))
+ k_yy = self.remove_self_distance(torch.mm(y, y.t()))
+ k_xy = torch.mm(x, y.t())
+ return k_xx.mean() + k_yy.mean() - 2 * k_xy.mean()
+
+ def poly_mmd(self, x, y, alpha=1.0, c=2.0, d=2):
+ # k(x, y) = (alpha * x^T y + c)^d
+ k_xx = self.remove_self_distance(torch.mm(x, x.t()))
+ k_xx = (alpha*k_xx + c).pow(d)
+ k_yy = self.remove_self_distance(torch.mm(y, y.t()))
+ k_yy = (alpha*k_yy + c).pow(d)
+ k_xy = torch.mm(x, y.t())
+ k_xy = (alpha*k_xy + c).pow(d)
+ return k_xx.mean() + k_yy.mean() - 2 * k_xy.mean()
+
+ def rbf_mmd(self, x, y):
+ # k_xx
+ d_xx = self.euclidean_squared_distance(x, x)
+ d_xx = self.remove_self_distance(d_xx)
+ k_xx = self.rbf_kernel_mixture(d_xx)
+ # k_yy
+ d_yy = self.euclidean_squared_distance(y, y)
+ d_yy = self.remove_self_distance(d_yy)
+ k_yy = self.rbf_kernel_mixture(d_yy)
+ # k_xy
+ d_xy = self.euclidean_squared_distance(x, y)
+ k_xy = self.rbf_kernel_mixture(d_xy)
+ return k_xx.mean() + k_yy.mean() - 2 * k_xy.mean()
+
+ @staticmethod
+ def rbf_kernel_mixture(exponent, sigmas=[1, 5, 10]):
+ K = 0
+ for sigma in sigmas:
+ gamma = 1.0 / (2.0 * sigma**2)
+ K += torch.exp(-gamma * exponent)
+ return K
+
+ @staticmethod
+ def remove_self_distance(distmat):
+ tmp_list = []
+ for i, row in enumerate(distmat):
+ row1 = torch.cat([row[:i], row[i + 1:]])
+ tmp_list.append(row1)
+ return torch.stack(tmp_list)
+
+ @staticmethod
+ def euclidean_squared_distance(x, y):
+ m, n = x.size(0), y.size(0)
+ distmat = (
+ torch.pow(x, 2).sum(dim=1, keepdim=True).expand(m, n) +
+ torch.pow(y, 2).sum(dim=1, keepdim=True).expand(n, m).t()
+ )
+ # distmat.addmm_(1, -2, x, y.t())
+ distmat.addmm_(x, y.t(), beta=1, alpha=-2)
+ return distmat
+
+
+if __name__ == "__main__":
+ mmd = MaximumMeanDiscrepancy(kernel_type="rbf")
+ input1, input2 = torch.rand(3, 100), torch.rand(3, 100)
+ d = mmd(input1, input2)
+ print(d.item())
diff --git a/dassl/modeling/ops/optimal_transport.py b/dassl/modeling/ops/optimal_transport.py
new file mode 100644
index 0000000..128ea96
--- /dev/null
+++ b/dassl/modeling/ops/optimal_transport.py
@@ -0,0 +1,147 @@
+import torch
+import torch.nn as nn
+from torch.nn import functional as F
+
+
+class OptimalTransport(nn.Module):
+
+ @staticmethod
+ def distance(batch1, batch2, dist_metric="cosine"):
+ if dist_metric == "cosine":
+ batch1 = F.normalize(batch1, p=2, dim=1)
+ batch2 = F.normalize(batch2, p=2, dim=1)
+ dist_mat = 1 - torch.mm(batch1, batch2.t())
+ elif dist_metric == "euclidean":
+ m, n = batch1.size(0), batch2.size(0)
+ dist_mat = (
+ torch.pow(batch1, 2).sum(dim=1, keepdim=True).expand(m, n) +
+ torch.pow(batch2, 2).sum(dim=1, keepdim=True).expand(n, m).t()
+ )
+ dist_mat.addmm_(
+ 1, -2, batch1, batch2.t()
+ ) # squared euclidean distance
+ elif dist_metric == "fast_euclidean":
+ batch1 = batch1.unsqueeze(-2)
+ batch2 = batch2.unsqueeze(-3)
+ dist_mat = torch.sum((torch.abs(batch1 - batch2))**2, -1)
+ else:
+ raise ValueError(
+ "Unknown cost function: {}. Expected to "
+ "be one of [cosine | euclidean]".format(dist_metric)
+ )
+ return dist_mat
+
+
+class SinkhornDivergence(OptimalTransport):
+ thre = 1e-3
+
+ def __init__(
+ self,
+ dist_metric="cosine",
+ eps=0.01,
+ max_iter=5,
+ bp_to_sinkhorn=False
+ ):
+ super().__init__()
+ self.dist_metric = dist_metric
+ self.eps = eps
+ self.max_iter = max_iter
+ self.bp_to_sinkhorn = bp_to_sinkhorn
+
+ def forward(self, x, y):
+ # x, y: two batches of data with shape (batch, dim)
+ W_xy = self.transport_cost(x, y)
+ W_xx = self.transport_cost(x, x)
+ W_yy = self.transport_cost(y, y)
+ return 2*W_xy - W_xx - W_yy
+
+ def transport_cost(self, x, y, return_pi=False):
+ C = self.distance(x, y, dist_metric=self.dist_metric)
+ pi = self.sinkhorn_iterate(C, self.eps, self.max_iter, self.thre)
+ if not self.bp_to_sinkhorn:
+ pi = pi.detach()
+ cost = torch.sum(pi * C)
+ if return_pi:
+ return cost, pi
+ return cost
+
+ @staticmethod
+ def sinkhorn_iterate(C, eps, max_iter, thre):
+ nx, ny = C.shape
+ mu = torch.ones(nx, dtype=C.dtype, device=C.device) * (1.0/nx)
+ nu = torch.ones(ny, dtype=C.dtype, device=C.device) * (1.0/ny)
+ u = torch.zeros_like(mu)
+ v = torch.zeros_like(nu)
+
+ def M(_C, _u, _v):
+ """Modified cost for logarithmic updates.
+ Eq: M_{ij} = (-c_{ij} + u_i + v_j) / epsilon
+ """
+ return (-_C + _u.unsqueeze(-1) + _v.unsqueeze(-2)) / eps
+
+ real_iter = 0 # check if algorithm terminates before max_iter
+ # Sinkhorn iterations
+ for i in range(max_iter):
+ u0 = u
+ u = eps * (
+ torch.log(mu + 1e-8) - torch.logsumexp(M(C, u, v), dim=1)
+ ) + u
+ v = (
+ eps * (
+ torch.log(nu + 1e-8) -
+ torch.logsumexp(M(C, u, v).permute(1, 0), dim=1)
+ ) + v
+ )
+ err = (u - u0).abs().sum()
+ real_iter += 1
+ if err.item() < thre:
+ break
+ # Transport plan pi = diag(a)*K*diag(b)
+ return torch.exp(M(C, u, v))
+
+
+class MinibatchEnergyDistance(SinkhornDivergence):
+
+ def __init__(
+ self,
+ dist_metric="cosine",
+ eps=0.01,
+ max_iter=5,
+ bp_to_sinkhorn=False
+ ):
+ super().__init__(
+ dist_metric=dist_metric,
+ eps=eps,
+ max_iter=max_iter,
+ bp_to_sinkhorn=bp_to_sinkhorn,
+ )
+
+ def forward(self, x, y):
+ x1, x2 = torch.split(x, x.size(0) // 2, dim=0)
+ y1, y2 = torch.split(y, y.size(0) // 2, dim=0)
+ cost = 0
+ cost += self.transport_cost(x1, y1)
+ cost += self.transport_cost(x1, y2)
+ cost += self.transport_cost(x2, y1)
+ cost += self.transport_cost(x2, y2)
+ cost -= 2 * self.transport_cost(x1, x2)
+ cost -= 2 * self.transport_cost(y1, y2)
+ return cost
+
+
+if __name__ == "__main__":
+ # example: https://dfdazac.github.io/sinkhorn.html
+ import numpy as np
+
+ n_points = 5
+ a = np.array([[i, 0] for i in range(n_points)])
+ b = np.array([[i, 1] for i in range(n_points)])
+ x = torch.tensor(a, dtype=torch.float)
+ y = torch.tensor(b, dtype=torch.float)
+ sinkhorn = SinkhornDivergence(
+ dist_metric="euclidean", eps=0.01, max_iter=5
+ )
+ dist, pi = sinkhorn.transport_cost(x, y, True)
+ import pdb
+
+ pdb.set_trace()
diff --git a/dassl/modeling/ops/reverse_grad.py b/dassl/modeling/ops/reverse_grad.py
new file mode 100644
index 0000000..34bab9d
--- /dev/null
+++ b/dassl/modeling/ops/reverse_grad.py
@@ -0,0 +1,34 @@
+import torch.nn as nn
+from torch.autograd import Function
+
+
+class _ReverseGrad(Function):
+
+ @staticmethod
+ def forward(ctx, input, grad_scaling):
+ ctx.grad_scaling = grad_scaling
+ return input.view_as(input)
+
+ @staticmethod
+ def backward(ctx, grad_output):
+ grad_scaling = ctx.grad_scaling
+ return -grad_scaling * grad_output, None
+
+
+reverse_grad = _ReverseGrad.apply
+
+
+class ReverseGrad(nn.Module):
+ """Gradient reversal layer.
+
+ It acts as an identity layer in the forward,
+ but reverses the sign of the gradient in
+ the backward.
+ """
+
+ def forward(self, x, grad_scaling=1.0):
+ assert (grad_scaling >=
+ 0), "grad_scaling must be non-negative, " "but got {}".format(
+ grad_scaling
+ )
+ return reverse_grad(x, grad_scaling)
diff --git a/dassl/modeling/ops/sequential2.py b/dassl/modeling/ops/sequential2.py
new file mode 100644
index 0000000..47a8383
--- /dev/null
+++ b/dassl/modeling/ops/sequential2.py
@@ -0,0 +1,15 @@
+import torch.nn as nn
+
+
+class Sequential2(nn.Sequential):
+ """An alternative sequential container to nn.Sequential,
+ which accepts an arbitrary number of input arguments.
+ """
+
+ def forward(self, *inputs):
+ for module in self._modules.values():
+ if isinstance(inputs, tuple):
+ inputs = module(*inputs)
+ else:
+ inputs = module(inputs)
+ return inputs
diff --git a/dassl/modeling/ops/transnorm.py b/dassl/modeling/ops/transnorm.py
new file mode 100644
index 0000000..453db77
--- /dev/null
+++ b/dassl/modeling/ops/transnorm.py
@@ -0,0 +1,138 @@
+import torch
+import torch.nn as nn
+
+
+class _TransNorm(nn.Module):
+ """Transferable normalization.
+
+ Reference:
+ - Wang et al. Transferable Normalization: Towards Improving
+ Transferability of Deep Neural Networks. NeurIPS 2019.
+
+ Args:
+ num_features (int): number of features.
+ eps (float): epsilon.
+ momentum (float): value for updating running_mean and running_var.
+ adaptive_alpha (bool): apply domain adaptive alpha.
+ """
+
+ def __init__(
+ self, num_features, eps=1e-5, momentum=0.1, adaptive_alpha=True
+ ):
+ super().__init__()
+ self.num_features = num_features
+ self.eps = eps
+ self.momentum = momentum
+ self.adaptive_alpha = adaptive_alpha
+
+ self.register_buffer("running_mean_s", torch.zeros(num_features))
+ self.register_buffer("running_var_s", torch.ones(num_features))
+ self.register_buffer("running_mean_t", torch.zeros(num_features))
+ self.register_buffer("running_var_t", torch.ones(num_features))
+
+ self.weight = nn.Parameter(torch.ones(num_features))
+ self.bias = nn.Parameter(torch.zeros(num_features))
+
+ def resnet_running_stats(self):
+ self.running_mean_s.zero_()
+ self.running_var_s.fill_(1)
+ self.running_mean_t.zero_()
+ self.running_var_t.fill_(1)
+
+ def reset_parameters(self):
+ nn.init.ones_(self.weight)
+ nn.init.zeros_(self.bias)
+
+ def _check_input(self, x):
+ raise NotImplementedError
+
+ def _compute_alpha(self, mean_s, var_s, mean_t, var_t):
+ C = self.num_features
+ ratio_s = mean_s / (var_s + self.eps).sqrt()
+ ratio_t = mean_t / (var_t + self.eps).sqrt()
+ dist = (ratio_s - ratio_t).abs()
+ dist_inv = 1 / (1+dist)
+ return C * dist_inv / dist_inv.sum()
+
+ def forward(self, input):
+ self._check_input(input)
+ C = self.num_features
+ if input.dim() == 2:
+ new_shape = (1, C)
+ elif input.dim() == 4:
+ new_shape = (1, C, 1, 1)
+ else:
+ raise ValueError
+
+ weight = self.weight.view(*new_shape)
+ bias = self.bias.view(*new_shape)
+
+ if not self.training:
+ mean_t = self.running_mean_t.view(*new_shape)
+ var_t = self.running_var_t.view(*new_shape)
+ output = (input-mean_t) / (var_t + self.eps).sqrt()
+ output = output*weight + bias
+
+ if self.adaptive_alpha:
+ mean_s = self.running_mean_s.view(*new_shape)
+ var_s = self.running_var_s.view(*new_shape)
+ alpha = self._compute_alpha(mean_s, var_s, mean_t, var_t)
+ alpha = alpha.reshape(*new_shape)
+ output = (1 + alpha.detach()) * output
+
+ return output
+
+ input_s, input_t = torch.split(input, input.shape[0] // 2, dim=0)
+
+ x_s = input_s.transpose(0, 1).reshape(C, -1)
+ mean_s = x_s.mean(1)
+ var_s = x_s.var(1)
+ self.running_mean_s.mul_(self.momentum)
+ self.running_mean_s.add_((1 - self.momentum) * mean_s.data)
+ self.running_var_s.mul_(self.momentum)
+ self.running_var_s.add_((1 - self.momentum) * var_s.data)
+ mean_s = mean_s.reshape(*new_shape)
+ var_s = var_s.reshape(*new_shape)
+ output_s = (input_s-mean_s) / (var_s + self.eps).sqrt()
+ output_s = output_s*weight + bias
+
+ x_t = input_t.transpose(0, 1).reshape(C, -1)
+ mean_t = x_t.mean(1)
+ var_t = x_t.var(1)
+ self.running_mean_t.mul_(self.momentum)
+ self.running_mean_t.add_((1 - self.momentum) * mean_t.data)
+ self.running_var_t.mul_(self.momentum)
+ self.running_var_t.add_((1 - self.momentum) * var_t.data)
+ mean_t = mean_t.reshape(*new_shape)
+ var_t = var_t.reshape(*new_shape)
+ output_t = (input_t-mean_t) / (var_t + self.eps).sqrt()
+ output_t = output_t*weight + bias
+
+ output = torch.cat([output_s, output_t], 0)
+
+ if self.adaptive_alpha:
+ alpha = self._compute_alpha(mean_s, var_s, mean_t, var_t)
+ alpha = alpha.reshape(*new_shape)
+ output = (1 + alpha.detach()) * output
+
+ return output
+
+
+class TransNorm1d(_TransNorm):
+
+ def _check_input(self, x):
+ if x.dim() != 2:
+ raise ValueError(
+ "Expected the input to be 2-D, "
+ "but got {}-D".format(x.dim())
+ )
+
+
+class TransNorm2d(_TransNorm):
+
+ def _check_input(self, x):
+ if x.dim() != 4:
+ raise ValueError(
+ "Expected the input to be 4-D, "
+ "but got {}-D".format(x.dim())
+ )
diff --git a/dassl/modeling/ops/utils.py b/dassl/modeling/ops/utils.py
new file mode 100644
index 0000000..6bfcc89
--- /dev/null
+++ b/dassl/modeling/ops/utils.py
@@ -0,0 +1,77 @@
+import numpy as np
+import torch
+
+
+def sharpen_prob(p, temperature=2):
+ """Sharpening probability with a temperature.
+
+ Args:
+ p (torch.Tensor): probability matrix (batch_size, n_classes)
+ temperature (float): temperature.
+ """
+ p = p.pow(temperature)
+ return p / p.sum(1, keepdim=True)
+
+
+def reverse_index(data, label):
+ """Reverse order."""
+ inv_idx = torch.arange(data.size(0) - 1, -1, -1).long()
+ return data[inv_idx], label[inv_idx]
+
+
+def shuffle_index(data, label):
+ """Shuffle order."""
+ rnd_idx = torch.randperm(data.shape[0])
+ return data[rnd_idx], label[rnd_idx]
+
+
+def create_onehot(label, num_classes):
+ """Create one-hot tensor.
+
+ We suggest using nn.functional.one_hot.
+
+ Args:
+ label (torch.Tensor): 1-D tensor.
+ num_classes (int): number of classes.
+ """
+ onehot = torch.zeros(label.shape[0], num_classes)
+ onehot = onehot.scatter(1, label.unsqueeze(1).data.cpu(), 1)
+ onehot = onehot.to(label.device)
+ return onehot
+
+
+def sigmoid_rampup(current, rampup_length):
+ """Exponential rampup.
+
+ Args:
+ current (int): current step.
+ rampup_length (int): maximum step.
+ """
+ assert rampup_length > 0
+ current = np.clip(current, 0.0, rampup_length)
+ phase = 1.0 - current/rampup_length
+ return float(np.exp(-5.0 * phase * phase))
+
+
+def linear_rampup(current, rampup_length):
+ """Linear rampup.
+
+ Args:
+ current (int): current step.
+ rampup_length (int): maximum step.
+ """
+ assert rampup_length > 0
+ ratio = np.clip(current / rampup_length, 0.0, 1.0)
+ return float(ratio)
+
+
+def ema_model_update(model, ema_model, alpha):
+ """Exponential moving average of model parameters.
+
+ Args:
+ model (nn.Module): model being trained.
+ ema_model (nn.Module): ema of the model.
+ alpha (float): ema decay rate.
+ """
+ for ema_param, param in zip(ema_model.parameters(), model.parameters()):
+ ema_param.data.mul_(alpha).add_(param.data, alpha=1 - alpha)
diff --git a/dassl/optim/__init__.py b/dassl/optim/__init__.py
new file mode 100644
index 0000000..e7ef4c0
--- /dev/null
+++ b/dassl/optim/__init__.py
@@ -0,0 +1,2 @@
+from .optimizer import build_optimizer
+from .lr_scheduler import build_lr_scheduler
diff --git a/dassl/optim/__pycache__/__init__.cpython-310.pyc b/dassl/optim/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000..75e14a8
Binary files /dev/null and b/dassl/optim/__pycache__/__init__.cpython-310.pyc differ
diff --git a/dassl/optim/__pycache__/__init__.cpython-311.pyc b/dassl/optim/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000..a78c0cc
Binary files /dev/null and b/dassl/optim/__pycache__/__init__.cpython-311.pyc differ
diff --git a/dassl/optim/__pycache__/__init__.cpython-38.pyc b/dassl/optim/__pycache__/__init__.cpython-38.pyc
new file mode 100644
index 0000000..8eab8f0
Binary files /dev/null and b/dassl/optim/__pycache__/__init__.cpython-38.pyc differ
diff --git a/dassl/optim/__pycache__/lr_scheduler.cpython-310.pyc b/dassl/optim/__pycache__/lr_scheduler.cpython-310.pyc
new file mode 100644
index 0000000..8468b04
Binary files /dev/null and b/dassl/optim/__pycache__/lr_scheduler.cpython-310.pyc differ
diff --git a/dassl/optim/__pycache__/lr_scheduler.cpython-311.pyc b/dassl/optim/__pycache__/lr_scheduler.cpython-311.pyc
new file mode 100644
index 0000000..54edc67
Binary files /dev/null and b/dassl/optim/__pycache__/lr_scheduler.cpython-311.pyc differ
diff --git a/dassl/optim/__pycache__/lr_scheduler.cpython-38.pyc b/dassl/optim/__pycache__/lr_scheduler.cpython-38.pyc
new file mode 100644
index 0000000..40822de
Binary files /dev/null and b/dassl/optim/__pycache__/lr_scheduler.cpython-38.pyc differ
diff --git a/dassl/optim/__pycache__/optimizer.cpython-310.pyc b/dassl/optim/__pycache__/optimizer.cpython-310.pyc
new file mode 100644
index 0000000..a453a57
Binary files /dev/null and b/dassl/optim/__pycache__/optimizer.cpython-310.pyc differ
diff --git a/dassl/optim/__pycache__/optimizer.cpython-311.pyc b/dassl/optim/__pycache__/optimizer.cpython-311.pyc
new file mode 100644
index 0000000..80f6994
Binary files /dev/null and b/dassl/optim/__pycache__/optimizer.cpython-311.pyc differ
diff --git a/dassl/optim/__pycache__/optimizer.cpython-38.pyc b/dassl/optim/__pycache__/optimizer.cpython-38.pyc
new file mode 100644
index 0000000..a0ef86d
Binary files /dev/null and b/dassl/optim/__pycache__/optimizer.cpython-38.pyc differ
diff --git a/dassl/optim/__pycache__/radam.cpython-310.pyc b/dassl/optim/__pycache__/radam.cpython-310.pyc
new file mode 100644
index 0000000..b19d1c7
Binary files /dev/null and b/dassl/optim/__pycache__/radam.cpython-310.pyc differ
diff --git a/dassl/optim/__pycache__/radam.cpython-311.pyc b/dassl/optim/__pycache__/radam.cpython-311.pyc
new file mode 100644
index 0000000..0b5dd24
Binary files /dev/null and b/dassl/optim/__pycache__/radam.cpython-311.pyc differ
diff --git a/dassl/optim/__pycache__/radam.cpython-38.pyc b/dassl/optim/__pycache__/radam.cpython-38.pyc
new file mode 100644
index 0000000..3c2f162
Binary files /dev/null and b/dassl/optim/__pycache__/radam.cpython-38.pyc differ
diff --git a/dassl/optim/lr_scheduler.py b/dassl/optim/lr_scheduler.py
new file mode 100644
index 0000000..48d5885
--- /dev/null
+++ b/dassl/optim/lr_scheduler.py
@@ -0,0 +1,152 @@
+"""
+Modified from https://github.com/KaiyangZhou/deep-person-reid
+"""
+import torch
+from torch.optim.lr_scheduler import _LRScheduler
+
+AVAI_SCHEDS = ["single_step", "multi_step", "cosine"]
+
+
+class _BaseWarmupScheduler(_LRScheduler):
+
+ def __init__(
+ self,
+ optimizer,
+ successor,
+ warmup_epoch,
+ last_epoch=-1,
+ verbose=False
+ ):
+ self.successor = successor
+ self.warmup_epoch = warmup_epoch
+ super().__init__(optimizer, last_epoch, verbose)
+
+ def get_lr(self):
+ raise NotImplementedError
+
+ def step(self, epoch=None):
+ if self.last_epoch >= self.warmup_epoch:
+ self.successor.step(epoch)
+ self._last_lr = self.successor.get_last_lr()
+ else:
+ super().step(epoch)
+
+
+class ConstantWarmupScheduler(_BaseWarmupScheduler):
+
+ def __init__(
+ self,
+ optimizer,
+ successor,
+ warmup_epoch,
+ cons_lr,
+ last_epoch=-1,
+ verbose=False
+ ):
+ self.cons_lr = cons_lr
+ super().__init__(
+ optimizer, successor, warmup_epoch, last_epoch, verbose
+ )
+
+ def get_lr(self):
+ if self.last_epoch >= self.warmup_epoch:
+ return self.successor.get_last_lr()
+ return [self.cons_lr for _ in self.base_lrs]
+
+
+class LinearWarmupScheduler(_BaseWarmupScheduler):
+
+ def __init__(
+ self,
+ optimizer,
+ successor,
+ warmup_epoch,
+ min_lr,
+ last_epoch=-1,
+ verbose=False
+ ):
+ self.min_lr = min_lr
+ super().__init__(
+ optimizer, successor, warmup_epoch, last_epoch, verbose
+ )
+
+ def get_lr(self):
+ if self.last_epoch >= self.warmup_epoch:
+ return self.successor.get_last_lr()
+ if self.last_epoch == 0:
+ return [self.min_lr for _ in self.base_lrs]
+ return [
+ lr * self.last_epoch / self.warmup_epoch for lr in self.base_lrs
+ ]
+
+
+def build_lr_scheduler(optimizer, optim_cfg):
+ """A function wrapper for building a learning rate scheduler.
+
+ Args:
+ optimizer (Optimizer): an Optimizer.
+ optim_cfg (CfgNode): optimization config.
+ """
+ lr_scheduler = optim_cfg.LR_SCHEDULER
+ stepsize = optim_cfg.STEPSIZE
+ gamma = optim_cfg.GAMMA
+ max_epoch = optim_cfg.MAX_EPOCH
+
+ if lr_scheduler not in AVAI_SCHEDS:
+ raise ValueError(
+ f"scheduler must be one of {AVAI_SCHEDS}, but got {lr_scheduler}"
+ )
+
+ if lr_scheduler == "single_step":
+ if isinstance(stepsize, (list, tuple)):
+ stepsize = stepsize[-1]
+
+ if not isinstance(stepsize, int):
+ raise TypeError(
+ "For single_step lr_scheduler, stepsize must "
+ f"be an integer, but got {type(stepsize)}"
+ )
+
+ if stepsize <= 0:
+ stepsize = max_epoch
+
+ scheduler = torch.optim.lr_scheduler.StepLR(
+ optimizer, step_size=stepsize, gamma=gamma
+ )
+
+ elif lr_scheduler == "multi_step":
+ if not isinstance(stepsize, (list, tuple)):
+ raise TypeError(
+ "For multi_step lr_scheduler, stepsize must "
+ f"be a list, but got {type(stepsize)}"
+ )
+
+ scheduler = torch.optim.lr_scheduler.MultiStepLR(
+ optimizer, milestones=stepsize, gamma=gamma
+ )
+
+ elif lr_scheduler == "cosine":
+ scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(
+ optimizer, float(max_epoch)
+ )
+
+ if optim_cfg.WARMUP_EPOCH > 0:
+ if not optim_cfg.WARMUP_RECOUNT:
+ scheduler.last_epoch = optim_cfg.WARMUP_EPOCH
+
+ if optim_cfg.WARMUP_TYPE == "constant":
+ scheduler = ConstantWarmupScheduler(
+ optimizer, scheduler, optim_cfg.WARMUP_EPOCH,
+ optim_cfg.WARMUP_CONS_LR
+ )
+
+ elif optim_cfg.WARMUP_TYPE == "linear":
+ scheduler = LinearWarmupScheduler(
+ optimizer, scheduler, optim_cfg.WARMUP_EPOCH,
+ optim_cfg.WARMUP_MIN_LR
+ )
+
+ else:
+ raise ValueError
+
+ return scheduler
diff --git a/dassl/optim/optimizer.py b/dassl/optim/optimizer.py
new file mode 100644
index 0000000..5ebcd62
--- /dev/null
+++ b/dassl/optim/optimizer.py
@@ -0,0 +1,142 @@
+"""
+Modified from https://github.com/KaiyangZhou/deep-person-reid
+"""
+import warnings
+import torch
+import torch.nn as nn
+
+from .radam import RAdam
+
+AVAI_OPTIMS = ["adam", "amsgrad", "sgd", "rmsprop", "radam", "adamw"]
+
+
+def build_optimizer(model, optim_cfg, param_groups=None):
+ """A function wrapper for building an optimizer.
+
+ Args:
+ model (nn.Module or iterable): model.
+ optim_cfg (CfgNode): optimization config.
+ param_groups: If provided, directly optimize param_groups and abandon model
+ """
+ optim = optim_cfg.NAME
+ lr = optim_cfg.LR
+ weight_decay = optim_cfg.WEIGHT_DECAY
+ momentum = optim_cfg.MOMENTUM
+ sgd_dampening = optim_cfg.SGD_DAMPNING
+ sgd_nesterov = optim_cfg.SGD_NESTEROV
+ rmsprop_alpha = optim_cfg.RMSPROP_ALPHA
+ adam_beta1 = optim_cfg.ADAM_BETA1
+ adam_beta2 = optim_cfg.ADAM_BETA2
+ staged_lr = optim_cfg.STAGED_LR
+ new_layers = optim_cfg.NEW_LAYERS
+ base_lr_mult = optim_cfg.BASE_LR_MULT
+
+ if optim not in AVAI_OPTIMS:
+ raise ValueError(
+ f"optim must be one of {AVAI_OPTIMS}, but got {optim}"
+ )
+
+ if param_groups is not None and staged_lr:
+ warnings.warn(
+ "staged_lr will be ignored, if you need to use staged_lr, "
+ "please bind it with param_groups yourself."
+ )
+
+ if param_groups is None:
+ if staged_lr:
+ if not isinstance(model, nn.Module):
+ raise TypeError(
+ "When staged_lr is True, model given to "
+ "build_optimizer() must be an instance of nn.Module"
+ )
+
+ if isinstance(model, nn.DataParallel):
+ model = model.module
+
+ if isinstance(new_layers, str):
+ if new_layers is None:
+ warnings.warn("new_layers is empty (staged_lr is useless)")
+ new_layers = [new_layers]
+
+ base_params = []
+ base_layers = []
+ new_params = []
+
+ for name, module in model.named_children():
+ if name in new_layers:
+ new_params += [p for p in module.parameters()]
+ else:
+ base_params += [p for p in module.parameters()]
+ base_layers.append(name)
+
+ param_groups = [
+ {
+ "params": base_params,
+ "lr": lr * base_lr_mult
+ },
+ {
+ "params": new_params
+ },
+ ]
+
+ else:
+ if isinstance(model, nn.Module):
+ param_groups = model.parameters()
+ else:
+ param_groups = model
+
+ if optim == "adam":
+ optimizer = torch.optim.Adam(
+ param_groups,
+ lr=lr,
+ weight_decay=weight_decay,
+ betas=(adam_beta1, adam_beta2),
+ )
+
+ elif optim == "amsgrad":
+ optimizer = torch.optim.Adam(
+ param_groups,
+ lr=lr,
+ weight_decay=weight_decay,
+ betas=(adam_beta1, adam_beta2),
+ amsgrad=True,
+ )
+
+ elif optim == "sgd":
+ optimizer = torch.optim.SGD(
+ param_groups,
+ lr=lr,
+ momentum=momentum,
+ weight_decay=weight_decay,
+ dampening=sgd_dampening,
+ nesterov=sgd_nesterov,
+ )
+
+ elif optim == "rmsprop":
+ optimizer = torch.optim.RMSprop(
+ param_groups,
+ lr=lr,
+ momentum=momentum,
+ weight_decay=weight_decay,
+ alpha=rmsprop_alpha,
+ )
+
+ elif optim == "radam":
+ optimizer = RAdam(
+ param_groups,
+ lr=lr,
+ weight_decay=weight_decay,
+ betas=(adam_beta1, adam_beta2),
+ )
+
+ elif optim == "adamw":
+ optimizer = torch.optim.AdamW(
+ param_groups,
+ lr=lr,
+ weight_decay=weight_decay,
+ betas=(adam_beta1, adam_beta2),
+ )
+ else:
+ raise NotImplementedError(f"Optimizer {optim} not implemented yet!")
+
+ return optimizer
diff --git a/dassl/optim/radam.py b/dassl/optim/radam.py
new file mode 100644
index 0000000..f4c1989
--- /dev/null
+++ b/dassl/optim/radam.py
@@ -0,0 +1,332 @@
+"""
+Imported from: https://github.com/LiyuanLucasLiu/RAdam
+
+https://arxiv.org/abs/1908.03265
+
+@article{liu2019radam,
+ title={On the Variance of the Adaptive Learning Rate and Beyond},
+ author={Liu, Liyuan and Jiang, Haoming and He, Pengcheng and Chen, Weizhu and Liu, Xiaodong and Gao, Jianfeng and Han, Jiawei},
+ journal={arXiv preprint arXiv:1908.03265},
+ year={2019}
+}
+"""
+import math
+import torch
+from torch.optim.optimizer import Optimizer
+
+
+class RAdam(Optimizer):
+
+ def __init__(
+ self,
+ params,
+ lr=1e-3,
+ betas=(0.9, 0.999),
+ eps=1e-8,
+ weight_decay=0,
+ degenerated_to_sgd=True,
+ ):
+ if not 0.0 <= lr:
+ raise ValueError("Invalid learning rate: {}".format(lr))
+ if not 0.0 <= eps:
+ raise ValueError("Invalid epsilon value: {}".format(eps))
+ if not 0.0 <= betas[0] < 1.0:
+ raise ValueError(
+ "Invalid beta parameter at index 0: {}".format(betas[0])
+ )
+ if not 0.0 <= betas[1] < 1.0:
+ raise ValueError(
+ "Invalid beta parameter at index 1: {}".format(betas[1])
+ )
+
+ self.degenerated_to_sgd = degenerated_to_sgd
+ defaults = dict(lr=lr, betas=betas, eps=eps, weight_decay=weight_decay)
+ self.buffer = [[None, None, None] for ind in range(10)]
+ super(RAdam, self).__init__(params, defaults)
+
+ def __setstate__(self, state):
+ super(RAdam, self).__setstate__(state)
+
+ def step(self, closure=None):
+
+ loss = None
+ if closure is not None:
+ loss = closure()
+
+ for group in self.param_groups:
+
+ for p in group["params"]:
+ if p.grad is None:
+ continue
+ grad = p.grad.data.float()
+ if grad.is_sparse:
+ raise RuntimeError(
+ "RAdam does not support sparse gradients"
+ )
+
+ p_data_fp32 = p.data.float()
+
+ state = self.state[p]
+
+ if len(state) == 0:
+ state["step"] = 0
+ state["exp_avg"] = torch.zeros_like(p_data_fp32)
+ state["exp_avg_sq"] = torch.zeros_like(p_data_fp32)
+ else:
+ state["exp_avg"] = state["exp_avg"].type_as(p_data_fp32)
+ state["exp_avg_sq"] = state["exp_avg_sq"].type_as(
+ p_data_fp32
+ )
+
+ exp_avg, exp_avg_sq = state["exp_avg"], state["exp_avg_sq"]
+ beta1, beta2 = group["betas"]
+
+ exp_avg_sq.mul_(beta2).addcmul_(1 - beta2, grad, grad)
+ exp_avg.mul_(beta1).add_(1 - beta1, grad)
+
+ state["step"] += 1
+ buffered = self.buffer[int(state["step"] % 10)]
+ if state["step"] == buffered[0]:
+ N_sma, step_size = buffered[1], buffered[2]
+ else:
+ buffered[0] = state["step"]
+ beta2_t = beta2**state["step"]
+ N_sma_max = 2 / (1-beta2) - 1
+ N_sma = N_sma_max - 2 * state["step"
+ ] * beta2_t / (1-beta2_t)
+ buffered[1] = N_sma
+
+ # more conservative since it's an approximated value
+ if N_sma >= 5:
+ step_size = math.sqrt(
+ (1-beta2_t) * (N_sma-4) / (N_sma_max-4) *
+ (N_sma-2) / N_sma * N_sma_max / (N_sma_max-2)
+ ) / (1 - beta1**state["step"])
+ elif self.degenerated_to_sgd:
+ step_size = 1.0 / (1 - beta1**state["step"])
+ else:
+ step_size = -1
+ buffered[2] = step_size
+
+ # more conservative since it's an approximated value
+ if N_sma >= 5:
+ if group["weight_decay"] != 0:
+ p_data_fp32.add_(
+ -group["weight_decay"] * group["lr"], p_data_fp32
+ )
+ denom = exp_avg_sq.sqrt().add_(group["eps"])
+ p_data_fp32.addcdiv_(
+ -step_size * group["lr"], exp_avg, denom
+ )
+ p.data.copy_(p_data_fp32)
+ elif step_size > 0:
+ if group["weight_decay"] != 0:
+ p_data_fp32.add_(
+ -group["weight_decay"] * group["lr"], p_data_fp32
+ )
+ p_data_fp32.add_(-step_size * group["lr"], exp_avg)
+ p.data.copy_(p_data_fp32)
+
+ return loss
+
+
+class PlainRAdam(Optimizer):
+
+ def __init__(
+ self,
+ params,
+ lr=1e-3,
+ betas=(0.9, 0.999),
+ eps=1e-8,
+ weight_decay=0,
+ degenerated_to_sgd=True,
+ ):
+ if not 0.0 <= lr:
+ raise ValueError("Invalid learning rate: {}".format(lr))
+ if not 0.0 <= eps:
+ raise ValueError("Invalid epsilon value: {}".format(eps))
+ if not 0.0 <= betas[0] < 1.0:
+ raise ValueError(
+ "Invalid beta parameter at index 0: {}".format(betas[0])
+ )
+ if not 0.0 <= betas[1] < 1.0:
+ raise ValueError(
+ "Invalid beta parameter at index 1: {}".format(betas[1])
+ )
+
+ self.degenerated_to_sgd = degenerated_to_sgd
+ defaults = dict(lr=lr, betas=betas, eps=eps, weight_decay=weight_decay)
+
+ super(PlainRAdam, self).__init__(params, defaults)
+
+ def __setstate__(self, state):
+ super(PlainRAdam, self).__setstate__(state)
+
+ def step(self, closure=None):
+
+ loss = None
+ if closure is not None:
+ loss = closure()
+
+ for group in self.param_groups:
+
+ for p in group["params"]:
+ if p.grad is None:
+ continue
+ grad = p.grad.data.float()
+ if grad.is_sparse:
+ raise RuntimeError(
+ "RAdam does not support sparse gradients"
+ )
+
+ p_data_fp32 = p.data.float()
+
+ state = self.state[p]
+
+ if len(state) == 0:
+ state["step"] = 0
+ state["exp_avg"] = torch.zeros_like(p_data_fp32)
+ state["exp_avg_sq"] = torch.zeros_like(p_data_fp32)
+ else:
+ state["exp_avg"] = state["exp_avg"].type_as(p_data_fp32)
+ state["exp_avg_sq"] = state["exp_avg_sq"].type_as(
+ p_data_fp32
+ )
+
+ exp_avg, exp_avg_sq = state["exp_avg"], state["exp_avg_sq"]
+ beta1, beta2 = group["betas"]
+
+ exp_avg_sq.mul_(beta2).addcmul_(1 - beta2, grad, grad)
+ exp_avg.mul_(beta1).add_(1 - beta1, grad)
+
+ state["step"] += 1
+ beta2_t = beta2**state["step"]
+ N_sma_max = 2 / (1-beta2) - 1
+ N_sma = N_sma_max - 2 * state["step"] * beta2_t / (1-beta2_t)
+
+ # more conservative since it's an approximated value
+ if N_sma >= 5:
+ if group["weight_decay"] != 0:
+ p_data_fp32.add_(
+ -group["weight_decay"] * group["lr"], p_data_fp32
+ )
+ step_size = (
+ group["lr"] * math.sqrt(
+ (1-beta2_t) * (N_sma-4) / (N_sma_max-4) *
+ (N_sma-2) / N_sma * N_sma_max / (N_sma_max-2)
+ ) / (1 - beta1**state["step"])
+ )
+ denom = exp_avg_sq.sqrt().add_(group["eps"])
+ p_data_fp32.addcdiv_(-step_size, exp_avg, denom)
+ p.data.copy_(p_data_fp32)
+ elif self.degenerated_to_sgd:
+ if group["weight_decay"] != 0:
+ p_data_fp32.add_(
+ -group["weight_decay"] * group["lr"], p_data_fp32
+ )
+ step_size = group["lr"] / (1 - beta1**state["step"])
+ p_data_fp32.add_(-step_size, exp_avg)
+ p.data.copy_(p_data_fp32)
+
+ return loss
+
+
+class AdamW(Optimizer):
+
+ def __init__(
+ self,
+ params,
+ lr=1e-3,
+ betas=(0.9, 0.999),
+ eps=1e-8,
+ weight_decay=0,
+ warmup=0
+ ):
+ if not 0.0 <= lr:
+ raise ValueError("Invalid learning rate: {}".format(lr))
+ if not 0.0 <= eps:
+ raise ValueError("Invalid epsilon value: {}".format(eps))
+ if not 0.0 <= betas[0] < 1.0:
+ raise ValueError(
+ "Invalid beta parameter at index 0: {}".format(betas[0])
+ )
+ if not 0.0 <= betas[1] < 1.0:
+ raise ValueError(
+ "Invalid beta parameter at index 1: {}".format(betas[1])
+ )
+
+ defaults = dict(
+ lr=lr,
+ betas=betas,
+ eps=eps,
+ weight_decay=weight_decay,
+ warmup=warmup
+ )
+ super(AdamW, self).__init__(params, defaults)
+
+ def __setstate__(self, state):
+ super(AdamW, self).__setstate__(state)
+
+ def step(self, closure=None):
+ loss = None
+ if closure is not None:
+ loss = closure()
+
+ for group in self.param_groups:
+
+ for p in group["params"]:
+ if p.grad is None:
+ continue
+ grad = p.grad.data.float()
+ if grad.is_sparse:
+ raise RuntimeError(
+ "Adam does not support sparse gradients, please consider SparseAdam instead"
+ )
+
+ p_data_fp32 = p.data.float()
+
+ state = self.state[p]
+
+ if len(state) == 0:
+ state["step"] = 0
+ state["exp_avg"] = torch.zeros_like(p_data_fp32)
+ state["exp_avg_sq"] = torch.zeros_like(p_data_fp32)
+ else:
+ state["exp_avg"] = state["exp_avg"].type_as(p_data_fp32)
+ state["exp_avg_sq"] = state["exp_avg_sq"].type_as(
+ p_data_fp32
+ )
+
+ exp_avg, exp_avg_sq = state["exp_avg"], state["exp_avg_sq"]
+ beta1, beta2 = group["betas"]
+
+ state["step"] += 1
+
+ exp_avg_sq.mul_(beta2).addcmul_(1 - beta2, grad, grad)
+ exp_avg.mul_(beta1).add_(1 - beta1, grad)
+
+ denom = exp_avg_sq.sqrt().add_(group["eps"])
+ bias_correction1 = 1 - beta1**state["step"]
+ bias_correction2 = 1 - beta2**state["step"]
+
+ if group["warmup"] > state["step"]:
+ scheduled_lr = 1e-8 + state["step"] * group["lr"] / group[
+ "warmup"]
+ else:
+ scheduled_lr = group["lr"]
+
+ step_size = (
+ scheduled_lr * math.sqrt(bias_correction2) /
+ bias_correction1
+ )
+
+ if group["weight_decay"] != 0:
+ p_data_fp32.add_(
+ -group["weight_decay"] * scheduled_lr, p_data_fp32
+ )
+
+ p_data_fp32.addcdiv_(-step_size, exp_avg, denom)
+
+ p.data.copy_(p_data_fp32)
+
+ return loss
diff --git a/dassl/utils/__init__.py b/dassl/utils/__init__.py
new file mode 100644
index 0000000..c47679f
--- /dev/null
+++ b/dassl/utils/__init__.py
@@ -0,0 +1,5 @@
+from .tools import *
+from .logger import *
+from .meters import *
+from .registry import *
+from .torchtools import *
diff --git a/dassl/utils/__pycache__/__init__.cpython-310.pyc b/dassl/utils/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000..cb00781
Binary files /dev/null and b/dassl/utils/__pycache__/__init__.cpython-310.pyc differ
diff --git a/dassl/utils/__pycache__/__init__.cpython-311.pyc b/dassl/utils/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000..c782165
Binary files /dev/null and b/dassl/utils/__pycache__/__init__.cpython-311.pyc differ
diff --git a/dassl/utils/__pycache__/__init__.cpython-38.pyc b/dassl/utils/__pycache__/__init__.cpython-38.pyc
new file mode 100644
index 0000000..ac1d747
Binary files /dev/null and b/dassl/utils/__pycache__/__init__.cpython-38.pyc differ
diff --git a/dassl/utils/__pycache__/logger.cpython-310.pyc b/dassl/utils/__pycache__/logger.cpython-310.pyc
new file mode 100644
index 0000000..6827e66
Binary files /dev/null and b/dassl/utils/__pycache__/logger.cpython-310.pyc differ
diff --git a/dassl/utils/__pycache__/logger.cpython-311.pyc b/dassl/utils/__pycache__/logger.cpython-311.pyc
new file mode 100644
index 0000000..69fba6c
Binary files /dev/null and b/dassl/utils/__pycache__/logger.cpython-311.pyc differ
diff --git a/dassl/utils/__pycache__/logger.cpython-38.pyc b/dassl/utils/__pycache__/logger.cpython-38.pyc
new file mode 100644
index 0000000..a590cd4
Binary files /dev/null and b/dassl/utils/__pycache__/logger.cpython-38.pyc differ
diff --git a/dassl/utils/__pycache__/meters.cpython-310.pyc b/dassl/utils/__pycache__/meters.cpython-310.pyc
new file mode 100644
index 0000000..8d2c7a0
Binary files /dev/null and b/dassl/utils/__pycache__/meters.cpython-310.pyc differ
diff --git a/dassl/utils/__pycache__/meters.cpython-311.pyc b/dassl/utils/__pycache__/meters.cpython-311.pyc
new file mode 100644
index 0000000..7ce4caa
Binary files /dev/null and b/dassl/utils/__pycache__/meters.cpython-311.pyc differ
diff --git a/dassl/utils/__pycache__/meters.cpython-38.pyc b/dassl/utils/__pycache__/meters.cpython-38.pyc
new file mode 100644
index 0000000..b20d84a
Binary files /dev/null and b/dassl/utils/__pycache__/meters.cpython-38.pyc differ
diff --git a/dassl/utils/__pycache__/registry.cpython-310.pyc b/dassl/utils/__pycache__/registry.cpython-310.pyc
new file mode 100644
index 0000000..d5d0ad9
Binary files /dev/null and b/dassl/utils/__pycache__/registry.cpython-310.pyc differ
diff --git a/dassl/utils/__pycache__/registry.cpython-311.pyc b/dassl/utils/__pycache__/registry.cpython-311.pyc
new file mode 100644
index 0000000..e16eaf7
Binary files /dev/null and b/dassl/utils/__pycache__/registry.cpython-311.pyc differ
diff --git a/dassl/utils/__pycache__/registry.cpython-38.pyc b/dassl/utils/__pycache__/registry.cpython-38.pyc
new file mode 100644
index 0000000..628a396
Binary files /dev/null and b/dassl/utils/__pycache__/registry.cpython-38.pyc differ
diff --git a/dassl/utils/__pycache__/tools.cpython-310.pyc b/dassl/utils/__pycache__/tools.cpython-310.pyc
new file mode 100644
index 0000000..d7f8847
Binary files /dev/null and b/dassl/utils/__pycache__/tools.cpython-310.pyc differ
diff --git a/dassl/utils/__pycache__/tools.cpython-311.pyc b/dassl/utils/__pycache__/tools.cpython-311.pyc
new file mode 100644
index 0000000..3e0e12d
Binary files /dev/null and b/dassl/utils/__pycache__/tools.cpython-311.pyc differ
diff --git a/dassl/utils/__pycache__/tools.cpython-38.pyc b/dassl/utils/__pycache__/tools.cpython-38.pyc
new file mode 100644
index 0000000..fb6cace
Binary files /dev/null and b/dassl/utils/__pycache__/tools.cpython-38.pyc differ
diff --git a/dassl/utils/__pycache__/torchtools.cpython-310.pyc b/dassl/utils/__pycache__/torchtools.cpython-310.pyc
new file mode 100644
index 0000000..972e03c
Binary files /dev/null and b/dassl/utils/__pycache__/torchtools.cpython-310.pyc differ
diff --git a/dassl/utils/__pycache__/torchtools.cpython-311.pyc b/dassl/utils/__pycache__/torchtools.cpython-311.pyc
new file mode 100644
index 0000000..439641a
Binary files /dev/null and b/dassl/utils/__pycache__/torchtools.cpython-311.pyc differ
diff --git a/dassl/utils/__pycache__/torchtools.cpython-38.pyc b/dassl/utils/__pycache__/torchtools.cpython-38.pyc
new file mode 100644
index 0000000..1739a21
Binary files /dev/null and b/dassl/utils/__pycache__/torchtools.cpython-38.pyc differ
diff --git a/dassl/utils/logger.py b/dassl/utils/logger.py
new file mode 100644
index 0000000..d5e680a
--- /dev/null
+++ b/dassl/utils/logger.py
@@ -0,0 +1,73 @@
+import os
+import sys
+import time
+import os.path as osp
+
+from .tools import mkdir_if_missing
+
+__all__ = ["Logger", "setup_logger"]
+
+
+class Logger:
+ """Write console output to external text file.
+
+ Imported from ``_
+
+ Args:
+ fpath (str): directory to save logging file.
+
+ Examples::
+ >>> import sys
+ >>> import os.path as osp
+ >>> save_dir = 'output/experiment-1'
+ >>> log_name = 'train.log'
+ >>> sys.stdout = Logger(osp.join(save_dir, log_name))
+ """
+
+ def __init__(self, fpath=None):
+ self.console = sys.stdout
+ self.file = None
+ if fpath is not None:
+ mkdir_if_missing(osp.dirname(fpath))
+ self.file = open(fpath, "w")
+
+ def __del__(self):
+ self.close()
+
+ def __enter__(self):
+ pass
+
+ def __exit__(self, *args):
+ self.close()
+
+ def write(self, msg):
+ self.console.write(msg)
+ if self.file is not None:
+ self.file.write(msg)
+
+ def flush(self):
+ self.console.flush()
+ if self.file is not None:
+ self.file.flush()
+ os.fsync(self.file.fileno())
+
+ def close(self):
+ self.console.close()
+ if self.file is not None:
+ self.file.close()
+
+
+def setup_logger(output=None):
+ if output is None:
+ return
+
+ if output.endswith(".txt") or output.endswith(".log"):
+ fpath = output
+ else:
+ fpath = osp.join(output, "log.txt")
+
+ if osp.exists(fpath):
+ # make sure the existing log file is not over-written
+ fpath += time.strftime("-%Y-%m-%d-%H-%M-%S")
+
+ sys.stdout = Logger(fpath)
diff --git a/dassl/utils/meters.py b/dassl/utils/meters.py
new file mode 100644
index 0000000..a779b59
--- /dev/null
+++ b/dassl/utils/meters.py
@@ -0,0 +1,80 @@
+from collections import defaultdict
+import torch
+
+__all__ = ["AverageMeter", "MetricMeter"]
+
+
+class AverageMeter:
+ """Compute and store the average and current value.
+
+ Examples::
+ >>> # 1. Initialize a meter to record loss
+ >>> losses = AverageMeter()
+ >>> # 2. Update meter after every mini-batch update
+ >>> losses.update(loss_value, batch_size)
+ """
+
+ def __init__(self, ema=False):
+ """
+ Args:
+ ema (bool, optional): apply exponential moving average.
+ """
+ self.ema = ema
+ self.reset()
+
+ def reset(self):
+ self.val = 0
+ self.avg = 0
+ self.sum = 0
+ self.count = 0
+
+ def update(self, val, n=1):
+ if isinstance(val, torch.Tensor):
+ val = val.item()
+
+ self.val = val
+ self.sum += val * n
+ self.count += n
+
+ if self.ema:
+ self.avg = self.avg * 0.9 + self.val * 0.1
+ else:
+ self.avg = self.sum / self.count
+
+
+class MetricMeter:
+ """Store the average and current value for a set of metrics.
+
+ Examples::
+ >>> # 1. Create an instance of MetricMeter
+ >>> metric = MetricMeter()
+ >>> # 2. Update using a dictionary as input
+ >>> input_dict = {'loss_1': value_1, 'loss_2': value_2}
+ >>> metric.update(input_dict)
+ >>> # 3. Convert to string and print
+ >>> print(str(metric))
+ """
+
+ def __init__(self, delimiter=" "):
+ self.meters = defaultdict(AverageMeter)
+ self.delimiter = delimiter
+
+ def update(self, input_dict):
+ if input_dict is None:
+ return
+
+ if not isinstance(input_dict, dict):
+ raise TypeError(
+ "Input to MetricMeter.update() must be a dictionary"
+ )
+
+ for k, v in input_dict.items():
+ if isinstance(v, torch.Tensor):
+ v = v.item()
+ self.meters[k].update(v)
+
+ def __str__(self):
+ output_str = []
+ for name, meter in self.meters.items():
+ output_str.append(f"{name} {meter.val:.4f} ({meter.avg:.4f})")
+ return self.delimiter.join(output_str)
diff --git a/dassl/utils/registry.py b/dassl/utils/registry.py
new file mode 100644
index 0000000..5079784
--- /dev/null
+++ b/dassl/utils/registry.py
@@ -0,0 +1,69 @@
+"""
+Modified from https://github.com/facebookresearch/fvcore
+"""
+__all__ = ["Registry"]
+
+
+class Registry:
+ """A registry providing name -> object mapping, to support
+ custom modules.
+
+ To create a registry (e.g. a backbone registry):
+
+ .. code-block:: python
+
+ BACKBONE_REGISTRY = Registry('BACKBONE')
+
+ To register an object:
+
+ .. code-block:: python
+
+ @BACKBONE_REGISTRY.register()
+ class MyBackbone(nn.Module):
+ ...
+
+ Or:
+
+ .. code-block:: python
+
+ BACKBONE_REGISTRY.register(MyBackbone)
+ """
+
+ def __init__(self, name):
+ self._name = name
+ self._obj_map = dict()
+
+ def _do_register(self, name, obj, force=False):
+ if name in self._obj_map and not force:
+ raise KeyError(
+ 'An object named "{}" was already '
+ 'registered in "{}" registry'.format(name, self._name)
+ )
+
+ self._obj_map[name] = obj
+
+ def register(self, obj=None, force=False):
+ if obj is None:
+ # Used as a decorator
+ def wrapper(fn_or_class):
+ name = fn_or_class.__name__
+ self._do_register(name, fn_or_class, force=force)
+ return fn_or_class
+
+ return wrapper
+
+ # Used as a function call
+ name = obj.__name__
+ self._do_register(name, obj, force=force)
+
+ def get(self, name):
+ if name not in self._obj_map:
+ raise KeyError(
+ 'Object name "{}" does not exist '
+ 'in "{}" registry'.format(name, self._name)
+ )
+
+ return self._obj_map[name]
+
+ def registered_names(self):
+ return list(self._obj_map.keys())
diff --git a/dassl/utils/tools.py b/dassl/utils/tools.py
new file mode 100644
index 0000000..62d4f30
--- /dev/null
+++ b/dassl/utils/tools.py
@@ -0,0 +1,185 @@
+"""
+Modified from https://github.com/KaiyangZhou/deep-person-reid
+"""
+import os
+import sys
+import json
+import time
+import errno
+import numpy as np
+import random
+import os.path as osp
+import warnings
+from difflib import SequenceMatcher
+import PIL
+import torch
+from PIL import Image
+
+__all__ = [
+ "mkdir_if_missing",
+ "check_isfile",
+ "read_json",
+ "write_json",
+ "set_random_seed",
+ "download_url",
+ "read_image",
+ "collect_env_info",
+ "listdir_nohidden",
+ "get_most_similar_str_to_a_from_b",
+ "check_availability",
+ "tolist_if_not",
+]
+
+
+def mkdir_if_missing(dirname):
+ """Create dirname if it is missing."""
+ if not osp.exists(dirname):
+ try:
+ os.makedirs(dirname)
+ except OSError as e:
+ if e.errno != errno.EEXIST:
+ raise
+
+
+def check_isfile(fpath):
+ """Check if the given path is a file.
+
+ Args:
+ fpath (str): file path.
+
+ Returns:
+ bool
+ """
+ isfile = osp.isfile(fpath)
+ if not isfile:
+ warnings.warn('No file found at "{}"'.format(fpath))
+ return isfile
+
+
+def read_json(fpath):
+ """Read json file from a path."""
+ with open(fpath, "r") as f:
+ obj = json.load(f)
+ return obj
+
+
+def write_json(obj, fpath):
+ """Writes to a json file."""
+ mkdir_if_missing(osp.dirname(fpath))
+ with open(fpath, "w") as f:
+ json.dump(obj, f, indent=4, separators=(",", ": "))
+
+
+def set_random_seed(seed):
+ random.seed(seed)
+ np.random.seed(seed)
+ torch.manual_seed(seed)
+ torch.cuda.manual_seed_all(seed)
+
+
+def download_url(url, dst):
+ """Download file from a url to a destination.
+
+ Args:
+ url (str): url to download file.
+ dst (str): destination path.
+ """
+ from six.moves import urllib
+
+ print('* url="{}"'.format(url))
+ print('* destination="{}"'.format(dst))
+
+ def _reporthook(count, block_size, total_size):
+ global start_time
+ if count == 0:
+ start_time = time.time()
+ return
+ duration = time.time() - start_time
+ progress_size = int(count * block_size)
+ speed = int(progress_size / (1024*duration))
+ percent = int(count * block_size * 100 / total_size)
+ sys.stdout.write(
+ "\r...%d%%, %d MB, %d KB/s, %d seconds passed" %
+ (percent, progress_size / (1024*1024), speed, duration)
+ )
+ sys.stdout.flush()
+
+ urllib.request.urlretrieve(url, dst, _reporthook)
+ sys.stdout.write("\n")
+
+
+def read_image(path):
+ """Read image from path using ``PIL.Image``.
+
+ Args:
+ path (str): path to an image.
+
+ Returns:
+ PIL image
+ """
+ return Image.open(path).convert("RGB")
+
+
+def collect_env_info():
+ """Return env info as a string.
+
+ Code source: github.com/facebookresearch/maskrcnn-benchmark
+ """
+ from torch.utils.collect_env import get_pretty_env_info
+
+ env_str = get_pretty_env_info()
+ env_str += "\n Pillow ({})".format(PIL.__version__)
+ return env_str
+
+
+def listdir_nohidden(path, sort=False):
+ """List non-hidden items in a directory.
+
+ Args:
+ path (str): directory path.
+ sort (bool): sort the items.
+ """
+ items = [f for f in os.listdir(path) if not f.startswith(".")]
+ if sort:
+ items.sort()
+ return items
+
+
+def get_most_similar_str_to_a_from_b(a, b):
+ """Return the most similar string to a in b.
+
+ Args:
+ a (str): probe string.
+ b (list): a list of candidate strings.
+ """
+ highest_sim = 0
+ chosen = None
+ for candidate in b:
+ sim = SequenceMatcher(None, a, candidate).ratio()
+ if sim >= highest_sim:
+ highest_sim = sim
+ chosen = candidate
+ return chosen
+
+
+def check_availability(requested, available):
+ """Check if an element is available in a list.
+
+ Args:
+ requested (str): probe string.
+ available (list): a list of available strings.
+ """
+ if requested not in available:
+ psb_ans = get_most_similar_str_to_a_from_b(requested, available)
+ raise ValueError(
+ "The requested one is expected "
+ "to belong to {}, but got [{}] "
+ "(do you mean [{}]?)".format(available, requested, psb_ans)
+ )
+
+
+def tolist_if_not(x):
+ """Convert to a list."""
+ if not isinstance(x, list):
+ x = [x]
+ return x
diff --git a/dassl/utils/torchtools.py b/dassl/utils/torchtools.py
new file mode 100644
index 0000000..2e14fa3
--- /dev/null
+++ b/dassl/utils/torchtools.py
@@ -0,0 +1,347 @@
+"""
+Modified from https://github.com/KaiyangZhou/deep-person-reid
+"""
+import pickle
+import shutil
+import os.path as osp
+import warnings
+from functools import partial
+from collections import OrderedDict
+import torch
+import torch.nn as nn
+
+from .tools import mkdir_if_missing
+
+__all__ = [
+ "save_checkpoint",
+ "load_checkpoint",
+ "resume_from_checkpoint",
+ "open_all_layers",
+ "open_specified_layers",
+ "count_num_param",
+ "load_pretrained_weights",
+ "init_network_weights",
+]
+
+
+def save_checkpoint(
+ state,
+ save_dir,
+ is_best=False,
+ remove_module_from_keys=True,
+ model_name=""
+):
+ r"""Save checkpoint.
+
+ Args:
+ state (dict): dictionary.
+ save_dir (str): directory to save checkpoint.
+ is_best (bool, optional): if True, this checkpoint will be copied and named
+ ``model-best.pth.tar``. Default is False.
+ remove_module_from_keys (bool, optional): whether to remove "module."
+ from layer names. Default is True.
+ model_name (str, optional): model name to save.
+ """
+ mkdir_if_missing(save_dir)
+
+ if remove_module_from_keys:
+ # remove 'module.' in state_dict's keys
+ state_dict = state["state_dict"]
+ new_state_dict = OrderedDict()
+ for k, v in state_dict.items():
+ if k.startswith("module."):
+ k = k[7:]
+ new_state_dict[k] = v
+ state["state_dict"] = new_state_dict
+
+ # save model
+ epoch = state["epoch"]
+ if not model_name:
+ model_name = "model.pth.tar-" + str(epoch)
+ fpath = osp.join(save_dir, model_name)
+ torch.save(state, fpath)
+ print(f"Checkpoint saved to {fpath}")
+
+ # save current model name
+ checkpoint_file = osp.join(save_dir, "checkpoint")
+ checkpoint = open(checkpoint_file, "w+")
+ checkpoint.write("{}\n".format(osp.basename(fpath)))
+ checkpoint.close()
+
+ if is_best:
+ best_fpath = osp.join(osp.dirname(fpath), "model-best.pth.tar")
+ shutil.copy(fpath, best_fpath)
+ print('Best checkpoint saved to "{}"'.format(best_fpath))
+
+
+def load_checkpoint(fpath):
+ r"""Load checkpoint.
+
+ ``UnicodeDecodeError`` can be well handled, which means
+ python2-saved files can be read from python3.
+
+ Args:
+ fpath (str): path to checkpoint.
+
+ Returns:
+ dict
+
+ Examples::
+ >>> fpath = 'log/my_model/model.pth.tar-10'
+ >>> checkpoint = load_checkpoint(fpath)
+ """
+ if fpath is None:
+ raise ValueError("File path is None")
+
+ if not osp.exists(fpath):
+ raise FileNotFoundError('File is not found at "{}"'.format(fpath))
+
+ map_location = None if torch.cuda.is_available() else "cpu"
+
+ try:
+ checkpoint = torch.load(fpath, map_location=map_location)
+
+ except UnicodeDecodeError:
+ pickle.load = partial(pickle.load, encoding="latin1")
+ pickle.Unpickler = partial(pickle.Unpickler, encoding="latin1")
+ checkpoint = torch.load(
+ fpath, pickle_module=pickle, map_location=map_location
+ )
+
+ except Exception:
+ print('Unable to load checkpoint from "{}"'.format(fpath))
+ raise
+
+ return checkpoint
+
+
+def resume_from_checkpoint(fdir, model, optimizer=None, scheduler=None):
+ r"""Resume training from a checkpoint.
+
+ This will load (1) model weights and (2) ``state_dict``
+ of optimizer if ``optimizer`` is not None.
+
+ Args:
+ fdir (str): directory where the model was saved.
+ model (nn.Module): model.
+ optimizer (Optimizer, optional): an Optimizer.
+ scheduler (Scheduler, optional): an Scheduler.
+
+ Returns:
+ int: start_epoch.
+
+ Examples::
+ >>> fdir = 'log/my_model'
+ >>> start_epoch = resume_from_checkpoint(fdir, model, optimizer, scheduler)
+ """
+ with open(osp.join(fdir, "checkpoint"), "r") as checkpoint:
+ model_name = checkpoint.readlines()[0].strip("\n")
+ fpath = osp.join(fdir, model_name)
+
+ print('Loading checkpoint from "{}"'.format(fpath))
+ checkpoint = load_checkpoint(fpath)
+ model.load_state_dict(checkpoint["state_dict"])
+ print("Loaded model weights")
+
+ if optimizer is not None and "optimizer" in checkpoint.keys():
+ optimizer.load_state_dict(checkpoint["optimizer"])
+ print("Loaded optimizer")
+
+ if scheduler is not None and "scheduler" in checkpoint.keys():
+ scheduler.load_state_dict(checkpoint["scheduler"])
+ print("Loaded scheduler")
+
+ start_epoch = checkpoint["epoch"]
+ print("Previous epoch: {}".format(start_epoch))
+
+ return start_epoch
+
+
+def adjust_learning_rate(
+ optimizer,
+ base_lr,
+ epoch,
+ stepsize=20,
+ gamma=0.1,
+ linear_decay=False,
+ final_lr=0,
+ max_epoch=100,
+):
+ r"""Adjust learning rate.
+
+ Deprecated.
+ """
+ if linear_decay:
+ # linearly decay learning rate from base_lr to final_lr
+ frac_done = epoch / max_epoch
+ lr = frac_done*final_lr + (1.0-frac_done) * base_lr
+ else:
+ # decay learning rate by gamma for every stepsize
+ lr = base_lr * (gamma**(epoch // stepsize))
+
+ for param_group in optimizer.param_groups:
+ param_group["lr"] = lr
+
+
+def set_bn_to_eval(m):
+ r"""Set BatchNorm layers to eval mode."""
+ # 1. no update for running mean and var
+ # 2. scale and shift parameters are still trainable
+ classname = m.__class__.__name__
+ if classname.find("BatchNorm") != -1:
+ m.eval()
+
+
+def open_all_layers(model):
+ r"""Open all layers in model for training.
+
+ Examples::
+ >>> open_all_layers(model)
+ """
+ model.train()
+ for p in model.parameters():
+ p.requires_grad = True
+
+
+def open_specified_layers(model, open_layers):
+ r"""Open specified layers in model for training while keeping
+ other layers frozen.
+
+ Args:
+ model (nn.Module): neural net model.
+ open_layers (str or list): layers open for training.
+
+ Examples::
+ >>> # Only model.classifier will be updated.
+ >>> open_layers = 'classifier'
+ >>> open_specified_layers(model, open_layers)
+ >>> # Only model.fc and model.classifier will be updated.
+ >>> open_layers = ['fc', 'classifier']
+ >>> open_specified_layers(model, open_layers)
+ """
+ if isinstance(model, nn.DataParallel):
+ model = model.module
+
+ if isinstance(open_layers, str):
+ open_layers = [open_layers]
+
+ for layer in open_layers:
+ assert hasattr(model, layer), f"{layer} is not an attribute"
+
+ for name, module in model.named_children():
+ if name in open_layers:
+ module.train()
+ for p in module.parameters():
+ p.requires_grad = True
+ else:
+ module.eval()
+ for p in module.parameters():
+ p.requires_grad = False
+
+
+def count_num_param(model=None, params=None):
+ r"""Count number of parameters in a model.
+
+ Args:
+ model (nn.Module): network model.
+ params: network model`s params.
+ Examples::
+ >>> model_size = count_num_param(model)
+ """
+
+ if model is not None:
+ return sum(p.numel() for p in model.parameters())
+
+ if params is not None:
+ s = 0
+ for p in params:
+ if isinstance(p, dict):
+ s += p["params"].numel()
+ else:
+ s += p.numel()
+ return s
+
+ raise ValueError("model and params must provide at least one.")
+
+
+def load_pretrained_weights(model, weight_path):
+ r"""Load pretrianed weights to model.
+
+ Features::
+ - Incompatible layers (unmatched in name or size) will be ignored.
+ - Can automatically deal with keys containing "module.".
+
+ Args:
+ model (nn.Module): network model.
+ weight_path (str): path to pretrained weights.
+
+ Examples::
+ >>> weight_path = 'log/my_model/model-best.pth.tar'
+ >>> load_pretrained_weights(model, weight_path)
+ """
+ checkpoint = load_checkpoint(weight_path)
+ if "state_dict" in checkpoint:
+ state_dict = checkpoint["state_dict"]
+ else:
+ state_dict = checkpoint
+
+ model_dict = model.state_dict()
+ new_state_dict = OrderedDict()
+ matched_layers, discarded_layers = [], []
+
+ for k, v in state_dict.items():
+ if k.startswith("module."):
+ k = k[7:] # discard module.
+
+ if k in model_dict and model_dict[k].size() == v.size():
+ new_state_dict[k] = v
+ matched_layers.append(k)
+ else:
+ discarded_layers.append(k)
+
+ model_dict.update(new_state_dict)
+ model.load_state_dict(model_dict)
+
+ if len(matched_layers) == 0:
+ warnings.warn(
+ f"Cannot load {weight_path} (check the key names manually)"
+ )
+ else:
+ print(f"Successfully loaded pretrained weights from {weight_path}")
+ if len(discarded_layers) > 0:
+ print(
+ f"Layers discarded due to unmatched keys or size: {discarded_layers}"
+ )
+
+
+def init_network_weights(model, init_type="normal", gain=0.02):
+
+ def _init_func(m):
+ classname = m.__class__.__name__
+
+ if hasattr(m, "weight") and (
+ classname.find("Conv") != -1 or classname.find("Linear") != -1
+ ):
+ if init_type == "normal":
+ nn.init.normal_(m.weight.data, 0.0, gain)
+ elif init_type == "xavier":
+ nn.init.xavier_normal_(m.weight.data, gain=gain)
+ elif init_type == "kaiming":
+ nn.init.kaiming_normal_(m.weight.data, a=0, mode="fan_in")
+ elif init_type == "orthogonal":
+ nn.init.orthogonal_(m.weight.data, gain=gain)
+ else:
+ raise NotImplementedError
+ if hasattr(m, "bias") and m.bias is not None:
+ nn.init.constant_(m.bias.data, 0.0)
+
+ elif classname.find("BatchNorm") != -1:
+ nn.init.constant_(m.weight.data, 1.0)
+ nn.init.constant_(m.bias.data, 0.0)
+
+ elif classname.find("InstanceNorm") != -1:
+ if m.weight is not None and m.bias is not None:
+ nn.init.constant_(m.weight.data, 1.0)
+ nn.init.constant_(m.bias.data, 0.0)
+
+ model.apply(_init_func)
diff --git a/datasets/__init__.py b/datasets/__init__.py
new file mode 100755
index 0000000..e69de29
diff --git a/datasets/__pycache__/__init__.cpython-310.pyc b/datasets/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000..17fdf0f
Binary files /dev/null and b/datasets/__pycache__/__init__.cpython-310.pyc differ
diff --git a/datasets/__pycache__/caltech101.cpython-310.pyc b/datasets/__pycache__/caltech101.cpython-310.pyc
new file mode 100644
index 0000000..982eaa2
Binary files /dev/null and b/datasets/__pycache__/caltech101.cpython-310.pyc differ
diff --git a/datasets/__pycache__/dtd.cpython-310.pyc b/datasets/__pycache__/dtd.cpython-310.pyc
new file mode 100644
index 0000000..6847160
Binary files /dev/null and b/datasets/__pycache__/dtd.cpython-310.pyc differ
diff --git a/datasets/__pycache__/eurosat.cpython-310.pyc b/datasets/__pycache__/eurosat.cpython-310.pyc
new file mode 100644
index 0000000..3a7934d
Binary files /dev/null and b/datasets/__pycache__/eurosat.cpython-310.pyc differ
diff --git a/datasets/__pycache__/fgvc_aircraft.cpython-310.pyc b/datasets/__pycache__/fgvc_aircraft.cpython-310.pyc
new file mode 100644
index 0000000..3eefb01
Binary files /dev/null and b/datasets/__pycache__/fgvc_aircraft.cpython-310.pyc differ
diff --git a/datasets/__pycache__/food101.cpython-310.pyc b/datasets/__pycache__/food101.cpython-310.pyc
new file mode 100644
index 0000000..bea1a5f
Binary files /dev/null and b/datasets/__pycache__/food101.cpython-310.pyc differ
diff --git a/datasets/__pycache__/oxford_flowers.cpython-310.pyc b/datasets/__pycache__/oxford_flowers.cpython-310.pyc
new file mode 100644
index 0000000..588ae18
Binary files /dev/null and b/datasets/__pycache__/oxford_flowers.cpython-310.pyc differ
diff --git a/datasets/__pycache__/oxford_pets.cpython-310.pyc b/datasets/__pycache__/oxford_pets.cpython-310.pyc
new file mode 100644
index 0000000..ffb0292
Binary files /dev/null and b/datasets/__pycache__/oxford_pets.cpython-310.pyc differ
diff --git a/datasets/__pycache__/stanford_cars.cpython-310.pyc b/datasets/__pycache__/stanford_cars.cpython-310.pyc
new file mode 100644
index 0000000..42644a1
Binary files /dev/null and b/datasets/__pycache__/stanford_cars.cpython-310.pyc differ
diff --git a/datasets/__pycache__/sun397.cpython-310.pyc b/datasets/__pycache__/sun397.cpython-310.pyc
new file mode 100644
index 0000000..fa87ce1
Binary files /dev/null and b/datasets/__pycache__/sun397.cpython-310.pyc differ
diff --git a/datasets/__pycache__/ucf101.cpython-310.pyc b/datasets/__pycache__/ucf101.cpython-310.pyc
new file mode 100644
index 0000000..c5ccfd2
Binary files /dev/null and b/datasets/__pycache__/ucf101.cpython-310.pyc differ
diff --git a/datasets/caltech101.py b/datasets/caltech101.py
new file mode 100755
index 0000000..172e2af
--- /dev/null
+++ b/datasets/caltech101.py
@@ -0,0 +1,59 @@
+import os
+import pickle
+
+from dassl.data.datasets import DATASET_REGISTRY, Datum, DatasetBase
+from dassl.utils import mkdir_if_missing
+
+from .oxford_pets import OxfordPets
+from .dtd import DescribableTextures as DTD
+
+IGNORED = ["BACKGROUND_Google", "Faces_easy"]
+NEW_CNAMES = {
+ "airplanes": "airplane",
+ "Faces": "face",
+ "Leopards": "leopard",
+ "Motorbikes": "motorbike",
+}
+
+
+@DATASET_REGISTRY.register()
+class Caltech101(DatasetBase):
+
+ dataset_dir = "caltech-101"
+
+ def __init__(self, cfg):
+ root = os.path.abspath(os.path.expanduser(cfg.DATASET.ROOT))
+ self.dataset_dir = os.path.join(root, self.dataset_dir)
+ self.image_dir = os.path.join(self.dataset_dir, "101_ObjectCategories")
+ self.split_path = os.path.join(self.dataset_dir, "split_zhou_Caltech101.json")
+ self.split_fewshot_dir = os.path.join(self.dataset_dir, "split_fewshot")
+ mkdir_if_missing(self.split_fewshot_dir)
+
+ if os.path.exists(self.split_path):
+ train, val, test = OxfordPets.read_split(self.split_path, self.image_dir)
+ else:
+ train, val, test = DTD.read_and_split_data(self.image_dir, ignored=IGNORED, new_cnames=NEW_CNAMES)
+ OxfordPets.save_split(train, val, test, self.split_path, self.image_dir)
+
+ num_shots = cfg.DATASET.NUM_SHOTS
+ # if num_shots >= 1:
+ seed = cfg.SEED
+ preprocessed = os.path.join(self.split_fewshot_dir, f"shot_{num_shots}-seed_{seed}.pkl")
+
+ if os.path.exists(preprocessed):
+ print(f"Loading preprocessed few-shot data from {preprocessed}")
+ with open(preprocessed, "rb") as file:
+ data = pickle.load(file)
+ train, val = data["train"], data["val"]
+ else:
+ train = self.generate_fewshot_dataset(train, num_shots=num_shots)
+ val = self.generate_fewshot_dataset(val, num_shots=min(num_shots, 4))
+ data = {"train": train, "val": val}
+ print(f"Saving preprocessed few-shot data to {preprocessed}")
+ with open(preprocessed, "wb") as file:
+ pickle.dump(data, file, protocol=pickle.HIGHEST_PROTOCOL)
+
+ subsample = cfg.DATASET.SUBSAMPLE_CLASSES
+ train, val, test = OxfordPets.subsample_classes(train, val, test, subsample=subsample)
+
+ super().__init__(train_x=train, val=val, test=test)
diff --git a/datasets/dtd.py b/datasets/dtd.py
new file mode 100755
index 0000000..1b2aa10
--- /dev/null
+++ b/datasets/dtd.py
@@ -0,0 +1,95 @@
+import os
+import pickle
+import random
+
+from dassl.data.datasets import DATASET_REGISTRY, Datum, DatasetBase
+from dassl.utils import listdir_nohidden, mkdir_if_missing
+
+from .oxford_pets import OxfordPets
+
+
+@DATASET_REGISTRY.register()
+class DescribableTextures(DatasetBase):
+
+ dataset_dir = "dtd"
+
+ def __init__(self, cfg):
+ root = os.path.abspath(os.path.expanduser(cfg.DATASET.ROOT))
+ self.dataset_dir = os.path.join(root, self.dataset_dir)
+ self.image_dir = os.path.join(self.dataset_dir, "images")
+ self.split_path = os.path.join(self.dataset_dir, "split_zhou_DescribableTextures.json")
+ self.split_fewshot_dir = os.path.join(self.dataset_dir, "split_fewshot")
+ mkdir_if_missing(self.split_fewshot_dir)
+
+ if os.path.exists(self.split_path):
+ train, val, test = OxfordPets.read_split(self.split_path, self.image_dir)
+ else:
+ train, val, test = self.read_and_split_data(self.image_dir)
+ OxfordPets.save_split(train, val, test, self.split_path, self.image_dir)
+
+ num_shots = cfg.DATASET.NUM_SHOTS
+ # if num_shots >= 1:
+ seed = cfg.SEED
+ preprocessed = os.path.join(self.split_fewshot_dir, f"shot_{num_shots}-seed_{seed}.pkl")
+
+ if os.path.exists(preprocessed):
+ print(f"Loading preprocessed few-shot data from {preprocessed}")
+ with open(preprocessed, "rb") as file:
+ data = pickle.load(file)
+ train, val = data["train"], data["val"]
+ else:
+ train = self.generate_fewshot_dataset(train, num_shots=num_shots)
+ val = self.generate_fewshot_dataset(val, num_shots=min(num_shots, 4))
+ data = {"train": train, "val": val}
+ print(f"Saving preprocessed few-shot data to {preprocessed}")
+ with open(preprocessed, "wb") as file:
+ pickle.dump(data, file, protocol=pickle.HIGHEST_PROTOCOL)
+
+ subsample = cfg.DATASET.SUBSAMPLE_CLASSES
+ train, val, test = OxfordPets.subsample_classes(train, val, test, subsample=subsample)
+
+ super().__init__(train_x=train, val=val, test=test)
+
+ @staticmethod
+ def read_and_split_data(image_dir, p_trn=0.5, p_val=0.2, ignored=[], new_cnames=None):
+ # The data are supposed to be organized into the following structure
+ # =============
+ # images/
+ # dog/
+ # cat/
+ # horse/
+ # =============
+ categories = listdir_nohidden(image_dir)
+ categories = [c for c in categories if c not in ignored]
+ categories.sort()
+
+ p_tst = 1 - p_trn - p_val
+ print(f"Splitting into {p_trn:.0%} train, {p_val:.0%} val, and {p_tst:.0%} test")
+
+ def _collate(ims, y, c):
+ items = []
+ for im in ims:
+ item = Datum(impath=im, label=y, classname=c) # is already 0-based
+ items.append(item)
+ return items
+
+ train, val, test = [], [], []
+ for label, category in enumerate(categories):
+ category_dir = os.path.join(image_dir, category)
+ images = listdir_nohidden(category_dir)
+ images = [os.path.join(category_dir, im) for im in images]
+ random.shuffle(images)
+ n_total = len(images)
+ n_train = round(n_total * p_trn)
+ n_val = round(n_total * p_val)
+ n_test = n_total - n_train - n_val
+ assert n_train > 0 and n_val > 0 and n_test > 0
+
+ if new_cnames is not None and category in new_cnames:
+ category = new_cnames[category]
+
+ train.extend(_collate(images[:n_train], label, category))
+ val.extend(_collate(images[n_train : n_train + n_val], label, category))
+ test.extend(_collate(images[n_train + n_val :], label, category))
+
+ return train, val, test
diff --git a/datasets/eurosat.py b/datasets/eurosat.py
new file mode 100755
index 0000000..9c7705f
--- /dev/null
+++ b/datasets/eurosat.py
@@ -0,0 +1,73 @@
+import os
+import pickle
+
+from dassl.data.datasets import DATASET_REGISTRY, Datum, DatasetBase
+from dassl.utils import mkdir_if_missing
+
+from .oxford_pets import OxfordPets
+from .dtd import DescribableTextures as DTD
+
+NEW_CNAMES = {
+ "annual crop land": "Annual Crop Land",
+ "Forest": "Forest",
+ "Herbaceous Vegetation Land": "Herbaceous Vegetation Land",
+ "Highway or Road": "Highway or Road",
+ "Industrial Buildings": "industrial buildings or commercial buildings",
+ "Pasture Land": "Pasture Land",
+ "Permanent Crop Land": "Permanent Crop Land",
+ "Residential Buildings": "residential buildings or homes or apartments",
+ "River": "River",
+ "Sea or Lake": "Sea or Lake",
+}
+
+
+@DATASET_REGISTRY.register()
+class EuroSAT(DatasetBase):
+
+ dataset_dir = "eurosat"
+
+ def __init__(self, cfg):
+ root = os.path.abspath(os.path.expanduser(cfg.DATASET.ROOT))
+ self.dataset_dir = os.path.join(root, self.dataset_dir)
+ self.image_dir = os.path.join(self.dataset_dir, "2750")
+ self.split_path = os.path.join(self.dataset_dir, "split_zhou_EuroSAT.json")
+ self.split_fewshot_dir = os.path.join(self.dataset_dir, "split_fewshot")
+ mkdir_if_missing(self.split_fewshot_dir)
+
+ if os.path.exists(self.split_path):
+ train, val, test = OxfordPets.read_split(self.split_path, self.image_dir)
+ else:
+ train, val, test = DTD.read_and_split_data(self.image_dir, new_cnames=NEW_CNAMES)
+ OxfordPets.save_split(train, val, test, self.split_path, self.image_dir)
+
+ num_shots = cfg.DATASET.NUM_SHOTS
+ # if num_shots >= 1:
+ seed = cfg.SEED
+ preprocessed = os.path.join(self.split_fewshot_dir, f"shot_{num_shots}-seed_{seed}.pkl")
+
+ if os.path.exists(preprocessed):
+ print(f"Loading preprocessed few-shot data from {preprocessed}")
+ with open(preprocessed, "rb") as file:
+ data = pickle.load(file)
+ train, val = data["train"], data["val"]
+ else:
+ train = self.generate_fewshot_dataset(train, num_shots=num_shots)
+ val = self.generate_fewshot_dataset(val, num_shots=min(num_shots, 4))
+ data = {"train": train, "val": val}
+ print(f"Saving preprocessed few-shot data to {preprocessed}")
+ with open(preprocessed, "wb") as file:
+ pickle.dump(data, file, protocol=pickle.HIGHEST_PROTOCOL)
+
+ subsample = cfg.DATASET.SUBSAMPLE_CLASSES
+ train, val, test = OxfordPets.subsample_classes(train, val, test, subsample=subsample)
+
+ super().__init__(train_x=train, val=val, test=test)
+
+ def update_classname(self, dataset_old):
+ dataset_new = []
+ for item_old in dataset_old:
+ cname_old = item_old.classname
+ cname_new = NEW_CNAMES[cname_old]
+ item_new = Datum(impath=item_old.impath, label=item_old.label, classname=cname_new)
+ dataset_new.append(item_new)
+ return dataset_new
diff --git a/datasets/fgvc_aircraft.py b/datasets/fgvc_aircraft.py
new file mode 100755
index 0000000..c44c3ec
--- /dev/null
+++ b/datasets/fgvc_aircraft.py
@@ -0,0 +1,71 @@
+import os
+import pickle
+
+from dassl.data.datasets import DATASET_REGISTRY, Datum, DatasetBase
+from dassl.utils import mkdir_if_missing
+
+from .oxford_pets import OxfordPets
+
+
+@DATASET_REGISTRY.register()
+class FGVCAircraft(DatasetBase):
+
+ dataset_dir = "fgvc_aircraft"
+
+ def __init__(self, cfg):
+ root = os.path.abspath(os.path.expanduser(cfg.DATASET.ROOT))
+ self.dataset_dir = os.path.join(root, self.dataset_dir)
+ self.image_dir = os.path.join(self.dataset_dir, "images")
+ self.split_fewshot_dir = os.path.join(self.dataset_dir, "split_fewshot")
+ mkdir_if_missing(self.split_fewshot_dir)
+
+ classnames = []
+ with open(os.path.join(self.dataset_dir, "variants.txt"), "r") as f:
+ lines = f.readlines()
+ for line in lines:
+ classnames.append(line.strip())
+ cname2lab = {c: i for i, c in enumerate(classnames)}
+
+ train = self.read_data(cname2lab, "images_variant_train.txt")
+ val = self.read_data(cname2lab, "images_variant_val.txt")
+ test = self.read_data(cname2lab, "images_variant_test.txt")
+
+ num_shots = cfg.DATASET.NUM_SHOTS
+ # if num_shots >= 1:
+ seed = cfg.SEED
+ preprocessed = os.path.join(self.split_fewshot_dir, f"shot_{num_shots}-seed_{seed}.pkl")
+
+ if os.path.exists(preprocessed):
+ print(f"Loading preprocessed few-shot data from {preprocessed}")
+ with open(preprocessed, "rb") as file:
+ data = pickle.load(file)
+ train, val = data["train"], data["val"]
+ else:
+ train = self.generate_fewshot_dataset(train, num_shots=num_shots)
+ val = self.generate_fewshot_dataset(val, num_shots=min(num_shots, 4))
+ data = {"train": train, "val": val}
+ print(f"Saving preprocessed few-shot data to {preprocessed}")
+ with open(preprocessed, "wb") as file:
+ pickle.dump(data, file, protocol=pickle.HIGHEST_PROTOCOL)
+
+ subsample = cfg.DATASET.SUBSAMPLE_CLASSES
+ train, val, test = OxfordPets.subsample_classes(train, val, test, subsample=subsample)
+
+ super().__init__(train_x=train, val=val, test=test)
+
+ def read_data(self, cname2lab, split_file):
+ filepath = os.path.join(self.dataset_dir, split_file)
+ items = []
+
+ with open(filepath, "r") as f:
+ lines = f.readlines()
+ for line in lines:
+ line = line.strip().split(" ")
+ imname = line[0] + ".jpg"
+ classname = " ".join(line[1:])
+ impath = os.path.join(self.image_dir, imname)
+ label = cname2lab[classname]
+ item = Datum(impath=impath, label=label, classname=classname)
+ items.append(item)
+
+ return items
diff --git a/datasets/food101.py b/datasets/food101.py
new file mode 100755
index 0000000..0ffb656
--- /dev/null
+++ b/datasets/food101.py
@@ -0,0 +1,51 @@
+import os
+import pickle
+
+from dassl.data.datasets import DATASET_REGISTRY, Datum, DatasetBase
+from dassl.utils import mkdir_if_missing
+
+from .oxford_pets import OxfordPets
+from .dtd import DescribableTextures as DTD
+
+
+@DATASET_REGISTRY.register()
+class Food101(DatasetBase):
+
+ dataset_dir = "food-101"
+
+ def __init__(self, cfg):
+ root = os.path.abspath(os.path.expanduser(cfg.DATASET.ROOT))
+ self.dataset_dir = os.path.join(root, self.dataset_dir)
+ self.image_dir = os.path.join(self.dataset_dir, "images")
+ self.split_path = os.path.join(self.dataset_dir, "split_zhou_Food101.json")
+ self.split_fewshot_dir = os.path.join(self.dataset_dir, "split_fewshot")
+ mkdir_if_missing(self.split_fewshot_dir)
+
+ if os.path.exists(self.split_path):
+ train, val, test = OxfordPets.read_split(self.split_path, self.image_dir)
+ else:
+ train, val, test = DTD.read_and_split_data(self.image_dir)
+ OxfordPets.save_split(train, val, test, self.split_path, self.image_dir)
+
+ num_shots = cfg.DATASET.NUM_SHOTS
+ # if num_shots >= 1:
+ seed = cfg.SEED
+ preprocessed = os.path.join(self.split_fewshot_dir, f"shot_{num_shots}-seed_{seed}.pkl")
+
+ if os.path.exists(preprocessed):
+ print(f"Loading preprocessed few-shot data from {preprocessed}")
+ with open(preprocessed, "rb") as file:
+ data = pickle.load(file)
+ train, val = data["train"], data["val"]
+ else:
+ train = self.generate_fewshot_dataset(train, num_shots=num_shots)
+ val = self.generate_fewshot_dataset(val, num_shots=min(num_shots, 4))
+ data = {"train": train, "val": val}
+ print(f"Saving preprocessed few-shot data to {preprocessed}")
+ with open(preprocessed, "wb") as file:
+ pickle.dump(data, file, protocol=pickle.HIGHEST_PROTOCOL)
+
+ subsample = cfg.DATASET.SUBSAMPLE_CLASSES
+ train, val, test = OxfordPets.subsample_classes(train, val, test, subsample=subsample)
+
+ super().__init__(train_x=train, val=val, test=test)
diff --git a/datasets/imagenet.py b/datasets/imagenet.py
new file mode 100755
index 0000000..4357105
--- /dev/null
+++ b/datasets/imagenet.py
@@ -0,0 +1,91 @@
+import os
+import pickle
+from collections import OrderedDict
+
+from dassl.data.datasets import DATASET_REGISTRY, Datum, DatasetBase
+from dassl.utils import listdir_nohidden, mkdir_if_missing
+
+from .oxford_pets import OxfordPets
+
+
+@DATASET_REGISTRY.register()
+class ImageNet(DatasetBase):
+
+ dataset_dir = "imagenet"
+
+ def __init__(self, cfg):
+ root = os.path.abspath(os.path.expanduser(cfg.DATASET.ROOT))
+ self.dataset_dir = os.path.join(root, self.dataset_dir)
+ self.image_dir = os.path.join(self.dataset_dir, "images")
+ self.preprocessed = os.path.join(self.dataset_dir, "preprocessed.pkl")
+ self.split_fewshot_dir = os.path.join(self.dataset_dir, "split_fewshot")
+ mkdir_if_missing(self.split_fewshot_dir)
+
+ if os.path.exists(self.preprocessed):
+ with open(self.preprocessed, "rb") as f:
+ preprocessed = pickle.load(f)
+ train = preprocessed["train"]
+ test = preprocessed["test"]
+ else:
+ text_file = os.path.join(self.dataset_dir, "classnames.txt")
+ classnames = self.read_classnames(text_file)
+ train = self.read_data(classnames, "train")
+ # Follow standard practice to perform evaluation on the val set
+ # Also used as the val set (so evaluate the last-step model)
+ test = self.read_data(classnames, "val")
+
+ preprocessed = {"train": train, "test": test}
+ with open(self.preprocessed, "wb") as f:
+ pickle.dump(preprocessed, f, protocol=pickle.HIGHEST_PROTOCOL)
+
+ num_shots = cfg.DATASET.NUM_SHOTS
+ if num_shots >= 1:
+ seed = cfg.SEED
+ preprocessed = os.path.join(self.split_fewshot_dir, f"shot_{num_shots}-seed_{seed}.pkl")
+
+ if os.path.exists(preprocessed):
+ print(f"Loading preprocessed few-shot data from {preprocessed}")
+ with open(preprocessed, "rb") as file:
+ data = pickle.load(file)
+ train = data["train"]
+ else:
+ train = self.generate_fewshot_dataset(train, num_shots=num_shots)
+ data = {"train": train}
+ print(f"Saving preprocessed few-shot data to {preprocessed}")
+ with open(preprocessed, "wb") as file:
+ pickle.dump(data, file, protocol=pickle.HIGHEST_PROTOCOL)
+
+ subsample = cfg.DATASET.SUBSAMPLE_CLASSES
+ train, test = OxfordPets.subsample_classes(train, test, subsample=subsample)
+
+ super().__init__(train_x=train, val=test, test=test)
+
+ @staticmethod
+ def read_classnames(text_file):
+ """Return a dictionary containing
+ key-value pairs of : .
+ """
+ classnames = OrderedDict()
+ with open(text_file, "r") as f:
+ lines = f.readlines()
+ for line in lines:
+ line = line.strip().split(" ")
+ folder = line[0]
+ classname = " ".join(line[1:])
+ classnames[folder] = classname
+ return classnames
+
+ def read_data(self, classnames, split_dir):
+ split_dir = os.path.join(self.image_dir, split_dir)
+ folders = sorted(f.name for f in os.scandir(split_dir) if f.is_dir())
+ items = []
+
+ for label, folder in enumerate(folders):
+ imnames = listdir_nohidden(os.path.join(split_dir, folder))
+ classname = classnames[folder]
+ for imname in imnames:
+ impath = os.path.join(split_dir, folder, imname)
+ item = Datum(impath=impath, label=label, classname=classname)
+ items.append(item)
+
+ return items
diff --git a/datasets/imagenet_a.py b/datasets/imagenet_a.py
new file mode 100755
index 0000000..6079850
--- /dev/null
+++ b/datasets/imagenet_a.py
@@ -0,0 +1,46 @@
+import os
+
+from dassl.data.datasets import DATASET_REGISTRY, Datum, DatasetBase
+from dassl.utils import listdir_nohidden
+
+from .imagenet import ImageNet
+
+TO_BE_IGNORED = ["README.txt"]
+
+
+@DATASET_REGISTRY.register()
+class ImageNetA(DatasetBase):
+ """ImageNet-A(dversarial).
+
+ This dataset is used for testing only.
+ """
+
+ dataset_dir = "imagenet-adversarial"
+
+ def __init__(self, cfg):
+ root = os.path.abspath(os.path.expanduser(cfg.DATASET.ROOT))
+ self.dataset_dir = os.path.join(root, self.dataset_dir)
+ self.image_dir = os.path.join(self.dataset_dir, "imagenet-a")
+
+ text_file = os.path.join(self.dataset_dir, "classnames.txt")
+ classnames = ImageNet.read_classnames(text_file)
+
+ data = self.read_data(classnames)
+
+ super().__init__(train_x=data, test=data)
+
+ def read_data(self, classnames):
+ image_dir = self.image_dir
+ folders = listdir_nohidden(image_dir, sort=True)
+ folders = [f for f in folders if f not in TO_BE_IGNORED]
+ items = []
+
+ for label, folder in enumerate(folders):
+ imnames = listdir_nohidden(os.path.join(image_dir, folder))
+ classname = classnames[folder]
+ for imname in imnames:
+ impath = os.path.join(image_dir, folder, imname)
+ item = Datum(impath=impath, label=label, classname=classname)
+ items.append(item)
+
+ return items
diff --git a/datasets/imagenet_r.py b/datasets/imagenet_r.py
new file mode 100755
index 0000000..396902c
--- /dev/null
+++ b/datasets/imagenet_r.py
@@ -0,0 +1,46 @@
+import os
+
+from dassl.data.datasets import DATASET_REGISTRY, Datum, DatasetBase
+from dassl.utils import listdir_nohidden
+
+from .imagenet import ImageNet
+
+TO_BE_IGNORED = ["README.txt"]
+
+
+@DATASET_REGISTRY.register()
+class ImageNetR(DatasetBase):
+ """ImageNet-R(endition).
+
+ This dataset is used for testing only.
+ """
+
+ dataset_dir = "imagenet-rendition"
+
+ def __init__(self, cfg):
+ root = os.path.abspath(os.path.expanduser(cfg.DATASET.ROOT))
+ self.dataset_dir = os.path.join(root, self.dataset_dir)
+ self.image_dir = os.path.join(self.dataset_dir, "imagenet-r")
+
+ text_file = os.path.join(self.dataset_dir, "classnames.txt")
+ classnames = ImageNet.read_classnames(text_file)
+
+ data = self.read_data(classnames)
+
+ super().__init__(train_x=data, test=data)
+
+ def read_data(self, classnames):
+ image_dir = self.image_dir
+ folders = listdir_nohidden(image_dir, sort=True)
+ folders = [f for f in folders if f not in TO_BE_IGNORED]
+ items = []
+
+ for label, folder in enumerate(folders):
+ imnames = listdir_nohidden(os.path.join(image_dir, folder))
+ classname = classnames[folder]
+ for imname in imnames:
+ impath = os.path.join(image_dir, folder, imname)
+ item = Datum(impath=impath, label=label, classname=classname)
+ items.append(item)
+
+ return items
diff --git a/datasets/imagenet_sketch.py b/datasets/imagenet_sketch.py
new file mode 100755
index 0000000..b0069eb
--- /dev/null
+++ b/datasets/imagenet_sketch.py
@@ -0,0 +1,43 @@
+import os
+
+from dassl.data.datasets import DATASET_REGISTRY, Datum, DatasetBase
+from dassl.utils import listdir_nohidden
+
+from .imagenet import ImageNet
+
+
+@DATASET_REGISTRY.register()
+class ImageNetSketch(DatasetBase):
+ """ImageNet-Sketch.
+
+ This dataset is used for testing only.
+ """
+
+ dataset_dir = "imagenet-sketch"
+
+ def __init__(self, cfg):
+ root = os.path.abspath(os.path.expanduser(cfg.DATASET.ROOT))
+ self.dataset_dir = os.path.join(root, self.dataset_dir)
+ self.image_dir = os.path.join(self.dataset_dir, "images")
+
+ text_file = os.path.join(self.dataset_dir, "classnames.txt")
+ classnames = ImageNet.read_classnames(text_file)
+
+ data = self.read_data(classnames)
+
+ super().__init__(train_x=data, test=data)
+
+ def read_data(self, classnames):
+ image_dir = self.image_dir
+ folders = listdir_nohidden(image_dir, sort=True)
+ items = []
+
+ for label, folder in enumerate(folders):
+ imnames = listdir_nohidden(os.path.join(image_dir, folder))
+ classname = classnames[folder]
+ for imname in imnames:
+ impath = os.path.join(image_dir, folder, imname)
+ item = Datum(impath=impath, label=label, classname=classname)
+ items.append(item)
+
+ return items
diff --git a/datasets/imagenetv2.py b/datasets/imagenetv2.py
new file mode 100755
index 0000000..69f9a8a
--- /dev/null
+++ b/datasets/imagenetv2.py
@@ -0,0 +1,46 @@
+import os
+
+from dassl.data.datasets import DATASET_REGISTRY, Datum, DatasetBase
+from dassl.utils import listdir_nohidden
+
+from .imagenet import ImageNet
+
+
+@DATASET_REGISTRY.register()
+class ImageNetV2(DatasetBase):
+ """ImageNetV2.
+
+ This dataset is used for testing only.
+ """
+
+ dataset_dir = "imagenetv2"
+
+ def __init__(self, cfg):
+ root = os.path.abspath(os.path.expanduser(cfg.DATASET.ROOT))
+ self.dataset_dir = os.path.join(root, self.dataset_dir)
+ image_dir = "imagenetv2-matched-frequency-format-val"
+ self.image_dir = os.path.join(self.dataset_dir, image_dir)
+
+ text_file = os.path.join(self.dataset_dir, "classnames.txt")
+ classnames = ImageNet.read_classnames(text_file)
+
+ data = self.read_data(classnames)
+
+ super().__init__(train_x=data, test=data)
+
+ def read_data(self, classnames):
+ image_dir = self.image_dir
+ folders = list(classnames.keys())
+ items = []
+
+ for label in range(1000):
+ class_dir = os.path.join(image_dir, str(label))
+ imnames = listdir_nohidden(class_dir)
+ folder = folders[label]
+ classname = classnames[folder]
+ for imname in imnames:
+ impath = os.path.join(class_dir, imname)
+ item = Datum(impath=impath, label=label, classname=classname)
+ items.append(item)
+
+ return items
diff --git a/datasets/oxford_flowers.py b/datasets/oxford_flowers.py
new file mode 100755
index 0000000..514dc3e
--- /dev/null
+++ b/datasets/oxford_flowers.py
@@ -0,0 +1,89 @@
+import os
+import pickle
+import random
+from scipy.io import loadmat
+from collections import defaultdict
+
+from dassl.data.datasets import DATASET_REGISTRY, Datum, DatasetBase
+from dassl.utils import read_json, mkdir_if_missing
+
+from .oxford_pets import OxfordPets
+
+
+@DATASET_REGISTRY.register()
+class OxfordFlowers(DatasetBase):
+
+ dataset_dir = "oxford_flowers"
+
+ def __init__(self, cfg):
+ root = os.path.abspath(os.path.expanduser(cfg.DATASET.ROOT))
+ self.dataset_dir = os.path.join(root, self.dataset_dir)
+ self.image_dir = os.path.join(self.dataset_dir, "jpg")
+ self.label_file = os.path.join(self.dataset_dir, "imagelabels.mat")
+ self.lab2cname_file = os.path.join(self.dataset_dir, "cat_to_name.json")
+ self.split_path = os.path.join(self.dataset_dir, "split_zhou_OxfordFlowers.json")
+ self.split_fewshot_dir = os.path.join(self.dataset_dir, "split_fewshot")
+ mkdir_if_missing(self.split_fewshot_dir)
+
+ if os.path.exists(self.split_path):
+ train, val, test = OxfordPets.read_split(self.split_path, self.image_dir)
+ else:
+ train, val, test = self.read_data()
+ OxfordPets.save_split(train, val, test, self.split_path, self.image_dir)
+
+ num_shots = cfg.DATASET.NUM_SHOTS
+ if num_shots >= 1:
+ seed = cfg.SEED
+ preprocessed = os.path.join(self.split_fewshot_dir, f"shot_{num_shots}-seed_{seed}.pkl")
+
+ if os.path.exists(preprocessed):
+ print(f"Loading preprocessed few-shot data from {preprocessed}")
+ with open(preprocessed, "rb") as file:
+ data = pickle.load(file)
+ train, val = data["train"], data["val"]
+ else:
+ train = self.generate_fewshot_dataset(train, num_shots=num_shots)
+ val = self.generate_fewshot_dataset(val, num_shots=min(num_shots, 4))
+ data = {"train": train, "val": val}
+ print(f"Saving preprocessed few-shot data to {preprocessed}")
+ with open(preprocessed, "wb") as file:
+ pickle.dump(data, file, protocol=pickle.HIGHEST_PROTOCOL)
+
+ subsample = cfg.DATASET.SUBSAMPLE_CLASSES
+ train, val, test = OxfordPets.subsample_classes(train, val, test, subsample=subsample)
+
+ super().__init__(train_x=train, val=val, test=test)
+
+ def read_data(self):
+ tracker = defaultdict(list)
+ label_file = loadmat(self.label_file)["labels"][0]
+ for i, label in enumerate(label_file):
+ imname = f"image_{str(i + 1).zfill(5)}.jpg"
+ impath = os.path.join(self.image_dir, imname)
+ label = int(label)
+ tracker[label].append(impath)
+
+ print("Splitting data into 50% train, 20% val, and 30% test")
+
+ def _collate(ims, y, c):
+ items = []
+ for im in ims:
+ item = Datum(impath=im, label=y - 1, classname=c) # convert to 0-based label
+ items.append(item)
+ return items
+
+ lab2cname = read_json(self.lab2cname_file)
+ train, val, test = [], [], []
+ for label, impaths in tracker.items():
+ random.shuffle(impaths)
+ n_total = len(impaths)
+ n_train = round(n_total * 0.5)
+ n_val = round(n_total * 0.2)
+ n_test = n_total - n_train - n_val
+ assert n_train > 0 and n_val > 0 and n_test > 0
+ cname = lab2cname[str(label)]
+ train.extend(_collate(impaths[:n_train], label, cname))
+ val.extend(_collate(impaths[n_train : n_train + n_val], label, cname))
+ test.extend(_collate(impaths[n_train + n_val :], label, cname))
+
+ return train, val, test
diff --git a/datasets/oxford_pets.py b/datasets/oxford_pets.py
new file mode 100755
index 0000000..ef02a11
--- /dev/null
+++ b/datasets/oxford_pets.py
@@ -0,0 +1,186 @@
+import os
+import pickle
+import math
+import random
+from collections import defaultdict
+
+from dassl.data.datasets import DATASET_REGISTRY, Datum, DatasetBase
+from dassl.utils import read_json, write_json, mkdir_if_missing
+
+
+@DATASET_REGISTRY.register()
+class OxfordPets(DatasetBase):
+
+ dataset_dir = "oxford_pets"
+
+ def __init__(self, cfg):
+ root = os.path.abspath(os.path.expanduser(cfg.DATASET.ROOT))
+ self.dataset_dir = os.path.join(root, self.dataset_dir)
+ self.image_dir = os.path.join(self.dataset_dir, "images")
+ self.anno_dir = os.path.join(self.dataset_dir, "annotations")
+ self.split_path = os.path.join(self.dataset_dir, "split_zhou_OxfordPets.json")
+ self.split_fewshot_dir = os.path.join(self.dataset_dir, "split_fewshot")
+ mkdir_if_missing(self.split_fewshot_dir)
+
+ if os.path.exists(self.split_path):
+ train, val, test = self.read_split(self.split_path, self.image_dir)
+ else:
+ trainval = self.read_data(split_file="trainval.txt")
+ test = self.read_data(split_file="test.txt")
+ train, val = self.split_trainval(trainval)
+ self.save_split(train, val, test, self.split_path, self.image_dir)
+
+ num_shots = cfg.DATASET.NUM_SHOTS
+ # if num_shots >= 1:
+ seed = cfg.SEED
+ preprocessed = os.path.join(self.split_fewshot_dir, f"shot_{num_shots}-seed_{seed}.pkl")
+
+ if os.path.exists(preprocessed):
+ print(f"Loading preprocessed few-shot data from {preprocessed}")
+ with open(preprocessed, "rb") as file:
+ data = pickle.load(file)
+ train, val = data["train"], data["val"]
+ else:
+ train = self.generate_fewshot_dataset(train, num_shots=num_shots)
+ val = self.generate_fewshot_dataset(val, num_shots=min(num_shots, 4))
+ data = {"train": train, "val": val}
+ print(f"Saving preprocessed few-shot data to {preprocessed}")
+ with open(preprocessed, "wb") as file:
+ pickle.dump(data, file, protocol=pickle.HIGHEST_PROTOCOL)
+
+ subsample = cfg.DATASET.SUBSAMPLE_CLASSES
+ train, val, test = self.subsample_classes(train, val, test, subsample=subsample)
+
+ super().__init__(train_x=train, val=val, test=test)
+
+ def read_data(self, split_file):
+ filepath = os.path.join(self.anno_dir, split_file)
+ items = []
+
+ with open(filepath, "r") as f:
+ lines = f.readlines()
+ for line in lines:
+ line = line.strip()
+ imname, label, species, _ = line.split(" ")
+ breed = imname.split("_")[:-1]
+ breed = "_".join(breed)
+ breed = breed.lower()
+ imname += ".jpg"
+ impath = os.path.join(self.image_dir, imname)
+ label = int(label) - 1 # convert to 0-based index
+ item = Datum(impath=impath, label=label, classname=breed)
+ items.append(item)
+
+ return items
+
+ @staticmethod
+ def split_trainval(trainval, p_val=0.2):
+ p_trn = 1 - p_val
+ print(f"Splitting trainval into {p_trn:.0%} train and {p_val:.0%} val")
+ tracker = defaultdict(list)
+ for idx, item in enumerate(trainval):
+ label = item.label
+ tracker[label].append(idx)
+
+ train, val = [], []
+ for label, idxs in tracker.items():
+ n_val = round(len(idxs) * p_val)
+ assert n_val > 0
+ random.shuffle(idxs)
+ for n, idx in enumerate(idxs):
+ item = trainval[idx]
+ if n < n_val:
+ val.append(item)
+ else:
+ train.append(item)
+
+ return train, val
+
+ @staticmethod
+ def save_split(train, val, test, filepath, path_prefix):
+ def _extract(items):
+ out = []
+ for item in items:
+ impath = item.impath
+ label = item.label
+ classname = item.classname
+ impath = impath.replace(path_prefix, "")
+ if impath.startswith("/"):
+ impath = impath[1:]
+ out.append((impath, label, classname))
+ return out
+
+ train = _extract(train)
+ val = _extract(val)
+ test = _extract(test)
+
+ split = {"train": train, "val": val, "test": test}
+
+ write_json(split, filepath)
+ print(f"Saved split to {filepath}")
+
+ @staticmethod
+ def read_split(filepath, path_prefix):
+ def _convert(items):
+ out = []
+ for impath, label, classname in items:
+ impath = os.path.join(path_prefix, impath)
+ item = Datum(impath=impath, label=int(label), classname=classname)
+ out.append(item)
+ return out
+
+ print(f"Reading split from {filepath}")
+ split = read_json(filepath)
+ train = _convert(split["train"])
+ val = _convert(split["val"])
+ test = _convert(split["test"])
+
+ return train, val, test
+
+ @staticmethod
+ def subsample_classes(*args, subsample="all"):
+ """Divide classes into two groups. The first group
+ represents base classes while the second group represents
+ new classes.
+
+ Args:
+ args: a list of datasets, e.g. train, val and test.
+ subsample (str): what classes to subsample.
+ """
+ assert subsample in ["all", "base", "new"]
+
+ if subsample == "all":
+ return args
+
+ dataset = args[0]
+ labels = set()
+ for item in dataset:
+ labels.add(item.label)
+ labels = list(labels)
+ labels.sort()
+ n = len(labels)
+ # Divide classes into two halves
+ m = math.ceil(n / 2)
+
+ print(f"SUBSAMPLE {subsample.upper()} CLASSES!")
+ if subsample == "base":
+ selected = labels[:m] # take the first half
+ else:
+ selected = labels[m:] # take the second half
+ relabeler = {y: y_new for y_new, y in enumerate(selected)}
+
+ output = []
+ for dataset in args:
+ dataset_new = []
+ for item in dataset:
+ if item.label not in selected:
+ continue
+ item_new = Datum(
+ impath=item.impath,
+ label=relabeler[item.label],
+ classname=item.classname
+ )
+ dataset_new.append(item_new)
+ output.append(dataset_new)
+
+ return output
diff --git a/datasets/stanford_cars.py b/datasets/stanford_cars.py
new file mode 100755
index 0000000..3bff66e
--- /dev/null
+++ b/datasets/stanford_cars.py
@@ -0,0 +1,75 @@
+import os
+import pickle
+from scipy.io import loadmat
+
+from dassl.data.datasets import DATASET_REGISTRY, Datum, DatasetBase
+from dassl.utils import mkdir_if_missing
+
+from .oxford_pets import OxfordPets
+
+
+@DATASET_REGISTRY.register()
+class StanfordCars(DatasetBase):
+
+ dataset_dir = "stanford_cars"
+
+ def __init__(self, cfg):
+ root = os.path.abspath(os.path.expanduser(cfg.DATASET.ROOT))
+ self.dataset_dir = os.path.join(root, self.dataset_dir)
+ self.split_path = os.path.join(self.dataset_dir, "split_zhou_StanfordCars.json")
+ self.split_fewshot_dir = os.path.join(self.dataset_dir, "split_fewshot")
+ mkdir_if_missing(self.split_fewshot_dir)
+
+ if os.path.exists(self.split_path):
+ train, val, test = OxfordPets.read_split(self.split_path, self.dataset_dir)
+ else:
+ trainval_file = os.path.join(self.dataset_dir, "devkit", "cars_train_annos.mat")
+ test_file = os.path.join(self.dataset_dir, "cars_test_annos_withlabels.mat")
+ meta_file = os.path.join(self.dataset_dir, "devkit", "cars_meta.mat")
+ trainval = self.read_data("cars_train", trainval_file, meta_file)
+ test = self.read_data("cars_test", test_file, meta_file)
+ train, val = OxfordPets.split_trainval(trainval)
+ OxfordPets.save_split(train, val, test, self.split_path, self.dataset_dir)
+
+ num_shots = cfg.DATASET.NUM_SHOTS
+ if num_shots >= 1:
+ seed = cfg.SEED
+ preprocessed = os.path.join(self.split_fewshot_dir, f"shot_{num_shots}-seed_{seed}.pkl")
+
+ if os.path.exists(preprocessed):
+ print(f"Loading preprocessed few-shot data from {preprocessed}")
+ with open(preprocessed, "rb") as file:
+ data = pickle.load(file)
+ train, val = data["train"], data["val"]
+ else:
+ train = self.generate_fewshot_dataset(train, num_shots=num_shots)
+ val = self.generate_fewshot_dataset(val, num_shots=min(num_shots, 4))
+ data = {"train": train, "val": val}
+ print(f"Saving preprocessed few-shot data to {preprocessed}")
+ with open(preprocessed, "wb") as file:
+ pickle.dump(data, file, protocol=pickle.HIGHEST_PROTOCOL)
+
+ subsample = cfg.DATASET.SUBSAMPLE_CLASSES
+ train, val, test = OxfordPets.subsample_classes(train, val, test, subsample=subsample)
+
+ super().__init__(train_x=train, val=val, test=test)
+
+ def read_data(self, image_dir, anno_file, meta_file):
+ anno_file = loadmat(anno_file)["annotations"][0]
+ meta_file = loadmat(meta_file)["class_names"][0]
+ items = []
+
+ for i in range(len(anno_file)):
+ imname = anno_file[i]["fname"][0]
+ impath = os.path.join(self.dataset_dir, image_dir, imname)
+ label = anno_file[i]["class"][0, 0]
+ label = int(label) - 1 # convert to 0-based index
+ classname = meta_file[label][0]
+ names = classname.split(" ")
+ year = names.pop(-1)
+ names.insert(0, year)
+ classname = " ".join(names)
+ item = Datum(impath=impath, label=label, classname=classname)
+ items.append(item)
+
+ return items
diff --git a/datasets/sun397.py b/datasets/sun397.py
new file mode 100755
index 0000000..b4507f5
--- /dev/null
+++ b/datasets/sun397.py
@@ -0,0 +1,80 @@
+import os
+import pickle
+
+from dassl.data.datasets import DATASET_REGISTRY, Datum, DatasetBase
+from dassl.utils import mkdir_if_missing
+
+from .oxford_pets import OxfordPets
+
+
+@DATASET_REGISTRY.register()
+class SUN397(DatasetBase):
+
+ dataset_dir = "sun397"
+
+ def __init__(self, cfg):
+ root = os.path.abspath(os.path.expanduser(cfg.DATASET.ROOT))
+ self.dataset_dir = os.path.join(root, self.dataset_dir)
+ self.image_dir = os.path.join(self.dataset_dir, "SUN397")
+ self.split_path = os.path.join(self.dataset_dir, "split_zhou_SUN397.json")
+ self.split_fewshot_dir = os.path.join(self.dataset_dir, "split_fewshot")
+ mkdir_if_missing(self.split_fewshot_dir)
+
+ if os.path.exists(self.split_path):
+ train, val, test = OxfordPets.read_split(self.split_path, self.image_dir)
+ else:
+ classnames = []
+ with open(os.path.join(self.dataset_dir, "ClassName.txt"), "r") as f:
+ lines = f.readlines()
+ for line in lines:
+ line = line.strip()[1:] # remove /
+ classnames.append(line)
+ cname2lab = {c: i for i, c in enumerate(classnames)}
+ trainval = self.read_data(cname2lab, "Training_01.txt")
+ test = self.read_data(cname2lab, "Testing_01.txt")
+ train, val = OxfordPets.split_trainval(trainval)
+ OxfordPets.save_split(train, val, test, self.split_path, self.image_dir)
+
+ num_shots = cfg.DATASET.NUM_SHOTS
+ if num_shots >= 1:
+ seed = cfg.SEED
+ preprocessed = os.path.join(self.split_fewshot_dir, f"shot_{num_shots}-seed_{seed}.pkl")
+
+ if os.path.exists(preprocessed):
+ print(f"Loading preprocessed few-shot data from {preprocessed}")
+ with open(preprocessed, "rb") as file:
+ data = pickle.load(file)
+ train, val = data["train"], data["val"]
+ else:
+ train = self.generate_fewshot_dataset(train, num_shots=num_shots)
+ val = self.generate_fewshot_dataset(val, num_shots=min(num_shots, 4))
+ data = {"train": train, "val": val}
+ print(f"Saving preprocessed few-shot data to {preprocessed}")
+ with open(preprocessed, "wb") as file:
+ pickle.dump(data, file, protocol=pickle.HIGHEST_PROTOCOL)
+
+ subsample = cfg.DATASET.SUBSAMPLE_CLASSES
+ train, val, test = OxfordPets.subsample_classes(train, val, test, subsample=subsample)
+
+ super().__init__(train_x=train, val=val, test=test)
+
+ def read_data(self, cname2lab, text_file):
+ text_file = os.path.join(self.dataset_dir, text_file)
+ items = []
+
+ with open(text_file, "r") as f:
+ lines = f.readlines()
+ for line in lines:
+ imname = line.strip()[1:] # remove /
+ classname = os.path.dirname(imname)
+ label = cname2lab[classname]
+ impath = os.path.join(self.image_dir, imname)
+
+ names = classname.split("/")[1:] # remove 1st letter
+ names = names[::-1] # put words like indoor/outdoor at first
+ classname = " ".join(names)
+
+ item = Datum(impath=impath, label=label, classname=classname)
+ items.append(item)
+
+ return items
diff --git a/datasets/ucf101.py b/datasets/ucf101.py
new file mode 100755
index 0000000..94439e4
--- /dev/null
+++ b/datasets/ucf101.py
@@ -0,0 +1,84 @@
+import os
+import pickle
+import re
+
+from dassl.data.datasets import DATASET_REGISTRY, Datum, DatasetBase
+from dassl.utils import mkdir_if_missing
+
+from .oxford_pets import OxfordPets
+
+
+@DATASET_REGISTRY.register()
+class UCF101(DatasetBase):
+
+ dataset_dir = "ucf101"
+
+ def __init__(self, cfg):
+ root = os.path.abspath(os.path.expanduser(cfg.DATASET.ROOT))
+ self.dataset_dir = os.path.join(root, self.dataset_dir)
+ self.image_dir = os.path.join(self.dataset_dir, "UCF-101-midframes")
+ self.split_path = os.path.join(self.dataset_dir, "split_zhou_UCF101.json")
+ self.split_fewshot_dir = os.path.join(self.dataset_dir, "split_fewshot")
+ mkdir_if_missing(self.split_fewshot_dir)
+
+ if os.path.exists(self.split_path):
+ train, val, test = OxfordPets.read_split(self.split_path, self.image_dir)
+ else:
+ cname2lab = {}
+ filepath = os.path.join(self.dataset_dir, "ucfTrainTestlist/classInd.txt")
+ with open(filepath, "r") as f:
+ lines = f.readlines()
+ for line in lines:
+ label, classname = line.strip().split(" ")
+ label = int(label) - 1 # conver to 0-based index
+ cname2lab[classname] = label
+
+ trainval = self.read_data(cname2lab, "ucfTrainTestlist/trainlist01.txt")
+ test = self.read_data(cname2lab, "ucfTrainTestlist/testlist01.txt")
+ train, val = OxfordPets.split_trainval(trainval)
+ OxfordPets.save_split(train, val, test, self.split_path, self.image_dir)
+
+ num_shots = cfg.DATASET.NUM_SHOTS
+ if num_shots >= 1:
+ seed = cfg.SEED
+ preprocessed = os.path.join(self.split_fewshot_dir, f"shot_{num_shots}-seed_{seed}.pkl")
+
+ if os.path.exists(preprocessed):
+ print(f"Loading preprocessed few-shot data from {preprocessed}")
+ with open(preprocessed, "rb") as file:
+ data = pickle.load(file)
+ train, val = data["train"], data["val"]
+ else:
+ train = self.generate_fewshot_dataset(train, num_shots=num_shots)
+ val = self.generate_fewshot_dataset(val, num_shots=min(num_shots, 4))
+ data = {"train": train, "val": val}
+ print(f"Saving preprocessed few-shot data to {preprocessed}")
+ with open(preprocessed, "wb") as file:
+ pickle.dump(data, file, protocol=pickle.HIGHEST_PROTOCOL)
+
+ subsample = cfg.DATASET.SUBSAMPLE_CLASSES
+ train, val, test = OxfordPets.subsample_classes(train, val, test, subsample=subsample)
+
+ super().__init__(train_x=train, val=val, test=test)
+
+ def read_data(self, cname2lab, text_file):
+ text_file = os.path.join(self.dataset_dir, text_file)
+ items = []
+
+ with open(text_file, "r") as f:
+ lines = f.readlines()
+ for line in lines:
+ line = line.strip().split(" ")[0] # trainlist: filename, label
+ action, filename = line.split("/")
+ label = cname2lab[action]
+
+ elements = re.findall("[A-Z][^A-Z]*", action)
+ renamed_action = "_".join(elements)
+
+ filename = filename.replace(".avi", ".jpg")
+ impath = os.path.join(self.image_dir, renamed_action, filename)
+
+ item = Datum(impath=impath, label=label, classname=renamed_action)
+ items.append(item)
+
+ return items
diff --git a/descriptors/descriptors_caltech101.json b/descriptors/descriptors_caltech101.json
new file mode 100644
index 0000000..2770d3d
--- /dev/null
+++ b/descriptors/descriptors_caltech101.json
@@ -0,0 +1 @@
+{"Airplane": ["metal body", "wings", "tail", "propellers or jet engines", "landing gear", "cockpit", "windows", "fuselage", "control surfaces"], "Face": ["Human face", "Eyes, nose, mouth, and ears", "Hair", "Skin tone", "Facial expressions", "Clothing", "Background"], "Motorbike": ["metal frame", "handlebars", "engine", "exhaust pipe", "seat", "fuel tank", "wheels", "brakes", "lights"], "Leopard": ["four-limbed mammal", "yellow, tan, or white fur with black spots", "long tail", "large eyes", "muscular body", "sharp claws", "tufted ears"], "accordion": ["a rectangular shape", "a bellows in the middle", "a keyboard on one side", "a set of buttons on the other side", "a strap for carrying", "a set of reeds that produce sound when air is forced through them"], "anchor": ["metal object", "four-pointed shape", "two arms that extend outward", "a ring at the top for attaching a rope", "a flat base for securing it to the ground"], "ant": ["small, six-legged insect", "black, brown, or red in color", "segmented body", "antennae", "mandibles", "two sets of wings (in some species)", "three body parts (head, thorax, and abdomen)"], "barrel": ["wooden or metal construction", "metal bands around the circumference", "a lid or bung hole", "a spigot or tap for draining liquid", "a handle for carrying or moving the barrel"], "bass": ["four strings", "frets on the neck", "a long neck", "a large body", "a pickguard", "tuning pegs", "a bridge", "a sound hole"], "beaver": ["large, flat tail", "webbed hind feet", "large, orange-brown incisors", "short, thick fur", "small ears and eyes", "large, paddle-shaped front feet", "wide, flat head"], "binocular": ["two eyepieces", "an adjustable focus knob", "a diopter adjustment knob", "a rubberized body", "a strap for carrying", "a lens cover or cap"], "bonsai": ["shallow pot or tray", "pruned branches and foliage", "exposed roots", "wire or string to shape the branches", "moss or rocks around the base", "small figurines or decorations"], "brain": ["three-dimensional organ", "wrinkled surface", "two hemispheres", "four lobes", "cerebellum", "brain stem", "ventricles", "corpus callosum"], "brontosaurus": ["four-legged", "long tail", "small head", "large body", "thick, scaly skin", "long, thin neck", "small, pointed teeth"], "buddha": ["serene facial expression", "bald head", "elongated earlobes", "wearing a robe", "seated in a lotus position", "hands in a mudra position", "surrounded by a halo of light"], "butterfly": ["colorful wings", "antennae", "three pairs of legs", "proboscis (long, thin tube for drinking nectar)", "compound eyes", "small, slender body"], "camera": ["electronic device", "black or silver", "a lens", "a viewfinder", "a shutter button", "a flash", "a power cord", "input ports for connecting to other devices", "a memory card slot", "a tripod mount"], "cannon": ["large, cylindrical barrel", "metal construction", "wheels for mobility", "a firing mechanism", "a muzzle for the projectile", "a base plate for stability", "a sight for aiming"], "car side": ["four wheels", "a hood", "a windshield", "side mirrors", "a door handle", "a side window", "a side panel", "a side skirt", "a wheel well", "a side marker light"], "ceiling fan": ["a motorized fan", "a central hub with blades attached", "a light fixture or other decorative elements", "a chain or pull cord for controlling the fan", "a wall switch or remote control for turning the fan on and off", "a mounting bracket for attaching the fan to the ceiling"], "cellphone": ["electronic device", "small, rectangular shape", "touchscreen display", "one or more buttons", "a microphone", "a camera", "a headphone jack", "a power cord", "input ports for connecting to other devices", "a SIM card slot"], "chair": ["four legs", "a seat", "a backrest", "armrests (optional)", "a cushion (optional)", "upholstery (optional)", "a frame made of wood, metal, or plastic"], "chandelier": ["hanging light fixture", "metal frame", "multiple arms with light bulbs", "decorative glass or crystal pieces", "a chain or cord for hanging", "a canopy or ceiling plate for mounting"], "cougar body": ["large, muscular body", "long tail", "short, rounded ears", "yellow-brown fur", "black-tipped tail", "white fur on the chest and chin", "black markings on the face", "long, sharp claws"], "cougar face": ["large, round head", "pointed ears", "long whiskers", "black nose", "yellow eyes", "black-tipped tail", "long, muscular body", "short fur with spots or stripes"], "crab": ["crustacean", "two large claws", "five pairs of legs", "a hard, segmented shell", "two eyes on stalks", "antennae", "a tail flap"], "crayfish": ["crustacean", "red, blue, or brown", "two large claws", "two antennae", "eight legs", "two compound eyes", "a tail with a fan-like shape"], "crocodile": ["four-limbed reptile", "long, powerful tail", "large, scaly body", "long, pointed snout", "large, sharp teeth", "webbed feet", "yellow, green, or brown in color"], "crocodile head": ["long, pointed snout", "large, powerful jaws", "rows of sharp, interlocking teeth", "two small eyes on the top of the head", "a bony ridge along the back of the head", "a thick, scaly hide", "a long, muscular tail"], "cup": ["cylindrical shape", "handle", "base", "rim", "lid", "spout", "material (ceramic, plastic, metal, etc.)", "color"], "dalmatian": ["black and white spotted coat", "short, dense fur", "long muzzle", "long, thin tail", "pointed ears", "muscular body", "webbed feet"], "dollar bill": ["green in color", "portrait of George Washington on the front", "the words \"One Dollar\" printed on the front", "the Great Seal of the United States on the back", "the words \"United States of America\" printed on the back", "a serial number printed on the front and back", "a series year printed on the front and back"], "dolphin": ["streamlined body", "curved dorsal fin", "pointed snout", "flippers", "gray, black, or white coloring", "blowhole on the top of the head", "long, curved mouth", "eyes located on the sides of the head"], "dragonfly": ["four wings", "long, thin body", "two large compound eyes", "two antennae", "three pairs of legs", "bright colors such as yellow, green, blue, or red", "a long, thin tail"], "electric guitar": ["six strings", "a long neck", "a body with a curved shape", "a pickguard", "a bridge", "pickups", "knobs and switches", "a headstock with tuning pegs"], "elephant": ["gray or brown skin", "long trunk", "two large ears", "four legs", "two tusks", "large, curved back", "long tail"], "emu": ["long neck and legs", "black and grey feathers", "long, thin beak", "small head", "long, thin tail", "two toes on each foot"], "euphonium": ["brass instrument", "conical bore", "three or four valves", "bell-shaped mouthpiece", "three- or four-valved piston", "long, curved tubing", "wide bell at the end of the tubing"], "ewer": ["a large, pitcher-like vessel", "a handle on one side", "a spout on the other side", "a lid or stopper", "a wide, flat base", "a narrow neck", "a decorative design or pattern"], "ferry": ["flat deck", "multiple decks", "large windows", "multiple ramps for loading and unloading", "multiple engines", "multiple lifeboats", "multiple masts", "multiple smoke stacks"], "flamingo": ["long, slender neck", "long, thin legs", "pink or reddish-orange feathers", "black-tipped wings", "curved beak", "webbed feet", "long, curved tail feathers"], "flamingo head": ["pink or reddish-pink feathers", "long, curved neck", "long, thin beak", "black eyes", "black legs", "black and white feathers on the head and neck"], "garfield": ["black stripes", "white muzzle", "large eyes", "long tail", "white paws", "large ears", "mischievous expression"], "gerenuk": ["slender body", "long, thin legs", "pointed ears", "short, curved horns", "reddish-brown coat", "white underbelly", "black stripes on the legs and face"], "gramophone": ["wooden or metal horn", "turntable", "needle arm", "crank handle", "metal or plastic platter", "tone arm", "volume control", "power switch"], "grand piano": ["large, rectangular instrument", "black or brown finish", "three legs", "88 keys", "a lid that can be opened and closed", "a music stand", "pedals at the base", "strings and hammers inside"], "hawksbill": ["large, curved beak", "long, pointed wings", "brown, black, and white feathers", "yellow or orange markings on the head and neck", "webbed feet", "long tail", "yellow eyes"], "headphone": ["electronic device", "black, white, or silver", "two earpieces connected by a headband", "foam or plastic earpads", "a 3.5mm audio jack", "a microphone", "a volume control", "a power switch"], "hedgehog": ["small mammal", "spines covering its body", "short legs", "small ears", "pointed snout", "black, brown, or white fur", "small eyes", "short tail"], "helicopter": ["rotary-wing aircraft", "a main rotor and a tail rotor", "a fuselage with a cockpit", "a tail boom", "landing skids", "a tail fin", "a tail rotor", "a main rotor", "a powerplant"], "ibis": ["long, curved bill", "white, black, or grey feathers", "long neck", "long wings", "long tail", "yellow or red facial skin"], "inline skate": ["a boot-like shoe with a hard outer shell", "four or five wheels arranged in a single line", "a brake on the back wheel", "a buckle or lacing system to secure the foot", "a toe stop for stopping and turning", "a frame connecting the wheels and the shoe"], "joshua tree": ["a large, spiky, evergreen tree", "a thick, gnarled trunk", "long, spiky branches", "small, green leaves", "yellow-green flowers", "round, greenish-brown fruits"], "kangaroo": ["four-limbed marsupial", "long, muscular tail", "large, powerful hind legs", "small front legs", "long, pointed ears", "short, soft fur", "pouch on the abdomen", "long, pointed snout"], "ketch": ["two-masted sailing vessel", "a main mast and a mizzen mast", "a gaff-rigged mainsail and a mizzen sail", "a bowsprit", "a jib and a staysail", "a boom", "a rudder and a tiller", "a cabin and a cockpit"], "lamp": ["a light source", "a base or stand", "a shade or cover", "a switch or button to turn the light on and off", "a power cord", "a bulb or LED", "a reflector or diffuser to spread the light"], "laptop": ["electronic device", "black or grey", "a flat, rectangular screen", "a keyboard and trackpad", "a power cord", "input ports for connecting to other devices", "a battery", "a hinge to open and close the laptop"], "llama": ["long, thick fur", "short ears", "long, curved neck", "short, stubby tail", "long legs", "two-toed hooves", "long, curved eyelashes"], "lobster": ["crustacean", "two large claws", "five pairs of legs", "two antennae", "a hard, spiny shell", "a tail", "red or brown in color"], "lotus": ["aquatic plant", "large, round leaves", "long, thin stems", "large, showy flowers", "yellow, pink, or white petals", "a seed pod at the center of the flower", "a root system that anchors the plant in the mud"], "mandolin": ["stringed instrument", "small, pear-shaped body", "8 strings", "frets on the neck", "two sound holes", "tuning pegs", "bridge", "pickguard"], "mayfly": ["small, delicate insect", "two or three pairs of wings", "long antennae", "slender body", "short life span", "usually found near water", "often have a pale or light-colored body with dark markings"], "menorah": ["a candelabra with seven or nine branches", "a base to support the branches", "a central stem or shaft", "a tray or plate to hold the candles", "a holder for the shamash (the candle used to light the other candles)", "a decorative design or motif on the base or stem"], "metronome": ["a mechanical device", "a pendulum or weighted arm", "a dial or knob to adjust the speed", "a ticking sound", "a base or stand to support the device", "a winding key to start the device"], "minaret": ["usually made of brick or stone", "typically found near a mosque", "often has a balcony or platform at the top", "may have a dome or spire at the top", "may have a crescent moon or other Islamic symbols at the top"], "nautilus": ["spiral shell", "tentacles", "two eyes on stalks", "two pairs of gills", "a siphon for jet propulsion", "a funnel-shaped opening", "a pair of retractable tentacles with suction cups"], "octopus": ["soft, slimy body", "two eyes and four pairs of arms", "two rows of suction cups on each arm", "a beak-like mouth", "a siphon for jet propulsion", "a mantle with an internal shell", "a variety of colors and patterns"], "okapi": ["reddish-brown or dark brown fur", "white stripes on the legs and hindquarters", "long neck and head", "short, tufted ears", "long, black tongue", "white stripes on the face", "white-tipped tail"], "pagoda": ["typically made of wood or stone", "typically has a curved roof with multiple eaves", "often has a spire or finial on the top", "often has ornate carvings or decorations", "often has a staircase leading up to the entrance"], "panda": ["large, round head", "small ears", "short tail", "black patches around the eyes", "white muzzle", "thick fur", "long, curved claws"], "pigeon": ["small, stout-bodied bird", "gray, white, or brown feathers", "short beak", "small head", "short legs", "long tail", "iridescent neck feathers", "cooing sound"], "pizza": ["round shape", "crust with a raised edge", "tomato sauce", "cheese", "toppings such as pepperoni, mushrooms, olives, etc.", "melted cheese", "herbs such as oregano or basil"], "platypus": ["egg-laying mammal", "brown fur", "webbed feet", "duck-like bill", "flat tail", "small eyes and ears", "two front legs with claws"], "pyramid": ["triangular shape", "pointed top", "flat base", "symmetrical sides", "smooth or rough stone blocks", "hieroglyphs or other decorations"], "revolver": ["handgun", "cylindrical shape", "metal body", "trigger", "hammer", "cylinder with multiple chambers", "barrel", "grip"], "rhino": ["two horns on its snout", "gray or brown in color", "large, square-shaped head", "short, stubby legs", "thick, leathery skin", "small ears", "large, curved mouth"], "rooster": ["four-limbed bird", "red or orange comb on top of head", "wattles on the side of the head", "long tail feathers", "spurs on the back of the legs", "bright, colorful feathers", "sharp beak and claws"], "saxophone": ["brass or silver metal body", "curved neck", "bell-shaped end", "keys along the body", "mouthpiece", "reed", "strap for carrying"], "schooner": ["two or more masts", "a bowsprit", "a long, narrow hull", "a large, triangular sail", "a jib sail", "a gaff sail", "a boom", "a rudder", "a bow and stern"], "scissors": ["handles for gripping", "sharp edges on the blades", "a pointed tip on one of the blades", "a thumb and finger loop on the handles", "a locking mechanism to keep the blades closed when not in use"], "scorpion": ["arachnid", "eight legs", "two large pincers", "a segmented tail with a stinger", "a hard exoskeleton", "a pair of eyes on the head", "a pair of antennae on the head"], "sea horse": ["small fish-like creature", "long, thin snout", "small eyes", "long, thin body", "long, thin tail", "small fins", "bony plates on the body", "bright colors such as yellow, orange, and red"], "snoopy": ["cartoon character", "white fur", "black ears", "black nose", "round head", "large eyes", "red collar", "yellow shirt with black stripes"], "soccer ball": ["round shape", "black and white pentagonal and hexagonal pattern", "made of leather or synthetic material", "inflated with air", "32 panels", "four or more layers of stitching"], "stapler": ["metal or plastic device", "rectangular shape", "a handle for squeezing", "a spring-loaded mechanism", "a base for holding staples", "a slot for inserting staples", "a release button for removing staples"], "starfish": ["usually orange, red, or brown", "star-shaped body", "spiny skin", "small, tube-like feet", "central disc with a mouth at the center"], "stegosaurus": ["large, bony plates along its back", "four spikes at the end of its tail", "small head with a beak-like mouth", "short, thick neck", "small, pointed teeth", "long hind legs and short forelegs"], "stop sign": ["red background with white lettering", "the word \"STOP\" in large, white capital letters", "a white border around the sign", "a white arrow pointing in the direction of the stop", "a reflective coating on the sign"], "strawberry": ["red, heart-shaped fruit", "small, green leaves", "white seeds on the surface", "yellow or white center", "pointed tip", "glossy texture"], "sunflower": ["yellow petals", "a large, dark center", "a long, thin stem", "large, green leaves", "a thick, woody stem", "a large, round seed head"], "tick": ["small, oval-shaped body", "eight legs", "two antennae", "a hard, scaly outer shell", "a pair of mouthparts", "a pair of eyes", "a pair of claws at the end of each leg"], "trilobite": ["an extinct marine arthropod", "a segmented body with three distinct lobes", "a hard exoskeleton", "two antennae", "two compound eyes", "a pair of mandibles", "a pair of maxillae", "a pair of legs per segment"], "umbrella": ["collapsible canopy", "metal or plastic ribs", "a handle", "a curved or straight shaft", "a pointed tip", "a fabric cover", "a closure mechanism such as a button or latch"], "watch": ["small, round or rectangular face", "metal or plastic band", "digital or analog display", "buttons or knobs for setting the time", "a crown for winding the watch", "a battery compartment", "a clasp or buckle for fastening the watch to the wrist"], "water lilly": ["aquatic plant", "large, round, floating leaves", "white, pink, or yellow flowers", "long, thin stems", "a root system that anchors the plant to the bottom of the water", "a thick, waxy coating on the leaves and flowers to protect them from the water"], "wheelchair": ["four wheels", "a seat and backrest", "armrests", "footrests", "a frame made of metal or plastic", "adjustable height and recline", "adjustable footplates", "a brake system", "a joystick or other control device"], "wild cat": ["four-legged mammal", "pointed ears", "long whiskers", "short fur", "long tail", "sharp claws", "round eyes", "pointed muzzle"], "windsor chair": ["wooden chair", "curved backrest", "spindles or slats", "armrests", "a seat with a saddle-shaped curve", "four legs, usually splayed outward", "a hoop-shaped backrest", "a comb-shaped crest rail"], "wrench": ["metal tool", "long handle", "adjustable head", "open or closed end", "various sizes and shapes", "a ring or loop at the end of the handle", "a flat or curved jaw"], "yin yang": ["two curved shapes, one black and one white, connected in the middle", "a black dot in the white shape and a white dot in the black shape", "a circle surrounding the two shapes", "a line dividing the two shapes in the middle"]}
\ No newline at end of file
diff --git a/descriptors/descriptors_dtd.json b/descriptors/descriptors_dtd.json
new file mode 100644
index 0000000..9955b56
--- /dev/null
+++ b/descriptors/descriptors_dtd.json
@@ -0,0 +1,289 @@
+{
+ "banded": [
+ "a repeating pattern of light and dark bands",
+ "the bands are of different widths",
+ "the bands may be of different colors",
+ "the bands may be curved or straight",
+ "the bands may be parallel or intersecting"
+ ],
+ "blotchy": [
+ "an uneven or mottled surface",
+ "a variety of colors or shades",
+ "a raised or bumpy texture",
+ "a matte finish"
+ ],
+ "braided": [
+ "three or more strands of material woven together",
+ "a tight, interlocking pattern"
+ ],
+ "bubbly": [
+ "small, round, and raised bumps",
+ "a smooth or glossy surface",
+ "a three-dimensional appearance",
+ "a light-reflecting quality"
+ ],
+ "bumpy": [
+ "an uneven surface",
+ "raised or indented areas",
+ "a rough or bumpy feel"
+ ],
+ "chequered": [
+ "a repeating pattern of squares or rectangles",
+ "alternating light and dark colors",
+ "sharp, defined lines between the squares or rectangles"
+ ],
+ "cobwebbed": [
+ "a web-like pattern",
+ "made of thin, silky strands",
+ "often found in dark, damp places",
+ "can be sticky to the touch",
+ "can be difficult to remove once entangled"
+ ],
+ "cracked": [
+ "a surface with cracks",
+ "the cracks may be straight or curved",
+ "the cracks may be of different sizes",
+ "the cracks may be close together or far apart",
+ "the cracks may be deep or shallow",
+ "the cracks may be filled with dirt or debris"
+ ],
+ "crosshatched": [
+ "a series of parallel lines that intersect to form a grid",
+ "the lines may be of different thicknesses",
+ "the lines may be of different colors",
+ "the texture may be regular or irregular",
+ "the texture may be applied to a surface or object"
+ ],
+ "crystalline": [
+ "a repeating pattern of shapes",
+ "sharp edges",
+ "a glossy or shiny surface",
+ "a transparent or translucent appearance",
+ "a three-dimensional structure"
+ ],
+ "dotted": [
+ "a series of small, round dots",
+ "evenly spaced",
+ "can be of any color",
+ "may be on a background of any color",
+ "may be in a regular or irregular pattern"
+ ],
+ "fibrous": [
+ "closeup view",
+ "many small, thin strands",
+ "light reflecting off of strands",
+ "strands of different colors",
+ "a textured surface"
+ ],
+ "flecked": [
+ "small, irregularly shaped pieces",
+ "a variety of colors",
+ "a rough or bumpy surface"
+ ],
+ "freckled": [
+ "small, round spots",
+ "evenly distributed",
+ "same color as surrounding skin",
+ "darker than surrounding skin"
+ ],
+ "frilly": [
+ "intricate, lacy patterns",
+ "delicate and often transparent",
+ "light and airy",
+ "can be made of various materials, including paper, fabric, or metal"
+ ],
+ "gauzy": [
+ "a thin, translucent fabric",
+ "a light, airy feel",
+ "a delicate or lacy appearance"
+ ],
+ "grid": [
+ "a repeating pattern of squares or rectangles",
+ "straight lines forming a consistent grid",
+ "evenly spaced lines and intersections",
+ "a consistent color or tone throughout"
+ ],
+ "grooved": [
+ "a series of parallel lines",
+ "a repeating pattern",
+ "a raised or indented surface"
+ ],
+ "honeycombed": [
+ "a repeating pattern of hexagonal shapes",
+ "a honey-like color",
+ "a smooth, glossy surface"
+ ],
+ "interlaced": [
+ "a repeating pattern of light and dark lines",
+ "the lines are usually perpendicular to each other",
+ "the lines may be of different thicknesses",
+ "the lines may be of different colors"
+ ],
+ "knitted": [
+ "small, interconnected loops",
+ "a variety of colors",
+ "a three-dimensional appearance"
+ ],
+ "lacelike": [
+ "intricate, detailed pattern",
+ "often made of lace or other delicate material",
+ "can be white, cream, or other light colors",
+ "often used for decoration",
+ "green leaves",
+ "stem",
+ "roots",
+ "flowers (optional)",
+ "fruit (optional)"
+ ],
+ "lined": [
+ "a series of parallel lines",
+ "can be straight or curved",
+ "may be of different colors",
+ "may be of different widths",
+ "may be of different thicknesses"
+ ],
+ "marbled": [
+ "a swirl or whorl pattern",
+ "two or more colors",
+ "a glossy or shiny surface",
+ "a smooth or textured surface"
+ ],
+ "matted": [
+ "a surface with a raised or relief pattern",
+ "a surface that is not smooth",
+ "a surface with a lot of texture",
+ "a surface that is not glossy or shiny"
+ ],
+ "meshed": [
+ "a repeating pattern of interlocking shapes",
+ "a regular, geometric shape",
+ "a consistent size and spacing between shapes",
+ "a symmetrical or nearly symmetrical design",
+ "straight or curved lines",
+ "a solid color or a limited color palette"
+ ],
+ "paisley": [
+ "a repeating pattern of curved shapes",
+ "usually brightly colored",
+ "often with a floral or geometric design"
+ ],
+ "perforated": [
+ "a series of small, evenly spaced holes",
+ "a surface with a regular pattern of indentations",
+ "a material with a porous or spongy appearance"
+ ],
+ "pitted": [
+ "a surface with small, shallow depressions",
+ "a rough or bumpy surface",
+ "a matte or dull finish"
+ ],
+ "pleated": [
+ "a series of parallel, evenly spaced folds or creases",
+ "fabric that is gathered or puffed up in between the folds",
+ "a smooth, flat surface on either side of the folds"
+ ],
+ "polka-dotted": [
+ "a series of small, round dots",
+ "evenly spaced",
+ "usually on a light background",
+ "can be any color",
+ "may be on a variety of surfaces"
+ ],
+ "porous": [
+ "small, irregular holes or pores",
+ "a rough or spongy surface",
+ "light and dark areas where the pores are more or less dense"
+ ],
+ "potholed": [
+ "a road or street with many small holes",
+ "the surface is bumpy and uneven",
+ "the holes are usually circular or oval-shaped",
+ "the holes may be filled with water or debris",
+ "the surrounding area may be cracked or damaged"
+ ],
+ "scaly": [
+ "a series of overlapping plates or scales",
+ "a dry, rough, or bumpy surface",
+ "a dull or matte finish",
+ "a lack of luster or shine"
+ ],
+ "smeared": [
+ "blurred or out of focus",
+ "colors running together",
+ "a smeared or streaked appearance"
+ ],
+ "spiralled": [
+ "a repeating pattern of interlocking curves",
+ "a three-dimensional appearance",
+ "a raised or embossed surface",
+ "a glossy or matte finish"
+ ],
+ "sprinkled": [
+ "small, uniform dots",
+ "evenly spaced",
+ "same size and shape",
+ "can be a variety of colors",
+ "may be shimmery or iridescent"
+ ],
+ "stained": [
+ "a discolored area",
+ "a raised or bumpy surface",
+ "a change in color or opacity",
+ "a change in texture"
+ ],
+ "stratified": [
+ "a series of layers",
+ "each layer is of a different material",
+ "the layers are parallel to each other",
+ "the layers may be of different thicknesses",
+ "the layers may be of different colors",
+ "the layers may have different textures"
+ ],
+ "striped": [
+ "alternating light and dark bands",
+ "regular, repeating pattern",
+ "can be horizontal, vertical, or diagonal",
+ "may be of different widths",
+ "may be of different colors"
+ ],
+ "studded": [
+ "a series of raised bumps or ridges",
+ "evenly spaced",
+ "may be arranged in a pattern",
+ "may be of different colors",
+ "may be of different sizes"
+ ],
+ "swirly": [
+ "a spiral or whorl pattern",
+ "a smooth or glossy surface",
+ "a light or dark color"
+ ],
+ "veined": [
+ "a repeating pattern of lines or shapes",
+ "a contrast between light and dark areas",
+ "a three-dimensional appearance"
+ ],
+ "waffled": [
+ "a series of raised, parallel lines",
+ "a honeycomb or grid-like appearance",
+ "a three-dimensional texture",
+ "a rough or bumpy surface"
+ ],
+ "woven": [
+ "a series of parallel, criss-crossing lines",
+ "a tight, interlocking pattern",
+ "a fabric or material with a textile weave"
+ ],
+ "wrinkled": [
+ "a surface with raised bumps or ridges",
+ "a surface with indentations or valleys",
+ "a surface with a complex, irregular pattern",
+ "a surface that appears dry or dehydrated"
+ ],
+ "zigzagged": [
+ "a repeating pattern of sharp angles",
+ "usually black and white",
+ "can be created with lines, shapes, or colors",
+ "often used to create a sense of movement or energy"
+ ]
+}
\ No newline at end of file
diff --git a/descriptors/descriptors_eurosat.json b/descriptors/descriptors_eurosat.json
new file mode 100644
index 0000000..5229cbc
--- /dev/null
+++ b/descriptors/descriptors_eurosat.json
@@ -0,0 +1,47 @@
+{
+ "annual crop land": [
+ "large, open fields",
+ "straight rows",
+ "different colors for different crops"
+ ],
+ "forest": [
+ "a large area of trees",
+ "green leaves"
+ ],
+ "herbaceous vegetation land": [
+ "an area of land with low-growing plants",
+ "little or no grass",
+ "dry conditions"
+ ],
+ "highway or road": [
+ "a long, straight, or gently curved line",
+ "typically has a smooth, paved surface"
+ ],
+ "industrial buildings or commercial buildings": [
+ "evidence of human activity"
+ ],
+ "pasture land": [
+ "green or brown vegetation",
+ "uninterrupted spaces"
+ ],
+ "permanent crop land": [
+ "large, rectangular fields",
+ "straight rows of crops",
+ "irrigation systems",
+ "green vegetation"
+ ],
+ "residential buildings or homes or apartments": [
+ "man-made structures",
+ "typically have a rectangular or square shape",
+ "may be clustered together in groups"
+ ],
+ "river": [
+ "a long, thin line of water",
+ "may be winding or straight",
+ "may be bordered by vegetation"
+ ],
+ "sea or lake": [
+ "large body of water",
+ "typically blue or green in color"
+ ]
+}
\ No newline at end of file
diff --git a/descriptors/descriptors_fgvc_aircraft.json b/descriptors/descriptors_fgvc_aircraft.json
new file mode 100644
index 0000000..e69d62c
--- /dev/null
+++ b/descriptors/descriptors_fgvc_aircraft.json
@@ -0,0 +1 @@
+{"707-320": ["large, four-engine jet airliner", "swept-back wings", "two vertical stabilizers", "two horizontal stabilizers", "two engines on each wing", "a long, slender fuselage", "a pointed nose", "a tail fin with a distinctive \"hockey stick\" shape"], "727-200": ["a narrow-body, three-engine jet airliner", "a swept-wing design", "a T-tail", "a distinctive nose profile", "two rows of windows on each side of the fuselage", "two overwing exits", "a large, swept-back tail fin", "two turbofan engines mounted on the rear of the fuselage"], "737-200": ["twin-engine jet airliner", "narrow fuselage", "swept wings", "two turbofan engines", "T-tail", "two-wheel main landing gear", "two-wheel nose landing gear", "two overwing emergency exits"], "737-300": ["twin-engine jet airliner", "narrow fuselage", "swept wings", "two turbofan engines", "T-tail", "two-wheel main landing gear", "two-wheel nose landing gear", "two overwing emergency exits"], "737-400": ["twin-engine jet airliner", "narrow fuselage", "swept wings", "two turbofan engines", "T-tail", "two-wheel main landing gear", "two-wheel nose landing gear", "two-wheel auxiliary landing gear", "two-wheel tail landing gear", "two-wheel wingtip landing gear"], "737-500": ["a narrow-body, twin-engine jet airliner", "a distinctive pointed nose", "two engines mounted on the rear of the fuselage", "two wings with ailerons and flaps", "a T-tail with a horizontal stabilizer", "a single-aisle cabin with six-abreast seating", "a distinctive livery with the Boeing logo on the tail"], "737-600": ["a narrow-body, twin-engine jet airliner", "a distinctive curved tail", "two turbofan engines", "a swept wing design", "a T-tail", "a single-aisle cabin", "a two-crew cockpit", "a maximum seating capacity of 149 passengers"], "737-700": ["a narrow-body, twin-engine jet airliner", "a distinctive curved tail", "two turbofan engines mounted on the wings", "a T-shaped tail", "a single-aisle cabin", "a distinctive nose shape", "two overwing exits", "a distinctive winglet design"], "737-800": ["twin-engine jet airliner", "white and blue livery", "two wings with winglets", "two turbofan engines", "a T-tail", "a single-aisle cabin", "a nose-mounted radome", "a two-wheel main landing gear", "a single-wheel nose landing gear"], "737-900": ["large, twin-engine jet airliner", "distinctive curved wingtips", "two engines mounted on the rear of the fuselage", "a T-tail configuration", "a large, swept-back tail fin", "a single-aisle cabin", "a distinctive nose section with a pointed tip", "a large, oval-shaped cockpit window"], "747-100": ["large, four-engine jet airliner", "distinctive hump on the upper fuselage", "two decks", "swept wings", "four engines mounted on the wings", "two vertical stabilizers", "a large tail fin", "a long, pointed nose"], "747-200": ["large, four-engine jet airliner", "distinctive hump on the upper fuselage", "two decks", "swept wings", "two tail fins", "four turbofan engines", "two main landing gear", "two auxiliary landing gear"], "747-300": ["four engines", "two decks", "a distinctive hump on the upper deck", "a long, pointed nose", "a tail fin with a curved tip", "two sets of wings with four engines each", "a large, oval-shaped fuselage"], "747-400": ["distinctive hump on the upper fuselage", "two decks", "swept wings", "four engines mounted on the wings", "two vertical stabilizers", "a large tail fin", "a distinctive nose shape"], "757-200": ["twin-engine jet airliner", "narrow fuselage", "swept wings", "two turbofan engines", "T-tail", "two-wheel main landing gear", "two-wheel nose landing gear", "two-wheel auxiliary landing gear", "two-wheel tail landing gear"], "757-300": ["large, twin-engine jet airliner", "long, slender fuselage", "swept-back wings", "two turbofan engines", "two vertical stabilizers", "a T-tail", "a large, oval-shaped cabin window", "a distinctive nose shape"], "767-200": ["twin-engine jet airliner", "two-aisle cabin", "swept wings", "two turbofan engines", "T-tail", "two-wheel main landing gear", "two-wheel nose landing gear", "two-wheel auxiliary landing gear", "two-wheel tail landing gear", "two-wheel wingtip landing gear"], "767-300": ["twin-engine jet airliner", "long, slender fuselage", "two wings with swept-back tips", "two turbofan engines mounted on the wings", "a T-tail", "a large, swept-back vertical stabilizer", "a nose-mounted radar", "two sets of landing gear"], "767-400": ["twin-engine jet airliner", "long, slender fuselage", "two high-bypass turbofan engines", "swept wings", "two vertical stabilizers", "two underwing engine nacelles", "a T-tail configuration", "a distinctive nose profile"], "777-200": ["two engines mounted on the wings", "a long, slender fuselage", "a distinctive tail fin", "a large, swept-back wing", "a pointed nose", "a two-person cockpit"], "777-300": ["long, slender fuselage", "two engines mounted on the wings", "two vertical stabilizers", "a distinctive nose shape", "a large, swept-back wing", "a T-tail configuration", "a large, oval-shaped cabin window"], "A300B4": ["Airbus A300B4", "twin-engine jet airliner", "white and blue livery", "large, swept-back wings", "two engines mounted on the wings", "a T-tail", "a long, slender fuselage", "a pointed nose", "a large, rectangular cockpit window"], "A310": ["white or light grey", "two engines mounted on the rear of the fuselage", "two vertical stabilizers", "two wings with a swept-back design", "a long, pointed nose", "a large, oval-shaped cockpit window", "a T-tail configuration"], "A318": ["Airbus A318 aircraft", "white or light grey", "two engines", "a pointed nose", "two wings", "a tail fin", "two vertical stabilizers", "two main landing gear", "two sets of flaps on the wings"], "A319": ["single-aisle, narrow-body jet airliner", "white or light-colored fuselage", "two engines mounted on the wings", "a pointed nose", "a single vertical stabilizer", "two horizontal stabilizers", "two overwing exits", "a single door at the rear of the cabin"], "A320": ["commercial airliner", "white and blue livery", "two engines", "two wings", "a tail fin", "a single aisle cabin", "two overwing exits", "a nose cone", "a cockpit window"], "A321": ["large, twin-engine jet airliner", "long, slender fuselage", "two wings with engines mounted on the wings", "two vertical stabilizers", "two horizontal stabilizers", "two main landing gear", "two nose landing gear", "two tail landing gear", "two overwing exits"], "A330-200": ["twin-engine, wide-body jet airliner", "two turbofan engines", "swept wings", "a T-tail", "a distinctive nose", "a large, oval-shaped fuselage", "two underwing pylons for mounting engines", "a retractable landing gear"], "A330-300": ["twin-engine, wide-body jet airliner", "long, slender fuselage", "two high-bypass turbofan engines", "swept wings with winglets", "two vertical stabilizers", "a T-tail", "a large, oval-shaped cabin window", "a distinctive nose profile"], "A340-200": ["four-engine wide-body jet airliner", "long, slender fuselage", "swept-back wings", "two vertical stabilizers", "four turbofan engines", "two underwing pylons", "two overwing exits", "two main landing gear", "two nose landing gear"], "A340-300": ["four-engine wide-body jet airliner", "long, slender fuselage", "swept-back wings", "four engines mounted on the wings", "two vertical stabilizers", "a large tail fin", "a distinctive nose shape", "a distinctive livery"], "A340-500": ["four-engine wide-body jet airliner", "long, slender fuselage", "swept-back wings", "two vertical stabilizers", "four turbofan engines", "two underwing pylons", "two overwing exits", "two main landing gear", "two nose landing gear"], "A340-600": ["four-engine wide-body jet airliner", "long, slender fuselage", "swept wings", "two vertical stabilizers", "four turbofan engines", "two underwing pylons for carrying fuel tanks or external payloads", "a large, distinctive tail fin", "a distinctive livery or paint scheme"], "A380": ["four engines", "two decks of windows", "curved wings", "a pointed nose", "a tail fin", "two sets of landing gear"], "ATR-42": ["twin-engine turboprop aircraft", "high-wing monoplane", "two propellers", "two engines", "a T-tail", "a large, oval-shaped fuselage", "a pointed nose", "two sets of landing gear"], "ATR-72": ["twin-engine turboprop aircraft", "high-wing monoplane", "two turboprop engines mounted on the wings", "T-tail", "two-bladed propellers", "two-wheeled landing gear", "two doors on the left side of the fuselage", "two windows on the right side of the fuselage"], "An-12": ["large, boxy fuselage", "swept wings", "two large engines mounted on the wings", "two smaller engines mounted on the tail", "two large cargo doors on the side of the fuselage", "two vertical stabilizers on the tail", "a large, pointed nose"], "BAE 146-200": ["four-engined regional airliner", "high-winged monoplane", "swept-back wings", "T-tail", "two-wheeled main landing gear", "two-wheeled nose landing gear", "two turbofan engines mounted on the wings", "two turboprop engines mounted on the tail", "two passenger doors on the left side of the fuselage"], "BAE 146-300": ["four-engined regional airliner", "high-winged monoplane", "swept-back wings", "T-tail", "four turbofan engines", "two-wheeled main landing gear", "two-wheeled nose landing gear", "two-wheeled tail landing gear", "two doors on the left side of the fuselage", "two doors on the right side of the fuselage", "two overwing exits"], "BAE-125": ["military aircraft", "twin-engine turboprop", "swept wings", "two vertical stabilizers", "two engines mounted on the wings", "a large, pointed nose", "a bubble canopy", "a tailhook for carrier landings"], "Beechcraft 1900": ["twin-engine turboprop aircraft", "high-wing monoplane", "two-bladed propellers", "two-wheeled landing gear", "a T-tail", "a rectangular fuselage", "a pointed nose", "a swept-back wing with ailerons and flaps"], "Boeing 717": ["twin-engine jet airliner", "narrow fuselage", "swept wings", "two turbofan engines", "T-tail", "two-crew cockpit", "two overwing exits", "two main landing gear", "two auxiliary landing gear"], "C-130": ["large, boxy fuselage", "high-mounted wings", "two sets of landing gear", "two large propellers", "two vertical stabilizers", "two horizontal stabilizers", "two tail fins"], "C-47": ["twin-engine, propeller-driven aircraft", "high-wing monoplane", "two large, round engines", "two sets of wings", "a tail with two vertical stabilizers", "a large, rectangular fuselage", "two large, round windows on the side of the fuselage", "two large, round doors on the side of the fuselage"], "CRJ-200": ["small regional jet", "two engines", "swept-back wings", "a T-tail", "a pointed nose", "a single-aisle cabin", "a distinctive blue and white livery"], "CRJ-700": ["small regional jet", "two engines", "swept-back wings", "a T-tail", "a pointed nose", "a single-aisle cabin", "a distinctive livery", "a distinctive engine nacelle shape"], "CRJ-900": ["small regional jet", "two engines", "swept-back wings", "a T-tail", "a pointed nose", "a single-aisle cabin", "a distinctive livery", "a distinctive engine nacelle shape"], "Cessna 172": ["single-engine, four-seat, high-wing aircraft", "fixed landing gear", "swept-back wings", "a single vertical stabilizer", "a single engine mounted on the rear of the fuselage", "two doors on the side of the fuselage", "a large, fixed-pitch propeller", "a distinctive \"V\" tail configuration"], "Cessna 208": ["single-engine, high-wing aircraft", "fixed landing gear", "swept-back wings", "a single vertical stabilizer", "a single engine mounted on the rear of the fuselage", "a cabin with two side-by-side seats", "a large cargo door on the rear of the fuselage", "a propeller mounted on the front of the fuselage"], "Cessna 525": ["small, single-engine aircraft", "high-wing monoplane", "swept-back wings", "two-bladed propeller", "retractable landing gear", "two doors on the side of the fuselage", "two windows on the side of the fuselage", "a tail fin with a horizontal stabilizer"], "Cessna 560": ["small, twin-engine aircraft", "white or light-colored body", "two wings with ailerons", "two engines mounted on the wings", "a tail with a rudder", "a cockpit with two or more windows", "a propeller at the front of each engine", "a landing gear with two main wheels and a nose wheel"], "Challenger 600": ["twin-engine business jet", "long, slender fuselage", "swept wings", "two turbofan engines", "T-tail", "retractable landing gear", "large windows", "distinctive nose cone"], "DC-10": ["three-engine jet airliner", "wide body", "swept wings", "two vertical stabilizers", "two engines mounted on the tail", "two engines mounted on the wings", "a large, distinctive nose", "a T-shaped tail"], "DC-3": ["twin-engine propeller aircraft", "two wings with three engines", "a large, rounded fuselage", "a tail with two vertical stabilizers", "a tricycle landing gear", "two large propellers", "a distinctive \"DC-3\" logo on the tail"], "DC-6": ["four-engine propeller-driven airliner", "large wings with four engines", "a long, slender fuselage", "a tail fin with two vertical stabilizers", "a tricycle landing gear", "a cockpit with two pilots", "a passenger cabin with windows"], "DC-8": ["four-engine jet airliner", "swept-wing design", "two- or three-crew cockpit", "two rows of windows along the fuselage", "two tail fins", "two turbofan engines mounted on the wings", "a large, oval-shaped fuselage", "a pointed nose"], "DC-9-30": ["twin-engine jet airliner", "swept wings", "two turbofan engines", "a T-tail", "a fuselage with a circular cross-section", "a single-aisle cabin", "a nose-mounted engine", "a two-wheel main landing gear", "a single-wheel nose landing gear"], "DH-82": ["fabric-covered steel tube fuselage", "wooden wings with fabric covering", "fixed tailwheel landing gear", "two-bladed propeller", "open cockpit with dual controls", "distinctive red and white paint scheme"], "DHC-1": ["high-wing monoplane", "fixed tricycle landing gear", "bubble canopy", "sweptback wings", "tailplane with a single fin and rudder"], "DHC-6": ["High-wing monoplane", "Fixed tricycle landing gear", "T-tail", "Large, rectangular windows", "Slender fuselage", "Propellers at the end of each engine", "Distinctive nose shape"], "DHC-8-100": ["twin-engine turboprop aircraft", "high-wing monoplane", "T-tail", "two turboprop engines mounted on the wings", "two-bladed propellers", "two-wheeled tricycle landing gear", "two doors on the left side of the fuselage", "two windows on the right side of the fuselage"], "DHC-8-300": ["twin-engine turboprop aircraft", "high-wing monoplane", "T-tail", "two turboprop engines", "two-bladed propellers", "two-wheeled landing gear", "two doors on the left side of the fuselage", "two windows on the right side of the fuselage", "two vertical stabilizers"], "DR-400": ["four-seat, single-engine, low-wing monoplane", "retractable tricycle landing gear", "two-blade propeller", "swept-back tail", "bubble canopy", "two side-by-side seats", "two fuel tanks", "two control sticks"], "Dornier 328": ["twin-engine turboprop aircraft", "high-wing monoplane", "two-bladed propellers", "two engines mounted on the wings", "a T-tail", "a pressurized cabin", "a retractable tricycle landing gear", "a distinctive nose section with a large window"], "E-170": ["small, single-engine aircraft", "high-wing monoplane", "two-bladed propeller", "two side-by-side seats", "two doors", "two windows", "two landing gear", "two wing flaps"], "E-190": ["small, single-aisle jet airliner", "distinctive curved wingtips", "two turbofan engines", "a T-tail", "a pointed nose", "a swept-back cockpit", "a single-piece windshield", "a two-person flight deck"], "E-195": ["twin-engine jet airliner", "white and blue livery", "swept wings", "two turbofan engines", "a T-tail", "a long, slender fuselage", "a pointed nose", "a large, oval-shaped cockpit window"], "EMB-120": ["twin-turboprop regional airliner", "white or light grey", "two engines mounted on the wings", "a T-tail", "a high-wing configuration", "a swept-back wing", "a single-piece windshield", "a single-piece nose cone", "a single-piece tail cone", "a single-piece fuselage"], "ERJ 135": ["small regional jet", "two engines", "swept wings", "T-tail", "two-crew cockpit", "two-by-two seating configuration", "distinctive livery", "large windows"], "ERJ 145": ["small regional jet", "twin-engine turbofan", "swept wings", "two vertical stabilizers", "two engines mounted on the rear of the fuselage", "a T-tail", "a pointed nose", "a single-aisle cabin"], "Embraer Legacy 600": ["mid-size business jet", "twin-engine turbofan", "swept-back wings", "T-tail", "two-crew cockpit", "oval-shaped fuselage", "retractable tricycle landing gear", "two large turbofan engines mounted on the wings"], "Eurofighter Typhoon": ["twin-engine, multirole fighter aircraft", "delta wing design", "canards", "two vertical stabilizers", "two air intakes", "two exhaust nozzles", "two underwing pylons for carrying weapons", "a bubble canopy for the pilot"], "F-16A/B": ["military aircraft", "single-engine, single-seat fighter jet", "swept-back wings", "two vertical stabilizers", "a bubble canopy", "a single engine exhaust", "a nose-mounted gun", "two air intakes on the sides of the fuselage"], "F/A-18": ["military aircraft", "twin-engine, single-seat fighter jet", "swept-wing design", "two vertical stabilizers", "two air intakes on the sides of the fuselage", "two exhaust nozzles at the rear of the fuselage", "a bubble canopy", "a tailhook for carrier landings"], "Falcon 2000": ["twin-engine business jet", "long, slender fuselage", "swept wings", "two engines mounted on the rear of the fuselage", "two vertical stabilizers", "a T-tail", "a retractable tricycle landing gear", "a large cabin with windows"], "Falcon 900": ["large, twin-engine business jet", "long, slender fuselage", "swept wings", "three vertical stabilizers", "two engines mounted on the rear of the fuselage", "retractable landing gear", "large windows", "distinctive nose cone"], "Fokker 100": ["twin-engine jet airliner", "narrow fuselage", "swept wings", "two turbofan engines", "T-tail", "two-crew cockpit", "two overwing exits", "two main landing gear", "two nose gear wheels"], "Fokker 50": ["twin-engine turboprop aircraft", "white or light grey body", "two engines mounted on the wings", "a T-tail", "a high-wing configuration", "a large, oval-shaped fuselage", "a pointed nose", "two sets of landing gear"], "Fokker 70": ["twin-engine turbofan airliner", "narrow fuselage", "swept wings", "two vertical stabilizers", "two engines mounted on the wings", "a T-tail", "a retractable tricycle landing gear", "a large, oval-shaped cabin window"], "Global Express": ["sleek, aerodynamic design", "two or three engines", "swept-back wings", "large, oval windows", "two or three tail fins", "retractable landing gear", "distinctive nose cone"], "Gulfstream IV": ["long, slender fuselage", "swept wings", "two engines mounted on the wings", "a T-tail", "a large, oval-shaped cockpit window", "a retractable landing gear", "a distinctive paint scheme"], "Gulfstream V": ["swept wings", "two engines", "a T-tail", "a long, slender fuselage", "a pointed nose", "a large, oval-shaped cockpit window", "a retractable landing gear"], "Hawk T1": ["swept-wing design", "distinctive \"hump\" on the fuselage", "two air intakes on the sides of the fuselage", "two exhausts on the rear of the fuselage", "two tail fins", "two underwing pylons for carrying weapons"], "Il-76": ["swept wings", "two vertical stabilizers", "a large cargo door on the rear fuselage", "a high-mounted T-tail", "a tricycle landing gear", "a large, bulbous nose", "a large, swept-back cockpit windshield"], "L-1011": ["large, wide-bodied aircraft", "three engines, two on the tail and one on the wing", "two sets of wings, one above the other", "a T-tail", "a long, slender fuselage", "a pointed nose", "a large, swept-back tail fin"], "MD-11": ["three-engine jet airliner", "long, slender fuselage", "swept-back wings", "two vertical stabilizers", "two engines mounted on the wings", "two engines mounted on the tail", "distinctive \"hump\" on the upper fuselage", "large, oval windows"], "MD-80": ["twin-engine, narrow-body jet airliner", "swept-back wings", "two turbofan engines", "a T-tail", "a distinctive \"double-bubble\" fuselage", "a single-piece windshield", "a two-person cockpit", "a large cargo door on the left side of the fuselage"], "MD-87": ["twin-engine, narrow-body jet airliner", "swept wings", "two turbofan engines", "a T-tail", "a distinctive \"hump\" on the fuselage", "a large, oval-shaped cabin window", "a pointed nose", "a single-piece windshield"], "MD-90": ["twin-engine jet airliner", "swept-back wings", "two turbofan engines", "a T-tail", "a long, slender fuselage", "a pointed nose", "a single-piece windshield", "a large, oval-shaped tail fin"], "Metroliner": ["a streamlined, aerodynamic shape", "a long, narrow body", "two or three sets of wings", "two or three engines", "a pointed nose", "a tail fin", "a cockpit with windows", "a cabin with windows"], "Model B200": ["black or grey", "a rectangular shape", "a handle on the top", "two wheels on the bottom", "a power cord", "a power switch", "a control panel with buttons and knobs", "a display screen"], "PA-28": ["four-seat, single-engine, low-wing aircraft", "tricycle landing gear", "swept-back wings", "a single, horizontally-opposed engine", "a T-tail", "a fixed-pitch propeller", "a cabin with two side-by-side seats and two rear-facing seats"], "SR-20": ["single-engine, low-wing, four-seat aircraft", "retractable tricycle landing gear", "composite construction", "swept-back wings", "two-blade propeller", "two side-by-side seats in the cockpit", "a large, bubble-style canopy", "a distinctive \"V\" tail"], "Saab 2000": ["four-door sedan", "aerodynamic design", "curved hood", "two-tone paint job", "large, round headlights", "chrome trim", "rear spoiler", "alloy wheels"], "Saab 340": ["twin-engine turboprop aircraft", "white or light grey body", "two propellers", "a T-tail", "a pointed nose", "a large, rectangular cabin window", "two engines mounted on the wings", "a high-wing design"], "Spitfire": ["single-engine, single-seat fighter aircraft", "elliptical wings", "retractable landing gear", "distinctive elliptical wing shape", "two-bladed propeller", "distinctive roundel markings on the wings and fuselage", "distinctive exhausts and air intakes"], "Tornado": ["dark, rotating funnel-shaped cloud", "strong winds", "debris and dust swirling around the funnel", "dark sky with heavy rain or hail", "loud, roaring sound", "power lines and trees bent or broken by the wind"], "Tu-134": ["twin-engine jet airliner", "swept wings", "two vertical stabilizers", "two turbofan engines", "a T-shaped tail", "a long, slender fuselage", "a pointed nose", "a single-piece windshield"], "Tu-154": ["three-engine jet airliner", "swept wings", "T-tail", "two-wheeled main landing gear", "two-wheeled nose landing gear", "two turbofan engines mounted on the sides of the fuselage", "two vertical stabilizers", "a large, oval-shaped fuselage"], "Yak-42": ["twin-engine jet airliner", "swept wings", "four turbofan engines", "a T-tail", "a long, slender fuselage", "a pointed nose", "a large, rectangular tail fin", "a high-mounted landing gear"]}
\ No newline at end of file
diff --git a/descriptors/descriptors_oxford_flowers.json b/descriptors/descriptors_oxford_flowers.json
new file mode 100644
index 0000000..0478dbf
--- /dev/null
+++ b/descriptors/descriptors_oxford_flowers.json
@@ -0,0 +1 @@
+{"pink primrose": ["pink, white, or yellow flower", "five petals", "long, thin stem", "oval-shaped leaves", "small, yellow center", "hairy stem and leaves"], "hard-leaved pocket orchid": ["small, compact plant", "thick, leathery leaves", "bright, colorful flowers", "long, thin stems", "small, round seed pods", "dark green, glossy leaves", "white or yellow-green flowers with purple spots"], "canterbury bells": ["bell-shaped flowers", "five petals", "white, pink, purple, or blue in color", "long, thin stems", "long, thin leaves", "a single, central stem with multiple flowers"], "sweet pea": ["a climbing plant", "long, thin stems", "heart-shaped leaves", "fragrant, colorful flowers", "pods containing small, round seeds"], "english marigold": ["bright yellow, orange, or red flowers", "five petals", "a single, central disc", "a long, thin stem", "dark green, serrated leaves", "a strong, sweet scent"], "tiger lily": ["orange or yellow petals with black spots", "long, thin stem", "large, green leaves", "a single, central pistil", "a cluster of stamens", "a bulbous base"], "moon orchid": ["white or yellow-green petals", "a long, thin stem", "a single, large, round bloom", "a yellow center", "a long, thin, curved spur", "a sweet, fragrant scent"], "bird of paradise": ["brightly colored feathers", "long tail feathers", "curved beak", "long legs", "long neck", "crest of feathers on the head", "unique courtship displays"], "monkshood": ["perennial plant", "dark green leaves", "tall, upright stem", "hooded, purple-blue flowers", "long, thin seed pods", "long, thin roots", "poisonous sap"], "globe thistle": ["spiny, globe-shaped flower heads", "purple, pink, or white petals", "long, thin stems", "large, spiny leaves", "a single, central stem", "a thick, woody root system"], "snapdragon": ["bright colors such as yellow, orange, pink, red, and purple", "long, tubular petals", "a two-lobed lower lip", "a long, thin stem", "a five-lobed upper lip", "a long, pointed seed pod"], "colt's foot": ["a perennial herb", "a rosette of leaves", "yellow, daisy-like flowers", "a thick, fleshy stem", "a deep taproot", "a hairy, grayish-green stem", "a strong, unpleasant odor"], "king protea": ["thick, leathery petals", "a large, cone-shaped center", "a ring of smaller, pointed petals around the center", "a long, curved stem", "dark green leaves with serrated edges"], "spear thistle": ["spiny, green leaves", "tall, spiny stems", "purple or pink flowers", "a large, spiny seed head", "a long, tapering root system", "a thick, woody stem base"], "yellow iris": ["yellow petals", "yellow center", "yellow stamens", "yellow anthers", "yellow pistil", "yellow sepals", "yellow veins", "yellow pollen"], "globe-flower": ["small, round flower head", "yellow or white petals", "green stem", "long, thin leaves", "small, black seeds", "a single, central stem", "a cluster of flowers at the top of the stem"], "purple coneflower": ["purple petals", "yellow center", "long, thin stem", "large, spiky leaves", "a cone-shaped seed head", "a single, long, thin stem", "a single flower head with multiple petals"], "peruvian lily": ["long, thin stem", "large, trumpet-shaped flower", "petals that are white, pink, or purple", "yellow stamens in the center of the flower", "long, narrow leaves", "a bulb at the base of the stem"], "balloon flower": ["a perennial plant", "a bell-shaped flower with five petals", "a long, thin stem", "a round, inflated seed pod", "a variety of colors, including white, pink, purple, and blue", "a long, thin, pointed seed head"], "giant white arum lily": ["large, white, trumpet-shaped flower", "long, pointed green leaves", "thick, white stem", "yellow-green center", "a sweet, fragrant smell"], "fire lily": ["bright orange or yellow petals", "long, thin stem", "large, round leaves", "a single, central pistil", "a cluster of stamens", "a distinctive, sweet scent"], "pincushion flower": ["small, round flower head", "bright colors such as pink, purple, yellow, or white", "a center of long, thin stamens", "a ring of short, stiff hairs around the center", "a cushion-like center of short, stiff hairs", "a ring of long, thin petals around the center"], "fritillary": ["butterfly", "orange, yellow, or brown wings with black spots", "long antennae", "slender body", "two pairs of wings", "four legs", "long proboscis"], "red ginger": ["bright red flower", "long, thin stem", "pointed leaves", "yellow-green buds", "yellow-green sepals", "yellow-green bracts", "yellow-green stamens"], "grape hyacinth": ["small, bell-shaped flowers", "clusters of 6-15 flowers", "deep blue, purple, or white petals", "long, thin leaves", "a single, slender stem", "a bulbous root system"], "corn poppy": ["bright red, pink, or white flower", "four petals", "a black or dark center", "a long, thin stem", "a single, long, thin leaf", "a seed head with several small, black seeds"], "prince of wales feathers": ["three feathers arranged in a fan shape", "the center feather is longer than the two side feathers", "the feathers are usually black, white, or grey", "the feathers have a distinctive pattern of stripes or spots", "the feathers are often curved or hooked at the end"], "stemless gentian": ["perennial herb", "bright blue, purple, or white flowers", "five petals fused together", "five sepals fused together", "no stem", "leaves arranged in a basal rosette"], "artichoke": ["green, spiny, and cone-shaped", "thick, fibrous stem", "edible heart at the center", "overlapping, pointed leaves", "fuzzy, purple-tinged tips", "edible inner leaves and choke"], "sweet william": ["perennial flowering plant", "bright pink, red, or white flowers", "long, thin stems", "oval-shaped leaves", "small, round seed pods", "fragrant scent"], "carnation": ["flower with a long stem", "five petals", "bright colors such as pink, red, white, yellow, or purple", "a single, long pistil in the center", "a cluster of stamens around the pistil", "a fragrant scent"], "garden phlox": ["perennial plant", "long, thin stems", "clusters of small, star-shaped flowers", "five-petaled flowers in shades of pink, purple, white, or blue", "fragrant blooms", "lance-shaped leaves"], "love in the mist": ["a white, pink, or blue flower", "a cluster of small, round petals", "a center of yellow stamens", "a ring of green sepals", "a misty or foggy background", "a soft, romantic atmosphere"], "mexican aster": ["perennial plant", "daisy-like flowers with yellow centers and white petals", "long, thin stems", "lance-shaped leaves", "grows in clumps", "blooms in late summer and early fall"], "alpine sea holly": ["perennial plant", "evergreen leaves", "spiny, toothed edges", "white, pink, or purple flowers", "long, thin stems", "yellow-green seed heads", "grows in rocky, alpine areas"], "ruby-lipped cattleya": ["large, showy flower", "petals that are usually white or pink", "a deep red lip or labellum", "three sepals and three petals", "a long, thin stem", "a bulbous base", "a long, thin, pointed stigma"], "cape flower": ["bright, vibrant colors", "five petals", "a yellow center", "a long, thin stem", "a large, round seed pod", "a hairy, fuzzy texture", "a sweet, fragrant smell"], "great masterwort": ["perennial herb", "dark green, glossy leaves", "white or pink flowers", "umbels of flowers", "hollow stems", "thick, fleshy roots", "a strong, pungent smell"], "siam tulip": ["bright red, orange, or yellow petals", "pointed petals", "long, thin stem", "dark green leaves", "yellow or orange center", "long, thin pistil and stamens"], "lenten rose": ["perennial flowering plant", "evergreen foliage", "white, pink, or purple flowers", "five petals", "yellow stamens", "dark green, glossy leaves", "thick, leathery stems"], "barbeton daisy": ["bright yellow flower", "five petals", "dark center", "long, thin stem", "leaves with serrated edges", "grows in clusters", "blooms in the spring and summer"], "daffodil": ["yellow or white trumpet-shaped flower", "long, thin stem", "green leaves", "six petals", "a central cup or corona", "a bulbous base"], "sword lily": ["long, sword-shaped leaves", "tall, slender stems", "white, pink, or purple flowers", "yellow anthers", "long, thin seed pods", "a bulbous root system"], "poinsettia": ["bright red, pink, white, or yellow bracts", "dark green, glossy leaves", "small yellow flowers in the center", "a star-shaped pattern of leaves", "a milky white sap when broken", "a woody stem"], "bolero deep blue": ["deep blue color", "short, cropped jacket", "three-quarter length sleeves", "round neckline", "two front pockets", "decorative buttons or embroidery", "fitted waistline"], "wallflower": ["small, yellow, four-petaled flowers", "long, thin stems", "dark green, oval-shaped leaves", "clusters of flowers growing close together", "a strong, sweet scent"], "marigold": ["five petals", "a central disc of yellow or orange stamens", "a green stem", "a green, oval-shaped leaf", "a long, thin stem with a single flower at the end"], "buttercup": ["five petals arranged in a cup-like shape", "green sepals at the base of the petals", "a yellow center with a cluster of yellow stamens", "a green stem", "a basal rosette of leaves"], "oxeye daisy": ["white or yellow flower", "yellow center", "long, thin stem", "long, thin leaves", "small, round seed head", "hairy stem and leaves", "grows in clusters"], "common dandelion": ["bright yellow flower head", "long, thin stem", "jagged leaves", "white, fluffy seed head", "deep taproot", "rosette of leaves at the base of the stem"], "petunia": ["flowering plant", "trumpet-shaped flowers in shades of pink, purple, white, or yellow", "oval-shaped leaves", "long, thin stems", "a spreading, mounding habit", "a sweet, pleasant scent"], "wild pansy": ["small, bright yellow or purple flower", "five petals with a frilled edge", "a single, long stem", "a basal rosette of leaves", "heart-shaped leaves", "a short, hairy stem", "a long, thin seed pod"], "primula": ["perennial flowering plant", "bright, colorful flowers", "five petals", "yellow or white center", "oval-shaped leaves", "long, thin stems", "rosette of leaves at the base of the stem"], "sunflower": ["yellow petals", "a large, dark center", "a long, thin stem", "large, green leaves", "a thick, woody stem", "a large, round seed head"], "pelargonium": ["perennial flowering plant", "green, oval-shaped leaves", "five-petaled flowers in shades of pink, red, white, or purple", "long, thin stems", "a strong, sweet scent", "a thick, woody stem at the base of the plant"], "bishop of llandaff": ["purple cassock", "purple and white mitre", "gold pectoral cross", "gold episcopal ring", "purple and white stole", "purple and white gloves", "purple and white crozier"], "gaura": ["perennial flowering plant", "long, slender stems", "small, white or pink flowers", "lance-shaped leaves", "long, pointed seed pods", "grows in clumps or mounds", "prefers full sun and well-drained soil"], "geranium": ["bright, colorful flowers", "long, thin stems", "oval-shaped leaves", "a woody stem", "a strong, sweet scent", "a star-shaped center", "a five-petal flower shape"], "orange dahlia": ["bright orange petals", "a central yellow disc", "a large, round flower head", "a long, thin stem", "a green, leafy base", "a pointed tip at the end of each petal"], "pink-yellow dahlia": ["pink and yellow petals", "a yellow center", "a long, thin stem", "a large, round head", "a green, leafy base", "a sweet, fragrant smell"], "cautleya spicata": ["perennial herb", "bright yellow flowers", "long, narrow leaves", "thick, fleshy roots", "upright stems", "fragrant flowers", "blooms in late spring and early summer"], "japanese anemone": ["perennial flowering plant", "large, showy flowers with five or more petals", "white, pink, or purple in color", "long, thin stems", "large, lobed leaves", "a deep taproot", "a thick, fleshy rhizome"], "black-eyed susan": ["bright yellow or orange flower with a black center", "petals that are pointed and slightly curved", "a dark green stem", "leaves that are lance-shaped and serrated", "a hairy stem and leaves", "a long, thin seed head"], "silverbush": ["small, evergreen shrub", "silvery-green foliage", "small, white flowers", "small, round, black berries", "upright, spreading branches", "reddish-brown bark", "grows in clusters or mounds"], "californian poppy": ["bright orange or yellow flower", "four petals", "a black center", "a long, thin stem", "a single leaf", "a hairy stem and leaves", "a long, thin seed pod"], "osteospermum": ["daisy-like flower", "petals with a yellow center and purple edges", "long, thin stems", "dark green, oval-shaped leaves", "a single, long, thin seed pod", "a single, long, thin seed head"], "spring crocus": ["small, cup-shaped flower", "three petals, usually purple, white, or yellow", "long, thin stem", "leaves that are long and narrow", "a single, round seed pod at the center of the flower"], "bearded iris": ["tall, upright stem", "sword-shaped leaves", "large, showy flowers with three petals and three sepals", "petals and sepals are usually purple, blue, white, or yellow", "a beard of fuzzy hairs on the lower petal", "a sweet fragrance"], "windflower": ["perennial plant", "white, pink, or purple petals", "yellow center", "long, thin stem", "leaves that are divided into three parts", "grows in clusters", "blooms in the spring and summer"], "tree poppy": ["a tall, slender plant with a single stem", "large, bright yellow or orange flowers", "long, thin leaves", "a thick, woody stem", "a deep taproot", "a crown of leaves at the top of the stem"], "gazania": ["bright, daisy-like flower", "yellow, orange, pink, or white petals", "dark center with yellow or white stamens", "long, narrow leaves", "thick, fleshy stems", "grows in clumps or mats"], "azalea": ["evergreen shrub", "glossy, dark green leaves", "clusters of funnel-shaped flowers in shades of pink, white, or red", "thick, leathery leaves", "shallow root system", "prefers acidic soil"], "water lily": ["aquatic plant", "round, floating leaves", "white, pink, or yellow flowers", "long, thin stems", "a thick, spongy root system", "a central, bulbous stem", "a thick, waxy coating on the leaves"], "rose": ["flower with five petals", "thorny stem", "green leaves", "red, pink, yellow, or white petals", "fragrant smell", "center of the flower with many stamens"], "thorn apple": ["small, round fruit", "green or yellow in color", "covered in thorns", "a single, large seed in the center", "a sweet, tart flavor", "a strong, pungent smell"], "morning glory": ["a climbing vine", "heart-shaped leaves", "trumpet-shaped flowers", "a variety of colors, including white, pink, purple, and blue", "a long, slender stem", "a large, round seed pod"], "passion flower": ["five-petaled flower", "white, pink, purple, or blue in color", "a crown of filaments in the center", "a ring of anthers around the crown", "a long, curved pistil", "a five-lobed calyx", "a long, slender stem"], "lotus": ["aquatic plant", "large, round leaves", "long, thin stems", "large, showy flowers", "yellow, pink, or white petals", "a seed pod at the center of the flower", "a root system that anchors the plant in the mud"], "toad lily": ["perennial plant", "heart-shaped leaves", "white, pink, or purple flowers", "spotted petals", "yellow or orange center", "long, thin stems", "bulbous root system"], "anthurium": ["bright, glossy, heart-shaped leaves", "waxy, red, pink, or white flowers", "long, thin stems", "a central spike or spadix", "a yellow or white spathe", "a root system of rhizomes or stolons"], "frangipani": ["a tropical flowering plant", "a woody shrub or small tree", "large, showy flowers in shades of white, pink, yellow, or red", "long, pointed leaves", "a sweet, fragrant scent", "a milky sap that can cause skin irritation"], "clematis": ["climbing vine", "woody stems", "large, showy flowers", "petals in shades of pink, purple, white, or blue", "sepals that are green or brown", "long, feathery stamens", "a central pistil", "a distinctive, bell-shaped seed head"], "hibiscus": ["large, showy flowers", "five petals", "bright colors such as red, pink, yellow, orange, or white", "a long, thin stem", "large, oval-shaped leaves", "a woody stem", "a seed pod at the base of the flower"], "columbine": ["perennial flower", "bell-shaped petals", "five petals in shades of blue, purple, pink, white, or yellow", "long, thin spurs", "green, lobed leaves", "long, thin stems"], "desert-rose": ["a succulent plant", "a rosette of fleshy leaves", "a thick, woody stem", "a crown of white, yellow, or pink flowers", "a taproot", "a waxy coating on the leaves", "a milky sap when broken"], "tree mallow": ["perennial shrub", "grey-green leaves", "white, pink, or purple flowers", "long, slender stems", "heart-shaped leaves", "fuzzy, velvety texture", "seed pods that are round and hairy"], "magnolia": ["large, glossy, dark green leaves", "cone-shaped seed pods", "a tall, straight trunk", "a wide, spreading canopy", "a distinctive, sweet smell"], "cyclamen": ["perennial flowering plant", "heart-shaped leaves", "white, pink, purple, or red flowers", "five-petaled flowers with a central cup", "long, thin stems", "dark green foliage", "small, round seed capsules"], "watercress": ["dark green, leafy plant", "small, round leaves", "thick, hollow stems", "small, white flowers", "small, round seeds", "a peppery taste and aroma"], "canna lily": ["large, showy flowers", "long, narrow leaves", "tall, upright stems", "bright colors such as red, orange, yellow, and pink", "a thick, fleshy rhizome", "a single, central flower stalk", "a bulbous root system"], "hippeastrum": ["large, showy flowers", "six petals in a star-like pattern", "bright colors such as red, pink, orange, yellow, or white", "long, thin leaves", "a stem with a bulb at the base"], "bee balm": ["perennial herb", "bright pink, purple, or white flowers", "oval-shaped leaves", "hairy stems", "fragrant aroma", "grows in clusters", "blooms in summer and early fall"], "ball moss": ["small, green, and leafy", "no roots", "thin, wiry stems", "small, white flowers", "fuzzy, silvery-gray leaves", "a thick, waxy coating on the leaves", "a bulbous base"], "foxglove": ["tall, slender plant", "bell-shaped flowers in shades of pink, purple, white, or yellow", "long, pointed leaves", "hairy stems", "a single stem with multiple flowers", "a long, thin seed capsule"], "bougainvillea": ["a woody, climbing vine", "bright, colorful flowers in shades of pink, purple, red, orange, or white", "thick, leathery leaves", "thorns on the stems", "a sprawling growth habit", "a trellis or other support structure for the vine to climb on"], "camellia": ["evergreen shrub or small tree", "glossy, dark green leaves", "white, pink, or red flowers with five petals", "yellow stamens in the center of the flower", "thick, leathery seed pods", "smooth, gray bark"], "mallow": ["small, round, and soft leaves", "white, pink, or purple flowers", "long, thin stems", "a shallow root system", "a soft, velvety texture", "a sweet, mild flavor"], "mexican petunia": ["perennial shrub", "dark green, lance-shaped leaves", "clusters of small, trumpet-shaped flowers", "flowers in shades of pink, purple, or white", "long, thin stems", "a woody base", "a mounding growth habit"], "bromelia": ["tropical plant", "spiky leaves", "rosette shape", "bright colors such as red, pink, yellow, or orange", "long, thin stem", "cup-shaped flowers", "spiky fruits"], "blanket flower": ["bright, daisy-like flower", "petals in shades of yellow, orange, red, and pink", "dark brown or black center", "long, thin stems", "lance-shaped leaves", "grows in clumps or mounds"], "trumpet creeper": ["a woody vine", "bright orange or yellow trumpet-shaped flowers", "heart-shaped leaves", "tendrils for climbing", "a long, thin stem", "a woody seed pod", "a sweet, fragrant smell"], "blackberry lily": ["perennial plant", "long, thin leaves", "bell-shaped flowers with six petals", "yellow or orange center", "dark purple or blackberry-colored petals", "long, thin stems", "seed pods that resemble blackberries"]}
\ No newline at end of file
diff --git a/descriptors/descriptors_oxford_pets.json b/descriptors/descriptors_oxford_pets.json
new file mode 100644
index 0000000..27ec2f3
--- /dev/null
+++ b/descriptors/descriptors_oxford_pets.json
@@ -0,0 +1,322 @@
+{
+ "abyssinian": [
+ "black, grey, or brown fur",
+ "long, slender legs",
+ "pointed ears",
+ "a long, bushy tail",
+ "a ruff of fur around the neck"
+ ],
+ "bengal": [
+ "a large, muscular body",
+ "short fur that is orange with black spots",
+ "long, black stripes on the face, back, and tail",
+ "black spots on the legs, belly, and chest",
+ "green or blue eyes"
+ ],
+ "birman": [
+ "four-limbed animal",
+ "long, fluffy fur",
+ "pointed ears",
+ "blue eyes",
+ "white paws"
+ ],
+ "bombay": [
+ "black or brown fur",
+ "short ears",
+ "long tail",
+ "muscular body",
+ "short legs",
+ "long claws"
+ ],
+ "british shorthair": [
+ "short, dense fur",
+ "large, round eyes",
+ "a short, broad muzzle",
+ "small, rounded ears",
+ "a thick, muscular body",
+ "short legs",
+ "a broad, round head"
+ ],
+ "egyptian mau": [
+ "a medium-sized, short-haired cat",
+ "a sleek, muscular body",
+ "large ears",
+ "long legs",
+ "a long, slender tail",
+ "a spotted or striped coat in shades of brown, black, silver, or blue"
+ ],
+ "maine coon": [
+ "large, muscular body",
+ "long, thick fur",
+ "large, bushy tail",
+ "large, tufted ears",
+ "large, expressive eyes"
+ ],
+ "persian": [
+ "long, thick fur",
+ "round face",
+ "short nose",
+ "large, round eyes",
+ "small ears",
+ "short legs",
+ "long body"
+ ],
+ "ragdoll": [
+ "a large, muscular body",
+ "a long, thick coat that is usually white with darker markings",
+ "blue eyes",
+ "a fluffy tail",
+ "large, pointy ears"
+ ],
+ "russian blue": [
+ "blue-grey fur",
+ "green or yellow eyes",
+ "long, fluffy tail",
+ "triangular head shape",
+ "pointed ears"
+ ],
+ "siamese": [
+ "blue eyes",
+ "point coloration",
+ "long, slender body",
+ "triangular head",
+ "large ears",
+ "short tail"
+ ],
+ "sphynx": [
+ "a breed of cat",
+ "hairless",
+ "large ears",
+ "long legs",
+ "a long, slender body",
+ "a short tail",
+ "almond-shaped eyes"
+ ],
+ "american bulldog": [
+ "four-legged mammal",
+ "short, stocky body",
+ "large head",
+ "square jaw",
+ "short snout",
+ "black, brown, or white fur",
+ "short tail",
+ "muscular build"
+ ],
+ "american pit bull terrier": [
+ "muscular body",
+ "short, stiff hair",
+ "short snout",
+ "wide head",
+ "large, powerful jaws",
+ "strong, powerful legs",
+ "thick tail",
+ "black, brown, or white coat"
+ ],
+ "basset hound": [
+ "short-legged dog breed",
+ "long, droopy ears",
+ "long, low-slung body",
+ "short, smooth coat",
+ "typically black, tan, or white in color",
+ "often has a \"sad\" expression"
+ ],
+ "beagle": [
+ "short-haired dog",
+ "brown, black, and white",
+ "floppy ears",
+ "short snout",
+ "long, droopy tail",
+ "small to medium size"
+ ],
+ "boxer": [
+ "short-haired dog",
+ "brindle, fawn, or black coat",
+ "square-shaped head",
+ "floppy ears",
+ "muscular body",
+ "stubby tail"
+ ],
+ "chihuahua": [
+ "small size",
+ "short legs",
+ "long body",
+ "large ears",
+ "round head",
+ "short snout",
+ "dark eyes"
+ ],
+ "english cocker spaniel": [
+ "a medium-sized dog",
+ "a long, silky coat",
+ "a feathered tail",
+ "long, floppy ears",
+ "a round head",
+ "dark, expressive eyes",
+ "a muscular body",
+ "short legs"
+ ],
+ "english setter": [
+ "four-limbed animal",
+ "black, white, or liver-colored",
+ "long, silky fur",
+ "long ears",
+ "long tail",
+ "webbed feet",
+ "large, dark eyes"
+ ],
+ "german shorthaired": [
+ "short, smooth coat",
+ "liver and white or black and white",
+ "large, round eyes",
+ "long ears",
+ "muscular body",
+ "long, docked tail",
+ "webbed feet"
+ ],
+ "great pyrenees": [
+ "a large, white, fluffy dog",
+ "often has a black or brown face",
+ "large, triangular ears",
+ "a long tail",
+ "four black paws"
+ ],
+ "havanese": [
+ "small to medium size",
+ "long, silky coat",
+ "may be any color or combination of colors",
+ "plumed tail that curls over the back",
+ "long, floppy ears",
+ "dark, expressive eyes"
+ ],
+ "japanese chin": [
+ "small, compact body",
+ "short legs",
+ "large, round head",
+ "black, white, or black and white coat",
+ "long, silky fur",
+ "small, black eyes",
+ "black nose",
+ "small, black ears"
+ ],
+ "keeshond": [
+ "a thick, double coat of fur that is black and silver or black and cream in color",
+ "a bushy tail that is carried over the back",
+ "a wedge-shaped head",
+ "small, triangular ears",
+ "dark brown eyes",
+ "a black nose"
+ ],
+ "leonberger": [
+ "four-limbed animal",
+ "black, brown, or yellow",
+ "wet nose",
+ "long tail",
+ "large eyes",
+ "furry body",
+ "clawed feet"
+ ],
+ "miniature pinscher": [
+ "small size",
+ "short coat",
+ "black, brown, or red coloration",
+ "pointed ears",
+ "long, slender muzzle",
+ "docked tail",
+ "muscular body",
+ "high energy level"
+ ],
+ "newfoundland": [
+ "large, stocky body",
+ "thick, waterproof coat",
+ "webbed feet",
+ "large head",
+ "droopy ears",
+ "soulful eyes"
+ ],
+ "pomeranian": [
+ "small size",
+ "round head",
+ "large, pointy ears",
+ "thick, fluffy coat",
+ "black, brown, white, or cream-colored fur"
+ ],
+ "pug": [
+ "short-snouted dog breed",
+ "wrinkled face",
+ "black, fawn, or silver coat",
+ "small, round eyes",
+ "curled tail",
+ "compact body",
+ "short legs"
+ ],
+ "saint bernard": [
+ "four-legged animal",
+ "large size",
+ "long, thick fur",
+ "dark brown or black fur",
+ "white markings on the chest and face",
+ "a short tail",
+ "a muscular build",
+ "a large head",
+ "droopy ears",
+ "a long snout"
+ ],
+ "samoyed": [
+ "a white, fluffy coat",
+ "a thick, double coat",
+ "a long, bushy tail",
+ "small, black eyes",
+ "small, black ears",
+ "a black nose"
+ ],
+ "scottish terrier": [
+ "small to medium-sized dog",
+ "short, thick coat",
+ "black, grey, or brindle",
+ "bushy eyebrows and beard",
+ "pointed ears",
+ "long, curved tail",
+ "strong, muscular build"
+ ],
+ "shiba inu": [
+ "a small to medium sized dog",
+ "a short, double-coated fur",
+ "a triangular head",
+ "small, pointed ears",
+ "dark, almond shaped eyes",
+ "a black nose",
+ "a compact body",
+ "short legs",
+ "a long, curled tail"
+ ],
+ "staffordshire bull terrier": [
+ "short, stocky body",
+ "short, thick legs",
+ "short, wide head",
+ "large, square jaw",
+ "small, dark eyes",
+ "short, stiff tail",
+ "short, stiff coat",
+ "brindle, black, or blue coat",
+ "white markings on the chest, feet, and face"
+ ],
+ "wheaten terrier": [
+ "a medium-sized, solidly-built dog",
+ "a square head with a short muzzle",
+ "dark, almond-shaped eyes",
+ "V-shaped ears that fold forward",
+ "a long neck that is slightly arched",
+ "a deep chest",
+ "a long, straight back",
+ "a tail that is carried low",
+ "a dense, wavy coat that is wheaten in color"
+ ],
+ "yorkshire terrier": [
+ "small size",
+ "long, silky hair",
+ "triangular ears",
+ "black, brown, or blue and tan coat",
+ "dark eyes",
+ "short muzzle"
+ ]
+}
\ No newline at end of file
diff --git a/descriptors/descriptors_stanford_cars.json b/descriptors/descriptors_stanford_cars.json
new file mode 100644
index 0000000..48018c7
--- /dev/null
+++ b/descriptors/descriptors_stanford_cars.json
@@ -0,0 +1 @@
+{"AM General Hummer SUV 2000": ["four wheels", "high ground clearance", "military-style design", "large front grille", "round headlights", "flat windshield", "spare tire mounted on the back", "AM General Hummer logo on the front and back", "possible camouflage paint or military green color"], "Acura RL Sedan 2012": ["four-door sedan body style", "Acura logo on the front grille", "sleek and aerodynamic design", "LED headlights and taillights", "alloy wheels", "sunroof", "leather seats", "navigation system", "dual exhaust pipes", "metallic paint color"], "Acura TL Sedan 2012": ["four-door sedan body style", "Acura logo on the front grille", "distinctive front grille design", "sleek and aerodynamic body shape", "alloy wheels", "LED headlights and taillights", "sunroof", "dual exhaust pipes", "leather seats and interior trim", "touchscreen display for navigation and entertainment system"], "Acura TL Type-S 2008": ["four-door sedan body style", "Acura logo on the front grille", "distinctive front grille design with horizontal bars", "angular headlights", "fog lights", "alloy wheels", "dual exhaust pipes", "Type-S badge on the rear", "sleek and sporty design", "metallic paint color options", "leather seats and interior trim", "navigation system and touchscreen display on the dashboard"], "Acura TSX Sedan 2012": ["four-door sedan body style", "Acura logo on the front grille and wheels", "sleek and aerodynamic design", "headlights and taillights with LED accents", "alloy wheels", "sunroof", "leather seats", "navigation system", "dual-zone automatic climate control", "keyless entry and push-button start"], "Acura Integra Type R 2001": ["compact, sporty car", "red or white exterior", "distinctive \"Type R\" badge on the front grille and rear hatch", "aerodynamic body kit with front and rear spoilers", "large, round headlights", "alloy wheels with a five-spoke design", "\"Integra\" badge on the rear hatch", "dual exhaust pipes", "low profile tires", "sleek, curved body shape"], "Acura ZDX Hatchback 2012": ["four-door hatchback body style", "Acura logo on the front grille", "sleek and aerodynamic design", "LED headlights and taillights", "alloy wheels", "sunroof", "leather seats", "touchscreen display for navigation and entertainment", "rearview camera", "dual exhaust pipes", "Acura emblem on the steering wheel"], "Aston Martin V8 Vantage Convertible 2012": ["sleek, aerodynamic design", "two doors", "convertible top", "signature Aston Martin grille", "round headlights", "low profile tires", "V8 engine badge", "Aston Martin logo on the front and back", "leather interior", "sporty and luxurious appearance"], "Aston Martin V8 Vantage Coupe 2012": ["sleek, aerodynamic body", "low to the ground", "two doors", "signature Aston Martin grille", "round headlights", "alloy wheels", "V8 badge on the side", "Aston Martin logo on the front and back", "dual exhaust pipes", "leather interior with sport seats", "dashboard with digital display and controls", "steering wheel with Aston Martin logo", "keyless entry and start system"], "Aston Martin Virage Convertible 2012": ["luxury sports car", "sleek and aerodynamic design", "convertible top", "signature Aston Martin grille", "round headlights", "low profile tires", "metallic paint", "Aston Martin logo on the front and back", "leather interior", "high-performance engine", "dual exhaust pipes"], "Aston Martin Virage Coupe 2012": ["luxury sports car", "sleek and aerodynamic design", "metallic paint", "iconic Aston Martin grille", "distinctive headlights and taillights", "low profile and wide stance", "two doors", "alloy wheels", "Aston Martin logo on the front and back", "leather interior with high-quality finishes", "dashboard with advanced technology and controls", "V12 engine", "dual exhaust pipes", "license plate with the model and year of the car."], "Audi RS 4 Convertible 2008": ["four-wheeled vehicle", "convertible top", "sleek and sporty design", "Audi logo on the front grille", "four doors", "alloy wheels", "dual exhaust pipes", "LED headlights and taillights", "leather seats", "dashboard with various controls and displays"], "Audi A5 Coupe 2012": ["four-wheeled vehicle", "sleek and aerodynamic design", "silver, black, or white color", "Audi logo on the front grille", "two doors", "sunroof", "alloy wheels", "LED headlights and taillights", "side mirrors with integrated turn signals", "license plate", "model name and year on the back of the car"], "Audi TTS Coupe 2012": ["four-wheeled vehicle", "sleek and sporty design", "Audi logo on the front grille", "LED headlights", "two doors", "low ground clearance", "alloy wheels", "dual exhaust pipes", "TTS badge on the rear", "black or silver color options"], "Audi R8 Coupe 2012": ["sleek, aerodynamic design", "two doors", "low ground clearance", "large, round headlights", "Audi logo on the front grille", "side air intakes", "dual exhaust pipes", "alloy wheels", "sporty spoiler on the back", "metallic paint finish", "\"R8\" badge on the side or back of the car"], "Audi V8 Sedan 1994": ["four-door sedan body style", "Audi logo on the front grille", "distinctive headlights and taillights", "sleek and aerodynamic design", "alloy wheels", "side mirrors with integrated turn signals", "V8 badge on the side or rear of the car", "license plate with a specific state or country", "specific color and trim options for the 1994 model year"], "Audi 100 Sedan 1994": ["four-door sedan body style", "Audi logo on the front grille", "distinctive headlights and taillights", "sleek and aerodynamic design", "alloy wheels", "model name and year on the back of the car", "possible color options such as silver, black, or red", "interior features such as leather seats and a dashboard with various controls and displays."], "Audi 100 Wagon 1994": ["four wheels", "metallic body", "four doors", "a wagon-style body with a long, flat roof", "Audi logo on the front grille and wheels", "headlights and taillights", "license plate", "side mirrors", "windshield wipers", "antenna on the roof", "visible engine under the hood", "visible exhaust pipes at the back", "specific design elements unique to the 1994 model, such as the shape of the headlights or grille."], "Audi TT Hatchback 2011": ["four wheels", "two doors", "a sloping roofline", "a small rear hatch for storage", "a front grille with the Audi logo", "headlights and taillights", "side mirrors", "a license plate", "a model name and year on the back or side of the car"], "Audi S6 Sedan 2011": ["four-door sedan body style", "Audi logo on the front grille", "sleek and aerodynamic design", "LED headlights and taillights", "alloy wheels", "dual exhaust pipes", "chrome accents", "model name and year on the back of the car", "leather seats and interior trim", "dashboard with digital display and controls", "Audi MMI (Multi Media Interface) system", "keyless entry and push-button start", "advanced safety features such as lane departure warning and adaptive"], "Audi S5 Convertible 2012": ["four-wheeled vehicle", "convertible top", "sleek and aerodynamic design", "Audi logo on the front grille", "LED headlights and taillights", "dual exhaust pipes", "alloy wheels", "leather seats", "dashboard with digital display and controls", "license plate with the year 2012"], "Audi S5 Coupe 2012": ["four-wheeled vehicle", "sleek and sporty design", "metallic paint", "Audi logo on the front grille", "LED headlights", "dual exhaust pipes", "sunroof", "alloy wheels", "side mirrors with integrated turn signals", "S5 badge on the front fender", "leather seats", "dashboard with digital display and infotainment system", "steering wheel with Audi logo and controls", "license plate with the year 2012"], "Audi S4 Sedan 2012": ["four-door sedan body style", "Audi logo on the front grille", "sleek and aerodynamic design", "LED headlights and taillights", "dual exhaust pipes", "alloy wheels", "S4 badge on the front fenders", "metallic paint color", "sunroof", "leather seats", "dashboard with digital display and infotainment system"], "Audi S4 Sedan 2007": ["four-door sedan body style", "Audi logo on the front grille", "distinctive front headlights and taillights", "sleek and aerodynamic design", "alloy wheels", "dual exhaust pipes", "\"S4\" badge on the rear of the car", "metallic paint color options", "leather interior with sport seats", "dashboard with digital display and controls for audio and climate control systems"], "Audi TT RS Coupe 2012": ["four-wheeled vehicle", "sleek and sporty design", "Audi logo on the front grille", "two doors", "low ground clearance", "large wheels with performance tires", "dual exhaust pipes", "LED headlights and taillights", "aerodynamic body shape", "red or black exterior color options"], "BMW ActiveHybrid 5 Sedan 2012": ["four-door sedan body style", "BMW logo on the front grille and wheels", "sleek and aerodynamic design", "hybrid badge on the side or rear of the car", "LED headlights and taillights", "dual exhaust pipes", "alloy wheels", "sunroof", "leather interior", "navigation system and infotainment display in the dashboard"], "BMW 1 Series Convertible 2012": ["four-wheeled vehicle", "convertible top", "BMW logo on the front grille", "round headlights", "kidney-shaped grille", "sleek and aerodynamic body design", "alloy wheels", "dual exhaust pipes", "model name and year on the back of the car"], "BMW 1 Series Coupe 2012": ["a sleek, aerodynamic body", "a signature kidney-shaped grille", "BMW logo on the front and back", "two doors", "alloy wheels", "dual exhaust pipes", "LED headlights and taillights", "a sunroof (if visible)", "a license plate (if visible)", "a model name and year (if visible)"], "BMW 3 Series Sedan 2012": ["four wheels", "a sleek, aerodynamic body", "a BMW logo on the front grille", "a distinctive kidney-shaped front grille", "a long hood", "a sunroof (if visible)", "a license plate (if visible)", "a model name and year (if visible)", "a distinctive headlight and taillight design", "a BMW emblem on the wheels", "a dual exhaust system (if visible)"], "BMW 3 Series Wagon 2012": ["four wheels", "a long, sleek body", "a BMW logo on the front grille", "a distinctive kidney-shaped front grille", "a sunroof", "a rear hatchback door", "a license plate", "a model name and year on the back of the car"], "BMW 6 Series Convertible 2007": ["a sleek, aerodynamic body", "a retractable soft top roof", "a BMW logo on the front grille and wheels", "a long hood and short trunk", "two doors", "a low ground clearance", "alloy wheels", "a sporty and luxurious interior with leather seats and a dashboard display", "a license plate with the model and year of the car."], "BMW X5 SUV 2007": ["a large, boxy body shape", "a distinctive kidney-shaped grille on the front", "round headlights", "a BMW logo on the front and back", "a sunroof", "alloy wheels", "a rear spoiler", "a license plate", "a model name and year on the back"], "BMW X6 SUV 2012": ["a large, boxy body shape", "a distinctive kidney-shaped grille on the front", "a BMW logo on the front and back", "four doors and a rear hatch", "large, alloy wheels", "a sloping roofline", "a dual exhaust system", "a model name and year on the back", "a sleek and modern design overall"], "BMW M3 Coupe 2012": ["a sleek, aerodynamic body", "a signature kidney-shaped grille", "a BMW logo on the front and back", "a long hood and short rear deck", "two doors", "a low ground clearance", "large, alloy wheels", "a dual exhaust system", "a sporty spoiler on the back", "a distinctive color, such as blue, white, or black"], "BMW M5 Sedan 2010": ["four-door sedan body style", "signature BMW kidney grille", "round headlights with LED accents", "sleek and aerodynamic design", "BMW logo on the hood and wheels", "M5 badge on the trunk", "dual exhaust pipes", "alloy wheels", "metallic paint finish", "leather interior with sport seats", "iDrive infotainment system", "M5-specific features such as carbon fiber trim and M steering wheel."], "BMW M6 Convertible 2010": ["a sleek, aerodynamic body", "a convertible top", "a BMW logo on the front grille and wheels", "a long, low profile", "two doors", "a sporty front bumper with air intakes", "a dual exhaust system", "alloy wheels", "a distinctive kidney-shaped front grille", "a model name and year on the back of the car"], "BMW X3 SUV 2012": ["a large, boxy body shape", "a distinctive kidney-shaped grille on the front", "round headlights with LED accents", "a BMW logo on the hood and wheels", "a sloping roofline", "a rear spoiler", "alloy wheels", "a dual exhaust system", "a model badge (X3) on the back", "a license plate", "a panoramic sunroof (optional feature)"], "BMW Z4 Convertible 2012": ["a sleek, aerodynamic body", "a retractable hardtop roof", "a BMW logo on the front grille", "round headlights with LED accents", "a long hood and short rear deck", "a low, sporty stance", "alloy wheels", "a BMW emblem on the wheels", "a dual exhaust system", "a BMW Z4 badge on the rear", "a leather interior with bucket seats", "a dashboard with a digital display and infotainment system", "a"], "Bentley Continental Supersports Conv. Convertible 2012": ["sleek and aerodynamic design", "convertible top", "large, round headlights", "signature Bentley grille", "four wheels with high-performance tires", "side mirrors with integrated turn signals", "dual exhaust pipes", "Bentley logo on the front and back of the car", "leather interior with high-end finishes and features such as a navigation system and premium sound system."], "Bentley Arnage Sedan 2009": ["large, sleek body", "signature Bentley grille and logo", "round headlights", "chrome accents", "four doors", "leather interior", "wood paneling on dashboard and doors", "advanced technology features (e.g. touchscreen display, navigation system)", "unique wheels and tires", "distinctive color options (e.g. metallic silver, deep red)"], "Bentley Mulsanne Sedan 2011": ["large, sleek body", "signature Bentley grille and logo", "round headlights", "chrome accents", "four doors", "leather interior", "wood paneling", "advanced technology features (e.g. touchscreen display, navigation system)", "unique wheels and tires"], "Bentley Continental GT Coupe 2012": ["sleek and aerodynamic design", "large, round headlights", "signature Bentley grille", "long hood", "low profile", "two doors", "large, shiny wheels", "Bentley logo on the front and back", "leather interior with high-end finishes", "advanced technology features such as touchscreen display and navigation system."], "Bentley Continental GT Coupe 2007": ["sleek and aerodynamic design", "large, round headlights", "signature Bentley grille", "long hood", "two doors", "low ground clearance", "large, shiny wheels", "\"Bentley\" logo on the front and back", "\"Continental GT\" badge on the side", "leather interior with high-quality finishes", "advanced technology features, such as a touchscreen display and navigation system."], "Bentley Continental Flying Spur Sedan 2007": ["sleek and aerodynamic design", "large, round headlights", "signature Bentley grille", "four doors", "chrome accents", "large wheels with Bentley logo", "leather interior", "wood trim", "dashboard with digital display and controls", "Bentley logo on steering wheel and seats"], "Bugatti Veyron 16.4 Convertible 2009": ["sleek, aerodynamic body", "two-seater convertible", "signature Bugatti horseshoe grille", "large air intakes on the sides", "distinctive Bugatti logo on the front and back", "quad exhaust pipes", "large, low-profile tires", "carbon fiber accents", "unique color and design options"], "Bugatti Veyron 16.4 Coupe 2009": ["a sleek, aerodynamic body", "a low profile", "a two-door design", "a large, powerful engine visible through the rear window", "a distinctive horseshoe-shaped grille", "a Bugatti logo on the front and back", "large, high-performance tires", "a sporty spoiler on the back", "a luxurious interior with leather seats and high-tech features"], "Buick Regal GS 2012": ["four-door sedan body style", "Buick logo on the front grille", "distinctive front grille design with vertical slats", "sleek and aerodynamic body shape", "dual exhaust pipes", "alloy wheels", "GS badge on the rear", "available in various colors such as black, white, silver, and red"], "Buick Rainier SUV 2007": ["four wheels", "a large, boxy body", "a front grille with the Buick logo", "a hood with a raised center section", "headlights and taillights", "side mirrors", "a rear hatch or trunk", "a license plate", "a model name and year on the back or side of the vehicle"], "Buick Verano Sedan 2012": ["silver, black, white, or other common car colors", "distinctive Buick grille and logo on the front", "sleek and aerodynamic body shape", "four wheels with hubcaps or rims", "side mirrors", "headlights and taillights", "license plate", "model name and year on the back or side of the car"], "Buick Enclave SUV 2012": ["four wheels", "a large, boxy body", "a front grille with the Buick logo", "a set of headlights and taillights", "a set of doors and windows", "a roof rack", "a rearview camera", "a license plate", "a model name and year on the back or side of the vehicle"], "Cadillac CTS-V Sedan 2012": ["sleek and aerodynamic design", "Cadillac emblem on the front grille", "large, chrome-accented front grille", "sharp, angular headlights", "low profile tires", "dual exhaust pipes", "metallic paint finish", "leather interior", "touchscreen display for navigation and entertainment system"], "Cadillac SRX SUV 2012": ["four wheels", "a large, boxy body", "a front grille with the Cadillac logo", "a sunroof", "a rear spoiler", "a rearview camera", "leather seats", "a touchscreen display for the infotainment system", "a keyless entry system", "a V6 engine"], "Cadillac Escalade EXT Crew Cab 2007": ["black, white, or silver exterior", "distinctive Cadillac logo on the front grille", "four doors and a spacious cab", "large, chrome wheels", "a truck bed in the back", "leather seats and interior", "advanced technology features, such as a touchscreen display and navigation system"], "Chevrolet Silverado 1500 Hybrid Crew Cab 2012": ["four-wheeled vehicle", "large, rectangular body", "metallic or glossy paint", "Chevrolet logo on the front grille", "four doors", "large, open truck bed", "hybrid badge on the side or rear of the vehicle", "2012 model year badge", "crew cab configuration with four full-sized doors and a spacious interior"], "Chevrolet Corvette Convertible 2012": ["sleek and aerodynamic design", "convertible top", "signature Corvette logo on the front and back", "dual exhaust pipes", "large, low-profile wheels", "distinctive front grille and headlights", "side air vents", "rear spoiler", "available in various colors, such as red, black, or white."], "Chevrolet Corvette ZR1 2012": ["sports car body style", "sleek and aerodynamic design", "signature Corvette logo on the front and back", "dual exhaust pipes", "large, low-profile tires", "distinctive hood scoop", "sharp, angular headlights and taillights", "metallic paint finish", "ZR1 badge on the side or back of the car"], "Chevrolet Corvette Ron Fellows Edition Z06 2007": ["bright, eye-catching color (such as Velocity Yellow)", "distinctive racing stripes (in black or silver)", "Z06 emblem on the front fenders", "Ron Fellows signature on the driver's side quarter panel", "large, round headlights", "wide, muscular body with flared fenders", "dual exhaust pipes", "unique wheels and tires", "Chevrolet emblem on the front grille and rear bumper"], "Chevrolet Traverse SUV 2012": ["four wheels", "a large, boxy body", "a front grille with the Chevrolet logo", "a rear hatchback or trunk", "four doors", "a roof rack", "a rearview mirror on each side", "a license plate", "a model name and year on the back or side of the vehicle"], "Chevrolet Camaro Convertible 2012": ["convertible top (can be black, grey, or other colors)", "two doors", "sleek and sporty design", "Chevrolet logo on the front and back", "round headlights", "large grille", "side mirrors", "alloy wheels", "dual exhaust pipes", "rear spoiler (optional)", "unique color options (e.g. Inferno Orange, Victory Red, etc.)"], "Chevrolet HHR SS 2010": ["silver, black, or white body color", "distinctive boxy shape", "Chevrolet logo on the front grille", "large, round headlights", "low ground clearance", "four doors", "alloy wheels", "SS badge on the rear", "dual exhaust pipes", "rear spoiler"], "Chevrolet Impala Sedan 2007": ["Chevrolet logo on the front grille", "distinctive front headlights and taillights", "chrome accents on the front grille and door handles", "specific body shape and design unique to the 2007 model", "specific color options for the 2007 model (e.g. silver, black, white)", "specific wheel design for the 2007 model", "\"Impala\" badge on the rear of the car", "visible license plate with a 200"], "Chevrolet Tahoe Hybrid SUV 2012": ["four wheels", "large, boxy body shape", "Chevrolet logo on the front grille", "hybrid badge on the side or rear of the vehicle", "aerodynamic design", "tinted windows", "roof rack", "rearview mirrors", "headlights and taillights", "license plate", "side doors and handles", "rear hatch or trunk", "interior features such as steering wheel, dashboard, and seats."], "Chevrolet Sonic Sedan 2012": ["Chevrolet logo on the front grille", "distinct headlights and taillights", "a license plate", "side mirrors", "four wheels with Chevrolet hubcaps", "a rear spoiler (optional)", "a sunroof (optional)", "a unique color or paint job", "a model name or badge on the back of the car."], "Chevrolet Express Cargo Van 2007": ["large, boxy shape", "white or silver color", "Chevrolet logo on the front grille", "two front doors and two sliding side doors", "large cargo area in the back", "windows on the front and sides", "license plate on the front and back", "side mirrors", "wheels and tires", "headlights and taillights"], "Chevrolet Avalanche Crew Cab 2012": ["black, white, or silver exterior", "Chevrolet logo on the front grille", "large, rectangular headlights", "a bed in the back for hauling cargo", "four wheels with tires", "side mirrors", "a license plate", "a model name and year on the back of the vehicle"], "Chevrolet Cobalt SS 2010": ["sporty design", "Chevrolet logo on the front grille", "distinctive front headlights and taillights", "aerodynamic body shape", "dual exhaust pipes", "SS badge on the rear", "2010 model year badge", "specific color options such as Victory Red or Black Granite Metallic"], "Chevrolet Malibu Hybrid Sedan 2010": ["silver, black, or white exterior", "Chevrolet logo on the front grille", "hybrid badge on the side or rear of the car", "aerodynamic design", "alloy wheels", "fuel cap on the side of the car", "headlights and taillights", "rearview mirrors", "license plate", "interior features such as a steering wheel, dashboard, and seats."], "Chevrolet TrailBlazer SS 2009": ["a large, boxy SUV body style", "a Chevrolet logo on the front grille", "a distinctive front bumper with fog lights", "a hood scoop", "a rear spoiler", "dual exhaust pipes", "SS badging on the front doors and tailgate", "20-inch aluminum wheels", "a black and red interior with leather seats and SS logos"], "Chevrolet Silverado 2500HD Regular Cab 2012": ["rectangular body shape", "four wheels", "a large front grille with the Chevrolet logo", "a long truck bed", "a regular cab with two doors", "a towing hitch", "a model year of 2012"], "Chevrolet Silverado 1500 Classic Extended Cab 2007": ["four wheels", "extended cab with two full-size doors and two smaller rear doors", "large, rectangular grille with the Chevrolet logo", "rectangular headlights", "long bed in the back for hauling cargo", "side mirrors", "side steps for easier access to the cab", "model name and year on the side or back of the truck"], "Chevrolet Express Van 2007": ["large, boxy shape", "front grille with Chevrolet logo", "two front headlights", "side mirrors", "sliding side door", "rear doors for cargo access", "wheels with Chevrolet hubcaps", "license plate", "model name and year on the side or back of the van"], "Chevrolet Monte Carlo Coupe 2007": ["two-door coupe body style", "Chevrolet logo on the front grille", "distinctive headlights and taillights", "sleek and aerodynamic design", "specific color and paint job", "specific model year (2007)", "specific trim level (LS, LT, SS)", "specific features (sunroof, spoiler, etc.)", "specific wheels and tires"], "Chevrolet Malibu Sedan 2007": ["Chevrolet logo on the front grille", "distinctive front headlights and taillights", "specific body shape and design of the 2007 model", "specific color options for the 2007 model (e.g. silver, black, blue)", "specific wheel design for the 2007 model", "\"Malibu\" badge on the rear of the car", "specific interior features such as dashboard design and seating arrangement"], "Chevrolet Silverado 1500 Extended Cab 2012": ["four-wheeled vehicle", "large, rectangular body", "extended cab with two full-sized doors and two smaller doors", "Chevrolet logo on the front grille", "model name and year on the side or back of the vehicle", "large truck bed in the back", "headlights and taillights", "side mirrors", "wheels with Chevrolet logo on the center cap", "license plate", "color (can vary)"], "Chevrolet Silverado 1500 Regular Cab 2012": ["large, rectangular body", "four wheels", "a front grille with the Chevrolet logo", "a truck bed in the back", "a single cab with two doors", "a model name and year on the side or back of the vehicle", "a license plate", "a rearview mirror and side mirrors", "headlights and taillights"], "Chrysler Aspen SUV 2009": ["four wheels", "large, boxy body shape", "front grille with the Chrysler logo", "headlights and taillights", "side mirrors", "roof rack", "rear spoiler", "chrome accents", "model name and year on the back or side of the vehicle"], "Chrysler Sebring Convertible 2010": ["four wheels", "convertible top", "Chrysler logo on the front and back", "sleek and aerodynamic body shape", "headlights and taillights", "side mirrors", "door handles", "license plate", "interior features such as steering wheel, dashboard, and seats"], "Chrysler Town and Country Minivan 2012": ["four wheels", "a boxy shape with a sloping front and back", "sliding doors on both sides", "a large front grille with the Chrysler logo", "a rear liftgate", "a roof rack", "a rear spoiler", "a rearview camera", "leather seats", "a DVD entertainment system", "a touchscreen display for navigation and audio controls"], "Chrysler 300 SRT-8 2010": ["four-door sedan body style", "signature Chrysler grille with winged emblem", "sleek and angular design", "large, low-profile wheels", "dual exhaust pipes", "SRT-8 badge on the front fenders", "2010 model year badge on the rear", "available in various colors, including black, silver, and red"], "Chrysler Crossfire Convertible 2008": ["two-door convertible", "sleek and sporty design", "Chrysler logo on the front grille and wheels", "retractable soft top", "two-tone exterior paint", "alloy wheels", "dual exhaust pipes", "leather seats", "dashboard with digital display and controls", "steering wheel with Chrysler logo", "side mirrors with integrated turn signals"], "Chrysler PT Cruiser Convertible 2008": ["four wheels", "convertible top", "round headlights", "chrome grille", "Chrysler emblem on the front and back", "curved body shape", "side mirrors", "door handles", "license plate", "taillights", "exhaust pipe", "antenna on the roof", "windshield wipers", "rearview mirror", "interior features such as steering wheel, dashboard, and seats."], "Daewoo Nubira Wagon 2002": ["four-door wagon body style", "silver or grey color", "Daewoo logo on the front grille", "Nubira badge on the rear hatch", "2002 model year", "alloy wheels", "roof rails", "side mirrors with turn signals", "fog lights", "license plate holder on the front and rear bumpers"], "Dodge Caliber Wagon 2012": ["four wheels", "a compact, boxy shape", "a front grille with the Dodge logo", "headlights and taillights", "a rear hatchback door", "a license plate", "side mirrors", "a roof rack (if present)", "a model name and year on the back or side of the car"], "Dodge Caliber Wagon 2007": ["four wheels", "a wagon-style body with a hatchback", "a Dodge emblem on the front grille", "a distinctive front bumper and headlights", "a rear spoiler", "a license plate", "a model name and year on the back of the car", "a unique color or pattern on the exterior"], "Dodge Caravan Minivan 1997": ["a boxy, rectangular shape", "a sliding side door", "a rear hatchback door", "a front grille with the Dodge logo", "a set of headlights and taillights", "a set of wheels and tires", "a license plate", "a model name and year on the back or side of the vehicle"], "Dodge Ram Pickup 3500 Crew Cab 2010": ["four doors", "large, rectangular grille", "round headlights", "large, flatbed cargo area", "dual rear wheels", "\"Dodge Ram\" logo on the front and/or sides", "model year (2010) displayed on the vehicle"], "Dodge Ram Pickup 3500 Quad Cab 2009": ["large, rectangular grille with the Dodge logo", "large, square headlights", "large, rectangular bed in the back", "four wheels with large tires", "a hitch for towing", "a tailgate with the Dodge logo", "a model and year badge on the side or back of the truck"], "Dodge Sprinter Cargo Van 2009": ["large, boxy shape", "white or silver color", "Dodge logo on the front grille", "large front windshield", "sliding side door", "rear double doors for cargo access", "high roof", "cargo racks on top", "license plate", "wheels with Dodge logo hubcaps"], "Dodge Journey SUV 2012": ["four wheels", "a large, boxy body", "a front grille with the Dodge logo", "a rear hatchback or trunk", "a set of headlights and taillights", "a license plate", "a model name and year on the body or license plate", "a set of doors and windows", "a roof rack (optional)"], "Dodge Dakota Crew Cab 2010": ["metallic paint", "Dodge logo on the front grille", "large, rectangular headlights", "chrome accents on the front bumper", "side mirrors with turn signal indicators", "four wheels with tires", "a truck bed with a tailgate", "a rear bumper with a hitch receiver", "a license plate on the rear", "a model name and year on the side or rear of the vehicle."], "Dodge Dakota Club Cab 2007": ["four wheels", "a truck bed", "a cab with two doors", "a Dodge logo on the front grille", "a model name and year on the back", "a license plate", "a steering wheel and dashboard inside the cab", "side mirrors", "headlights and taillights"], "Dodge Magnum Wagon 2008": ["four-door wagon body style", "distinctive front grille with Dodge logo", "rectangular headlights", "long, sleek body shape", "large wheels and tires", "rear spoiler", "\"Dodge Magnum\" badge on the back", "metallic paint job", "visible exhaust pipes", "chrome accents on the body"], "Dodge Challenger SRT8 2011": ["a sleek, muscular body design", "a large front grille with the Dodge logo", "a hood scoop", "dual exhaust pipes", "racing stripes on the hood and sides", "large, low-profile tires", "a spoiler on the back", "the model name and year on the car's body or license plate"], "Dodge Durango SUV 2012": ["four wheels", "large, boxy body shape", "front grille with Dodge logo", "headlights and taillights", "side mirrors", "roof rack", "rear spoiler", "rear window wiper", "Dodge Durango emblem on the back", "specific color and trim options for the 2012 model year (e.g. Citadel, R/T, SXT)"], "Dodge Durango SUV 2007": ["large, boxy body shape", "four doors", "front grille with Dodge logo", "headlights and taillights", "side mirrors", "roof rack", "alloy wheels", "\"Durango\" badge on the back", "license plate", "specific color options (e.g. Inferno Red, Bright Silver, etc.)"], "Dodge Charger Sedan 2012": ["sleek and sporty design", "signature crosshair grille", "Dodge logo on the front and back", "dual exhaust pipes", "alloy wheels", "LED headlights and taillights", "distinct body lines and curves", "model name and year on the back or side of the car"], "Dodge Charger SRT-8 2009": ["four-door sedan body style", "sleek and sporty design", "large front grille with Dodge logo", "distinctive hood scoop", "dual exhaust pipes", "SRT-8 badge on the side", "2009 model year badge", "black or dark colored paint job", "alloy wheels with performance tires"], "Eagle Talon Hatchback 1998": ["compact car body style", "two doors", "hatchback trunk", "angular and aerodynamic design", "eagle emblem on the front grille", "circular headlights", "alloy wheels", "side mirrors", "license plate", "model name and year on the back of the car"], "FIAT 500 Abarth 2012": ["red, white, or black exterior", "round headlights", "small, circular FIAT logo on the front and back", "Abarth scorpion logo on the side", "sporty design with a low profile", "dual exhaust pipes", "alloy wheels", "hatchback style with a small rear window", "FIAT 500 Abarth badge on the back"], "FIAT 500 Convertible 2012": ["convertible top", "round headlights", "circular FIAT emblem on the front grille", "two doors", "small, circular side mirrors", "alloy wheels", "FIAT 500 logo on the side of the car", "sleek, curved body shape", "available in various colors such as red, white, black, and blue."], "Ferrari FF Coupe 2012": ["red or other bright color", "sleek, aerodynamic body", "two doors", "low ground clearance", "large, round headlights", "Ferrari logo on the front and back", "four exhaust pipes", "alloy wheels with the Ferrari logo", "a long hood and short rear end", "a sporty interior with leather seats and a steering wheel with the Ferrari logo"], "Ferrari California Convertible 2012": ["red or black exterior", "sleek, aerodynamic design", "retractable hardtop roof", "two doors", "large, round headlights", "Ferrari logo on the front and back", "low ground clearance", "sporty wheels and tires", "exhaust pipes visible at the back", "luxurious interior with leather seats and a dashboard with various controls and displays."], "Ferrari 458 Italia Convertible 2012": ["red or other bright color", "sleek, aerodynamic body", "convertible top", "Ferrari logo on the front and back", "large, round headlights", "low to the ground", "two doors", "large, shiny wheels with the Ferrari logo", "exhaust pipes on the back", "sporty interior with leather seats and a steering wheel with the Ferrari logo"], "Ferrari 458 Italia Coupe 2012": ["red or yellow exterior color", "sleek and aerodynamic body shape", "Ferrari logo on the front and back", "two doors", "low ground clearance", "large, round headlights", "dual exhaust pipes", "alloy wheels with the Ferrari logo", "leather interior with sporty seats", "dashboard with various controls and displays"], "Fisker Karma Sedan 2012": ["sleek and aerodynamic design", "low ground clearance", "four doors", "large, curved front grille", "LED headlights", "chrome accents", "large wheels with low-profile tires", "\"Fisker\" logo on the front and back", "\"Karma\" badge on the side", "plug-in hybrid technology (visible charging port or \"EVer\" badge)", "unique color options (such as \"Deep Ocean\" or \"Silver Wind\")"], "Ford F-450 Super Duty Crew Cab 2012": ["Ford logo on the front grille", "rectangular headlights", "large, boxy body", "four doors", "extended cab with four full-sized doors", "long bed for hauling cargo", "dual rear wheels", "chrome accents on the exterior", "model name and year on the side or rear of the vehicle"], "Ford Mustang Convertible 2007": ["a convertible top that can be lowered or raised", "a long, sleek body", "a front grille with the Ford logo", "round headlights", "a hood scoop", "a rear spoiler", "a dual exhaust system", "a Mustang emblem on the back", "a specific color and trim package (e.g. red with white racing stripes)"], "Ford Freestar Minivan 2007": ["a large, boxy shape", "a Ford logo on the front grille", "a sliding side door", "a rear liftgate", "four wheels", "a license plate", "a steering wheel and dashboard visible through the windshield", "a model name and year on the back of the vehicle"], "Ford Expedition EL SUV 2009": ["Ford logo on the front grille", "rectangular headlights", "large, boxy body shape", "four wheels with tires", "side mirrors", "rearview mirrors", "license plate", "rear hatch or trunk", "possible roof rack or tow hitch", "specific color and trim options for the 2009 model year (e.g. metallic silver, chrome accents)"], "Ford Edge SUV 2012": ["four wheels", "a large, boxy body", "a front grille with the Ford logo", "a rear liftgate", "a roof rack", "a rear spoiler", "a panoramic sunroof", "a specific color and trim level (e.g. SEL, Limited)", "a specific model year (2012)"], "Ford Ranger SuperCab 2011": ["four-wheeled vehicle", "pickup truck body style", "Ford logo on the front grille", "rectangular headlights", "extended cab with two small rear doors", "short bed in the back", "side mirrors", "license plate", "specific color and trim options for the 2011 model year (e.g. black exterior with chrome accents)"], "Ford GT Coupe 2006": ["a sleek, low-profile design", "a two-door body style", "a large front grille with the Ford logo", "a long, curved hood", "two racing stripes running down the center of the car", "large, round headlights", "a rear spoiler", "a dual exhaust system", "a Ford GT emblem on the back of the car"], "Ford F-150 Regular Cab 2012": ["large, rectangular body", "four wheels", "a Ford logo on the front grille", "a truck bed in the back", "a single row of seats in the cab", "a rearview mirror on each side", "a license plate on the front and back", "a model name and year on the side or back of the vehicle"], "Ford F-150 Regular Cab 2007": ["large, rectangular body", "two doors", "a Ford logo on the front grille", "a bed in the back for hauling items", "four wheels", "a license plate", "a rearview mirror", "a steering wheel", "a dashboard with various controls and gauges"], "Ford Focus Sedan 2007": ["four-door sedan body style", "Ford logo on the front grille", "specific body design and shape", "specific color options (e.g. silver, black, blue)", "specific wheel design and size", "specific headlight and taillight design", "specific interior features (e.g. dashboard, steering wheel, seats)", "specific model name and year (Ford Focus Sedan 2007)"], "Ford E-Series Wagon Van 2012": ["large, boxy shape", "Ford logo on the front grille", "rectangular headlights", "side mirrors", "sliding side doors", "multiple rows of seats visible through the windows", "license plate", "model name and year visible on the body of the van"], "Ford Fiesta Sedan 2012": ["Ford logo on the front grille", "specific body design and shape", "specific color options (e.g. blue, red, silver)", "specific wheel design and size", "specific headlight and taillight design", "specific interior features (e.g. dashboard, steering wheel)", "specific model year (2012) displayed on the car or in the photo's description"], "GMC Terrain SUV 2012": ["four wheels", "a large, boxy body", "a front grille with the GMC logo", "a set of headlights and taillights", "a rearview mirror on each side", "a set of doors and windows", "a license plate", "a model name and year on the back or side of the vehicle"], "GMC Savana Van 2012": ["large, boxy shape", "front grille with the GMC logo", "rectangular headlights", "side mirrors", "sliding side door", "rear doors with windows", "large wheels", "GMC Savana badge on the side or back of the van", "specific color options (e.g. Summit White, Onyx Black, Dark Blue Metallic)"], "GMC Yukon Hybrid SUV 2012": ["large, boxy body shape", "four doors", "large front grille with GMC logo", "headlights and taillights", "roof rack", "alloy wheels", "hybrid badge", "rearview camera", "leather seats", "touchscreen display for navigation and entertainment system"], "GMC Acadia SUV 2012": ["large, boxy body shape", "four doors", "front grille with GMC logo", "headlights and taillights", "side mirrors", "roof rack", "alloy wheels", "GMC Acadia badge on the back", "specific color options (e.g. white, black, silver)", "specific trim features (e.g. chrome accents, fog lights)"], "GMC Canyon Extended Cab 2012": ["four wheels", "a truck bed", "a cab with two doors", "a GMC logo on the front grille", "a model name and year on the side or back of the vehicle", "a license plate", "a steering wheel and dashboard visible through the windshield", "a rearview mirror", "headlights and taillights", "a distinctive color or design on the exterior of the vehicle."], "Geo Metro Convertible 1993": ["convertible top", "two doors", "round headlights", "a small grille", "a long, flat hood", "a short trunk", "a license plate", "four wheels with hubcaps", "a side mirror", "a windshield", "a rearview mirror", "a steering wheel", "seats and seatbelts", "a gear shift", "a dashboard with gauges and controls"], "HUMMER H3T Crew Cab 2010": ["four wheels", "high ground clearance", "large, aggressive front grille", "HUMMER logo on the front and back", "four doors", "a truck bed in the back", "tinted windows", "side mirrors", "headlights and taillights", "license plate", "specific color and trim options for the 2010 model year (e.g. black, silver, red, etc.)"], "HUMMER H2 SUT Crew Cab 2009": ["four wheels", "large, rugged tires", "a front grille with the HUMMER logo", "a flat, rectangular windshield", "a roof rack", "a truck bed with a cover", "a spare tire mounted on the back", "a side step for easy access", "a rearview mirror on each side", "a license plate on the front and back", "a model and year badge on the back."], "Honda Odyssey Minivan 2012": ["four wheels", "a large, rectangular body", "sliding doors on both sides", "a rear hatchback door", "a Honda emblem on the front grille", "a model name and year on the back", "a license plate", "a steering wheel and dashboard visible through the windshield"], "Honda Odyssey Minivan 2007": ["four wheels", "a large, boxy body", "sliding doors on both sides", "a front grille with the Honda logo", "a rear hatchback door", "a roof rack", "a rear spoiler", "a license plate", "a model name and year on the back or side of the vehicle"], "Honda Accord Coupe 2012": ["four wheels", "two doors", "a sloping roofline", "a Honda emblem on the front grille", "a license plate", "a sunroof (optional)", "a rear spoiler (optional)", "a sleek and sporty design", "a model name and year on the back of the car"], "Honda Accord Sedan 2012": ["Honda emblem on the front grille", "sleek and aerodynamic design", "headlights and taillights", "alloy wheels", "side mirrors", "door handles", "license plate", "model name and year on the back of the car"], "Hyundai Veloster Hatchback 2012": ["four-door hatchback body style", "unique asymmetrical design with one door on the driver's side and two doors on the passenger side", "Hyundai logo on the front grille and rear hatch", "sleek and sporty design", "alloy wheels", "LED headlights and taillights", "rear spoiler", "available in various colors such as red, black, white, and blue"], "Hyundai Santa Fe SUV 2012": ["four wheels", "a large, boxy body", "a front grille with the Hyundai logo", "headlights and taillights", "a rear hatch or trunk", "a roof rack", "a rearview camera", "a sunroof (optional)", "a model badge (Santa Fe) on the back or side of the vehicle"], "Hyundai Tucson SUV 2012": ["compact SUV body style", "Hyundai logo on the front grille", "distinctive headlight and taillight design", "alloy wheels", "roof rails", "rear spoiler", "side mirrors with turn signal indicators", "rearview camera", "touchscreen display in the center console", "leather seats", "panoramic sunroof"], "Hyundai Veracruz SUV 2012": ["four wheels", "a large, boxy body", "a front grille with the Hyundai logo", "headlights and taillights", "a rear hatch or trunk", "a roof rack", "a rearview camera", "a sunroof (optional)", "a model badge (Veracruz) on the back of the vehicle"], "Hyundai Sonata Hybrid Sedan 2012": ["four-door sedan body style", "hybrid badge or logo", "distinctive front grille design", "LED headlights", "aerodynamic shape", "alloy wheels", "rear spoiler", "hybrid powertrain components (e.g. battery pack, electric motor)", "\"Sonata\" or \"Hyundai\" branding on the car's exterior or interior"], "Hyundai Elantra Sedan 2007": ["Hyundai logo on the front grille", "specific body shape and design unique to the 2007 model", "specific color options for the 2007 model (e.g. black, silver, blue)", "specific wheel design for the 2007 model", "specific headlights and taillights for the 2007 model", "specific placement of the license plate on the front and back of the car", "specific interior features such as dashboard design and seat upholstery"], "Hyundai Accent Sedan 2012": ["compact size", "Hyundai logo on the front grille", "specific body shape and design unique to the 2012 model", "specific color options for the 2012 model (e.g. Boston Red, Ultra Black, Cyclone Gray)", "specific wheel design for the 2012 model", "specific headlights and taillights for the 2012 model", "specific interior features such as dashboard design and seat upholstery for the 2012 model"], "Hyundai Genesis Sedan 2012": ["silver, black, or white exterior", "distinctive front grille with the Hyundai logo", "sleek and aerodynamic body shape", "four wheels with rims", "side mirrors", "headlights and taillights", "license plate", "model name and year on the back of the car"], "Hyundai Sonata Sedan 2012": ["silver, white, black, or other color", "Hyundai logo on the front and back", "distinct grille design", "headlights and taillights", "side mirrors", "wheels and tires", "license plate", "model name and year on the back", "interior features such as steering wheel, dashboard, and seats"], "Hyundai Elantra Touring Hatchback 2012": ["four-door hatchback body style", "Hyundai logo on the front grille", "distinct headlights and taillights", "alloy wheels", "rear spoiler", "side mirrors with turn signal indicators", "sunroof (if present)", "license plate (if visible)", "specific color and trim options (e.g. black, silver, SE, GLS)"], "Hyundai Azera Sedan 2012": ["sleek and modern design", "Hyundai logo on the front grille", "distinct headlights and taillights", "alloy wheels", "side mirrors with turn signals", "sunroof (if visible)", "license plate (if visible)", "specific color and trim level (e.g. Limited, SE, etc.)"], "Infiniti G Coupe IPL 2012": ["a sleek, sporty design", "a distinctive Infiniti logo on the front grille", "a low, aerodynamic body", "a two-door coupe body style", "a sunroof or moonroof", "large, alloy wheels", "a dual exhaust system", "LED headlights and taillights", "a rear spoiler", "a leather interior with sport seats", "a touchscreen display for navigation and entertainment controls"], "Infiniti QX56 SUV 2011": ["large, boxy body shape", "four doors", "large front grille with Infiniti logo", "headlights and taillights", "roof rack", "alloy wheels", "side mirrors", "Infiniti QX56 badge on the back", "tinted windows", "sunroof", "leather seats", "dashboard with navigation system and other controls", "steering wheel with Infiniti logo", "rearview camera", "exhaust pipes", "license plate."], "Isuzu Ascender SUV 2008": ["four wheels", "a large, boxy body", "a front grille with the Isuzu logo", "a rear hatch or trunk", "a roof rack", "a spare tire on the back", "a license plate", "a model name and year on the back or side of the vehicle"], "Jaguar XK XKR 2012": ["sleek and aerodynamic design", "metallic paint", "signature Jaguar grille and emblem", "dual exhaust pipes", "large, low-profile wheels", "convertible top (if applicable)", "distinctive headlights and taillights", "Jaguar logo on the hood and trunk", "leather interior with high-tech features (e.g. touchscreen display, navigation system)"], "Jeep Patriot SUV 2012": ["four wheels", "a boxy, compact body shape", "a front grille with the Jeep logo", "round headlights", "a spare tire on the back", "a raised ground clearance", "a roof rack", "a rear hatchback door", "a model year badge or sticker"], "Jeep Wrangler SUV 2012": ["round headlights", "seven-slot grille", "removable doors and roof", "spare tire mounted on the back", "high ground clearance", "off-road tires", "Jeep logo on the front and back", "model name and year on the side or back of the vehicle"], "Jeep Liberty SUV 2012": ["four wheels", "a boxy, angular body shape", "a front grille with the Jeep logo", "a spare tire on the back", "a raised ground clearance", "a roof rack", "a rear hatchback or trunk", "a license plate", "a model year badge or sticker"], "Jeep Grand Cherokee SUV 2012": ["four wheels", "large, boxy body", "raised ground clearance", "signature seven-slot grille", "round headlights", "Jeep logo on the front and back", "side mirrors", "roof rack", "rear spoiler", "tail lights", "license plate", "model name and year on the back", "various color options (e.g. black, white, silver, etc.)"], "Jeep Compass SUV 2012": ["compact SUV body style", "signature seven-slot grille", "round headlights", "Jeep logo on the front grille and wheels", "raised ground clearance", "four doors", "roof rails", "alloy wheels", "rear spoiler", "available in various colors such as black, white, silver, red, etc."], "Lamborghini Reventon Coupe 2008": ["sleek, aerodynamic body", "low to the ground", "signature Lamborghini logo on the front and back", "scissor doors", "large, powerful engine visible through the rear window", "distinctive angular headlights and taillights", "carbon fiber accents", "unique color and design elements specific to the Reventon Coupe 2008 model"], "Lamborghini Aventador Coupe 2012": ["sleek, aerodynamic body", "low ground clearance", "two doors", "large, curved windshield", "signature Lamborghini logo on the front and back", "dual exhaust pipes", "large, alloy wheels", "sharp, angular headlights and taillights", "distinctive color and design (e.g. bright red or yellow with black accents)"], "Lamborghini Gallardo LP 570-4 Superleggera 2012": ["sleek, low-profile design", "two doors", "large, curved air intakes on the sides", "a large rear wing", "a prominent Lamborghini logo on the front and back", "a sporty, aerodynamic shape", "a bright, eye-catching color (such as yellow, orange, or red)", "a powerful engine visible through the rear window", "a low ground clearance", "large, high-performance tires", "a sporty, luxurious interior with leather seats and"], "Lamborghini Diablo Coupe 2001": ["sleek, low-profile design", "two doors", "signature Lamborghini logo on the front and back", "large, curved air intakes on the sides", "dual exhaust pipes", "distinctive headlights and taillights", "glossy paint job", "Lamborghini emblem on the steering wheel", "leather seats with Lamborghini logo", "speedometer and other gauges on the dashboard"], "Land Rover Range Rover SUV 2012": ["four-wheeled vehicle", "large, boxy body shape", "raised ground clearance", "large, round headlights", "signature front grille with Land Rover logo", "alloy wheels", "side mirrors with integrated turn signals", "roof rack", "rear spoiler", "tailgate with Range Rover badge", "dual exhaust pipes", "leather interior with wood trim accents", "touchscreen display for navigation and entertainment system", "steering wheel with Range Rover logo", "gear shift knob with Range Rover"], "Land Rover LR2 SUV 2012": ["four-wheeled vehicle", "silver, black, or white", "boxy, angular shape", "large, round headlights", "a prominent grille", "a Land Rover logo on the front and back", "a sunroof", "a spare tire on the back", "a license plate", "a model name and year on the back"], "Lincoln Town Car Sedan 2011": ["four-door sedan body style", "signature Lincoln grille and emblem on the front", "sleek and elongated body shape", "chrome accents on the exterior", "large, round headlights", "a long wheelbase", "a sunroof or moonroof", "leather seats and wood trim interior", "a dashboard with digital displays and controls", "a Lincoln logo on the steering wheel", "a model and year badge on the rear of the car."], "MINI Cooper Roadster Convertible 2012": ["two doors", "convertible top", "round headlights", "circular logo on the front grille", "horizontal taillights", "low ground clearance", "sporty design", "unique color options (e.g. British Racing Green, Chili Red)"], "Maybach Landaulet Convertible 2012": ["sleek and elegant design", "convertible top", "large, shiny wheels", "Maybach logo on the front grille", "two-tone exterior paint", "leather interior", "high-end features such as a navigation system, premium sound system, and advanced safety features."], "Mazda Tribute SUV 2011": ["four wheels", "a compact, boxy body shape", "a front grille with the Mazda logo", "a rear hatchback or trunk", "a sunroof (optional)", "a roof rack (optional)", "a license plate", "a model name and year on the back or side of the vehicle"], "McLaren MP4-12C Coupe 2012": ["sleek, aerodynamic body", "low to the ground", "two doors", "large, curved windshield", "signature McLaren logo on the front and back", "distinctive headlights and taillights", "large air intakes on the sides", "dual exhaust pipes", "alloy wheels with a unique design", "carbon fiber accents on the body", "sporty and luxurious interior with leather seats and a digital dashboard display."], "Mercedes-Benz 300-Class Convertible 1993": ["luxury car", "convertible top", "sleek and aerodynamic design", "Mercedes-Benz logo on the front grille and wheels", "round headlights", "chrome accents", "leather interior", "1993 model year"], "Mercedes-Benz C-Class Sedan 2012": ["silver, black, or white", "iconic three-pointed star emblem on the front grille", "sleek and aerodynamic body design", "four doors", "alloy wheels", "LED headlights and taillights", "leather interior", "dashboard with digital display and controls", "Mercedes-Benz logo on the steering wheel"], "Mercedes-Benz SL-Class Coupe 2009": ["luxury sports car", "sleek and aerodynamic design", "silver or black exterior", "iconic Mercedes-Benz logo on the front grille", "two doors", "low ground clearance", "large, round headlights", "leather interior", "dashboard with digital display and controls", "steering wheel with Mercedes-Benz logo", "license plate with model and year information"], "Mercedes-Benz E-Class Sedan 2012": ["silver, black, or white exterior", "distinctive Mercedes-Benz logo on the front grille", "sleek and aerodynamic body shape", "four doors", "alloy wheels", "LED headlights and taillights", "leather interior", "advanced technology features such as a navigation system and touchscreen display."], "Mercedes-Benz S-Class Sedan 2012": ["silver, black, or white exterior", "iconic Mercedes-Benz logo on the front grille", "sleek and aerodynamic body shape", "four doors", "large, round headlights", "chrome accents on the exterior", "leather interior with wood or metal trim", "advanced technology features such as a touchscreen display and navigation system"], "Mercedes-Benz Sprinter Van 2012": ["large, boxy shape", "Mercedes-Benz logo on the front grille", "large, rectangular headlights", "side mirrors", "sliding side door", "rear doors that open outward", "large wheels with Mercedes-Benz logo on the center cap", "\"Sprinter\" badge on the side of the van", "metallic or glossy paint finish", "tinted windows", "roof rack or ladder on top of the van"], "Mitsubishi Lancer Sedan 2012": ["Mitsubishi logo on the front grille", "distinctive front grille design with chrome accents", "angular headlights", "fog lights (if equipped)", "side mirrors with integrated turn signals", "alloy wheels", "Lancer badge on the rear trunk", "taillights with a unique design", "rear spoiler (if equipped)", "license plate holder on the front and rear", "overall sleek and sporty appearance."], "Nissan Leaf Hatchback 2012": ["compact, hatchback body style", "Nissan logo on the front grille and rear of the car", "aerodynamic design with a sloping roofline", "electric charging port on the front of the car", "LED headlights and taillights", "alloy wheels", "\"Leaf\" badge on the rear of the car", "unique blue color (depending on the specific model)"], "Nissan NV Passenger Van 2012": ["large, boxy shape", "sliding side doors", "multiple rows of seats", "Nissan logo on the front grille", "distinctive headlights and taillights", "side mirrors", "license plate", "wheels and tires", "roof rack (if present)", "specific color and trim options (e.g. silver, SV trim)"], "Nissan Juke Hatchback 2012": ["hatchback body style", "distinctive front grille and headlights", "Nissan logo on the front and back", "four doors", "alloy wheels", "rear spoiler", "unique color options (e.g. Electric Blue, Solar Yellow)", "model name and year on the back or side of the car"], "Nissan 240SX Coupe 1998": ["two-door coupe body style", "Nissan logo on the front grille and rear trunk", "round headlights and taillights", "curved body lines and aerodynamic design", "alloy wheels", "side mirrors", "license plate", "model name and year on the rear of the car"], "Plymouth Neon Coupe 1999": ["four wheels", "two doors", "a sloping roofline", "a front grille with the Plymouth logo", "headlights and taillights", "a license plate", "a rear spoiler (optional)", "a distinct body shape and design unique to the 1999 model"], "Porsche Panamera Sedan 2012": ["four-door sedan body style", "sleek and aerodynamic design", "Porsche logo on the front and back", "distinctive headlights and taillights", "low ground clearance", "large wheels with low-profile tires", "dual exhaust pipes", "leather interior with high-quality finishes", "advanced technology features, such as a touchscreen display and navigation system"], "Ram CV Cargo Van Minivan 2012": ["a large, boxy shape", "a front grille with the Ram logo", "a sliding side door", "a rear cargo door", "a roof rack", "a cargo area with tie-downs and storage compartments", "a steering wheel with the Ram logo", "a dashboard with various controls and displays"], "Rolls-Royce Phantom Drophead Coupe Convertible 2012": ["large, sleek body", "iconic Rolls-Royce grille", "round headlights", "convertible top", "large, shiny wheels", "leather interior", "wood paneling on dashboard and doors", "Rolls-Royce emblem on hood and wheels"], "Rolls-Royce Ghost Sedan 2012": ["large, rectangular grille with the iconic \"Spirit of Ecstasy\" hood ornament", "sleek and aerodynamic body design", "signature \"suicide\" doors that open backwards", "large, round headlights with LED accents", "chrome accents and trim", "large, multi-spoke wheels", "\"RR\" logo on the wheels and front fenders", "long wheelbase and overall length", "high-quality leather interior with wood and metal accents", "advanced technology features such"], "Rolls-Royce Phantom Sedan 2012": ["large, sleek body", "iconic \"Spirit of Ecstasy\" hood ornament", "signature grille with vertical slats", "round headlights with LED accents", "long wheelbase", "chrome accents and trim", "leather interior with wood paneling", "iconic \"RR\" logo on wheels and hood", "unique coach doors that open backwards", "V12 engine badge on side panels."], "Scion xD Hatchback 2012": ["boxy shape", "four doors", "hatchback design", "Scion logo on the front grille", "distinct headlights and taillights", "alloy wheels", "side mirrors with integrated turn signals", "rear spoiler", "unique color options (such as Electric Wasabi or Hot Lava)"], "Spyker C8 Convertible 2009": ["a sleek, low-profile design", "a convertible top", "a long, pointed hood", "a distinctive front grille", "large, round headlights", "a small windshield", "two doors", "a sporty, aerodynamic shape", "the Spyker logo on the front and back of the car", "a unique color scheme or pattern on the exterior", "a license plate or registration sticker", "a steering wheel and dashboard visible through the windshield", "a luxurious interior with leather"], "Spyker C8 Coupe 2009": ["a sleek, low-profile body", "a distinctive front grille with the Spyker logo", "a long, pointed hood", "two doors", "large, round headlights", "a small windshield", "a low, curved roofline", "a rear spoiler", "two exhaust pipes", "a unique color or design pattern on the body"], "Suzuki Aerio Sedan 2007": ["silver, black, or white exterior", "Suzuki logo on the front grille and rear of the car", "aerodynamic design with curved lines", "four wheels with hubcaps or alloy rims", "side mirrors", "headlights and taillights", "license plate", "rear spoiler (optional)"], "Suzuki Kizashi Sedan 2012": ["Suzuki logo on the front grille", "sleek and aerodynamic design", "headlights and taillights", "alloy wheels", "side mirrors", "door handles", "license plate", "model name and year on the back of the car"], "Suzuki SX4 Hatchback 2012": ["hatchback body style", "four doors", "small size", "Suzuki logo on the front grille", "distinct headlights and taillights", "alloy wheels", "rear spoiler", "side mirrors with integrated turn signals", "roof rails", "model name and year on the back of the car"], "Suzuki SX4 Sedan 2012": ["compact size", "silver, black, or white color", "Suzuki logo on the front grille", "distinct headlights and taillights", "side mirrors", "four wheels with rims", "license plate", "antenna on the roof", "door handles", "gas cap on the side of the car", "rear spoiler (optional)"], "Tesla Model S Sedan 2012": ["four-door sedan body style", "sleek and aerodynamic design", "electric vehicle", "large, touchscreen display in the center console", "Tesla logo on the front grille and wheels", "charging port on the side of the car", "LED headlights and taillights", "unique door handles that retract into the body of the car", "panoramic sunroof", "aerodynamic wheels with a distinctive design"], "Toyota Sequoia SUV 2012": ["silver, black, or white", "Toyota logo on the front grille", "rectangular headlights and taillights", "large, boxy body shape", "roof rack", "alloy wheels", "rearview mirrors on both sides", "license plate on the front and back", "model name and year on the back of the vehicle"], "Toyota Camry Sedan 2012": ["Toyota logo on the front grille", "specific body design and shape", "specific color options (e.g. silver, white, black)", "specific wheel design and size", "specific headlight and taillight design", "specific interior features (e.g. dashboard, steering wheel)", "specific model year (2012)"], "Toyota Corolla Sedan 2012": ["Toyota logo on the front grille", "specific body shape and design unique to the 2012 model", "specific color options for the 2012 model", "specific wheel design for the 2012 model", "specific headlights and taillights for the 2012 model", "specific placement of the license plate", "specific interior features such as dashboard design and seat upholstery."], "Toyota 4Runner SUV 2012": ["four-wheeled vehicle", "silver, black, or white", "boxy, angular shape", "large, prominent grille", "Toyota logo on the front and back", "four doors", "raised ground clearance", "roof rack", "alloy wheels", "rear spoiler", "fog lights", "side mirrors with turn signals", "rearview camera", "\"4Runner\" badge on the back", "model year (2012) on the back or side of the vehicle"], "Volkswagen Golf Hatchback 2012": ["hatchback body style", "VW logo on the front grille", "round headlights", "horizontal taillights", "four doors", "alloy wheels", "rear spoiler", "license plate", "specific color and trim options for the 2012 model year (e.g. Tornado Red, Sunroof Package)"], "Volkswagen Golf Hatchback 1991": ["hatchback design with a rear door that opens upwards", "round headlights", "VW logo on the front grille", "rectangular taillights", "four doors", "license plate", "specific color and model year (1991)"], "Volkswagen Beetle Hatchback 2012": ["compact car", "round, bulbous shape", "curved fenders", "circular headlights", "VW logo on the front and back", "hatchback style trunk", "four doors", "alloy wheels", "available in various colors such as red, blue, white, and black"], "Volvo C30 Hatchback 2012": ["four wheels", "a hatchback body style", "a Volvo logo on the front grille", "a distinctive front grille design with diagonal lines", "a sloping roofline", "a rear spoiler", "a license plate", "a model name and year on the back of the car", "a unique color or paint job"], "Volvo 240 Sedan 1993": ["four-door sedan body style", "boxy and angular shape", "Volvo logo on the front grille and rear trunk", "rectangular headlights and taillights", "chrome trim on the bumpers and side panels", "license plate holder on the front and rear", "specific color options such as red, blue, or silver", "specific features such as a sunroof or roof rack"], "Volvo XC90 SUV 2007": ["four-wheeled vehicle", "silver, black, or white", "large, boxy body shape", "Volvo logo on the front grille", "rectangular headlights and taillights", "roof rails", "alloy wheels", "rearview mirrors with integrated turn signals", "\"XC90\" badge on the rear", "license plate", "leather seats and wood trim interior (specific to 2007 model)"], "smart fortwo Convertible 2012": ["two-seater car", "convertible top", "round headlights", "compact body shape", "two doors", "small wheels", "logo or branding on the front or back of the car"]}
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
new file mode 100755
index 0000000..5096eac
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,11 @@
+ftfy
+regex
+tqdm
+torch==2.0.1
+torchvision==0.15.2
+yacs
+tensorboard
+tabulate
+gdown
+wilds
+numpy==1.24.1
diff --git a/scripts/alvlm/main.sh b/scripts/alvlm/main.sh
new file mode 100755
index 0000000..76114f6
--- /dev/null
+++ b/scripts/alvlm/main.sh
@@ -0,0 +1,69 @@
+#!/bin/bash
+
+# custom config
+DATASET=$1
+CFG=$2 # config file
+ALMETHOD=$3 # Active learning method (random, entropy, coreset, badge)
+SEED=$4 # SEED number
+MODE=$5 # [none, AS, AE]
+
+
+DATA=/go/to/data # YOU NEED TO FIX IT
+
+
+TRAINER=ALVLM
+CTP="end" # class token position (end or middle)
+NCTX=16 # number of context tokens
+SHOTS=-1 # number of shots (1, 2, 4, 8, 16)
+CSC=True # class-specific context (False or True)
+
+DIR=output/${DATASET}/${TRAINER}/${CFG}_${SHOTS}shots/nctx${NCTX}_csc${CSC}_ctp${CTP}_al${ALMETHOD}_mode${MODE}/seed${SEED}
+if [ -d "$DIR" ]; then
+ echo "Oops! The results exist at ${DIR} (so skip this job)"
+elif [ "$MODE" = "AS" ]; then
+ python train.py \
+ --root ${DATA} \
+ --seed ${SEED} \
+ --trainer ${TRAINER} \
+ --dataset-config-file configs/datasets/${DATASET}.yaml \
+ --config-file configs/trainers/${TRAINER}/${CFG}.yaml \
+ --output-dir ${DIR} \
+ TRAINER.COOP.N_CTX ${NCTX} \
+ TRAINER.COOP.CSC ${CSC} \
+ TRAINER.COOP.CLASS_TOKEN_POSITION ${CTP} \
+ DATASET.NUM_SHOTS ${SHOTS} \
+ TRAINER.COOPAL.METHOD ${ALMETHOD} \
+ TRAINER.COOPAL.ASPATH ${DATASET}.json \
+ TRAINER.COOPAL.GAMMA 0.1
+elif [ "$MODE" = "AE" ]; then
+ python train.py \
+ --root ${DATA} \
+ --seed ${SEED} \
+ --trainer ${TRAINER} \
+ --dataset-config-file configs/datasets/${DATASET}.yaml \
+ --config-file configs/trainers/${TRAINER}/${CFG}.yaml \
+ --output-dir ${DIR} \
+ TRAINER.COOP.N_CTX ${NCTX} \
+ TRAINER.COOP.CSC ${CSC} \
+ TRAINER.COOP.CLASS_TOKEN_POSITION ${CTP} \
+ DATASET.NUM_SHOTS ${SHOTS} \
+ TRAINER.COOPAL.METHOD ${ALMETHOD} \
+ TRAINER.COOPAL.AEPATH ${DATASET}.json \
+ TRAINER.COOPAL.GAMMA 0.1
+elif [ "$MODE" = "none" ]; then
+ python train.py \
+ --root ${DATA} \
+ --seed ${SEED} \
+ --trainer ${TRAINER} \
+ --dataset-config-file configs/datasets/${DATASET}.yaml \
+ --config-file configs/trainers/${TRAINER}/${CFG}.yaml \
+ --output-dir ${DIR} \
+ TRAINER.COOP.N_CTX ${NCTX} \
+ TRAINER.COOP.CSC ${CSC} \
+ TRAINER.COOP.CLASS_TOKEN_POSITION ${CTP} \
+ DATASET.NUM_SHOTS ${SHOTS} \
+ TRAINER.COOPAL.METHOD ${ALMETHOD} \
+ TRAINER.COOPAL.GAMMA 0.1
+else
+ echo "MODE should be selected in [none, AS, AE]"
+fi
diff --git a/scripts/coop/README.md b/scripts/coop/README.md
new file mode 100755
index 0000000..7f21eaa
--- /dev/null
+++ b/scripts/coop/README.md
@@ -0,0 +1 @@
+These scripts are only for reproducing the results on the IJCV'22 paper.
\ No newline at end of file
diff --git a/scripts/coop/eval.sh b/scripts/coop/eval.sh
new file mode 100755
index 0000000..e4d3c8c
--- /dev/null
+++ b/scripts/coop/eval.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+# custom config
+DATA=/data/jhbang/coop/data
+TRAINER=CoOp
+SHOTS=16
+NCTX=16
+CSC=False
+CTP=end
+
+DATASET=$1
+CFG=$2
+
+for SEED in 1 2 3
+do
+ python train.py \
+ --root ${DATA} \
+ --seed ${SEED} \
+ --trainer ${TRAINER} \
+ --dataset-config-file configs/datasets/${DATASET}.yaml \
+ --config-file configs/trainers/${TRAINER}/${CFG}.yaml \
+ --output-dir output/evaluation/${TRAINER}/${CFG}_${SHOTS}shots/nctx${NCTX}_csc${CSC}_ctp${CTP}/${DATASET}/seed${SEED} \
+ --model-dir output/imagenet/${TRAINER}/${CFG}_${SHOTS}shots/nctx${NCTX}_csc${CSC}_ctp${CTP}/seed${SEED} \
+ # --load-epoch 50 \
+ --eval-only \
+ TRAINER.COOP.CTX_INIT a_photo_of_a \
+ # TRAINER.COOP.CSC ${CSC} \
+ # TRAINER.COOP.CLASS_TOKEN_POSITION ${CTP}
+done
\ No newline at end of file
diff --git a/scripts/coop/main.sh b/scripts/coop/main.sh
new file mode 100755
index 0000000..a9fd66f
--- /dev/null
+++ b/scripts/coop/main.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+
+# custom config
+DATA=/data/jhbang/coop/data
+TRAINER=CoOp
+
+DATASET=$1
+CFG=$2 # config file
+CTP=$3 # class token position (end or middle)
+NCTX=$4 # number of context tokens
+SHOTS=$5 # number of shots (1, 2, 4, 8, 16)
+CSC=$6 # class-specific context (False or True)
+
+for SHOTS in 4 8
+do
+ for SEED in 1 2 3
+ do
+ DIR=output/${DATASET}/${TRAINER}/${CFG}_${SHOTS}shots/nctx${NCTX}_csc${CSC}_ctp${CTP}/seed${SEED}
+ if [ -d "$DIR" ]; then
+ echo "Oops! The results exist at ${DIR} (so skip this job)"
+ else
+ python train.py \
+ --root ${DATA} \
+ --seed ${SEED} \
+ --trainer ${TRAINER} \
+ --dataset-config-file configs/datasets/${DATASET}.yaml \
+ --config-file configs/trainers/${TRAINER}/${CFG}.yaml \
+ --output-dir ${DIR} \
+ TRAINER.COOP.N_CTX ${NCTX} \
+ TRAINER.COOP.CSC ${CSC} \
+ TRAINER.COOP.CLASS_TOKEN_POSITION ${CTP} \
+ DATASET.NUM_SHOTS ${SHOTS}
+ fi
+ done
+done
\ No newline at end of file
diff --git a/scripts/coop/zeroshot.sh b/scripts/coop/zeroshot.sh
new file mode 100755
index 0000000..d6d6641
--- /dev/null
+++ b/scripts/coop/zeroshot.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+# custom config
+DATA=/path/to/datasets
+TRAINER=ZeroshotCLIP
+DATASET=$1
+CFG=$2 # rn50, rn101, vit_b32 or vit_b16
+
+python train.py \
+--root ${DATA} \
+--trainer ${TRAINER} \
+--dataset-config-file configs/datasets/${DATASET}.yaml \
+--config-file configs/trainers/CoOp/${CFG}.yaml \
+--output-dir output/${TRAINER}/${CFG}/${DATASET} \
+--eval-only
\ No newline at end of file
diff --git a/train.py b/train.py
new file mode 100755
index 0000000..2530b76
--- /dev/null
+++ b/train.py
@@ -0,0 +1,213 @@
+import argparse
+import torch
+
+from dassl.utils import setup_logger, set_random_seed, collect_env_info
+from dassl.config import get_cfg_default
+from dassl.engine import build_trainer
+
+# custom
+import datasets.oxford_pets
+import datasets.oxford_flowers
+import datasets.fgvc_aircraft
+import datasets.dtd
+import datasets.eurosat
+import datasets.stanford_cars
+import datasets.food101
+import datasets.sun397
+import datasets.caltech101
+import datasets.ucf101
+
+
+
+import trainers.alvlm
+
+
+def print_args(args, cfg):
+ print("***************")
+ print("** Arguments **")
+ print("***************")
+ optkeys = list(args.__dict__.keys())
+ optkeys.sort()
+ for key in optkeys:
+ print("{}: {}".format(key, args.__dict__[key]))
+ print("************")
+ print("** Config **")
+ print("************")
+ print(cfg)
+
+
+def reset_cfg(cfg, args):
+ if args.root:
+ cfg.DATASET.ROOT = args.root
+
+ if args.output_dir:
+ cfg.OUTPUT_DIR = args.output_dir
+
+ if args.resume:
+ cfg.RESUME = args.resume
+
+ if args.seed:
+ cfg.SEED = args.seed
+
+ if args.source_domains:
+ cfg.DATASET.SOURCE_DOMAINS = args.source_domains
+
+ if args.target_domains:
+ cfg.DATASET.TARGET_DOMAINS = args.target_domains
+
+ if args.transforms:
+ cfg.INPUT.TRANSFORMS = args.transforms
+
+ if args.trainer:
+ cfg.TRAINER.NAME = args.trainer
+
+ if args.backbone:
+ cfg.MODEL.BACKBONE.NAME = args.backbone
+
+ if args.head:
+ cfg.MODEL.HEAD.NAME = args.head
+
+
+def extend_cfg(cfg):
+ """
+ Add new config variables.
+
+ E.g.
+ from yacs.config import CfgNode as CN
+ cfg.TRAINER.MY_MODEL = CN()
+ cfg.TRAINER.MY_MODEL.PARAM_A = 1.
+ cfg.TRAINER.MY_MODEL.PARAM_B = 0.5
+ cfg.TRAINER.MY_MODEL.PARAM_C = False
+ """
+ from yacs.config import CfgNode as CN
+
+ cfg.TRAINER.COOP = CN()
+ cfg.TRAINER.COOP.N_CTX = 16 # number of context vectors
+ cfg.TRAINER.COOP.CSC = False # class-specific context
+ cfg.TRAINER.COOP.CTX_INIT = "" # initialization words
+ cfg.TRAINER.COOP.PREC = "fp16" # fp16, fp32, amp
+ cfg.TRAINER.COOP.CLASS_TOKEN_POSITION = "end" # 'middle' or 'end' or 'front'
+ cfg.TRAINER.COOP.TRAIN_TYPE="freeze"
+
+ cfg.TRAINER.COCOOP = CN()
+ cfg.TRAINER.COCOOP.N_CTX = 16 # number of context vectors
+ cfg.TRAINER.COCOOP.CTX_INIT = "" # initialization words
+ cfg.TRAINER.COCOOP.PREC = "fp16" # fp16, fp32, amp
+
+ cfg.TRAINER.COOPAL = CN()
+ cfg.TRAINER.COOPAL.METHOD = ""
+ cfg.TRAINER.COOPAL.ASPATH = ""
+ cfg.TRAINER.COOPAL.AEPATH = ""
+ cfg.TRAINER.COOPAL.GAMMA = 0.1
+ cfg.DATASET.SUBSAMPLE_CLASSES = "all" # all, base or new
+
+ cfg.TRAINER.MAPLE = CN()
+ cfg.TRAINER.MAPLE.N_CTX = 2 # number of context vectors
+ cfg.TRAINER.MAPLE.CTX_INIT = "a photo of a" # initialization words
+ cfg.TRAINER.MAPLE.PREC = "fp16" # fp16, fp32, amp
+ cfg.TRAINER.MAPLE.PROMPT_DEPTH = 9 # Max 12, minimum 0, for 1 it will act as shallow MaPLe (J=1)
+ cfg.DATASET.SUBSAMPLE_CLASSES = "all" # all, base or new
+
+def setup_cfg(args):
+ cfg = get_cfg_default()
+ extend_cfg(cfg)
+
+ # 1. From the dataset config file
+ if args.dataset_config_file:
+ cfg.merge_from_file(args.dataset_config_file)
+
+ # 2. From the method config file
+ if args.config_file:
+ cfg.merge_from_file(args.config_file)
+
+ # 3. From input arguments
+ reset_cfg(cfg, args)
+
+ # 4. From optional input arguments
+ cfg.merge_from_list(args.opts)
+
+ cfg.freeze()
+
+ return cfg
+
+
+def main(args):
+ cfg = setup_cfg(args)
+ if cfg.SEED >= 0:
+ print("Setting fixed seed: {}".format(cfg.SEED))
+ set_random_seed(cfg.SEED)
+ setup_logger(cfg.OUTPUT_DIR)
+
+ if torch.cuda.is_available() and cfg.USE_CUDA:
+ torch.backends.cudnn.benchmark = True
+
+ print_args(args, cfg)
+ print("Collecting env info ...")
+ print("** System info **\n{}\n".format(collect_env_info()))
+
+ trainer = build_trainer(cfg)
+
+ if args.eval_only:
+ trainer.load_model(args.model_dir, epoch=args.load_epoch)
+ trainer.test()
+ return
+
+ if not args.no_train:
+ trainer.train()
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser()
+ parser.add_argument("--root", type=str, default="", help="path to dataset")
+ parser.add_argument("--output-dir", type=str, default="", help="output directory")
+ parser.add_argument(
+ "--resume",
+ type=str,
+ default="",
+ help="checkpoint directory (from which the training resumes)",
+ )
+ parser.add_argument(
+ "--seed", type=int, default=-1, help="only positive value enables a fixed seed"
+ )
+ parser.add_argument(
+ "--source-domains", type=str, nargs="+", help="source domains for DA/DG"
+ )
+ parser.add_argument(
+ "--target-domains", type=str, nargs="+", help="target domains for DA/DG"
+ )
+ parser.add_argument(
+ "--transforms", type=str, nargs="+", help="data augmentation methods"
+ )
+ parser.add_argument(
+ "--config-file", type=str, default="", help="path to config file"
+ )
+ parser.add_argument(
+ "--dataset-config-file",
+ type=str,
+ default="",
+ help="path to config file for dataset setup",
+ )
+ parser.add_argument("--trainer", type=str, default="", help="name of trainer")
+ parser.add_argument("--backbone", type=str, default="", help="name of CNN backbone")
+ parser.add_argument("--head", type=str, default="", help="name of head")
+ parser.add_argument("--eval-only", action="store_true", help="evaluation only")
+ parser.add_argument(
+ "--model-dir",
+ type=str,
+ default="",
+ help="load model from this directory for eval-only mode",
+ )
+ parser.add_argument(
+ "--load-epoch", type=int, help="load model weights at this epoch for evaluation"
+ )
+ parser.add_argument(
+ "--no-train", action="store_true", help="do not call trainer.train()"
+ )
+ parser.add_argument(
+ "opts",
+ default=None,
+ nargs=argparse.REMAINDER,
+ help="modify config options using the command-line",
+ )
+ args = parser.parse_args()
+ main(args)
diff --git a/trainers/__init__.py b/trainers/__init__.py
new file mode 100755
index 0000000..e69de29
diff --git a/trainers/__pycache__/__init__.cpython-310.pyc b/trainers/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000..31d0fd6
Binary files /dev/null and b/trainers/__pycache__/__init__.cpython-310.pyc differ
diff --git a/trainers/__pycache__/alvlm.cpython-310.pyc b/trainers/__pycache__/alvlm.cpython-310.pyc
new file mode 100644
index 0000000..78e793e
Binary files /dev/null and b/trainers/__pycache__/alvlm.cpython-310.pyc differ
diff --git a/trainers/active_learning/AL.py b/trainers/active_learning/AL.py
new file mode 100644
index 0000000..64fae27
--- /dev/null
+++ b/trainers/active_learning/AL.py
@@ -0,0 +1,15 @@
+import torch
+
+class AL(object):
+ def __init__(self, cfg, model, unlabeled_dst, U_index, n_class, **kwargs):
+ self.unlabeled_dst = unlabeled_dst
+ self.U_index = U_index
+ self.unlabeled_set = torch.utils.data.Subset(unlabeled_dst, U_index)
+ self.n_unlabeled = len(self.unlabeled_set)
+ self.n_class = n_class
+ self.model = model
+ self.index = []
+ self.cfg = cfg
+
+ def select(self, **kwargs):
+ return
\ No newline at end of file
diff --git a/trainers/active_learning/__pycache__/AL.cpython-310.pyc b/trainers/active_learning/__pycache__/AL.cpython-310.pyc
new file mode 100644
index 0000000..fbd0afe
Binary files /dev/null and b/trainers/active_learning/__pycache__/AL.cpython-310.pyc differ
diff --git a/trainers/active_learning/__pycache__/badge.cpython-310.pyc b/trainers/active_learning/__pycache__/badge.cpython-310.pyc
new file mode 100644
index 0000000..56f86a3
Binary files /dev/null and b/trainers/active_learning/__pycache__/badge.cpython-310.pyc differ
diff --git a/trainers/active_learning/__pycache__/coreset.cpython-310.pyc b/trainers/active_learning/__pycache__/coreset.cpython-310.pyc
new file mode 100644
index 0000000..1b50349
Binary files /dev/null and b/trainers/active_learning/__pycache__/coreset.cpython-310.pyc differ
diff --git a/trainers/active_learning/__pycache__/entropy.cpython-310.pyc b/trainers/active_learning/__pycache__/entropy.cpython-310.pyc
new file mode 100644
index 0000000..36febdc
Binary files /dev/null and b/trainers/active_learning/__pycache__/entropy.cpython-310.pyc differ
diff --git a/trainers/active_learning/__pycache__/pcb.cpython-310.pyc b/trainers/active_learning/__pycache__/pcb.cpython-310.pyc
new file mode 100644
index 0000000..d4cd212
Binary files /dev/null and b/trainers/active_learning/__pycache__/pcb.cpython-310.pyc differ
diff --git a/trainers/active_learning/badge.py b/trainers/active_learning/badge.py
new file mode 100644
index 0000000..50031c4
--- /dev/null
+++ b/trainers/active_learning/badge.py
@@ -0,0 +1,131 @@
+import torch
+import numpy as np
+from sklearn.metrics import pairwise_distances
+import pdb
+from scipy import stats
+from dassl.data.transforms.transforms import build_transform
+from dassl.data.data_manager import build_data_loader
+
+from .AL import AL
+
+
+class BADGE(AL):
+ def __init__(self, cfg, model, unlabeled_dst, U_index, n_class, device, **kwargs):
+ super().__init__(cfg, model, unlabeled_dst, U_index, n_class, **kwargs)
+ self.device = device
+ self.pred = []
+
+ def get_grad_features(self):
+ self.pred = []
+ self.model.eval()
+ # embDim = self.model.image_encoder.attnpool.c_proj.out_features
+ if self.cfg.MODEL.BACKBONE.NAME != "RN50":
+ embDim = 512
+ else:
+ embDim = 1024
+ num_unlabeled = len(self.U_index)
+ assert len(self.unlabeled_set) == num_unlabeled, f"{len(self.unlabeled_dst)} != {num_unlabeled}"
+ grad_embeddings = torch.zeros([num_unlabeled, embDim * self.n_class])
+ with torch.no_grad():
+ unlabeled_loader = build_data_loader(
+ self.cfg,
+ data_source=self.unlabeled_set,
+ batch_size=self.cfg.DATALOADER.TRAIN_X.BATCH_SIZE,
+ n_domain=self.cfg.DATALOADER.TRAIN_X.N_DOMAIN,
+ n_ins=self.cfg.DATALOADER.TRAIN_X.N_INS,
+ tfm=build_transform(self.cfg, is_train=False),
+ is_train=False,
+ )
+ # unlabeled_loader = torch.utils.data.DataLoader(self.unlabeled_set, batch_size=self.cfg.DATALOADER.TRAIN_X.BATCH_SIZE,
+ # num_workers=self.cfg.DATALOADER.NUM_WORKERS)
+ # generate entire unlabeled features set
+ for i, batch in enumerate(unlabeled_loader):
+ inputs = batch["img"].to(self.device)
+ out, features = self.model(inputs, get_feature=True)
+ batchProbs = torch.nn.functional.softmax(out, dim=1).data
+ maxInds = torch.argmax(batchProbs, 1)
+ # _, preds = torch.max(out.data, 1)
+ self.pred.append(maxInds.detach().cpu())
+
+ for j in range(len(inputs)):
+ for c in range(self.n_class):
+ if c == maxInds[j]:
+ grad_embeddings[i * len(inputs) + j][embDim * c: embDim * (c + 1)] = features[j].clone() * (
+ 1 - batchProbs[j][c])
+ else:
+ grad_embeddings[i * len(inputs) + j][embDim * c: embDim * (c + 1)] = features[j].clone() * (
+ -1 * batchProbs[j][c])
+ return grad_embeddings.cpu().numpy()
+
+ # kmeans ++ initialization
+ def k_means_plus_centers(self, X, K):
+ ind = np.argmax([np.linalg.norm(s, 2) for s in X])
+ mu = [X[ind]]
+ indsAll = [ind]
+ centInds = [0.] * len(X)
+ cent = 0
+ print('#Samps\tTotal Distance')
+ while len(mu) < K:
+ if len(mu) == 1:
+ D2 = pairwise_distances(X, mu).ravel().astype(float)
+ else:
+ newD = pairwise_distances(X, [mu[-1]]).ravel().astype(float)
+ for i in range(len(X)):
+ if D2[i] > newD[i]:
+ centInds[i] = cent
+ D2[i] = newD[i]
+ if len(mu) % 100 == 0:
+ print(str(len(mu)) + '\t' + str(sum(D2)), flush=True)
+ if sum(D2) == 0.0: pdb.set_trace()
+ D2 = D2.ravel().astype(float)
+ Ddist = (D2 ** 2) / sum(D2 ** 2)
+ customDist = stats.rv_discrete(name='custm', values=(np.arange(len(D2)), Ddist))
+ ind = customDist.rvs(size=1)[0]
+ while ind in indsAll: ind = customDist.rvs(size=1)[0]
+ mu.append(X[ind])
+ indsAll.append(ind)
+ cent += 1
+ return indsAll
+
+ def select(self, n_query, **kwargs):
+ unlabeled_features = self.get_grad_features()
+ selected_indices = self.k_means_plus_centers(X=unlabeled_features, K=n_query)
+ scores = list(np.ones(len(selected_indices))) # equally assign 1 (meaningless)
+
+ Q_index = [self.U_index[idx] for idx in selected_indices]
+ return Q_index
+
+ def select_by_filter(self, n_query, **kwargs):
+ unlabeled_features = self.get_grad_features()
+ self.pred = torch.cat(self.pred)
+
+ pred_idx = []
+ ret_idx = []
+ Q_index = self.k_means_plus_centers(X=unlabeled_features, K=10*n_query)
+
+ # Q_index = [self.U_index[idx] for idx in selected_indices]
+
+ for q in Q_index:
+ if int(self.pred[q]) not in pred_idx:
+ pred_idx.append(int(self.pred[q]))
+ ret_idx.append(q)
+
+ if len(pred_idx) == self.n_class:
+ ret_idx = [self.U_index[idx] for idx in ret_idx]
+ print(f"pred idx(all the classes): {pred_idx}")
+ return ret_idx, None
+
+ print("Fail to get all the classes!!!")
+ for q in Q_index:
+ if len(ret_idx) == self.n_class:
+ ret_idx = [self.U_index[idx] for idx in ret_idx]
+ print(f"pred idx: {pred_idx}")
+ return ret_idx, None
+
+ if q not in ret_idx:
+ pred_idx.append(int(self.pred[q]))
+ ret_idx.append(q)
+
+ raise EnvironmentError
+
+
\ No newline at end of file
diff --git a/trainers/active_learning/coreset.py b/trainers/active_learning/coreset.py
new file mode 100644
index 0000000..b8e9887
--- /dev/null
+++ b/trainers/active_learning/coreset.py
@@ -0,0 +1,93 @@
+from .AL import AL
+import torch
+import numpy as np
+
+from dassl.data.transforms.transforms import build_transform
+from dassl.data.data_manager import build_data_loader
+
+
+class Coreset(AL):
+ def __init__(self, cfg, model, unlabeled_dst, U_index, val_set, n_class, **kwargs):
+ super().__init__(cfg, model, unlabeled_dst, U_index, n_class, **kwargs)
+ # self.I_index = I_index
+ # self.labeled_in_set = torch.utils.data.Subset(self.unlabeled_dst, self.I_index)
+ self.labeled_in_set = val_set
+
+ def get_features(self):
+ self.model.eval()
+ labeled_features, unlabeled_features = None, None
+ with torch.no_grad():
+ labeled_in_loader = build_data_loader(
+ self.cfg,
+ data_source=self.labeled_in_set,
+ batch_size=self.cfg.DATALOADER.TRAIN_X.BATCH_SIZE,
+ n_domain=self.cfg.DATALOADER.TRAIN_X.N_DOMAIN,
+ n_ins=self.cfg.DATALOADER.TRAIN_X.N_INS,
+ tfm=build_transform(self.cfg, is_train=False),
+ is_train=False,
+ )
+ unlabeled_loader = build_data_loader(
+ self.cfg,
+ data_source=self.unlabeled_set,
+ batch_size=self.cfg.DATALOADER.TRAIN_X.BATCH_SIZE,
+ n_domain=self.cfg.DATALOADER.TRAIN_X.N_DOMAIN,
+ n_ins=self.cfg.DATALOADER.TRAIN_X.N_INS,
+ tfm=build_transform(self.cfg, is_train=False),
+ is_train=False,
+ )
+ # labeled_in_loader = torch.utils.data.DataLoader(self.labeled_in_set, batch_size=self.args.test_batch_size, num_workers=self.args.workers)
+ # unlabeled_loader = torch.utils.data.DataLoader(self.unlabeled_set, batch_size=self.args.test_batch_size, num_workers=self.args.workers)
+
+ # generate entire labeled_in features set
+ for data in labeled_in_loader:
+ inputs = data["img"].cuda()
+ out, features = self.model(inputs, get_feature=True)
+
+ if labeled_features is None:
+ labeled_features = features
+ else:
+ labeled_features = torch.cat((labeled_features, features), 0)
+
+ # generate entire unlabeled features set
+ for data in unlabeled_loader:
+ inputs = data["img"].cuda()
+ out, features = self.model(inputs, get_feature=True)
+ if unlabeled_features is None:
+ unlabeled_features = features
+ else:
+ unlabeled_features = torch.cat((unlabeled_features, features), 0)
+ return labeled_features, unlabeled_features
+
+ def k_center_greedy(self, labeled, unlabeled, n_query):
+ # get the minimum distances between the labeled and unlabeled examples (iteratively, to avoid memory issues):
+ min_dist = torch.min(torch.cdist(labeled[0:2, :], unlabeled), 0).values
+ for j in range(2, labeled.shape[0], 100):
+ if j + 100 < labeled.shape[0]:
+ dist_matrix = torch.cdist(labeled[j:j + 100, :], unlabeled)
+ else:
+ dist_matrix = torch.cdist(labeled[j:, :], unlabeled)
+ min_dist = torch.stack((min_dist, torch.min(dist_matrix, 0).values))
+ min_dist = torch.min(min_dist, 0).values
+
+ min_dist = min_dist.reshape((1, min_dist.size(0)))
+ farthest = torch.argmax(min_dist)
+
+ greedy_indices = torch.tensor([farthest])
+ for i in range(n_query - 1):
+ dist_matrix = torch.cdist(unlabeled[greedy_indices[-1], :].reshape((1, -1)), unlabeled)
+ min_dist = torch.stack((min_dist, dist_matrix))
+ min_dist = torch.min(min_dist, 0).values
+
+ farthest = torch.tensor([torch.argmax(min_dist)])
+ greedy_indices = torch.cat((greedy_indices, farthest), 0)
+
+ return greedy_indices.cpu().numpy()
+
+ def select(self, n_query, **kwargs):
+ labeled_features, unlabeled_features = self.get_features()
+ selected_indices = self.k_center_greedy(labeled_features, unlabeled_features, n_query)
+ scores = list(np.ones(len(selected_indices))) # equally assign 1 (meaningless)
+
+ Q_index = [self.U_index[idx] for idx in selected_indices]
+
+ return Q_index
\ No newline at end of file
diff --git a/trainers/active_learning/entropy.py b/trainers/active_learning/entropy.py
new file mode 100644
index 0000000..ab26657
--- /dev/null
+++ b/trainers/active_learning/entropy.py
@@ -0,0 +1,48 @@
+import torch
+import numpy as np
+from dassl.data.transforms.transforms import build_transform
+from dassl.data.data_manager import build_data_loader
+
+from .AL import AL
+
+class Entropy(AL):
+ def __init__(self, cfg, model, unlabeled_dst, U_index, n_class, device, **kwargs):
+ super().__init__(cfg, model, unlabeled_dst, U_index, n_class, **kwargs)
+ self.device= device
+
+ def run(self, n_query):
+ scores = self.rank_uncertainty()
+ selection_result = np.argsort(scores)[:n_query]
+ return selection_result, scores
+
+ def rank_uncertainty(self):
+ self.model.eval()
+ with torch.no_grad():
+ # selection_loader = torch.utils.data.DataLoader(self.unlabeled_set, batch_size=self.args.test_batch_size, num_workers=self.args.workers)
+ selection_loader = build_data_loader(
+ self.cfg,
+ data_source=self.unlabeled_set,
+ batch_size=self.cfg.DATALOADER.TRAIN_X.BATCH_SIZE,
+ n_domain=self.cfg.DATALOADER.TRAIN_X.N_DOMAIN,
+ n_ins=self.cfg.DATALOADER.TRAIN_X.N_INS,
+ tfm=build_transform(self.cfg, is_train=False),
+ is_train=False,
+ )
+ scores = np.array([])
+
+ print("| Calculating uncertainty of Unlabeled set")
+ for i, data in enumerate(selection_loader):
+ inputs = data["img"].to(self.device)
+
+ preds = self.model(inputs, get_feature=False)
+ preds = torch.nn.functional.softmax(preds, dim=1).cpu().numpy()
+ entropys = (np.log(preds + 1e-6) * preds).sum(axis=1)
+ scores = np.append(scores, entropys)
+
+ return scores
+
+ def select(self, n_query, **kwargs):
+ selected_indices, scores = self.run(n_query)
+ Q_index = [self.U_index[idx] for idx in selected_indices]
+
+ return Q_index
diff --git a/trainers/active_learning/pcb.py b/trainers/active_learning/pcb.py
new file mode 100644
index 0000000..90f5ddc
--- /dev/null
+++ b/trainers/active_learning/pcb.py
@@ -0,0 +1,68 @@
+import torch
+from dassl.data.transforms.transforms import build_transform
+from dassl.data.data_manager import build_data_loader
+import random
+
+from .AL import AL
+
+
+class PCB(AL):
+ def __init__(self, cfg, model, unlabeled_dst, U_index, n_class, statistics, device, **kwargs):
+ super().__init__(cfg, model, unlabeled_dst, U_index, n_class, **kwargs)
+ self.device = device
+ self.pred = []
+ self.statistics = statistics
+
+ def select(self, n_query, **kwargs):
+ self.pred = []
+ self.model.eval()
+ # embDim = self.model.image_encoder.attnpool.c_proj.out_features
+ num_unlabeled = len(self.U_index)
+ assert len(self.unlabeled_set) == num_unlabeled, f"{len(self.unlabeled_dst)} != {num_unlabeled}"
+ with torch.no_grad():
+ unlabeled_loader = build_data_loader(
+ self.cfg,
+ data_source=self.unlabeled_set,
+ batch_size=self.cfg.DATALOADER.TRAIN_X.BATCH_SIZE,
+ n_domain=self.cfg.DATALOADER.TRAIN_X.N_DOMAIN,
+ n_ins=self.cfg.DATALOADER.TRAIN_X.N_INS,
+ tfm=build_transform(self.cfg, is_train=False),
+ is_train=False,
+ )
+
+ # generate entire unlabeled features set
+ for i, batch in enumerate(unlabeled_loader):
+ inputs = batch["img"].to(self.device)
+ out, features = self.model(inputs, get_feature=True)
+ batchProbs = torch.nn.functional.softmax(out, dim=1).data
+ maxInds = torch.argmax(batchProbs, 1)
+ # _, preds = torch.max(out.data, 1)
+ self.pred.append(maxInds.detach().cpu())
+ self.pred = torch.cat(self.pred)
+
+ Q_index = []
+
+ while len(Q_index) < n_query:
+ min_cls = int(torch.argmin(self.statistics))
+ sub_pred = (self.pred == min_cls).nonzero().squeeze(dim=1).tolist()
+ if len(sub_pred) == 0:
+ num = random.randint(0, num_unlabeled-1)
+ while num in Q_index:
+ num = random.randint(0, num_unlabeled-1)
+ Q_index.append(num)
+ else:
+ random.shuffle(sub_pred)
+ for idx in sub_pred:
+ if idx not in Q_index:
+ Q_index.append(idx)
+ self.statistics[min_cls] += 1
+ break
+ else:
+ num = random.randint(0, num_unlabeled-1)
+ while num in Q_index:
+ num = random.randint(0, num_unlabeled-1)
+ Q_index.append(num)
+
+ Q_index = [self.U_index[idx] for idx in Q_index]
+
+ return Q_index
\ No newline at end of file
diff --git a/trainers/active_learning/strategy.py b/trainers/active_learning/strategy.py
new file mode 100644
index 0000000..f7ca3e2
--- /dev/null
+++ b/trainers/active_learning/strategy.py
@@ -0,0 +1,57 @@
+from copy import deepcopy
+
+
+class Strategy:
+ def __init__(self, X, Y, idxs_lb, X_val, Y_val, model, args, device, writer):
+ self.X = X
+ self.Y = Y
+ self.X_val = X_val
+ self.Y_val = Y_val
+ self.idxs_lb = idxs_lb
+ self.device = device
+ self.model = model
+ self.args = args
+ self.n_pool = len(Y)
+
+ self.writer = writer
+
+ self.query_count = 0
+
+ def query(self, n):
+ pass
+
+ def update(self, idxs_lb):
+ self.idxs_lb = idxs_lb
+
+ def train(self, name):
+ self.model.train(name, self.X, self.Y, self.idxs_lb, self.X_val, self.Y_val)
+
+ def predict(self, X, Y):
+ return self.model.predict(X, Y)
+
+ def predict_prob(self, X, Y):
+ return self.model.predict_prob(X, Y)
+
+ def predict_prob_embed(self, X, Y, eval=True):
+ return self.model.predict_prob_embed(X, Y, eval)
+
+ def predict_all_representations(self, X, Y):
+ return self.model.predict_all_representations(X, Y)
+
+ def predict_embedding_prob(self, X_embedding):
+ return self.model.predict_embedding_prob(X_embedding)
+
+ def predict_prob_dropout(self, X, Y, n_drop):
+ return self.model.predict_prob_dropout(X, Y, n_drop)
+
+ def predict_prob_dropout_split(self, X, Y, n_drop):
+ return self.model.predict_prob_dropout_split(X, Y, n_drop)
+
+ def predict_prob_embed_dropout_split(self, X, Y, n_drop):
+ return self.model.predict_prob_embed_dropout_split(X, Y, n_drop)
+
+ def get_embedding(self, X, Y):
+ return self.model.get_embedding(X, Y)
+
+ def get_grad_embedding(self, X, Y, is_embedding=False):
+ return self.model.get_grad_embedding(X, Y, is_embedding)
\ No newline at end of file
diff --git a/trainers/alvlm.py b/trainers/alvlm.py
new file mode 100755
index 0000000..fb1078a
--- /dev/null
+++ b/trainers/alvlm.py
@@ -0,0 +1,500 @@
+import os.path as osp
+from random import sample
+import time
+import json
+
+import torch
+import torch.nn as nn
+from torch.nn import functional as F
+from torch.cuda.amp import GradScaler, autocast
+
+from dassl.engine import TRAINER_REGISTRY, TrainerX
+from dassl.metrics import compute_accuracy
+from dassl.utils import load_pretrained_weights, load_checkpoint
+from dassl.optim import build_optimizer, build_lr_scheduler
+from dassl.data.datasets import build_dataset
+from dassl.data.transforms.transforms import build_transform
+from dassl.data.data_manager import build_data_loader
+
+from clip import clip
+from clip.simple_tokenizer import SimpleTokenizer as _Tokenizer
+from .active_learning.pcb import PCB
+from .active_learning.badge import BADGE
+from .active_learning.coreset import Coreset
+from .active_learning.entropy import Entropy
+
+_tokenizer = _Tokenizer()
+
+
+
+def load_clip_to_cpu(cfg):
+ backbone_name = cfg.MODEL.BACKBONE.NAME
+ url = clip._MODELS[backbone_name]
+ model_path = clip._download(url)
+
+ try:
+ # loading JIT archive
+ model = torch.jit.load(model_path, map_location="cpu").eval()
+ state_dict = None
+
+ except RuntimeError:
+ state_dict = torch.load(model_path, map_location="cpu")
+
+ model = clip.build_model(state_dict or model.state_dict())
+
+ return model
+
+
+class TextEncoder(nn.Module):
+ def __init__(self, clip_model):
+ super().__init__()
+ self.transformer = clip_model.transformer
+ self.positional_embedding = clip_model.positional_embedding
+ self.ln_final = clip_model.ln_final
+ self.text_projection = clip_model.text_projection
+ self.dtype = clip_model.dtype
+
+
+ def forward(self, prompts, tokenized_prompts):
+ x = prompts + self.positional_embedding.type(self.dtype)
+ x = x.permute(1, 0, 2) # NLD -> LND
+ x = self.transformer(x)
+ x = x.permute(1, 0, 2) # LND -> NLD
+ x = self.ln_final(x).type(self.dtype)
+
+ x = x[torch.arange(x.shape[0]), tokenized_prompts.argmax(dim=-1)] @ self.text_projection
+ return x
+
+
+class PromptLearner(nn.Module):
+ def __init__(self, cfg, classnames, clip_model):
+ super().__init__()
+ n_cls = len(classnames)
+ n_ctx = cfg.TRAINER.COOP.N_CTX
+ ctx_init = cfg.TRAINER.COOP.CTX_INIT
+ dtype = clip_model.dtype
+ ctx_dim = clip_model.ln_final.weight.shape[0]
+ clip_imsize = clip_model.visual.input_resolution
+ cfg_imsize = cfg.INPUT.SIZE[0]
+ assert cfg_imsize == clip_imsize, f"cfg_imsize ({cfg_imsize}) must equal to clip_imsize ({clip_imsize})"
+
+ # if not ctx_init.endswith(".json"):
+ prompt_prefix = " ".join(["X"] * n_ctx)
+
+ classnames = [name.replace("_", " ") for name in classnames]
+ n_desc_per_cls = None
+ if cfg.TRAINER.COOPAL.ASPATH:
+ with open(f"descriptors/descriptors_{cfg.TRAINER.COOPAL.ASPATH}", "r") as f:
+ desc_dict = json.load(f)
+ desc_dict = dict((k.lower(), v) for k,v in desc_dict.items())
+
+ name_lens, prompts = [], []
+ for name in classnames:
+ name = name.lower()
+ for desc in desc_dict[name]:
+ name_lens.append(len(_tokenizer.encode(f"{name}, which is/has {desc}")))
+ prompts.append(prompt_prefix + " " + f"{name}, which is/has {desc}.")
+
+ elif cfg.TRAINER.COOPAL.AEPATH:
+ with open(f"descriptors/descriptors_{cfg.TRAINER.COOPAL.AEPATH}", "r") as f:
+ desc_dict = json.load(f)
+ desc_dict = dict((k.lower(), v) for k,v in desc_dict.items())
+
+ name_lens, prompts = [], []
+ for name in classnames:
+ name = name.lower()
+ for desc in desc_dict[name]:
+ name_lens.append(len(_tokenizer.encode(f"{name}, which is/has {desc}")))
+ prompts.append(prompt_prefix + " " + f"{name}, which is/has {desc}.")
+
+ else:
+ name_lens = [len(_tokenizer.encode(name)) for name in classnames]
+ prompts = [prompt_prefix + " " + name + "." for name in classnames]
+ print(prompts)
+ tokenized_prompts = torch.cat([clip.tokenize(p) for p in prompts])
+ with torch.no_grad():
+ embedding = clip_model.token_embedding(tokenized_prompts).type(dtype)
+
+
+ # These token vectors will be saved when in save_model(),
+ # but they should be ignored in load_model() as we want to use
+ # those computed using the current class names
+ self.register_buffer("token_prefix", embedding[:, :1, :]) # SOS
+ self.register_buffer("token_suffix", embedding[:, 1 + n_ctx :, :]) # CLS, EOS
+
+ self.n_cls = embedding.size(0)
+ self.n_ctx = n_ctx
+ self.tokenized_prompts = tokenized_prompts # torch.Tensor
+ self.name_lens = name_lens
+ self.class_token_position = cfg.TRAINER.COOP.CLASS_TOKEN_POSITION
+
+ if ctx_init:
+ # use given words to initialize context vectors
+ ctx_init = ctx_init.replace("_", " ")
+ n_ctx = len(ctx_init.split(" "))
+ prompt = clip.tokenize(ctx_init)
+ with torch.no_grad():
+ embedding = clip_model.token_embedding(prompt).type(dtype)
+ ctx_vectors = embedding[0, 1 : 1 + n_ctx, :]
+ prompt_prefix = ctx_init
+
+ else:
+ # random initialization
+ if cfg.TRAINER.COOP.CSC:
+ print("Initializing class-specific contexts")
+ ctx_vectors = torch.empty(self.n_cls, n_ctx, ctx_dim, dtype=dtype)
+ else:
+ print("Initializing a generic context")
+ ctx_vectors = torch.empty(n_ctx, ctx_dim, dtype=dtype)
+ nn.init.normal_(ctx_vectors, std=0.02)
+
+ print(f'Initial context: "{prompt_prefix}"')
+ print(f"Number of context words (tokens): {n_ctx}")
+
+ self.ctx = nn.Parameter(ctx_vectors) # to be optimized
+
+ def forward(self):
+ ctx = self.ctx
+ if ctx.dim() == 2:
+ ctx = ctx.unsqueeze(0).expand(self.n_cls, -1, -1)
+
+ prefix = self.token_prefix
+ suffix = self.token_suffix
+
+ if self.class_token_position == "end":
+ prompts = torch.cat(
+ [
+ prefix, # (n_cls, 1, dim)
+ ctx, # (n_cls, n_ctx, dim)
+ suffix, # (n_cls, *, dim)
+ ],
+ dim=1,
+ )
+
+ elif self.class_token_position == "middle":
+ half_n_ctx = self.n_ctx // 2
+ prompts = []
+ for i in range(self.n_cls):
+ name_len = self.name_lens[i]
+ prefix_i = prefix[i : i + 1, :, :]
+ class_i = suffix[i : i + 1, :name_len, :]
+ suffix_i = suffix[i : i + 1, name_len:, :]
+ ctx_i_half1 = ctx[i : i + 1, :half_n_ctx, :]
+ ctx_i_half2 = ctx[i : i + 1, half_n_ctx:, :]
+ prompt = torch.cat(
+ [
+ prefix_i, # (1, 1, dim)
+ ctx_i_half1, # (1, n_ctx//2, dim)
+ class_i, # (1, name_len, dim)
+ ctx_i_half2, # (1, n_ctx//2, dim)
+ suffix_i, # (1, *, dim)
+ ],
+ dim=1,
+ )
+ prompts.append(prompt)
+ prompts = torch.cat(prompts, dim=0)
+
+ elif self.class_token_position == "front":
+ prompts = []
+ for i in range(self.n_cls):
+ name_len = self.name_lens[i]
+ prefix_i = prefix[i : i + 1, :, :]
+ class_i = suffix[i : i + 1, :name_len, :]
+ suffix_i = suffix[i : i + 1, name_len:, :]
+ ctx_i = ctx[i : i + 1, :, :]
+ prompt = torch.cat(
+ [
+ prefix_i, # (1, 1, dim)
+ class_i, # (1, name_len, dim)
+ ctx_i, # (1, n_ctx, dim)
+ suffix_i, # (1, *, dim)
+ ],
+ dim=1,
+ )
+ prompts.append(prompt)
+ prompts = torch.cat(prompts, dim=0)
+
+ else:
+ raise ValueError
+
+ return prompts
+
+
+class CustomCLIP(nn.Module):
+ def __init__(self, cfg, classnames, clip_model, desc_file=None):
+ super().__init__()
+
+ self.prompt_learner = PromptLearner(cfg, classnames, clip_model)
+ self.tokenized_prompts = self.prompt_learner.tokenized_prompts
+ self.image_encoder = clip_model.visual
+ self.text_encoder = TextEncoder(clip_model)
+
+ self.logit_scale = clip_model.logit_scale
+ self.dtype = clip_model.dtype
+ self.n_class_desc=[]
+ self.n_cls = len(classnames)
+ self.cfg = cfg
+
+ if desc_file is not None:
+ with open(f"descriptors/descriptors_{desc_file}", "r") as f:
+ desc_dict = json.load(f)
+ desc_dict = dict((k.lower(), v) for k,v in desc_dict.items())
+ classnames = [name.replace("_", " ") for name in classnames]
+ for name in classnames:
+ name = name.lower()
+ self.n_class_desc.append(len(desc_dict[name]))
+
+
+ def forward(self, image, get_feature=False):
+ image_features = self.image_encoder(image.type(self.dtype))
+
+ prompts = self.prompt_learner()
+ tokenized_prompts = self.tokenized_prompts
+
+
+ text_features = self.text_encoder(prompts, tokenized_prompts)
+
+ if self.cfg.TRAINER.COOPAL.AEPATH:
+ tmp = []
+ start = 0
+ for n in self.n_class_desc:
+ tmp.append(text_features[start:start+n].mean(dim=0))
+ start += n
+ text_features = torch.stack(tmp)
+
+ image_features = image_features / image_features.norm(dim=-1, keepdim=True)
+ text_features = text_features / text_features.norm(dim=-1, keepdim=True)
+
+ logit_scale = self.logit_scale.exp()
+ logits = logit_scale * image_features @ text_features.t()
+
+ if self.cfg.TRAINER.COOPAL.ASPATH:
+ tmp = []
+ start = 0
+ for n in self.n_class_desc:
+ tmp.append(torch.sum(logits[:, start:start+n], dim=1)/n)
+ start += n
+ logits = torch.stack(tmp, dim=1)
+
+ if get_feature:
+ return logits, image_features
+ else:
+ return logits
+
+
+@TRAINER_REGISTRY.register()
+class ALVLM(TrainerX):
+ """Context Optimization (CoOp).
+
+ Learning to Prompt for Vision-Language Models
+ https://arxiv.org/abs/2109.01134
+ """
+ def __init__(self, cfg):
+ super().__init__(cfg)
+ self.acc = []
+
+ def check_cfg(self, cfg):
+ assert cfg.TRAINER.COOP.PREC in ["fp16", "fp32", "amp"]
+
+ def build_model(self):
+ cfg = self.cfg
+ classnames = self.dm.dataset.classnames
+
+ print(f"Loading CLIP (backbone: {cfg.MODEL.BACKBONE.NAME})")
+ clip_model = load_clip_to_cpu(cfg)
+
+ if cfg.TRAINER.COOP.PREC == "fp32" or cfg.TRAINER.COOP.PREC == "amp":
+ # CLIP's default precision is fp16
+ clip_model.float()
+
+ print("Building custom CLIP")
+ if cfg.TRAINER.COOPAL.ASPATH:
+ self.model = CustomCLIP(cfg, classnames, clip_model, desc_file=cfg.TRAINER.COOPAL.ASPATH)
+ elif cfg.TRAINER.COOPAL.AEPATH:
+ self.model = CustomCLIP(cfg, classnames, clip_model, desc_file=cfg.TRAINER.COOPAL.AEPATH)
+ else:
+ self.model = CustomCLIP(cfg, classnames, clip_model)
+ print(self.model)
+
+ print("Turning off gradients in both the image and the text encoder")
+ for name, param in self.model.named_parameters():
+ if "prompt_learner" not in name:
+ param.requires_grad_(False)
+
+ if cfg.MODEL.INIT_WEIGHTS:
+ load_pretrained_weights(self.model.prompt_learner, cfg.MODEL.INIT_WEIGHTS)
+
+ self.model.to(self.device)
+
+ # NOTE: only give prompt_learner to the optimizer
+ self.optim = build_optimizer(self.model.prompt_learner, cfg.OPTIM)
+ self.sched = build_lr_scheduler(self.optim, cfg.OPTIM)
+ self.register_model(f"prompt_learner", self.model.prompt_learner, self.optim, self.sched)
+
+ self.scaler = GradScaler() if cfg.TRAINER.COOP.PREC == "amp" else None
+
+ # Note that multi-gpu training could be slow because CLIP's size is
+ # big, which slows down the copy operation in DataParallel
+ device_count = torch.cuda.device_count()
+ if device_count > 1:
+ print(f"Multiple GPUs detected (n_gpus={device_count}), use all of them!")
+ self.model = nn.DataParallel(self.model)
+ print(self.model)
+
+ def forward_backward(self, batch):
+ image, label = self.parse_batch_train(batch)
+
+ prec = self.cfg.TRAINER.COOP.PREC
+ if prec == "amp":
+ with autocast():
+ output = self.model(image)
+ loss = F.cross_entropy(output, label)
+ self.optim.zero_grad()
+ self.scaler.scale(loss).backward()
+ self.scaler.step(self.optim)
+ self.scaler.update()
+ else:
+ output = self.model(image)
+ loss = F.cross_entropy(output, label)
+ self.model_backward_and_update(loss)
+
+ loss_summary = {
+ "loss": loss.item(),
+ "acc": compute_accuracy(output, label)[0].item(),
+ }
+
+ if (self.batch_idx + 1) == self.num_batches:
+ self.update_lr()
+
+ return loss_summary
+
+ def parse_batch_train(self, batch):
+ input = batch["img"]
+ label = batch["label"]
+ input = input.to(self.device)
+ label = label.to(self.device)
+ return input, label
+
+ def load_model(self, directory, epoch=None):
+ if not directory:
+ print("Note that load_model() is skipped as no pretrained model is given")
+ return
+
+ names = self.get_model_names()
+
+ # By default, the best model is loaded
+ model_file = "model-best.pth.tar"
+
+ if epoch is not None:
+ model_file = "model.pth.tar-" + str(epoch)
+
+ for name in names:
+ model_path = osp.join(directory, name, model_file)
+
+ if not osp.exists(model_path):
+ raise FileNotFoundError('Model not found at "{}"'.format(model_path))
+
+ checkpoint = load_checkpoint(model_path)
+ state_dict = checkpoint["state_dict"]
+ epoch = checkpoint["epoch"]
+
+ # Ignore fixed token vectors
+ if "token_prefix" in state_dict:
+ del state_dict["token_prefix"]
+
+ if "token_suffix" in state_dict:
+ del state_dict["token_suffix"]
+
+ print("Loading weights to {} " 'from "{}" (epoch = {})'.format(name, model_path, epoch))
+ # set strict=False
+ self._models[name].load_state_dict(state_dict, strict=False)
+
+ def before_train(self):
+ print("INITIALIZE the prompts weights")
+ self.build_model()
+
+ def after_train(self):
+ print("Finish training")
+ do_test = not self.cfg.TEST.NO_TEST
+ if do_test:
+ if self.cfg.TEST.FINAL_MODEL == "best_val":
+ print("Deploy the model with the best val performance")
+ self.load_model(self.output_dir)
+ else:
+ print("Deploy the last-epoch model")
+ self.acc.append(self.test())
+
+ # Close writer
+ self.close_writer()
+
+ def train(self):
+ """Generic training loops."""
+ dataset = build_dataset(self.cfg)
+
+ print(f"dataset length: {len(dataset.train_x)}")
+ unlabeled_dst = dataset.train_x
+ U_index = list(range(len(unlabeled_dst)))
+ if self.cfg.TRAINER.COOP.CSC:
+ n_query = dataset.get_num_classes(unlabeled_dst)
+ else:
+ n_query = dataset.get_num_classes(unlabeled_dst)
+ n_cand = int(len(unlabeled_dst) * self.cfg.TRAINER.COOPAL.GAMMA) # 10% of entire dataset
+
+
+
+ dataset._train_x = []
+ for i in range(8):
+ start = time.time()
+ if self.cfg.TRAINER.COOPAL.METHOD == "random" or i ==0:
+ idx = sample(U_index, n_query)
+ elif self.cfg.TRAINER.COOPAL.METHOD == "entropy":
+ selector = Entropy(self.cfg, self.model, unlabeled_dst, U_index, dataset.get_num_classes(unlabeled_dst), self.device)
+ idx = selector.select(n_cand)
+ elif self.cfg.TRAINER.COOPAL.METHOD == "badge":
+ selector = BADGE(self.cfg, self.model, unlabeled_dst, U_index, dataset.get_num_classes(unlabeled_dst), self.device)
+ idx = selector.select(n_cand)
+ elif self.cfg.TRAINER.COOPAL.METHOD == "coreset":
+ val_x = dataset._train_x.copy()
+ selector = Coreset(self.cfg, self.model, unlabeled_dst, U_index, val_x, dataset.get_num_classes(unlabeled_dst))
+ idx = selector.select(n_cand)
+ else:
+ print("NotImplementedError")
+ idx = U_index
+
+ if i != 0:
+ statistics = torch.zeros(self.num_classes)
+ for elem in dataset._train_x:
+ statistics[elem.label] += 1
+ selector = PCB(self.cfg, self.model, unlabeled_dst, idx, dataset.get_num_classes(unlabeled_dst), statistics, self.device)
+ idx = selector.select(n_query)
+
+ # Filtering
+ for k in idx:
+ dataset._train_x.append(unlabeled_dst[k])
+ U_index.remove(k)
+ assert len(U_index) + len(dataset.train_x) == len(unlabeled_dst), f"u index: {len(U_index)}\t train set: {len(dataset.train_x)}\t unlabeled_dst: {len(unlabeled_dst)}"
+
+ self.train_loader_x = build_data_loader(
+ self.cfg,
+ sampler_type=self.cfg.DATALOADER.TRAIN_X.SAMPLER,
+ data_source=dataset.train_x,
+ batch_size=self.cfg.DATALOADER.TRAIN_X.BATCH_SIZE,
+ n_domain=self.cfg.DATALOADER.TRAIN_X.N_DOMAIN,
+ n_ins=self.cfg.DATALOADER.TRAIN_X.N_INS,
+ tfm=build_transform(self.cfg, is_train=True),
+ is_train=True,
+ dataset_wrapper=None
+ )
+ # self.model.train()
+ self.before_train()
+ for self.epoch in range(self.start_epoch, self.max_epoch):
+ self.before_epoch()
+ self.run_epoch()
+ self.after_epoch()
+ self.after_train()
+ print("training time for {}-th round: {:.2f} seconds".format(i, time.time() - start))
+ print("=== Result Overview ===")
+ for i in range(len(self.acc)):
+ print(f"{i}: {self.acc[i]}")
+ print("=======================")
+
diff --git a/trainers/coop.py b/trainers/coop.py
new file mode 100755
index 0000000..15e85d8
--- /dev/null
+++ b/trainers/coop.py
@@ -0,0 +1,325 @@
+import os.path as osp
+
+import torch
+import torch.nn as nn
+from torch.nn import functional as F
+from torch.cuda.amp import GradScaler, autocast
+
+from dassl.engine import TRAINER_REGISTRY, TrainerX
+from dassl.metrics import compute_accuracy
+from dassl.utils import load_pretrained_weights, load_checkpoint
+from dassl.optim import build_optimizer, build_lr_scheduler
+
+from clip import clip
+from clip.simple_tokenizer import SimpleTokenizer as _Tokenizer
+
+_tokenizer = _Tokenizer()
+
+
+def load_clip_to_cpu(cfg):
+ backbone_name = cfg.MODEL.BACKBONE.NAME
+ url = clip._MODELS[backbone_name]
+ model_path = clip._download(url)
+
+ try:
+ # loading JIT archive
+ model = torch.jit.load(model_path, map_location="cpu").eval()
+ state_dict = None
+
+ except RuntimeError:
+ state_dict = torch.load(model_path, map_location="cpu")
+
+ model = clip.build_model(state_dict or model.state_dict())
+
+ return model
+
+
+class TextEncoder(nn.Module):
+ def __init__(self, clip_model):
+ super().__init__()
+ self.transformer = clip_model.transformer
+ self.positional_embedding = clip_model.positional_embedding
+ self.ln_final = clip_model.ln_final
+ self.text_projection = clip_model.text_projection
+ self.dtype = clip_model.dtype
+
+ def forward(self, prompts, tokenized_prompts):
+ x = prompts + self.positional_embedding.type(self.dtype)
+ x = x.permute(1, 0, 2) # NLD -> LND
+ x = self.transformer(x)
+ x = x.permute(1, 0, 2) # LND -> NLD
+ x = self.ln_final(x).type(self.dtype)
+
+ # x.shape = [batch_size, n_ctx, transformer.width]
+ # take features from the eot embedding (eot_token is the highest number in each sequence)
+ x = x[torch.arange(x.shape[0]), tokenized_prompts.argmax(dim=-1)] @ self.text_projection
+
+ return x
+
+
+class PromptLearner(nn.Module):
+ def __init__(self, cfg, classnames, clip_model):
+ super().__init__()
+ n_cls = len(classnames)
+ n_ctx = cfg.TRAINER.COOP.N_CTX
+ ctx_init = cfg.TRAINER.COOP.CTX_INIT
+ dtype = clip_model.dtype
+ ctx_dim = clip_model.ln_final.weight.shape[0]
+ clip_imsize = clip_model.visual.input_resolution
+ cfg_imsize = cfg.INPUT.SIZE[0]
+ assert cfg_imsize == clip_imsize, f"cfg_imsize ({cfg_imsize}) must equal to clip_imsize ({clip_imsize})"
+
+ if ctx_init:
+ # use given words to initialize context vectors
+ ctx_init = ctx_init.replace("_", " ")
+ n_ctx = len(ctx_init.split(" "))
+ prompt = clip.tokenize(ctx_init)
+ with torch.no_grad():
+ embedding = clip_model.token_embedding(prompt).type(dtype)
+ ctx_vectors = embedding[0, 1 : 1 + n_ctx, :]
+ prompt_prefix = ctx_init
+
+ else:
+ # random initialization
+ if cfg.TRAINER.COOP.CSC:
+ print("Initializing class-specific contexts")
+ ctx_vectors = torch.empty(n_cls, n_ctx, ctx_dim, dtype=dtype)
+ else:
+ print("Initializing a generic context")
+ ctx_vectors = torch.empty(n_ctx, ctx_dim, dtype=dtype)
+ nn.init.normal_(ctx_vectors, std=0.02)
+ prompt_prefix = " ".join(["X"] * n_ctx)
+
+ print(f'Initial context: "{prompt_prefix}"')
+ print(f"Number of context words (tokens): {n_ctx}")
+
+ self.ctx = nn.Parameter(ctx_vectors) # to be optimized
+
+ classnames = [name.replace("_", " ") for name in classnames]
+ name_lens = [len(_tokenizer.encode(name)) for name in classnames]
+ prompts = [prompt_prefix + " " + name + "." for name in classnames]
+
+ tokenized_prompts = torch.cat([clip.tokenize(p) for p in prompts])
+ with torch.no_grad():
+ embedding = clip_model.token_embedding(tokenized_prompts).type(dtype)
+
+ # These token vectors will be saved when in save_model(),
+ # but they should be ignored in load_model() as we want to use
+ # those computed using the current class names
+ self.register_buffer("token_prefix", embedding[:, :1, :]) # SOS
+ self.register_buffer("token_suffix", embedding[:, 1 + n_ctx :, :]) # CLS, EOS
+
+ self.n_cls = n_cls
+ self.n_ctx = n_ctx
+ self.tokenized_prompts = tokenized_prompts # torch.Tensor
+ self.name_lens = name_lens
+ self.class_token_position = cfg.TRAINER.COOP.CLASS_TOKEN_POSITION
+
+ def forward(self):
+ ctx = self.ctx
+ if ctx.dim() == 2:
+ ctx = ctx.unsqueeze(0).expand(self.n_cls, -1, -1)
+
+ prefix = self.token_prefix
+ suffix = self.token_suffix
+
+ if self.class_token_position == "end":
+ prompts = torch.cat(
+ [
+ prefix, # (n_cls, 1, dim)
+ ctx, # (n_cls, n_ctx, dim)
+ suffix, # (n_cls, *, dim)
+ ],
+ dim=1,
+ )
+
+ elif self.class_token_position == "middle":
+ half_n_ctx = self.n_ctx // 2
+ prompts = []
+ for i in range(self.n_cls):
+ name_len = self.name_lens[i]
+ prefix_i = prefix[i : i + 1, :, :]
+ class_i = suffix[i : i + 1, :name_len, :]
+ suffix_i = suffix[i : i + 1, name_len:, :]
+ ctx_i_half1 = ctx[i : i + 1, :half_n_ctx, :]
+ ctx_i_half2 = ctx[i : i + 1, half_n_ctx:, :]
+ prompt = torch.cat(
+ [
+ prefix_i, # (1, 1, dim)
+ ctx_i_half1, # (1, n_ctx//2, dim)
+ class_i, # (1, name_len, dim)
+ ctx_i_half2, # (1, n_ctx//2, dim)
+ suffix_i, # (1, *, dim)
+ ],
+ dim=1,
+ )
+ prompts.append(prompt)
+ prompts = torch.cat(prompts, dim=0)
+
+ elif self.class_token_position == "front":
+ prompts = []
+ for i in range(self.n_cls):
+ name_len = self.name_lens[i]
+ prefix_i = prefix[i : i + 1, :, :]
+ class_i = suffix[i : i + 1, :name_len, :]
+ suffix_i = suffix[i : i + 1, name_len:, :]
+ ctx_i = ctx[i : i + 1, :, :]
+ prompt = torch.cat(
+ [
+ prefix_i, # (1, 1, dim)
+ class_i, # (1, name_len, dim)
+ ctx_i, # (1, n_ctx, dim)
+ suffix_i, # (1, *, dim)
+ ],
+ dim=1,
+ )
+ prompts.append(prompt)
+ prompts = torch.cat(prompts, dim=0)
+
+ else:
+ raise ValueError
+
+ return prompts
+
+
+class CustomCLIP(nn.Module):
+ def __init__(self, cfg, classnames, clip_model):
+ super().__init__()
+ self.prompt_learner = PromptLearner(cfg, classnames, clip_model)
+ self.tokenized_prompts = self.prompt_learner.tokenized_prompts
+ self.image_encoder = clip_model.visual
+ self.text_encoder = TextEncoder(clip_model)
+ self.logit_scale = clip_model.logit_scale
+ self.dtype = clip_model.dtype
+
+ def forward(self, image):
+ image_features = self.image_encoder(image.type(self.dtype))
+
+ prompts = self.prompt_learner()
+ tokenized_prompts = self.tokenized_prompts
+ text_features = self.text_encoder(prompts, tokenized_prompts)
+
+ image_features = image_features / image_features.norm(dim=-1, keepdim=True)
+ text_features = text_features / text_features.norm(dim=-1, keepdim=True)
+
+ logit_scale = self.logit_scale.exp()
+ logits = logit_scale * image_features @ text_features.t()
+
+ return logits
+
+
+@TRAINER_REGISTRY.register()
+class CoOp(TrainerX):
+ """Context Optimization (CoOp).
+
+ Learning to Prompt for Vision-Language Models
+ https://arxiv.org/abs/2109.01134
+ """
+
+ def check_cfg(self, cfg):
+ assert cfg.TRAINER.COOP.PREC in ["fp16", "fp32", "amp"]
+
+ def build_model(self):
+ cfg = self.cfg
+ classnames = self.dm.dataset.classnames
+
+ print(f"Loading CLIP (backbone: {cfg.MODEL.BACKBONE.NAME})")
+ clip_model = load_clip_to_cpu(cfg)
+
+ if cfg.TRAINER.COOP.PREC == "fp32" or cfg.TRAINER.COOP.PREC == "amp":
+ # CLIP's default precision is fp16
+ clip_model.float()
+
+ print("Building custom CLIP")
+ self.model = CustomCLIP(cfg, classnames, clip_model)
+
+ print("Turning off gradients in both the image and the text encoder")
+ for name, param in self.model.named_parameters():
+ if "prompt_learner" not in name:
+ param.requires_grad_(False)
+
+ if cfg.MODEL.INIT_WEIGHTS:
+ load_pretrained_weights(self.model.prompt_learner, cfg.MODEL.INIT_WEIGHTS)
+
+ self.model.to(self.device)
+ # NOTE: only give prompt_learner to the optimizer
+ self.optim = build_optimizer(self.model.prompt_learner, cfg.OPTIM)
+ self.sched = build_lr_scheduler(self.optim, cfg.OPTIM)
+ self.register_model("prompt_learner", self.model.prompt_learner, self.optim, self.sched)
+
+ self.scaler = GradScaler() if cfg.TRAINER.COOP.PREC == "amp" else None
+
+ # Note that multi-gpu training could be slow because CLIP's size is
+ # big, which slows down the copy operation in DataParallel
+ device_count = torch.cuda.device_count()
+ if device_count > 1:
+ print(f"Multiple GPUs detected (n_gpus={device_count}), use all of them!")
+ self.model = nn.DataParallel(self.model)
+
+ def forward_backward(self, batch):
+ image, label = self.parse_batch_train(batch)
+
+ prec = self.cfg.TRAINER.COOP.PREC
+ if prec == "amp":
+ with autocast():
+ output = self.model(image)
+ loss = F.cross_entropy(output, label)
+ self.optim.zero_grad()
+ self.scaler.scale(loss).backward()
+ self.scaler.step(self.optim)
+ self.scaler.update()
+ else:
+ output = self.model(image)
+ loss = F.cross_entropy(output, label)
+ self.model_backward_and_update(loss)
+
+ loss_summary = {
+ "loss": loss.item(),
+ "acc": compute_accuracy(output, label)[0].item(),
+ }
+
+ if (self.batch_idx + 1) == self.num_batches:
+ self.update_lr()
+
+ return loss_summary
+
+ def parse_batch_train(self, batch):
+ input = batch["img"]
+ label = batch["label"]
+ input = input.to(self.device)
+ label = label.to(self.device)
+ return input, label
+
+ def load_model(self, directory, epoch=None):
+ if not directory:
+ print("Note that load_model() is skipped as no pretrained model is given")
+ return
+
+ names = self.get_model_names()
+
+ # By default, the best model is loaded
+ model_file = "model-best.pth.tar"
+
+ if epoch is not None:
+ model_file = "model.pth.tar-" + str(epoch)
+
+ for name in names:
+ model_path = osp.join(directory, name, model_file)
+
+ if not osp.exists(model_path):
+ raise FileNotFoundError('Model not found at "{}"'.format(model_path))
+
+ checkpoint = load_checkpoint(model_path)
+ state_dict = checkpoint["state_dict"]
+ epoch = checkpoint["epoch"]
+
+ # Ignore fixed token vectors
+ if "token_prefix" in state_dict:
+ del state_dict["token_prefix"]
+
+ if "token_suffix" in state_dict:
+ del state_dict["token_suffix"]
+
+ print("Loading weights to {} " 'from "{}" (epoch = {})'.format(name, model_path, epoch))
+ # set strict=False
+ self._models[name].load_state_dict(state_dict, strict=False)
diff --git a/trainers/imagenet_templates.py b/trainers/imagenet_templates.py
new file mode 100755
index 0000000..560c5a5
--- /dev/null
+++ b/trainers/imagenet_templates.py
@@ -0,0 +1,94 @@
+# source: https://github.com/openai/CLIP/blob/main/notebooks/Prompt_Engineering_for_ImageNet.ipynb
+
+IMAGENET_TEMPLATES = [
+ "a bad photo of a {}.",
+ "a photo of many {}.",
+ "a sculpture of a {}.",
+ "a photo of the hard to see {}.",
+ "a low resolution photo of the {}.",
+ "a rendering of a {}.",
+ "graffiti of a {}.",
+ "a bad photo of the {}.",
+ "a cropped photo of the {}.",
+ "a tattoo of a {}.",
+ "the embroidered {}.",
+ "a photo of a hard to see {}.",
+ "a bright photo of a {}.",
+ "a photo of a clean {}.",
+ "a photo of a dirty {}.",
+ "a dark photo of the {}.",
+ "a drawing of a {}.",
+ "a photo of my {}.",
+ "the plastic {}.",
+ "a photo of the cool {}.",
+ "a close-up photo of a {}.",
+ "a black and white photo of the {}.",
+ "a painting of the {}.",
+ "a painting of a {}.",
+ "a pixelated photo of the {}.",
+ "a sculpture of the {}.",
+ "a bright photo of the {}.",
+ "a cropped photo of a {}.",
+ "a plastic {}.",
+ "a photo of the dirty {}.",
+ "a jpeg corrupted photo of a {}.",
+ "a blurry photo of the {}.",
+ "a photo of the {}.",
+ "a good photo of the {}.",
+ "a rendering of the {}.",
+ "a {} in a video game.",
+ "a photo of one {}.",
+ "a doodle of a {}.",
+ "a close-up photo of the {}.",
+ "a photo of a {}.",
+ "the origami {}.",
+ "the {} in a video game.",
+ "a sketch of a {}.",
+ "a doodle of the {}.",
+ "a origami {}.",
+ "a low resolution photo of a {}.",
+ "the toy {}.",
+ "a rendition of the {}.",
+ "a photo of the clean {}.",
+ "a photo of a large {}.",
+ "a rendition of a {}.",
+ "a photo of a nice {}.",
+ "a photo of a weird {}.",
+ "a blurry photo of a {}.",
+ "a cartoon {}.",
+ "art of a {}.",
+ "a sketch of the {}.",
+ "a embroidered {}.",
+ "a pixelated photo of a {}.",
+ "itap of the {}.",
+ "a jpeg corrupted photo of the {}.",
+ "a good photo of a {}.",
+ "a plushie {}.",
+ "a photo of the nice {}.",
+ "a photo of the small {}.",
+ "a photo of the weird {}.",
+ "the cartoon {}.",
+ "art of the {}.",
+ "a drawing of the {}.",
+ "a photo of the large {}.",
+ "a black and white photo of a {}.",
+ "the plushie {}.",
+ "a dark photo of a {}.",
+ "itap of a {}.",
+ "graffiti of the {}.",
+ "a toy {}.",
+ "itap of my {}.",
+ "a photo of a cool {}.",
+ "a photo of a small {}.",
+ "a tattoo of the {}.",
+]
+
+IMAGENET_TEMPLATES_SELECT = [
+ "itap of a {}.",
+ "a bad photo of the {}.",
+ "a origami {}.",
+ "a photo of the large {}.",
+ "a {} in a video game.",
+ "art of the {}.",
+ "a photo of the small {}.",
+]