lucid-hf's picture
CI: deploy Docker/PDM Space
98a3af2 verified
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}')
@staticmethod
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')
# ]