Spaces:
Running
on
Zero
Running
on
Zero
import atexit | |
from datetime import datetime | |
from pathlib import Path | |
from typing import Dict | |
import torch | |
import torch.nn as nn | |
from ..core import BaseConfig | |
from ..misc import dist_utils | |
def to(m: nn.Module, device: str): | |
if m is None: | |
return None | |
return m.to(device) | |
def remove_module_prefix(state_dict): | |
new_state_dict = {} | |
for k, v in state_dict.items(): | |
if k.startswith("module."): | |
new_state_dict[k[7:]] = v | |
else: | |
new_state_dict[k] = v | |
return new_state_dict | |
class BaseSolver(object): | |
def __init__(self, cfg: BaseConfig) -> None: | |
self.cfg = cfg | |
self.obj365_ids = [ | |
0, | |
46, | |
5, | |
58, | |
114, | |
55, | |
116, | |
65, | |
21, | |
40, | |
176, | |
127, | |
249, | |
24, | |
56, | |
139, | |
92, | |
78, | |
99, | |
96, | |
144, | |
295, | |
178, | |
180, | |
38, | |
39, | |
13, | |
43, | |
120, | |
219, | |
148, | |
173, | |
165, | |
154, | |
137, | |
113, | |
145, | |
146, | |
204, | |
8, | |
35, | |
10, | |
88, | |
84, | |
93, | |
26, | |
112, | |
82, | |
265, | |
104, | |
141, | |
152, | |
234, | |
143, | |
150, | |
97, | |
2, | |
50, | |
25, | |
75, | |
98, | |
153, | |
37, | |
73, | |
115, | |
132, | |
106, | |
61, | |
163, | |
134, | |
277, | |
81, | |
133, | |
18, | |
94, | |
30, | |
169, | |
70, | |
328, | |
226, | |
] | |
def _setup(self): | |
"""Avoid instantiating unnecessary classes""" | |
cfg = self.cfg | |
if cfg.device: | |
device = torch.device(cfg.device) | |
else: | |
device = torch.device("cuda" if torch.cuda.is_available() else "cpu") | |
self.model = cfg.model | |
# NOTE: Must load_tuning_state before EMA instance building | |
if self.cfg.tuning: | |
print(f"Tuning checkpoint from {self.cfg.tuning}") | |
self.load_tuning_state(self.cfg.tuning) | |
self.model = dist_utils.warp_model( | |
self.model.to(device), | |
sync_bn=cfg.sync_bn, | |
find_unused_parameters=cfg.find_unused_parameters, | |
) | |
self.criterion = self.to(cfg.criterion, device) | |
self.postprocessor = self.to(cfg.postprocessor, device) | |
self.ema = self.to(cfg.ema, device) | |
self.scaler = cfg.scaler | |
self.device = device | |
self.last_epoch = self.cfg.last_epoch | |
self.output_dir = Path(cfg.output_dir) | |
self.output_dir.mkdir(parents=True, exist_ok=True) | |
self.writer = cfg.writer | |
if self.writer: | |
atexit.register(self.writer.close) | |
if dist_utils.is_main_process(): | |
self.writer.add_text("config", "{:s}".format(cfg.__repr__()), 0) | |
self.use_wandb = self.cfg.use_wandb | |
if self.use_wandb: | |
try: | |
import wandb | |
self.use_wandb = True | |
except ImportError: | |
self.use_wandb = False | |
def cleanup(self): | |
if self.writer: | |
atexit.register(self.writer.close) | |
def train(self): | |
self._setup() | |
self.optimizer = self.cfg.optimizer | |
self.lr_scheduler = self.cfg.lr_scheduler | |
self.lr_warmup_scheduler = self.cfg.lr_warmup_scheduler | |
self.train_dataloader = dist_utils.warp_loader( | |
self.cfg.train_dataloader, shuffle=self.cfg.train_dataloader.shuffle | |
) | |
self.val_dataloader = dist_utils.warp_loader( | |
self.cfg.val_dataloader, shuffle=self.cfg.val_dataloader.shuffle | |
) | |
self.evaluator = self.cfg.evaluator | |
# NOTE: Instantiating order | |
if self.cfg.resume: | |
print(f"Resume checkpoint from {self.cfg.resume}") | |
self.load_resume_state(self.cfg.resume) | |
def eval(self): | |
self._setup() | |
self.val_dataloader = dist_utils.warp_loader( | |
self.cfg.val_dataloader, shuffle=self.cfg.val_dataloader.shuffle | |
) | |
self.evaluator = self.cfg.evaluator | |
if self.cfg.resume: | |
print(f"Resume checkpoint from {self.cfg.resume}") | |
self.load_resume_state(self.cfg.resume) | |
def to(self, module, device): | |
return module.to(device) if hasattr(module, "to") else module | |
def state_dict(self): | |
"""State dict, train/eval""" | |
state = {} | |
state["date"] = datetime.now().isoformat() | |
# For resume | |
state["last_epoch"] = self.last_epoch | |
for k, v in self.__dict__.items(): | |
if hasattr(v, "state_dict"): | |
v = dist_utils.de_parallel(v) | |
state[k] = v.state_dict() | |
return state | |
def load_state_dict(self, state): | |
"""Load state dict, train/eval""" | |
if "last_epoch" in state: | |
self.last_epoch = state["last_epoch"] | |
print("Load last_epoch") | |
for k, v in self.__dict__.items(): | |
if hasattr(v, "load_state_dict") and k in state: | |
v = dist_utils.de_parallel(v) | |
v.load_state_dict(state[k]) | |
print(f"Load {k}.state_dict") | |
if hasattr(v, "load_state_dict") and k not in state: | |
if k == "ema": | |
model = getattr(self, "model", None) | |
if model is not None: | |
ema = dist_utils.de_parallel(v) | |
model_state_dict = remove_module_prefix(model.state_dict()) | |
ema.load_state_dict({"module": model_state_dict}) | |
print(f"Load {k}.state_dict from model.state_dict") | |
else: | |
print(f"Not load {k}.state_dict") | |
def load_resume_state(self, path: str): | |
"""Load resume""" | |
if path.startswith("http"): | |
state = torch.hub.load_state_dict_from_url(path, map_location="cpu") | |
else: | |
state = torch.load(path, map_location="cpu") | |
# state['model'] = remove_module_prefix(state['model']) | |
self.load_state_dict(state) | |
def load_tuning_state(self, path: str): | |
"""Load model for tuning and adjust mismatched head parameters""" | |
if path.startswith("http"): | |
state = torch.hub.load_state_dict_from_url(path, map_location="cpu") | |
else: | |
state = torch.load(path, map_location="cpu") | |
module = dist_utils.de_parallel(self.model) | |
# Load the appropriate state dict | |
if "ema" in state: | |
pretrain_state_dict = state["ema"]["module"] | |
else: | |
pretrain_state_dict = state["model"] | |
# Adjust head parameters between datasets | |
try: | |
adjusted_state_dict = self._adjust_head_parameters( | |
module.state_dict(), pretrain_state_dict | |
) | |
stat, infos = self._matched_state(module.state_dict(), adjusted_state_dict) | |
except Exception: | |
stat, infos = self._matched_state(module.state_dict(), pretrain_state_dict) | |
module.load_state_dict(stat, strict=False) | |
print(f"Load model.state_dict, {infos}") | |
def _matched_state(state: Dict[str, torch.Tensor], params: Dict[str, torch.Tensor]): | |
missed_list = [] | |
unmatched_list = [] | |
matched_state = {} | |
for k, v in state.items(): | |
if k in params: | |
if v.shape == params[k].shape: | |
matched_state[k] = params[k] | |
else: | |
unmatched_list.append(k) | |
else: | |
missed_list.append(k) | |
return matched_state, {"missed": missed_list, "unmatched": unmatched_list} | |
def _adjust_head_parameters(self, cur_state_dict, pretrain_state_dict): | |
"""Adjust head parameters between datasets.""" | |
# List of parameters to adjust | |
if ( | |
pretrain_state_dict["decoder.denoising_class_embed.weight"].size() | |
!= cur_state_dict["decoder.denoising_class_embed.weight"].size() | |
): | |
del pretrain_state_dict["decoder.denoising_class_embed.weight"] | |
head_param_names = ["decoder.enc_score_head.weight", "decoder.enc_score_head.bias"] | |
for i in range(8): | |
head_param_names.append(f"decoder.dec_score_head.{i}.weight") | |
head_param_names.append(f"decoder.dec_score_head.{i}.bias") | |
adjusted_params = [] | |
for param_name in head_param_names: | |
if param_name in cur_state_dict and param_name in pretrain_state_dict: | |
cur_tensor = cur_state_dict[param_name] | |
pretrain_tensor = pretrain_state_dict[param_name] | |
adjusted_tensor = self.map_class_weights(cur_tensor, pretrain_tensor) | |
if adjusted_tensor is not None: | |
pretrain_state_dict[param_name] = adjusted_tensor | |
adjusted_params.append(param_name) | |
else: | |
print(f"Cannot adjust parameter '{param_name}' due to size mismatch.") | |
return pretrain_state_dict | |
def map_class_weights(self, cur_tensor, pretrain_tensor): | |
"""Map class weights from pretrain model to current model based on class IDs.""" | |
if pretrain_tensor.size() == cur_tensor.size(): | |
return pretrain_tensor | |
adjusted_tensor = cur_tensor.clone() | |
adjusted_tensor.requires_grad = False | |
if pretrain_tensor.size() > cur_tensor.size(): | |
for coco_id, obj_id in enumerate(self.obj365_ids): | |
adjusted_tensor[coco_id] = pretrain_tensor[obj_id + 1] | |
else: | |
for coco_id, obj_id in enumerate(self.obj365_ids): | |
adjusted_tensor[obj_id + 1] = pretrain_tensor[coco_id] | |
return adjusted_tensor | |
def fit(self): | |
raise NotImplementedError("") | |
def val(self): | |
raise NotImplementedError("") | |
# obj365_classes = [ | |
# 'Person', 'Sneakers', 'Chair', 'Other Shoes', 'Hat', 'Car', 'Lamp', 'Glasses', | |
# 'Bottle', 'Desk', 'Cup', 'Street Lights', 'Cabinet/shelf', 'Handbag/Satchel', | |
# 'Bracelet', 'Plate', 'Picture/Frame', 'Helmet', 'Book', 'Gloves', 'Storage box', | |
# 'Boat', 'Leather Shoes', 'Flower', 'Bench', 'Potted Plant', 'Bowl/Basin', 'Flag', | |
# 'Pillow', 'Boots', 'Vase', 'Microphone', 'Necklace', 'Ring', 'SUV', 'Wine Glass', | |
# 'Belt', 'Moniter/TV', 'Backpack', 'Umbrella', 'Traffic Light', 'Speaker', 'Watch', | |
# 'Tie', 'Trash bin Can', 'Slippers', 'Bicycle', 'Stool', 'Barrel/bucket', 'Van', | |
# 'Couch', 'Sandals', 'Bakset', 'Drum', 'Pen/Pencil', 'Bus', 'Wild Bird', 'High Heels', | |
# 'Motorcycle', 'Guitar', 'Carpet', 'Cell Phone', 'Bread', 'Camera', 'Canned', 'Truck', | |
# 'Traffic cone', 'Cymbal', 'Lifesaver', 'Towel', 'Stuffed Toy', 'Candle', 'Sailboat', | |
# 'Laptop', 'Awning', 'Bed', 'Faucet', 'Tent', 'Horse', 'Mirror', 'Power outlet', | |
# 'Sink', 'Apple', 'Air Conditioner', 'Knife', 'Hockey Stick', 'Paddle', 'Pickup Truck', | |
# 'Fork', 'Traffic Sign', 'Ballon', 'Tripod', 'Dog', 'Spoon', 'Clock', 'Pot', 'Cow', | |
# 'Cake', 'Dinning Table', 'Sheep', 'Hanger', 'Blackboard/Whiteboard', 'Napkin', | |
# 'Other Fish', 'Orange/Tangerine', 'Toiletry', 'Keyboard', 'Tomato', 'Lantern', | |
# 'Machinery Vehicle', 'Fan', 'Green Vegetables', 'Banana', 'Baseball Glove', | |
# 'Airplane', 'Mouse', 'Train', 'Pumpkin', 'Soccer', 'Skiboard', 'Luggage', 'Nightstand', | |
# 'Tea pot', 'Telephone', 'Trolley', 'Head Phone', 'Sports Car', 'Stop Sign', 'Dessert', | |
# 'Scooter', 'Stroller', 'Crane', 'Remote', 'Refrigerator', 'Oven', 'Lemon', 'Duck', | |
# 'Baseball Bat', 'Surveillance Camera', 'Cat', 'Jug', 'Broccoli', 'Piano', 'Pizza', | |
# 'Elephant', 'Skateboard', 'Surfboard', 'Gun', 'Skating and Skiing shoes', 'Gas stove', | |
# 'Donut', 'Bow Tie', 'Carrot', 'Toilet', 'Kite', 'Strawberry', 'Other Balls', 'Shovel', | |
# 'Pepper', 'Computer Box', 'Toilet Paper', 'Cleaning Products', 'Chopsticks', 'Microwave', | |
# 'Pigeon', 'Baseball', 'Cutting/chopping Board', 'Coffee Table', 'Side Table', 'Scissors', | |
# 'Marker', 'Pie', 'Ladder', 'Snowboard', 'Cookies', 'Radiator', 'Fire Hydrant', 'Basketball', | |
# 'Zebra', 'Grape', 'Giraffe', 'Potato', 'Sausage', 'Tricycle', 'Violin', 'Egg', | |
# 'Fire Extinguisher', 'Candy', 'Fire Truck', 'Billards', 'Converter', 'Bathtub', | |
# 'Wheelchair', 'Golf Club', 'Briefcase', 'Cucumber', 'Cigar/Cigarette ', 'Paint Brush', | |
# 'Pear', 'Heavy Truck', 'Hamburger', 'Extractor', 'Extention Cord', 'Tong', | |
# 'Tennis Racket', 'Folder', 'American Football', 'earphone', 'Mask', 'Kettle', | |
# 'Tennis', 'Ship', 'Swing', 'Coffee Machine', 'Slide', 'Carriage', 'Onion', | |
# 'Green beans', 'Projector', 'Frisbee', 'Washing Machine/Drying Machine', 'Chicken', | |
# 'Printer', 'Watermelon', 'Saxophone', 'Tissue', 'Toothbrush', 'Ice cream', | |
# 'Hotair ballon', 'Cello', 'French Fries', 'Scale', 'Trophy', 'Cabbage', 'Hot dog', | |
# 'Blender', 'Peach', 'Rice', 'Wallet/Purse', 'Volleyball', 'Deer', 'Goose', 'Tape', | |
# 'Tablet', 'Cosmetics', 'Trumpet', 'Pineapple', 'Golf Ball', 'Ambulance', 'Parking meter', | |
# 'Mango', 'Key', 'Hurdle', 'Fishing Rod', 'Medal', 'Flute', 'Brush', 'Penguin', | |
# 'Megaphone', 'Corn', 'Lettuce', 'Garlic', 'Swan', 'Helicopter', 'Green Onion', | |
# 'Sandwich', 'Nuts', 'Speed Limit Sign', 'Induction Cooker', 'Broom', 'Trombone', | |
# 'Plum', 'Rickshaw', 'Goldfish', 'Kiwi fruit', 'Router/modem', 'Poker Card', 'Toaster', | |
# 'Shrimp', 'Sushi', 'Cheese', 'Notepaper', 'Cherry', 'Pliers', 'CD', 'Pasta', 'Hammer', | |
# 'Cue', 'Avocado', 'Hamimelon', 'Flask', 'Mushroon', 'Screwdriver', 'Soap', 'Recorder', | |
# 'Bear', 'Eggplant', 'Board Eraser', 'Coconut', 'Tape Measur/ Ruler', 'Pig', | |
# 'Showerhead', 'Globe', 'Chips', 'Steak', 'Crosswalk Sign', 'Stapler', 'Campel', | |
# 'Formula 1 ', 'Pomegranate', 'Dishwasher', 'Crab', 'Hoverboard', 'Meat ball', | |
# 'Rice Cooker', 'Tuba', 'Calculator', 'Papaya', 'Antelope', 'Parrot', 'Seal', | |
# 'Buttefly', 'Dumbbell', 'Donkey', 'Lion', 'Urinal', 'Dolphin', 'Electric Drill', | |
# 'Hair Dryer', 'Egg tart', 'Jellyfish', 'Treadmill', 'Lighter', 'Grapefruit', | |
# 'Game board', 'Mop', 'Radish', 'Baozi', 'Target', 'French', 'Spring Rolls', 'Monkey', | |
# 'Rabbit', 'Pencil Case', 'Yak', 'Red Cabbage', 'Binoculars', 'Asparagus', 'Barbell', | |
# 'Scallop', 'Noddles', 'Comb', 'Dumpling', 'Oyster', 'Table Teniis paddle', | |
# 'Cosmetics Brush/Eyeliner Pencil', 'Chainsaw', 'Eraser', 'Lobster', 'Durian', 'Okra', | |
# 'Lipstick', 'Cosmetics Mirror', 'Curling', 'Table Tennis ' | |
# ] | |
# coco_classes = ['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', | |
# 'train', 'truck', 'boat', 'traffic light', 'fire hydrant', | |
# 'stop sign', 'parking meter', 'bench', 'wild bird', 'cat', 'dog', | |
# 'horse', 'sheep', 'cow', 'elephant', 'bear', 'zebra', 'giraffe', | |
# 'backpack', 'umbrella', 'handbag/satchel', 'tie', 'luggage', 'frisbee', | |
# 'skating and skiing shoes', 'snowboard', 'baseball', 'kite', 'baseball bat', | |
# 'baseball glove', 'skateboard', 'surfboard', 'tennis racket', | |
# 'bottle', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl/basin', | |
# 'banana', 'apple', 'sandwich', 'orange/tangerine', 'broccoli', 'carrot', | |
# 'hot dog', 'pizza', 'donut', 'cake', 'chair', 'couch', | |
# 'potted plant', 'bed', 'dinning table', 'toilet', 'moniter/tv', 'laptop', | |
# 'mouse', 'remote', 'keyboard', 'cell phone', 'microwave', | |
# 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', | |
# 'vase', 'scissors', 'stuffed toy', 'hair dryer', 'toothbrush'] | |
# obj365_classes = [ | |
# (0, 'Person'), | |
# (1, 'Sneakers'), | |
# (2, 'Chair'), | |
# (3, 'Other Shoes'), | |
# (4, 'Hat'), | |
# (5, 'Car'), | |
# (6, 'Lamp'), | |
# (7, 'Glasses'), | |
# (8, 'Bottle'), | |
# (9, 'Desk'), | |
# (10, 'Cup'), | |
# (11, 'Street Lights'), | |
# (12, 'Cabinet/shelf'), | |
# (13, 'Handbag/Satchel'), | |
# (14, 'Bracelet'), | |
# (15, 'Plate'), | |
# (16, 'Picture/Frame'), | |
# (17, 'Helmet'), | |
# (18, 'Book'), | |
# (19, 'Gloves'), | |
# (20, 'Storage box'), | |
# (21, 'Boat'), | |
# (22, 'Leather Shoes'), | |
# (23, 'Flower'), | |
# (24, 'Bench'), | |
# (25, 'Potted Plant'), | |
# (26, 'Bowl/Basin'), | |
# (27, 'Flag'), | |
# (28, 'Pillow'), | |
# (29, 'Boots'), | |
# (30, 'Vase'), | |
# (31, 'Microphone'), | |
# (32, 'Necklace'), | |
# (33, 'Ring'), | |
# (34, 'SUV'), | |
# (35, 'Wine Glass'), | |
# (36, 'Belt'), | |
# (37, 'Monitor/TV'), | |
# (38, 'Backpack'), | |
# (39, 'Umbrella'), | |
# (40, 'Traffic Light'), | |
# (41, 'Speaker'), | |
# (42, 'Watch'), | |
# (43, 'Tie'), | |
# (44, 'Trash bin Can'), | |
# (45, 'Slippers'), | |
# (46, 'Bicycle'), | |
# (47, 'Stool'), | |
# (48, 'Barrel/bucket'), | |
# (49, 'Van'), | |
# (50, 'Couch'), | |
# (51, 'Sandals'), | |
# (52, 'Basket'), | |
# (53, 'Drum'), | |
# (54, 'Pen/Pencil'), | |
# (55, 'Bus'), | |
# (56, 'Wild Bird'), | |
# (57, 'High Heels'), | |
# (58, 'Motorcycle'), | |
# (59, 'Guitar'), | |
# (60, 'Carpet'), | |
# (61, 'Cell Phone'), | |
# (62, 'Bread'), | |
# (63, 'Camera'), | |
# (64, 'Canned'), | |
# (65, 'Truck'), | |
# (66, 'Traffic cone'), | |
# (67, 'Cymbal'), | |
# (68, 'Lifesaver'), | |
# (69, 'Towel'), | |
# (70, 'Stuffed Toy'), | |
# (71, 'Candle'), | |
# (72, 'Sailboat'), | |
# (73, 'Laptop'), | |
# (74, 'Awning'), | |
# (75, 'Bed'), | |
# (76, 'Faucet'), | |
# (77, 'Tent'), | |
# (78, 'Horse'), | |
# (79, 'Mirror'), | |
# (80, 'Power outlet'), | |
# (81, 'Sink'), | |
# (82, 'Apple'), | |
# (83, 'Air Conditioner'), | |
# (84, 'Knife'), | |
# (85, 'Hockey Stick'), | |
# (86, 'Paddle'), | |
# (87, 'Pickup Truck'), | |
# (88, 'Fork'), | |
# (89, 'Traffic Sign'), | |
# (90, 'Balloon'), | |
# (91, 'Tripod'), | |
# (92, 'Dog'), | |
# (93, 'Spoon'), | |
# (94, 'Clock'), | |
# (95, 'Pot'), | |
# (96, 'Cow'), | |
# (97, 'Cake'), | |
# (98, 'Dining Table'), | |
# (99, 'Sheep'), | |
# (100, 'Hanger'), | |
# (101, 'Blackboard/Whiteboard'), | |
# (102, 'Napkin'), | |
# (103, 'Other Fish'), | |
# (104, 'Orange/Tangerine'), | |
# (105, 'Toiletry'), | |
# (106, 'Keyboard'), | |
# (107, 'Tomato'), | |
# (108, 'Lantern'), | |
# (109, 'Machinery Vehicle'), | |
# (110, 'Fan'), | |
# (111, 'Green Vegetables'), | |
# (112, 'Banana'), | |
# (113, 'Baseball Glove'), | |
# (114, 'Airplane'), | |
# (115, 'Mouse'), | |
# (116, 'Train'), | |
# (117, 'Pumpkin'), | |
# (118, 'Soccer'), | |
# (119, 'Skiboard'), | |
# (120, 'Luggage'), | |
# (121, 'Nightstand'), | |
# (122, 'Tea pot'), | |
# (123, 'Telephone'), | |
# (124, 'Trolley'), | |
# (125, 'Head Phone'), | |
# (126, 'Sports Car'), | |
# (127, 'Stop Sign'), | |
# (128, 'Dessert'), | |
# (129, 'Scooter'), | |
# (130, 'Stroller'), | |
# (131, 'Crane'), | |
# (132, 'Remote'), | |
# (133, 'Refrigerator'), | |
# (134, 'Oven'), | |
# (135, 'Lemon'), | |
# (136, 'Duck'), | |
# (137, 'Baseball Bat'), | |
# (138, 'Surveillance Camera'), | |
# (139, 'Cat'), | |
# (140, 'Jug'), | |
# (141, 'Broccoli'), | |
# (142, 'Piano'), | |
# (143, 'Pizza'), | |
# (144, 'Elephant'), | |
# (145, 'Skateboard'), | |
# (146, 'Surfboard'), | |
# (147, 'Gun'), | |
# (148, 'Skating and Skiing Shoes'), | |
# (149, 'Gas Stove'), | |
# (150, 'Donut'), | |
# (151, 'Bow Tie'), | |
# (152, 'Carrot'), | |
# (153, 'Toilet'), | |
# (154, 'Kite'), | |
# (155, 'Strawberry'), | |
# (156, 'Other Balls'), | |
# (157, 'Shovel'), | |
# (158, 'Pepper'), | |
# (159, 'Computer Box'), | |
# (160, 'Toilet Paper'), | |
# (161, 'Cleaning Products'), | |
# (162, 'Chopsticks'), | |
# (163, 'Microwave'), | |
# (164, 'Pigeon'), | |
# (165, 'Baseball'), | |
# (166, 'Cutting/chopping Board'), | |
# (167, 'Coffee Table'), | |
# (168, 'Side Table'), | |
# (169, 'Scissors'), | |
# (170, 'Marker'), | |
# (171, 'Pie'), | |
# (172, 'Ladder'), | |
# (173, 'Snowboard'), | |
# (174, 'Cookies'), | |
# (175, 'Radiator'), | |
# (176, 'Fire Hydrant'), | |
# (177, 'Basketball'), | |
# (178, 'Zebra'), | |
# (179, 'Grape'), | |
# (180, 'Giraffe'), | |
# (181, 'Potato'), | |
# (182, 'Sausage'), | |
# (183, 'Tricycle'), | |
# (184, 'Violin'), | |
# (185, 'Egg'), | |
# (186, 'Fire Extinguisher'), | |
# (187, 'Candy'), | |
# (188, 'Fire Truck'), | |
# (189, 'Billiards'), | |
# (190, 'Converter'), | |
# (191, 'Bathtub'), | |
# (192, 'Wheelchair'), | |
# (193, 'Golf Club'), | |
# (194, 'Briefcase'), | |
# (195, 'Cucumber'), | |
# (196, 'Cigar/Cigarette'), | |
# (197, 'Paint Brush'), | |
# (198, 'Pear'), | |
# (199, 'Heavy Truck'), | |
# (200, 'Hamburger'), | |
# (201, 'Extractor'), | |
# (202, 'Extension Cord'), | |
# (203, 'Tong'), | |
# (204, 'Tennis Racket'), | |
# (205, 'Folder'), | |
# (206, 'American Football'), | |
# (207, 'Earphone'), | |
# (208, 'Mask'), | |
# (209, 'Kettle'), | |
# (210, 'Tennis'), | |
# (211, 'Ship'), | |
# (212, 'Swing'), | |
# (213, 'Coffee Machine'), | |
# (214, 'Slide'), | |
# (215, 'Carriage'), | |
# (216, 'Onion'), | |
# (217, 'Green Beans'), | |
# (218, 'Projector'), | |
# (219, 'Frisbee'), | |
# (220, 'Washing Machine/Drying Machine'), | |
# (221, 'Chicken'), | |
# (222, 'Printer'), | |
# (223, 'Watermelon'), | |
# (224, 'Saxophone'), | |
# (225, 'Tissue'), | |
# (226, 'Toothbrush'), | |
# (227, 'Ice Cream'), | |
# (228, 'Hot Air Balloon'), | |
# (229, 'Cello'), | |
# (230, 'French Fries'), | |
# (231, 'Scale'), | |
# (232, 'Trophy'), | |
# (233, 'Cabbage'), | |
# (234, 'Hot Dog'), | |
# (235, 'Blender'), | |
# (236, 'Peach'), | |
# (237, 'Rice'), | |
# (238, 'Wallet/Purse'), | |
# (239, 'Volleyball'), | |
# (240, 'Deer'), | |
# (241, 'Goose'), | |
# (242, 'Tape'), | |
# (243, 'Tablet'), | |
# (244, 'Cosmetics'), | |
# (245, 'Trumpet'), | |
# (246, 'Pineapple'), | |
# (247, 'Golf Ball'), | |
# (248, 'Ambulance'), | |
# (249, 'Parking Meter'), | |
# (250, 'Mango'), | |
# (251, 'Key'), | |
# (252, 'Hurdle'), | |
# (253, 'Fishing Rod'), | |
# (254, 'Medal'), | |
# (255, 'Flute'), | |
# (256, 'Brush'), | |
# (257, 'Penguin'), | |
# (258, 'Megaphone'), | |
# (259, 'Corn'), | |
# (260, 'Lettuce'), | |
# (261, 'Garlic'), | |
# (262, 'Swan'), | |
# (263, 'Helicopter'), | |
# (264, 'Green Onion'), | |
# (265, 'Sandwich'), | |
# (266, 'Nuts'), | |
# (267, 'Speed Limit Sign'), | |
# (268, 'Induction Cooker'), | |
# (269, 'Broom'), | |
# (270, 'Trombone'), | |
# (271, 'Plum'), | |
# (272, 'Rickshaw'), | |
# (273, 'Goldfish'), | |
# (274, 'Kiwi Fruit'), | |
# (275, 'Router/Modem'), | |
# (276, 'Poker Card'), | |
# (277, 'Toaster'), | |
# (278, 'Shrimp'), | |
# (279, 'Sushi'), | |
# (280, 'Cheese'), | |
# (281, 'Notepaper'), | |
# (282, 'Cherry'), | |
# (283, 'Pliers'), | |
# (284, 'CD'), | |
# (285, 'Pasta'), | |
# (286, 'Hammer'), | |
# (287, 'Cue'), | |
# (288, 'Avocado'), | |
# (289, 'Hami Melon'), | |
# (290, 'Flask'), | |
# (291, 'Mushroom'), | |
# (292, 'Screwdriver'), | |
# (293, 'Soap'), | |
# (294, 'Recorder'), | |
# (295, 'Bear'), | |
# (296, 'Eggplant'), | |
# (297, 'Board Eraser'), | |
# (298, 'Coconut'), | |
# (299, 'Tape Measure/Ruler'), | |
# (300, 'Pig'), | |
# (301, 'Showerhead'), | |
# (302, 'Globe'), | |
# (303, 'Chips'), | |
# (304, 'Steak'), | |
# (305, 'Crosswalk Sign'), | |
# (306, 'Stapler'), | |
# (307, 'Camel'), | |
# (308, 'Formula 1'), | |
# (309, 'Pomegranate'), | |
# (310, 'Dishwasher'), | |
# (311, 'Crab'), | |
# (312, 'Hoverboard'), | |
# (313, 'Meatball'), | |
# (314, 'Rice Cooker'), | |
# (315, 'Tuba'), | |
# (316, 'Calculator'), | |
# (317, 'Papaya'), | |
# (318, 'Antelope'), | |
# (319, 'Parrot'), | |
# (320, 'Seal'), | |
# (321, 'Butterfly'), | |
# (322, 'Dumbbell'), | |
# (323, 'Donkey'), | |
# (324, 'Lion'), | |
# (325, 'Urinal'), | |
# (326, 'Dolphin'), | |
# (327, 'Electric Drill'), | |
# (328, 'Hair Dryer'), | |
# (329, 'Egg Tart'), | |
# (330, 'Jellyfish'), | |
# (331, 'Treadmill'), | |
# (332, 'Lighter'), | |
# (333, 'Grapefruit'), | |
# (334, 'Game Board'), | |
# (335, 'Mop'), | |
# (336, 'Radish'), | |
# (337, 'Baozi'), | |
# (338, 'Target'), | |
# (339, 'French'), | |
# (340, 'Spring Rolls'), | |
# (341, 'Monkey'), | |
# (342, 'Rabbit'), | |
# (343, 'Pencil Case'), | |
# (344, 'Yak'), | |
# (345, 'Red Cabbage'), | |
# (346, 'Binoculars'), | |
# (347, 'Asparagus'), | |
# (348, 'Barbell'), | |
# (349, 'Scallop'), | |
# (350, 'Noodles'), | |
# (351, 'Comb'), | |
# (352, 'Dumpling'), | |
# (353, 'Oyster'), | |
# (354, 'Table Tennis Paddle'), | |
# (355, 'Cosmetics Brush/Eyeliner Pencil'), | |
# (356, 'Chainsaw'), | |
# (357, 'Eraser'), | |
# (358, 'Lobster'), | |
# (359, 'Durian'), | |
# (360, 'Okra'), | |
# (361, 'Lipstick'), | |
# (362, 'Cosmetics Mirror'), | |
# (363, 'Curling'), | |
# (364, 'Table Tennis') | |
# ] | |