private async void btnTrain_Click(object sender, RoutedEventArgs e) { //btnTrain.IsEnabled = false; //var someTask = Task.Factory.StartNew(() => Train()); //await someTask; //btnTrain.IsEnabled = true; // Now there are images with tags start training the project Log("Training"); var iteration = await trainingApi.TrainProjectAsync(project.Id); // The returned iteration will be in progress, and can be queried periodically to see when it has completed while (iteration.Status == "Training") { Thread.Sleep(1000); // Re-query the iteration to get it's updated status iteration = trainingApi.GetIteration(project.Id, iteration.Id); } // The iteration is now trained. Make it the default project endpoint iteration.IsDefault = true; trainingApi.UpdateIteration(project.Id, iteration.Id, iteration); Log("Done Training!"); }
private static async Task TrainProject(TrainingApi trainingApi, Guid projectId) { var iteration = await trainingApi.TrainProjectAsync(projectId); while (iteration.Status == "Training") { Console.Clear(); Console.WriteLine("Training in progress..."); Thread.Sleep(1000); iteration = await trainingApi.GetIterationAsync(projectId, iteration.Id); } iteration.IsDefault = true; trainingApi.UpdateIteration(projectId, iteration.Id, iteration); Console.WriteLine(); Console.WriteLine("Project successfully trained... Press any key to continue"); Console.ReadLine(); }
private async Task TrainProjectsAsync() { this.progressControl.IsActive = true; bool trainingSucceeded = true; try { Iteration iterationModel = await trainingApi.TrainProjectAsync(this.CurrentProject.Id); while (true) { iterationModel = await trainingApi.GetIterationAsync(this.CurrentProject.Id, iterationModel.Id); if (iterationModel.Status != "Training") { if (iterationModel.Status == "Failed") { trainingSucceeded = false; } break; } await Task.Delay(500); } this.needsTraining = false; } catch (Exception ex) { await Util.GenericApiCallExceptionHandler(ex, "Failure requesting training"); } this.progressControl.IsActive = false; if (!trainingSucceeded) { await new MessageDialog("Training failed.").ShowAsync(); } }
private async void TriggerActiveLearningButtonClicked(object sender, RoutedEventArgs e) { this.activeLearningFlyout.Hide(); var currentProject = ((ProjectViewModel)this.projectsComboBox.SelectedValue).Model; try { var tags = this.PredictionDataForRetraining.Where(d => d.HasTag).Select(d => d.TagId).ToList(); if (tags.Any()) { var test = await this.userProvidedTrainingApi.CreateImagesFromPredictionsAsync(currentProject.Id, new ImageIdCreateBatch { TagIds = tags, Images = new List <ImageIdCreateEntry>(new ImageIdCreateEntry[] { new ImageIdCreateEntry(this.PredictionDataForRetraining.First().PredictionResultId) }) }); } else { await new MessageDialog("You need to select at least one Tag in order to save and re-train.").ShowAsync(); return; } } catch (Exception ex) { await Util.GenericApiCallExceptionHandler(ex, "Failure adding image to the training set"); return; } this.progressRing.IsActive = true; bool trainingSucceeded = true; try { Iteration iterationModel = await userProvidedTrainingApi.TrainProjectAsync(currentProject.Id); while (true) { iterationModel = await userProvidedTrainingApi.GetIterationAsync(currentProject.Id, iterationModel.Id); if (iterationModel.Status != "Training") { if (iterationModel.Status == "Failed") { trainingSucceeded = false; } break; } await Task.Delay(500); } } catch (Exception ex) { await Util.GenericApiCallExceptionHandler(ex, "The image was added to the training set, but re-training failed. You can try re-training later via the Custom Vision Setup page."); } if (!trainingSucceeded) { await new MessageDialog("The image was added to the training set, but re-training failed. You can try re-training later via the Custom Vision Setup page.").ShowAsync(); } this.progressRing.IsActive = false; }
public static async Task TrainAsync(ParsingOptions options) { // Create the Api, passing in the training key var trainingApi = new TrainingApi { ApiKey = options.TrainingKey }; if (options.Delete) { try { await DeleteImagesAndTagsAsync(options, trainingApi); Console.WriteLine("Images and tags successfully deleted."); } catch { } return; } var fullFolder = Path.GetFullPath(options.Folder); if (!Directory.Exists(fullFolder)) { Console.WriteLine($"Error: folder \"{fullFolder}\" does not exist."); Console.WriteLine(string.Empty); return; } try { await DeleteImagesAndTagsAsync(options, trainingApi); // Creates the string for resized images. string resizeString = null; if (options.Width.GetValueOrDefault() > 0) { resizeString += $"width={options.Width}&"; } if (options.Height.GetValueOrDefault() > 0) { resizeString += $"height={options.Height}&"; } if (!string.IsNullOrWhiteSpace(resizeString)) { resizeString += "crop=auto&scale=both"; } foreach (var dir in Directory.EnumerateDirectories(fullFolder).Where(f => !Path.GetFileName(f).StartsWith("!"))) { var tagName = Path.GetFileName(dir).ToLower(); Console.WriteLine($"\nCreating tag '{tagName}'..."); var tag = await trainingApi.CreateTagAsync(options.ProjectId, tagName); var images = Directory.EnumerateFiles(dir, "*.*", SearchOption.AllDirectories) .Where(s => s.EndsWith(".jpg", StringComparison.InvariantCultureIgnoreCase) || s.EndsWith(".jpeg", StringComparison.InvariantCultureIgnoreCase) || s.EndsWith(".png", StringComparison.InvariantCultureIgnoreCase) || s.EndsWith(".bmp", StringComparison.InvariantCultureIgnoreCase)); foreach (var image in images) { var imageName = Path.GetFileName(image); Console.WriteLine($"Uploading image {imageName}..."); // Resizes the image before sending it to the service. using (var input = new MemoryStream(File.ReadAllBytes(image))) { if (!string.IsNullOrWhiteSpace(resizeString)) { using (var output = new MemoryStream()) { ImageBuilder.Current.Build(input, output, new ResizeSettings(resizeString)); output.Position = 0; await trainingApi.CreateImagesFromDataAsync(options.ProjectId, output, new List <string>() { tag.Id.ToString() }); } } else { await trainingApi.CreateImagesFromDataAsync(options.ProjectId, input, new List <string>() { tag.Id.ToString() }); } } } } // Now there are images with tags start training the project Console.WriteLine("\nTraining..."); var iteration = await trainingApi.TrainProjectAsync(options.ProjectId); // The returned iteration will be in progress, and can be queried periodically to see when it has completed while (iteration.Status == "Training") { await Task.Delay(1000); // Re-query the iteration to get it's updated status iteration = trainingApi.GetIteration(options.ProjectId, iteration.Id); } // The iteration is now trained. Make it the default project endpoint iteration.IsDefault = true; trainingApi.UpdateIteration(options.ProjectId, iteration.Id, iteration); Console.WriteLine("Training completed.\n"); } catch (Exception ex) { Console.WriteLine($"\nUnexpected error: {ex.GetBaseException()?.Message}.\n"); } }
public static async Task TrainAsync(ParsingOptions options) { // Create the Api, passing in the training key var trainingApi = new TrainingApi { ApiKey = options.TrainingKey }; CognitiveServiceTrainerStorage storageImages = new CognitiveServiceTrainerStorage(); if (options.Delete) { try { await DeleteImagesAndTagsAsync(options, trainingApi); storageImages.DeleteDB(); Console.WriteLine("Images and tags successfully deleted."); } catch { } if (string.IsNullOrEmpty(options.Folder)) { return; } } var fullFolder = Path.GetFullPath(options.Folder); if (!Directory.Exists(fullFolder)) { Console.WriteLine($"Error: folder \"{fullFolder}\" does not exist."); Console.WriteLine(string.Empty); return; } try { //await DeleteImagesAndTagsAsync(options, trainingApi); foreach (var dir in Directory.EnumerateDirectories(fullFolder).Where(f => !Path.GetFileName(f).StartsWith("!"))) { var tagName = Path.GetFileName(dir).ToLower(); Console.WriteLine($"\nCheck latest images uploaded '{tagName}'..."); IList <Microsoft.Cognitive.CustomVision.Training.Models.Image> imagesAlreadyExists = new List <Microsoft.Cognitive.CustomVision.Training.Models.Image>(); IList <Microsoft.Cognitive.CustomVision.Training.Models.Image> imagesAlreadyExistsTmp = new List <Microsoft.Cognitive.CustomVision.Training.Models.Image>(); int skip = 0; while ((imagesAlreadyExistsTmp = await trainingApi.GetTaggedImagesAsync(options.ProjectId, tagIds: new[] { tagName }, take: 50, skip: skip)).Any()) { skip += 50; foreach (var item in imagesAlreadyExistsTmp) { imagesAlreadyExists.Add(item); } } Console.WriteLine($"\nCreating tag '{tagName}'..."); var tagExist = storageImages.FindTag(tagName, options.ProjectId); Tag tag = null; if (tagExist == null) { tag = await trainingApi.CreateTagAsync(options.ProjectId, tagName); storageImages.InsertTag(new Storage.Collections.StorageTag { IdCustomVision = tag.Id, TagName = tag.Name, ProjectId = options.ProjectId }); } else { if (trainingApi.GetTag(tagExist.ProjectId, tagExist.IdCustomVision) == null) { await trainingApi.DeleteTagAsync(options.ProjectId, tagExist.IdCustomVision); tag = await trainingApi.CreateTagAsync(options.ProjectId, tagName); storageImages.InsertTag(new Storage.Collections.StorageTag { IdCustomVision = tag.Id, TagName = tag.Name, ProjectId = options.ProjectId }); } else { tag = new Tag(tagExist.IdCustomVision, tagName); } } var images = Directory.EnumerateFiles(dir, "*.*", SearchOption.AllDirectories) .Where(s => s.EndsWith(".jpg", StringComparison.InvariantCultureIgnoreCase) || s.EndsWith(".jpeg", StringComparison.InvariantCultureIgnoreCase) || s.EndsWith(".png", StringComparison.InvariantCultureIgnoreCase) || s.EndsWith(".bmp", StringComparison.InvariantCultureIgnoreCase)).ToList(); List <ImageDto> tempImages = new List <ImageDto>(); for (int i = 0; i < images.Count; i++) { Stream imageToUpload = null; string image = images.ElementAt(i); var imageName = Path.GetFileName(image); var storageImage = storageImages.FindImage(image, options.ProjectId); if (storageImage == null || !imagesAlreadyExists.Any(x => x.Id == storageImage.IdCustomVision)) { // Resizes the image before sending it to the service. using (var input = new MemoryStream(File.ReadAllBytes(image))) { if (options.Width.GetValueOrDefault() > 0 || options.Height.GetValueOrDefault() > 0) { imageToUpload = await ResizeImageAsync(input, options.Width.GetValueOrDefault(), options.Height.GetValueOrDefault()); } else { imageToUpload = input; } tempImages.Add(new ImageDto { FullName = image, FileName = imageName, Content = imageToUpload.ToByteArray(), Tag = tag }); imageToUpload.Dispose(); } } else { Console.WriteLine($"Image already exist {imageName}..."); } //Persist batch images if (tempImages.Count % 32 == 0 && tempImages.Any() || (i == images.Count - 1)) { await UploadImagesAsync(tempImages); tempImages.Clear(); tempImages.Capacity = 0; } } } // Now there are images with tags start training the project Console.WriteLine("\nTraining..."); var iteration = await trainingApi.TrainProjectAsync(options.ProjectId); // The returned iteration will be in progress, and can be queried periodically to see when it has completed while (iteration.Status == "Training") { await Task.Delay(1000); // Re-query the iteration to get it's updated status iteration = trainingApi.GetIteration(options.ProjectId, iteration.Id); } // The iteration is now trained. Make it the default project endpoint iteration.IsDefault = true; trainingApi.UpdateIteration(options.ProjectId, iteration.Id, iteration); Console.WriteLine("Training completed.\n"); } catch (Exception ex) { Console.WriteLine($"\nUnexpected error: {ex.GetBaseException()?.Message}.\n"); } async Task UploadImagesAsync(List <ImageDto> images) { ImageFileCreateBatch imageFileCreateBatch = new ImageFileCreateBatch(); imageFileCreateBatch.Images = new List <ImageFileCreateEntry>(); foreach (var img in images) { imageFileCreateBatch.Images.Add(new ImageFileCreateEntry { Name = img.FullName, TagIds = new [] { img.Tag.Id }, Contents = img.Content }); Console.WriteLine($"Uploading image {img.FileName}..."); } await Policy .Handle <Exception>() .WaitAndRetryAsync(retries) .ExecuteAsync(async() => { ImageCreateSummary reponseCognitiveService = await trainingApi.CreateImagesFromFilesAsync(options.ProjectId, imageFileCreateBatch); if (reponseCognitiveService.Images != null) { for (int i = 0; i < reponseCognitiveService.Images.Count; i++) { var img = reponseCognitiveService.Images.ElementAt(i); // https://docs.microsoft.com/en-us/rest/api/cognitiveservices/customvisiontraining/createimagesfrompredictions/createimagesfrompredictions if ((img.Status == "OK" || img.Status == "OKDuplicate") && img.Image != null) { var uploadedImage = img.Image; var tagsToStore = uploadedImage.Tags? .Select(x => new Storage.Collections.StorageImageTag() { Created = x.Created, TagId = x.TagId }).ToList(); storageImages.InsertImage(new Storage.Collections.StorageImage() { ProjectId = options.ProjectId, FullFileName = imageFileCreateBatch.Images.ElementAt(i).Name, IdCustomVision = uploadedImage.Id, ImageUri = uploadedImage.ImageUri, Created = uploadedImage.Created, Height = uploadedImage.Height, Tags = tagsToStore, ThumbnailUri = uploadedImage.ThumbnailUri, Width = uploadedImage.Width }); } else { Console.WriteLine($"API bad response: {img.Status }"); throw new InvalidOperationException($"API bad response: {img.Status }"); } } } }); await Task.Delay(500); } }
private static async Task <bool> MainAsync(string[] args) { try { trainingApi.ApiKey = CustomVisionTrainingApiKey; // Create project var projects = await trainingApi.GetProjectsAsync(); var project = projects.Where(x => x.Name == projectName).FirstOrDefault(); if (project == null) { Console.WriteLine($"\nCreating project '{projectName}'"); project = await trainingApi.CreateProjectAsync(projectName); } // Retrieve all tags var tagsList = await trainingApi.GetTagsAsync(project.Id); #region Create Object tag var objectTag = tagsList.Tags.Where(x => x.Name == objectTagName).FirstOrDefault(); if (objectTag == null) { Console.WriteLine($"\nCreating tag '{objectTagName}'"); objectTag = await trainingApi.CreateTagAsync(project.Id, objectTagName); } // add images to tag Console.WriteLine($"\nAdding images to tag '{objectTagName}'"); List <ImageFileCreateEntry> imageFiles = (Directory.GetFiles(objectTrainImagesPath)).Select(img => new ImageFileCreateEntry(Path.GetFileName(img), File.ReadAllBytes(img))).ToList(); await trainingApi.CreateImagesFromFilesAsync(project.Id, new ImageFileCreateBatch(imageFiles, new List <Guid>() { objectTag.Id })); #endregion #region Create Ocean tag var oceanTag = tagsList.Tags.Where(x => x.Name == oceanTagName).FirstOrDefault(); if (oceanTag == null) { Console.WriteLine($"\nCreating tag '{oceanTagName}'"); oceanTag = await trainingApi.CreateTagAsync(project.Id, oceanTagName); } // add images Console.WriteLine($"\nAdding images to tag '{oceanTagName}'"); imageFiles = (Directory.GetFiles(noObjectTrainImagesPath)).Select(img => new ImageFileCreateEntry(Path.GetFileName(img), File.ReadAllBytes(img))).ToList(); await trainingApi.CreateImagesFromFilesAsync(project.Id, new ImageFileCreateBatch(imageFiles, new List <Guid>() { oceanTag.Id })); #endregion #region Train the classifier Console.WriteLine("\nTraining"); var iteration = await trainingApi.TrainProjectAsync(project.Id); do { Thread.Sleep(1000); iteration = await trainingApi.GetIterationAsync(project.Id, iteration.Id); }while (string.Equals("training", iteration.Status, StringComparison.OrdinalIgnoreCase)); if (!string.Equals(iteration.Status, "completed", StringComparison.OrdinalIgnoreCase)) { throw new Exception($"An error occurred training the classifier. Iteration status is {iteration.Status}"); } iteration.IsDefault = true; await trainingApi.UpdateIterationAsync(project.Id, iteration.Id, iteration); #endregion Console.WriteLine( $@"\n Your custom vision project ID is {project.Id.ToString()}. Copy this Guid and add it to your application settings under the name 'CustomVisionProjectId' " ); Console.WriteLine("\nFinished. Press Enter to exit"); Console.Read(); return(true); } catch (Exception e) { Console.Write(e); Console.WriteLine("\nPress Enter to exit"); Console.Read(); return(false); } }