partial void TappedTestSet(UIButton sender) { // placeholder to count number of correct detections on the test set var correctDetections = 0; var total = 10000f; AccuracyLabel.Hidden = false; Atomics.Reset(); // validate NeuralNetwork was initialized properly if (runningNet == null) { throw new InvalidProgramException(); } for (int i = 0; i < total; i++) { Inference(i, Mnistdata.LabelsCount); if (i % 100 == 0) { AccuracyLabel.Text = $"{i / 100}% Done"; // this command helps update the UI in the loop regularly NSRunLoop.Current.RunUntil(NSRunLoopMode.Default, NSDate.DistantPast); } } // display accuracy of the network on the MNIST test set correctDetections = Atomics.GetCount(); AccuracyLabel.Hidden = false; AccuracyLabel.Text = $"Accuracy = {(correctDetections * 100) / total}%"; }
/// <summary> /// This function encodes all the layers of the network into given commandBuffer, it calls subroutines for each piece of the network /// Returns: Guess of the network as to what the digit is as uint /// </summary> /// <param name="inputImage">Image coming in on which the network will run</param> /// <param name="imageNum">If the test set is being used we will get a value between 0 and 9999 for which of the 10,000 images is being evaluated</param> /// <param name="correctLabel">The correct label for the inputImage while testing</param> public override uint Forward(MPSImage inputImage = null, int imageNum = 9999, int correctLabel = 10) { uint label = 99; // Get command buffer to use in MetalPerformanceShaders. using (var commandBuffer = commandQueue.CommandBuffer()) { // output will be stored in this image var finalLayer = new MPSImage(commandBuffer.Device, DID); // encode layers to metal commandBuffer if (inputImage == null) { conv1.EncodeToCommandBuffer(commandBuffer, SrcImage, c1Image); } else { conv1.EncodeToCommandBuffer(commandBuffer, inputImage, c1Image); } pool.EncodeToCommandBuffer(commandBuffer, c1Image, p1Image); conv2.EncodeToCommandBuffer(commandBuffer, p1Image, c2Image); pool.EncodeToCommandBuffer(commandBuffer, c2Image, p2Image); fc1.EncodeToCommandBuffer(commandBuffer, p2Image, fc1Image); fc2.EncodeToCommandBuffer(commandBuffer, fc1Image, dstImage); softmax.EncodeToCommandBuffer(commandBuffer, dstImage, finalLayer); // add a completion handler to get the correct label the moment GPU is done and compare it to the correct output or return it commandBuffer.AddCompletedHandler(buffer => { label = GetLabel(finalLayer); if (correctLabel == label) { Atomics.Increment(); } }); // commit commandbuffer to run on GPU and wait for completion commandBuffer.Commit(); if (imageNum == 9999 || inputImage == null) { commandBuffer.WaitUntilCompleted(); } } return(label); }