| 96 | } |
| 97 | |
| 98 | void Detector::Train(std::string train_val_path, std::string image_type, int num_epochs, int batch_size, |
| 99 | float learning_rate, std::string save_path, std::string pretrained_path) { |
| 100 | if (!does_exist(pretrained_path)) |
| 101 | { |
| 102 | std::cout << "Pretrained path is invalid: " << pretrained_path <<"\t random initialzed the model"<< std::endl; |
| 103 | } |
| 104 | else { |
| 105 | loadPretrained(pretrained_path); |
| 106 | } |
| 107 | std::string train_label_path = train_val_path + "\\train\\images"; |
| 108 | std::string train_image_path = train_val_path + "\\train\\labels"; |
| 109 | std::string val_label_path = train_val_path + "\\val\\images"; |
| 110 | std::string val_image_path = train_val_path + "\\val\\labels"; |
| 111 | |
| 112 | std::vector<std::string> list_images_train = {}; |
| 113 | std::vector<std::string> list_labels_train = {}; |
| 114 | std::vector<std::string> list_images_val = {}; |
| 115 | std::vector<std::string> list_labels_val = {}; |
| 116 | |
| 117 | load_det_data_from_folder(train_image_path, image_type, list_images_train, list_labels_train); |
| 118 | load_det_data_from_folder(val_image_path, image_type, list_images_val, list_labels_val); |
| 119 | |
| 120 | if (list_images_train.size() < batch_size || list_images_val.size() < batch_size) { |
| 121 | std::cout << "Image numbers less than batch size or empty image folder" << std::endl; |
| 122 | return; |
| 123 | } |
| 124 | if (!does_exist(list_images_train[0])) |
| 125 | { |
| 126 | std::cout << "Image path is invalid get first train image " << list_images_train[0] << std::endl; |
| 127 | return; |
| 128 | } |
| 129 | auto custom_dataset_train = DetDataset(list_images_train, list_labels_train, name_list, true, |
| 130 | width, height); |
| 131 | auto custom_dataset_val = DetDataset(list_images_val, list_labels_val, name_list, false, width, height); |
| 132 | auto data_loader_train = torch::data::make_data_loader<torch::data::samplers::RandomSampler>(std::move(custom_dataset_train), batch_size); |
| 133 | auto data_loader_val = torch::data::make_data_loader<torch::data::samplers::RandomSampler>(std::move(custom_dataset_val), batch_size); |
| 134 | |
| 135 | float anchor[12] = { 10,14, 23,27, 37,58, 81,82, 135,169, 344,319 }; |
| 136 | auto anchors_ = torch::from_blob(anchor, { 6,2 }, torch::TensorOptions(torch::kFloat32)).to(device); |
| 137 | int image_size[2] = { width, height }; |
| 138 | |
| 139 | bool normalize = false; |
| 140 | auto critia1 = YOLOLossImpl(anchors_, name_list.size(), image_size, 0.01, device, normalize); |
| 141 | auto critia2 = YOLOLossImpl(anchors_, name_list.size(), image_size, 0.01, device, normalize); |
| 142 | |
| 143 | auto pretrained_dict = detector->named_parameters(); |
| 144 | auto FloatType = torch::ones(1).to(torch::kFloat).to(device).options(); |
| 145 | for (int epoc_count = 0; epoc_count < num_epochs; epoc_count++) { |
| 146 | float loss_sum = 0; |
| 147 | int batch_count = 0; |
| 148 | float loss_train = 0; |
| 149 | float loss_val = 0; |
| 150 | float best_loss = 1e10; |
| 151 | |
| 152 | if (epoc_count == int(num_epochs / 2)) { learning_rate /= 10; } |
| 153 | torch::optim::Adam optimizer(detector->parameters(), learning_rate); // Learning Rate |
| 154 | if (epoc_count < int(num_epochs / 10)) { |
| 155 | for (auto mm : pretrained_dict) |
nothing calls this directly
no test coverage detected