def from_coco_128( val_split: float = 0.1, transform_kwargs: Optional[Dict[str, Any]] = None, batch_size: int = 1, **data_module_kwargs, ) -> ObjectDetectionData: """Downloads and loads the COCO 128 data set.""" download_data("https://github.com/zhiqwang/yolov5-rt-stack/releases/download/v0.3.0/coco128.zip", "data/") return ObjectDetectionData.from_coco( train_folder="data/coco128/images/train2017/", train_ann_file="data/coco128/annotations/instances_train2017.json", val_split=val_split, transform_kwargs=dict(image_size=(128, 128)) if transform_kwargs is None else transform_kwargs, batch_size=batch_size, **data_module_kwargs, )
def from_coco_128( val_split: float = 0.1, batch_size: int = 4, num_workers: int = 0, **preprocess_kwargs, ) -> ObjectDetectionData: """Downloads and loads the COCO 128 data set.""" download_data( "https://github.com/zhiqwang/yolov5-rt-stack/releases/download/v0.3.0/coco128.zip", "data/") return ObjectDetectionData.from_coco( train_folder="data/coco128/images/train2017/", train_ann_file="data/coco128/annotations/instances_train2017.json", val_split=val_split, batch_size=batch_size, num_workers=num_workers, **preprocess_kwargs, )
def train_with_hydra(cfg: DictConfig): # ---------- # TRAINING REPRODUCIBILITY # ----------- # print augmentation applied #print(instantiate(cfg.dataset.train_transform, _convert_="all").transform.tfms_list) # set this off if you want different random initialization every time seed_everything(42, workers=cfg.trainer.workers) # Dataclass for custom Image transform See dataset configuration in .yaml @dataclass class ObjectDetectionInputTransform(InputTransform): # transforms added to training data def train_per_sample_transform(self): return instantiate(cfg.dataset.train_transform, _convert_="all") # transforms added to validation data def val_per_sample_transform(self): return instantiate(cfg.dataset.val_transform, _convert_="all") # ---------- # INSTANTIATE DATASET FROM HYDRA CONF # ----------- # train_trans = instantiate(cfg.dataset.train_transform, _convert_="all") # print(train_trans.transform.tfms_list) # input("TEST") dm = ObjectDetectionData.from_coco( train_folder=cfg.dataset.path_folder_images, train_ann_file=cfg.dataset.path_folder_annotations, val_split=cfg.dataset.val_split, train_transform=ObjectDetectionInputTransform, val_transform=ObjectDetectionInputTransform, batch_size=cfg.dataset.batch_size) # ---------- # INSTANTIATE MODEL FROM HYDRA CONF # ----------- # setup number of class at runtime. Number of output classes cfg.model.model.num_classes = dm.num_classes model = instantiate(cfg.model.model) # ---------- # INSTANTIATE TRAINER FROM HYDRA CONF # ----------- # instantiate trainer trainer = instantiate(cfg.trainer.default) # ---------- # LOG HYDRA CONF AS ML FLOW ARTIFACT # ----------- # To use MlFlow with Pytorch Lightning you need Run id because PL is using MlflowClient mlFlowRunId = trainer.logger[0].run_id mlFlowClient = trainer.logger.experiment[0] mlFlowArtifactPath = HydraConfig.get()["runtime"]["cwd"] + "/conf/" print("HYDRA RUNTIME CWD {}".format(HydraConfig.get()["runtime"]["cwd"])) modelFile = mlFlowArtifactPath + "model/" + \ HydraConfig.get()["runtime"]["choices"]["model"] + ".yaml" trainerFile = mlFlowArtifactPath + "trainer/" + \ HydraConfig.get()["runtime"]["choices"]["trainer"] + ".yaml" datasetFile = mlFlowArtifactPath + "dataset/" + \ HydraConfig.get()["runtime"]["choices"]["dataset"] + ".yaml" # Save yaml file as mlflow artifacts mlFlowClient.log_artifact(mlFlowRunId, modelFile, "model") mlFlowClient.log_artifact(mlFlowRunId, trainerFile, "trainer") mlFlowClient.log_artifact(mlFlowRunId, datasetFile, "dataset") # Keep track to model path mlFlowClient.log_param( mlFlowRunId, "model_path", HydraConfig.get()["runtime"]["cwd"] + "/" + cfg.experiment_name + "/exp_" + str(cfg.experiment_number)) # Path to saved models if not os.path.exists(trainer.checkpoint_callback.dirpath): os.makedirs(trainer.checkpoint_callback.dirpath) # ---------- # START TRAINING # ----------- if cfg.model.from_scratch: print("FROM SCRATCH") trainer.fit(model=model, datamodule=dm) else: if (cfg.trainer.ckpt_path != None): print("RESUME TRAINING") model = model.load_from_checkpoint(cfg.trainer.ckpt_path) trainer.finetune(model=model, datamodule=dm, strategy=cfg.trainer.strategy)
os.getcwd(), "data/coco128/annotations/instances_train2017.json")) parser.add_argument('--max_epochs', type=int, default=1) parser.add_argument('--learning_rate', type=float, default=1e-3) parser.add_argument('--gpus', type=int, default=None) args = parser.parse_args() # 1. Download the data if args.download: # Dataset Credit: https://www.kaggle.com/ultralytics/coco128 download_data( "https://github.com/zhiqwang/yolov5-rt-stack/releases/download/v0.3.0/coco128.zip", os.path.join(os.getcwd(), "data/")) # 2. Load the Data datamodule = ObjectDetectionData.from_coco( train_folder=args.train_folder, train_ann_file=args.train_ann_file, batch_size=2) # 3. Build the model model = ObjectDetector(num_classes=datamodule.num_classes) # 4. Create the trainer trainer = flash.Trainer(max_epochs=args.max_epochs, gpus=args.gpus) # 5. Finetune the model trainer.finetune(model, datamodule) # 6. Save it! trainer.save_checkpoint("object_detection_model.pt")
from flash.core.integrations.fiftyone import visualize from flash.core.utilities.imports import example_requires from flash.image import ObjectDetectionData, ObjectDetector from flash.image.detection.serialization import FiftyOneDetectionLabels example_requires("image") import icedata # noqa: E402 # 1. Create the DataModule data_dir = icedata.fridge.load_data() datamodule = ObjectDetectionData.from_folders( train_folder=data_dir, predict_folder=data_dir, val_split=0.1, image_size=128, parser=icedata.fridge.parser, ) # 2. Build the task model = ObjectDetector(head="efficientdet", backbone="d0", num_classes=datamodule.num_classes, image_size=128) # 3. Create the trainer and finetune the model trainer = flash.Trainer(max_epochs=1) trainer.finetune(model, datamodule=datamodule, strategy="freeze") # 4. Set the serializer and get some predictions
def test_training_yolov5(capsys): Path("testModels").mkdir(parents=True, exist_ok=True) with capsys.disabled(): with initialize(config_path="conf"): cfg = compose(config_name="objectdetection") cfg.trainer.default.callbacks[0].dirpath = os.getcwd( ) + "/testModels" cfg.trainer.default.max_epochs = 2 cfg.model.model.backbone = "medium" cfg.model.model.head = "yolov5" # TRAINING REPRODUCIBILITY # ----------- # set this off if you want different random initialization every time seed_everything(42, workers=cfg.trainer.workers) # Dataclass for custom Image transform See dataset configuration in .yaml @dataclass class ObjectDetectionInputTransform(InputTransform): # transforms added to training data def train_per_sample_transform(self): return instantiate(cfg.dataset.train_transform, _convert_="all") # transforms added to validation data def val_per_sample_transform(self): return instantiate(cfg.dataset.val_transform, _convert_="all") # ---------- # INSTANTIATE DATASET FROM HYDRA CONF # ----------- # train_trans = instantiate(cfg.dataset.train_transform, _convert_="all") # print(train_trans.transform.tfms_list) # input("TEST") dm = ObjectDetectionData.from_coco( train_folder=cfg.dataset.path_folder_images, train_ann_file=cfg.dataset.path_folder_annotations, val_split=cfg.dataset.val_split, train_transform=ObjectDetectionInputTransform, val_transform=ObjectDetectionInputTransform, batch_size=cfg.dataset.batch_size) # ---------- # INSTANTIATE MODEL FROM HYDRA CONF # ----------- #setup number of class at runtime. Number of output classes cfg.model.model.num_classes = dm.num_classes model = instantiate(cfg.model.model) # ---------- # INSTANTIATE TRAINER FROM HYDRA CONF # ----------- # instantiate trainer trainer = instantiate(cfg.trainer.default) # ---------- # START TRAINING # ----------- trainer.fit(model=model, datamodule=dm) assert True
def test_onnx_conversion(capsys): with capsys.disabled(): with initialize(config_path="conf"): cfg = compose(config_name="objectdetection") cfg.model.model.backbone = "medium" cfg.model.model.head = "yolov5" # TRAINING REPRODUCIBILITY # ----------- # set this off if you want different random initialization every time seed_everything(42, workers=cfg.trainer.workers) # Dataclass for custom Image transform See dataset configuration in .yaml @dataclass class ObjectDetectionInputTransform(InputTransform): # transforms added to training data def train_per_sample_transform(self): return instantiate(cfg.dataset.train_transform, _convert_="all") # transforms added to validation data def val_per_sample_transform(self): return instantiate(cfg.dataset.val_transform, _convert_="all") # ---------- # INSTANTIATE DATASET FROM HYDRA CONF # ----------- # train_trans = instantiate(cfg.dataset.train_transform, _convert_="all") # print(train_trans.transform.tfms_list) # input("TEST") dm = ObjectDetectionData.from_coco( train_folder=cfg.dataset.path_folder_images, train_ann_file=cfg.dataset.path_folder_annotations, val_split=cfg.dataset.val_split, train_transform=ObjectDetectionInputTransform, val_transform=ObjectDetectionInputTransform, batch_size=cfg.dataset.batch_size) # ---------- # INSTANTIATE MODEL FROM HYDRA CONF # ----------- #setup number of class at runtime. Number of output classes cfg.model.model.num_classes = dm.num_classes model = instantiate(cfg.model.model) model = model.load_from_checkpoint(os.getcwd() + "/testModels/modelName.ckpt") #---------- # CONVERT MODEL TO ONNX #----------- dummy_input_real = torch.randn(cfg.onnx.model_batch_size, cfg.onnx.model_channel_input, cfg.onnx.model_height_input, cfg.onnx.model_width_input) # model is in model.adapter.model model_to_convert = model.adapter.model # Now model is a pytorch nn..Module model_to_convert = model_to_convert.cpu() # output class value #print(model_to_convert.nc) cfg.onnx.model_onnx_path = os.getcwd( ) + "/testModels/modelName.onnx" torch.onnx.export(model_to_convert, dummy_input_real, cfg.onnx.model_onnx_path, opset_version=cfg.onnx.opset_version) #---------- # CHECK ONNX MODEL #----------- onnx_model = onnx.load(cfg.onnx.model_onnx_path) onnx.checker.check_model(onnx_model) # ---------- # ONNXRUNTIME CHECK WITH PL MODEL # ----------- # Test Onnxruntime ort_session = onnxruntime.InferenceSession( cfg.onnx.model_onnx_path) ort_inputs = { ort_session.get_inputs()[0].name: to_numpy(dummy_input_real) } ort_outs = ort_session.run(None, ort_inputs) modelPl = model_to_convert.eval() score = modelPl(dummy_input_real) np.testing.assert_allclose(to_numpy(score[0]), ort_outs[0], rtol=1e-03, atol=1e-05) assert True
def train_with_hydra(cfg: DictConfig): cfg.inference.base_path= cfg.inference.model_path_to_load.split("train/",1)[0] +"inference" print("INFERENCE RESULTS WILL BE SAVED {}".format(cfg.inference.base_path)) device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") # For inferece set always batch_size = 1 cfg.inference.batch_size = 1 createFolderForExplanation(cfg) # ---------- # INSTANTIATE TEST TRANSFORM DATA # ----------- # Dataclass for custom Image transform See dataset configuration in .yaml @dataclass class ObjectDetectionInputTransform(InputTransform): def predict_per_sample_transform(self): return instantiate(cfg.dataset.test_transform, _convert_="all") # ---------- # INSTANTIATE COCO DATA # ----------- # Load COCO formatted dataset in fiftyone fiftyone_predict_dataset = fo.Dataset.from_dir( dataset_type=fo.types.COCODetectionDataset, data_path=cfg.inference.path_folder_images, labels_path=cfg.inference.path_folder_annotations, include_id=True, label_field="ground_truth" ) class_labels = fiftyone_predict_dataset.default_classes # create datamodule to load data in lightning datamodule = ObjectDetectionData.from_fiftyone( predict_dataset=fiftyone_predict_dataset, predict_transform=ObjectDetectionInputTransform, label_field="ground_truth_detections", batch_size=cfg.inference.batch_size ) # ---------- # INSTANTIATE MODEL AND TRAINER # ----------- model = instantiate(cfg.model.model) # if((cfg.inference.model_path_to_load != None) and (cfg.inference.model_path_to_load != "")): # print("LOAD PRETRAINED WEIGHT") # model = model.load_from_checkpoint( # cfg.inference.model_path_to_load) # instantiate trainer trainer = instantiate(cfg.trainer.default) # ---------- # RUN PREDICTION # ----------- # All prediction in your dataset predictions = trainer.predict(model, datamodule=datamodule) # model needs to put on gpu after train.predict in order to run explanation on gpu if(torch.cuda.is_available()): model = model.to(device) # model in eval model for explainability model.eval() # over all predictions for i, sample in enumerate(fiftyone_predict_dataset): detections = [] # 0 is because batch_size = 1 #over all bboxes in one image for bbox,score,label_index in zip(predictions[i][0][DataKeys.PREDS]["bboxes"],predictions[i][0][DataKeys.PREDS]["scores"],predictions[i][0][DataKeys.PREDS]["labels"]): # Original Image Dimension img_width_orig = sample.metadata["width"] img_height_orig = sample.metadata["height"] # model input dimension model_input_height, model_input_width = predictions[i][0][DataKeys.METADATA]["size"] # Coordinate rescale format is (x1,y1,x2,y2) rescale_coordinate = scale_coords( (model_input_height, model_input_width), bbox, (img_height_orig, img_width_orig)) # Need to change from (x1,y1,x2,y2)-> (x1,y1,width,heigth). Coco annotations are in this format rescale_coordinate[2] = rescale_coordinate[2] - \ rescale_coordinate[0] rescale_coordinate[3] = rescale_coordinate[3] - \ rescale_coordinate[1] # Coordinates in Fiftyone are normalized for Coco rescale_coordinate[[0, 2]] /= img_width_orig rescale_coordinate[[1, 3]] /= img_height_orig # Detection threshold if(score> cfg.inference.threshold): detections.append( fo.Detection( label=class_labels[label_index], bounding_box=rescale_coordinate.tolist(), confidence=score )) # save new detection to fifyone dataset sample["inference"] = fo.Detections(detections=detections) sample.save() results = fiftyone_predict_dataset.evaluate_detections( "inference", gt_field="ground_truth_detections", eval_key="objectDetection_eval", compute_mAP=True, ) # Save Confusion Matrix plot = results.plot_confusion_matrix(classes=class_labels, backend="matplotlib", figsize=(6, 6)) plot.savefig(cfg.inference.confusion_matrix.path_to_confusion_matrix_image) print(results.mAP()) print(results.metrics())
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import flash from flash.core.data.utils import download_data from flash.image import ObjectDetectionData, ObjectDetector # 1. Create the DataModule # Dataset Credit: https://www.kaggle.com/ultralytics/coco128 download_data( "https://github.com/zhiqwang/yolov5-rt-stack/releases/download/v0.3.0/coco128.zip", "data/") datamodule = ObjectDetectionData.from_coco( train_folder="data/coco128/images/train2017/", train_ann_file="data/coco128/annotations/instances_train2017.json", val_split=0.1, image_size=128, ) # 2. Build the task model = ObjectDetector(head="efficientdet", backbone="d0", num_classes=datamodule.num_classes, image_size=128) # 3. Create the trainer and finetune the model trainer = flash.Trainer(max_epochs=1) trainer.finetune(model, datamodule=datamodule, strategy="freeze") # 4. Detect objects in a few images! predictions = model.predict([
import flash from flash.core.integrations.fiftyone import visualize from flash.core.utilities.imports import example_requires from flash.image import ObjectDetectionData, ObjectDetector example_requires("image") import icedata # noqa: E402 # 1. Create the DataModule data_dir = icedata.fridge.load_data() datamodule = ObjectDetectionData.from_icedata( train_folder=data_dir, predict_folder=os.path.join(data_dir, "odFridgeObjects", "images"), val_split=0.1, transform_kwargs={"image_size": 128}, parser=icedata.fridge.parser, batch_size=8, ) # 2. Build the task model = ObjectDetector( head="efficientdet", backbone="d0", labels=datamodule.labels, image_size=128, lr_scheduler=("multisteplr", { "milestones": [20] }), )
# See the License for the specific language governing permissions and # limitations under the License. import flash from flash.core.data.utils import download_data from flash.image import ObjectDetectionData, ObjectDetector # 1. Create the DataModule # Dataset Credit: https://www.kaggle.com/ultralytics/coco128 download_data( "https://github.com/zhiqwang/yolov5-rt-stack/releases/download/v0.3.0/coco128.zip", "data/") datamodule = ObjectDetectionData.from_coco( train_folder="data/coco128/images/train2017/", train_ann_file="data/coco128/annotations/instances_train2017.json", val_split=0.1, transform_kwargs={"image_size": 512}, batch_size=4, ) # 2. Build the task model = ObjectDetector(head="efficientdet", backbone="d0", num_classes=datamodule.num_classes, image_size=512) # 3. Create the trainer and finetune the model trainer = flash.Trainer(max_epochs=1) trainer.finetune(model, datamodule=datamodule, strategy="freeze") # 4. Detect objects in a few images!
# limitations under the License. import flash from flash.core.data.utils import download_data from flash.image import ObjectDetectionData, ObjectDetector # 1. Download the data # Dataset Credit: https://www.kaggle.com/ultralytics/coco128 download_data( "https://github.com/zhiqwang/yolov5-rt-stack/releases/download/v0.3.0/coco128.zip", "data/") # 2. Load the Data datamodule = ObjectDetectionData.from_coco( train_folder="data/coco128/images/train2017/", train_ann_file="data/coco128/annotations/instances_train2017.json", val_split=0.3, batch_size=4, num_workers=4, ) # 3. Build the model model = ObjectDetector(model="retinanet", num_classes=datamodule.num_classes) # 4. Create the trainer trainer = flash.Trainer(max_epochs=3, limit_train_batches=1, limit_val_batches=1) # 5. Finetune the model trainer.finetune(model, datamodule=datamodule)