Esempio n. 1
0
    private void TrainMinibatch()
    {
        UnityEngine.Profiling.Profiler.BeginSample("TrainMiniBatch");

        const int numClasses = 10;
        const int batchSize  = 10;
        var       target     = new float[numClasses];
        var       dCdO       = new float[numClasses];

        float avgTrainCost       = 0f;
        int   correctTrainLabels = 0;

        ZeroGradients(_gradientBucket);
        var trainBatch = DataManager.GetBatch(batchSize, DataManager.Train, ref _rng);

        for (int i = 0; i < trainBatch.Indices.Length; i++)
        {
            int lbl = DataManager.Train.Labels[trainBatch.Indices[i]];

            // Copy image to input layer (Todo: this is a waste of time/memory)
            UnityEngine.Profiling.Profiler.BeginSample("CopyInputs");

            for (int p = 0; p < DataManager.Train.ImgDims; p++)
            {
                _net.Input[p] = DataManager.Train.Images[trainBatch.Indices[i], p];
            }

            UnityEngine.Profiling.Profiler.EndSample();

            NetUtils.Forward(_net);

            int predictedLbl = NetUtils.GetMaxOutput(_net);
            NetUtils.LabelToOneHot(lbl, target);

            if (predictedLbl == lbl)
            {
                correctTrainLabels++;
            }
            //Debug.Log(outputClass + ", " + batch.Labels[i]);

            // Calculate error between output layer and target
            NetUtils.Subtract(target, _net.Output, dCdO);
            float cost = NetUtils.Cost(dCdO);
            avgTrainCost += cost;

            // Propagate error back
            // Calculate per-parameter gradient, store it

            NetUtils.Backward(_net, target);
            AddGradients(_net, _gradientBucket);
        }

        avgTrainCost /= (float)batchSize;

        // Update weights and biases according to averaged gradient and learning rate
        _rate = 3.0f / (float)batchSize;
        NetUtils.UpdateParameters(_net, _gradientBucket, _rate);

        _batch++;
        _trainingLoss = (float)Math.Round(avgTrainCost, 6);

        // Debug.Log(
        //     "Batch: " + _batchesTrained +
        //     ", TrainLoss: " + Math.Round(avgTrainCost, 6) +
        //     ", Rate: " + Math.Round(rate, 6));
        // Mnist.ToTexture(batch, batch.Labels.Length-1, _tex);
        // _label = batch.Labels[batch.Labels.Length-1];

        UnityEngine.Profiling.Profiler.EndSample();
    }