Ejemplo n.º 1
0
        public static void RunSimple()
        {
            var mnist      = TestUtils.GetMNIST(); //Get the MNIST dataset, it will download if not found
            var batch_size = 100;                  //Set training batch size
            var train_data = new NDArrayIter(mnist["train_data"], mnist["train_label"], batch_size);
            var val_data   = new NDArrayIter(mnist["test_data"], mnist["test_label"], batch_size);

            // Define simple network with dense layers
            var net = new Sequential();

            net.Add(new Dense(128, ActivationType.Relu));
            net.Add(new Dense(64, ActivationType.Relu));
            net.Add(new Dense(10));

            //Set context, multi-gpu supported
            var gpus = TestUtils.ListGpus();
            var ctx  = gpus.Count > 0 ? gpus.Select(x => Context.Gpu(x)).ToArray() : new[] { Context.Cpu(0) };

            //Initialize the weights
            net.Initialize(new Xavier(magnitude: 2.24f), ctx);

            //Create the trainer with all the network parameters and set the optimizer
            var trainer = new Trainer(net.CollectParams(), new Adam());

            var   epoch  = 10;
            var   metric = new Accuracy(); //Use Accuracy as the evaluation metric.
            var   softmax_cross_entropy_loss = new SoftmaxCrossEntropyLoss();
            float lossVal = 0;             //For loss calculation

            for (var iter = 0; iter < epoch; iter++)
            {
                var tic = DateTime.Now;
                // Reset the train data iterator.
                train_data.Reset();
                lossVal = 0;

                // Loop over the train data iterator.
                while (!train_data.End())
                {
                    var batch = train_data.Next();

                    // Splits train data into multiple slices along batch_axis
                    // and copy each slice into a context.
                    var data = Utils.SplitAndLoad(batch.Data[0], ctx, batch_axis: 0);

                    // Splits train labels into multiple slices along batch_axis
                    // and copy each slice into a context.
                    var label = Utils.SplitAndLoad(batch.Label[0], ctx, batch_axis: 0);

                    var outputs = new NDArrayList();

                    // Inside training scope
                    NDArray loss = null;
                    for (int i = 0; i < data.Length; i++)
                    {
                        using (var ag = Autograd.Record())
                        {
                            var x = data[i];
                            var y = label[i];
                            var z = net.Call(x);
                            // Computes softmax cross entropy loss.
                            loss = softmax_cross_entropy_loss.Call(z, y);
                            outputs.Add(z);
                        }

                        // Backpropagate the error for one iteration.
                        loss.Backward();
                        lossVal += loss.Mean();
                    }

                    // Updates internal evaluation
                    metric.Update(label, outputs.ToArray());

                    // Make one step of parameter update. Trainer needs to know the
                    // batch size of data to normalize the gradient by 1/batch_size.
                    trainer.Step(batch.Data[0].Shape[0]);
                }

                var toc = DateTime.Now;

                // Gets the evaluation result.
                var(name, acc) = metric.Get();

                // Reset evaluation result to initial state.
                metric.Reset();
                Console.Write($"Loss: {lossVal} ");
                Console.WriteLine($"Training acc at epoch {iter}: {name}={(acc * 100).ToString("0.##")}%, Duration: {(toc - tic).TotalSeconds.ToString("0.#")}s");
            }
        }
Ejemplo n.º 2
0
        public static void Run()
        {
            var mnist_train = new FashionMNIST(train: true);

            var(x, y) = mnist_train[0];
            Console.WriteLine($"X shape: {x.Shape}, X dtype: {x.DataType}, Y shape: {y.Shape}, Y dtype: {y.DataType}");

            var transformer = new Compose(
                new ToTensor(),
                new Normalize(new MxNet.Tuple <float>(0.13f, 0.31f))
                );

            var train      = mnist_train.TransformFirst(transformer);
            int batch_size = 256;
            var train_data = new DataLoader(train, batch_size: batch_size, shuffle: true);

            foreach (var(data, label) in train_data)
            {
                Console.WriteLine(data.Shape + ", " + label.Shape);
                break;
            }

            var mnist_valid = new FashionMNIST(train: false);
            var valid_data  = new DataLoader(mnist_valid, batch_size: batch_size, shuffle: true);

            var net = new Sequential();

            net.Add(new Conv2D(channels: 6, kernel_size: (5, 5), activation: ActivationType.Relu),
                    new MaxPool2D(pool_size: (2, 2), strides: (2, 2)),
                    new Conv2D(channels: 16, kernel_size: (3, 3), activation: ActivationType.Relu),
                    new MaxPool2D(pool_size: (2, 2), strides: (2, 2)),
                    new Flatten(),
                    new Dense(120, activation: ActivationType.Relu),
                    new Dense(84, activation: ActivationType.Relu),
                    new Dense(10));

            net.Initialize(new Xavier());

            var softmax_cross_entropy = new SoftmaxCrossEntropyLoss();
            var trainer = new Trainer(net.CollectParams(), new SGD(learning_rate: 0.1f));

            for (int epoch = 0; epoch < 10; epoch++)
            {
                var   tic        = DateTime.Now;
                float train_loss = 0;
                float train_acc  = 0;
                float valid_acc  = 0;

                foreach (var(data, label) in train_data)
                {
                    NDArray loss   = null;
                    NDArray output = null;
                    // forward + backward
                    using (Autograd.Record())
                    {
                        output = net.Call(data);
                        loss   = softmax_cross_entropy.Call(output, label);
                    }

                    loss.Backward();

                    //update parameters
                    trainer.Step(batch_size);

                    //calculate training metrics
                    train_loss += loss.Mean();
                    train_acc  += Acc(output, label);
                }

                // calculate validation accuracy
                foreach (var(data, label) in valid_data)
                {
                    valid_acc += Acc(net.Call(data), label);
                }

                Console.WriteLine($"Epoch {epoch}: loss {train_loss / train_data.Length}," +
                                  $" train acc {train_acc / train_data.Length}, " +
                                  $"test acc {train_acc / train_data.Length} " +
                                  $"in {(DateTime.Now - tic).TotalMilliseconds} ms");
            }

            net.SaveParameters("net.params");
        }