Spaces:
Sleeping
Sleeping
| import torch | |
| import torch.nn as nn | |
| from datetime import datetime | |
| from pathlib import Path | |
| from typing import Dict | |
| import atexit | |
| from ..misc import dist_utils | |
| from ..core import BaseConfig | |
| 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) | |
| 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') | |
| # ] | |