-
Notifications
You must be signed in to change notification settings - Fork 110
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Question] Network with different output kind (softmax & scalar) #145
Comments
Do you want to output the two output kinds at the same time ? |
Yes, i want two output kinds at the same time. Is it possible? |
Do you want to get the output of the softmax layer And the output of the layer just before softmax ? |
@cbovar Thanks, yes i need 2 distinct branches, any example with computation graph? |
Here is a quick example: (to make it simple, I only don't use any dataset: I use one constant input and two constant outputs) using System;
using System.Collections.Generic;
using System.Linq;
using ConvNetSharp.Flow;
using ConvNetSharp.Flow.Ops;
using ConvNetSharp.Flow.Training;
using ConvNetSharp.Volume;
namespace Demo
{
internal static class TwoOutputsExample
{
public static void Main()
{
var cns = new ConvNetSharp<double>();
// Graph Creation
var y_class = cns.PlaceHolder("class_ground_truth");
var y_scalar = cns.PlaceHolder("scalar_ground_truth");
Op<double> x = cns.PlaceHolder("x");
x = cns.Conv(x, 3, 3, 16);
x = cns.Flatten(x);
var output1 = cns.Softmax(cns.Dense(x, 10)); // 1st branch: proba
var output2 = cns.Dense(x, 1); // 2nd branch: scalar
// Loss
var classification_loss = cns.CrossEntropyLoss(output1, y_class); // should output y_class
var scalar_loss = (output2 - y_scalar) * (output2 - y_scalar); // should output a scalar near y_scalar
var total_loss = classification_loss + scalar_loss;
var optimizer = new GradientDescentOptimizer<double>(cns, learningRate: 0.0001);
var input = BuilderInstance<double>.Volume.Random(Shape.From(16, 16, 1, 1));
using (var session = new Session<double>())
{
session.Differentiate(total_loss); // computes dCost/dW at every node of the graph
// Training
double currentLoss;
do
{
// Build dico containing 1 input and 2 x outputs (1 for each output branch).
var class_ground_truth = BuilderInstance<double>.Volume.SameAs(Shape.From(1, 1, 10, 1));
class_ground_truth.Set(0, 0, 5, 0, 1.0); // target is class 5
var scalar_ground_truth = 0.5;
var dico = new Dictionary<string, Volume<double>> {
{ "x", input },
{ "class_ground_truth", class_ground_truth },
{ "scalar_ground_truth", scalar_ground_truth },
};
// Compute loss
currentLoss = session.Run(total_loss, dico);
Console.WriteLine($"cost: {currentLoss}");
// Run optimizer (will update weights in the network)
session.Run(optimizer, dico);
} while (currentLoss > 0.1);
// Test
var result1 = session.Run(output1, new Dictionary<string, Volume<double>> { { "x", input } });
var class_output = result1.ToArray().ToList().IndexOf(result1.ToArray().Max()); // should be 5
var result2 = (double)session.Run(output2, new Dictionary<string, Volume<double>> { { "x", input } }); // should be ~0.5
}
Console.ReadLine();
}
}
} |
Is it possible to create network with different outputs kind? For example, some outputs should be probability outputs (using softmax), some should be scalar values (from 0 to 1). If it possible, it would be good if anyone can provide example, thanks.
The text was updated successfully, but these errors were encountered: