/// <summary> /// Create learning rate time decay operation. /// </summary> protected TFOutput CreateDecayOps(float decay, TFOutput initialLearningRate) { if (decay > 0) { var _decay = _graph.Const(decay, "Decay"); var one = _graph.Const(1f); return (_graph.Mul(initialLearningRate, _graph.Div(one, _graph.Add(one, _graph.Mul(_decay, _graph.Cast(_graph.Sub(Iterations.ReadAfter(_graph.CurrentDependencies), _graph.Const(1L)), _decay.OutputType) ) ) ), operName: "learningrate" )); } else { return(initialLearningRate); } }
/// <summary> /// Construct optimizer. /// </summary> /// <param name="graph">The graph object.</param> /// <param name="operName">Name of the operation.</param> /// <param name="learningRate">The learning rate for the SGD update.</param> /// <param name="decay">Learning rate decay over each update.</param> /// /// <param name="initialAccumulatorValue">A floating point value. Starting value for the accumulators, must be >=0.</param> public Optimizer(TFGraph graph, string operName, float learningRate, float decay, float initialAccumulatorValue) { if (initialAccumulatorValue < 0) { throw new ArgumentException($"Value must be positive. initialAccumulatorValue = {initialAccumulatorValue}"); } _graph = graph; _optimizerName = operName; _initialAccumulatorValue = initialAccumulatorValue; using (var scope = _graph.WithScope(_optimizerName)) { Iterations = _graph.Variable(_graph.Const(new TFTensor(0L)), trainable: false, operName: "iterations"); var initialLearningRate = _graph.Const(learningRate); var inc = _graph.AssignAddVariableOp(Iterations, _graph.Const(1L)); _updateOps.Add(inc); using (_graph.WithDependencies(inc)) { LearningRate = CreateDecayOps(decay, initialLearningRate); } } }
// Additional pointers for using TensorFlow & CustomVision together // Python: https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/label_image/label_image.py // C++: https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/label_image/main.cc // Java: https://github.com/Azure-Samples/cognitive-services-android-customvision-sample/blob/master/app/src/main/java/demo/tensorflow/org/customvision_sample/MSCognitiveServicesClassifier.java private static TFGraph ConstructGraphToNormalizeImage(out TFOutput input, out TFOutput output, TFDataType destinationDataType = TFDataType.Float) { const int W = 227; const int H = 227; const float Scale = 1; // Depending on your CustomVision.ai Domain - set appropriate Mean Values (RGB) // https://github.com/Azure-Samples/cognitive-services-android-customvision-sample for RGB values (in BGR order) var bgrValues = new TFTensor(new float[] { 104.0f, 117.0f, 123.0f }); // General (Compact) & Landmark (Compact) //var bgrValues = new TFTensor(0f); // Retail (Compact) var graph = new TFGraph(); input = graph.Placeholder(TFDataType.String); var caster = graph.Cast(graph.DecodeJpeg(contents: input, channels: 3), DstT: TFDataType.Float); var dims_expander = graph.ExpandDims(caster, graph.Const(0, "batch")); var resized = graph.ResizeBilinear(dims_expander, graph.Const(new int[] { H, W }, "size")); var resized_mean = graph.Sub(resized, graph.Const(bgrValues, "mean")); var normalised = graph.Div(resized_mean, graph.Const(Scale)); output = normalised; return(graph); }