TFOperation Add(TFOperation left, TFOperation right, TFGraph graph, TFStatus status) { var op = new TFOperationDesc(graph, "AddN", "add"); op.AddInputs(new TFOutput(left, 0), new TFOutput(right, 0)); return(op.FinishOperation()); }
/// <summary> /// Enqueues a tuple of one or more tensors in this queue and runs the session. /// </summary> /// <param name="components"> /// One or more tensors from which the enqueued tensors should be taken. /// </param> /// <param name="operationName"> /// If specified, the created operation in the graph will be this one, otherwise it will be named 'QueueEnqueueV2'. /// </param> /// <param name="inputValues"> /// Values to enqueue /// </param> /// <param name="timeout_ms"> /// Optional argument /// If the queue is full, this operation will block for up to /// timeout_ms milliseconds. /// Note: This option is not supported yet. /// </param> /// <returns> /// Returns the description of the operation /// </returns> /// <remarks> /// The components input has k elements, which correspond to the components of /// tuples stored in the given queue. /// </remarks> public TFTensor [] EnqueueExecute(TFOutput [] components, TFTensor [] inputValues, long?timeout_ms = null, string operationName = null) { TFOperation enqueueOp = Enqueue(components, timeout_ms, operationName); TFTensor [] tensors = Session.Run(components, inputValues, Array.Empty <TFOutput> (), new [] { enqueueOp }); return(tensors); }
/// <summary> /// Registers a specified variable as an initialization variable. /// </summary> /// <param name="variable">Variable to register.</param> /// <remarks> /// <para> /// This is a convenience method to track the variables that need to be initialized in the graph, /// you can retrieve the list of all those variables by calling the <see cref="M:TensorFlow.TFGraph.GetGlobalVariablesInitializer"/> /// which will return this list and clear the state at that point. /// </para> /// <para> /// You typically use this method from helper methods to register all the variables that you want /// initialized, and a higher level method will retrieve all these variables and initialize them /// at their convenience. /// </para> /// </remarks> public void AddInitVariable(TFOperation variable) { if (pending_init_variables == null) { pending_init_variables = new List <TFOperation> (); } pending_init_variables.Add(variable); }
/// <summary> /// Variable node, with a starting initial value. /// </summary> /// <param name="initialValue">Initial value.</param> /// <param name="init">Returns the operation that initializes the value of the variable.</param> /// <param name="value">Returns the value of the variable.</param> /// <param name="trainable">If true, this add the variable to the graph's TrainableVariables, this collection is intended to be used by the Optimizer classes.</param> /// <param name="operName">Operation name, optional.</param> /// <returns>The returning Variable contains the variable, with three nodes with the operations making up the variable assignment.</returns> /// <remarks> /// Variables need to be initialized before the main execution so you will typically want to /// run the session on the variable /// </remarks> public Variable Variable(TFOutput initialValue, out TFOperation init, out TFOutput value, bool trainable = true, string operName = null) { var nv = MakeVariable(initialValue, trainable, operName); init = nv.Assign; value = nv.Read; return(nv); }
void ExpectMeta(TFOperation op, string name, int expectedListSize, TFAttributeType expectedType, int expectedTotalSize) { var meta = op.GetAttributeMetadata(name); Assert(meta.IsList == (expectedListSize >= 0 ? 1 : 0)); Assert(expectedListSize == meta.ListSize); Assert(expectedTotalSize == expectedTotalSize); Assert(expectedType == meta.Type); }
/// <summary> /// Variable node, with a starting initial value. /// </summary> /// <param name="initialValue">Initial value.</param> /// <param name="init">Returns the operation that initializes the value of the variable.</param> /// <param name="value">Returns the value of the variable.</param> /// <param name="operName">Operation name, optional.</param> /// <returns>The returning TFOutput returns the handle to the variable.</returns> /// <remarks> /// Variables need to be initialized before the main execution so you will typically want to /// run the session on the variable /// </remarks> public TFOutput Variable(TFOutput initialValue, out TFOperation init, out TFOutput value, string operName = null) { var scopeName = MakeName("Variable", operName); using (var newScope = WithScope(scopeName)) { var type = initialValue.OutputType; var handle = VarHandleOp(type, new TFShape(GetShape(initialValue))); using (var aScope = WithScope("Assign")) { init = AssignVariableOp(handle, initialValue); using (var rScope = WithScope("Read")) { value = ReadVariableOp(handle, type); return(handle); } } } }
internal Variable(TFOutput variableHandle, TFOutput readHandle, TFOperation assignOp) { this.variableHandle = variableHandle; this.readHandle = readHandle; this.assignOp = assignOp; }
// .length = layers public void Train(double[][] input, double[][] output) { int InputSize = input[0].Length; int OutputSize = output[0].Length; using (var graph = new TFGraph()) { TFOutput X = graph.Placeholder(TFDataType.Float, new TFShape(new long[] { -1, InputSize })); TFOutput Y = graph.Placeholder(TFDataType.Float, new TFShape(new long[] { -1, OutputSize })); TFOutput[] weights = new TFOutput[NodeSize.Length + 1]; TFOutput[] biases = new TFOutput[NodeSize.Length + 1]; int prevSize = InputSize; for (int i = 0; i < NodeSize.Length; i++) { weights[i] = graph.VariableV2(new TFShape(new long[] { prevSize, NodeSize[i] }), TFDataType.Float, operName: "weight_" + i); biases[i] = graph.VariableV2(new TFShape(new long[] { NodeSize[i] }), TFDataType.Float, operName: "bias_" + i); prevSize = NodeSize[i]; } weights[NodeSize.Length] = graph.VariableV2(new TFShape(new long[] { prevSize, OutputSize }), TFDataType.Float, operName: "weight_out"); biases[NodeSize.Length] = graph.VariableV2(new TFShape(new long[] { OutputSize }), TFDataType.Float, operName: "bias_out"); TFOutput pred = Predict(X, weights, biases, graph); TFOutput cost = graph.ReduceMean(graph.SigmoidCrossEntropyWithLogits(Y, pred)); TFOutput[] parameters = new TFOutput[weights.Length + biases.Length]; weights.CopyTo(parameters, 0); biases.CopyTo(parameters, weights.Length); TFOutput[] grad = graph.AddGradients(new TFOutput[] { cost }, parameters); TFOperation[] optimize = new TFOperation[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { optimize[i] = graph.AssignSub(parameters[i], graph.Mul(grad[i], graph.Const(LearningRate))).Operation; } TFSession sess = new TFSession(graph); TFOperation[] InitParams = new TFOperation[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { InitParams[i] = graph.Assign(parameters[i], graph.RandomNormal(graph.GetTensorShape(parameters[i]))).Operation; } sess.GetRunner().AddTarget(InitParams); for (int i = 0; i < Epochs; i++) { TFTensor result = sess.GetRunner() .AddInput(X, input) .AddInput(Y, output) .AddTarget(optimize) .Fetch(cost) .Run(); if (i % DisplaySteps == 0) { Console.WriteLine("Epoch - " + i + " | Cost - " + result.GetValue()); } } } }
/* * public static TFOutput cond(this TFGraph g, TFOutput pred, Func<TFOutput> true_fn = null, Func<TFOutput> false_fn = null, bool strict = false, string operName = null) * { * using (var name = g.WithScope(g.MakeName("cond", operName))) * { * // Add the Switch to the graph. * (TFOutput p_2, TFOutput p_1) = g.Switch(pred, pred); * TFOutput pivot_1 = g.Identity(p_1, operName: "switch_t"); * TFOutput pivot_2 = g.Identity(p_2, operName: "switch_f"); * pred = g.Identity(pred, operName: "pred_id"); * * // Disable the fetching of tensors that are only on one branch of cond. * foreach (TFOutput tensor in new[] { p_1, p_2, pivot_1, pivot_2, pred }) * g.PreventFetching(tensor.Operation); * * // Build the graph for the true branch in a new context. * CondContext context_t = new CondContext(pred, pivot_1, branch: 1); * context_t.Enter(); * (TFTensor orig_res_t, TFTensor res_t) = context_t.BuildCondBranch(true_fn); * if (orig_res_t == null) * throw new ArgumentException("true_fn must have a return value."); * context_t.ExitResult(res_t); * context_t.Exit(); * * // Build the graph for the false branch in a new context. * CondContext context_f = new CondContext(pred, pivot_2, branch: 0); * context_f.Enter(); * (TFTensor orig_res_f, TFTensor res_f) = context_f.BuildCondBranch(false_fn); * if (orig_res_f == null) * throw new ArgumentException("false_fn must have a return value."); * context_f.ExitResult(res_f); * context_f.Exit(); * * if (!strict) * { * orig_res_t = _UnpackIfSingleton(orig_res_t); * orig_res_f = _UnpackIfSingleton(orig_res_f); * } * * // Check that the return values of the two branches have the same structure. * try * { * nest.assert_same_structure(orig_res_t, orig_res_f); * } * catch (InvalidOperationException e) * { * throw new InvalidOperationException("Incompatible return values of true_fn and false_fn", e); * } * * // Add the final merge to the graph. * if (res_t == null) * throw new ArgumentException("true_fn and false_fn must return at least one result."); * * TFTensor res_t_flat = nest.flatten(res_t); * TFTensor res_f_flat = nest.flatten(res_f); * * foreach (var (x, y) in Enumerable.Zip(res_t_flat, res_f_flat, (a, b) => (a, b))) * { * Trace.Assert((isinstance(x, ops.IndexedSlices) && * isinstance(y, ops.IndexedSlices)) || * (isinstance(x, sparse_tensor.SparseTensor) && * isinstance(y, sparse_tensor.SparseTensor)) || * (isinstance(x, ops.Tensor) && isinstance(y, ops.Tensor))); * val_x = isinstance(x, ops.Tensor) ? x : x.values; * val_y = isinstance(y, ops.Tensor) ? y : y.values; * if (val_x.dtype.base_dtype != val_y.dtype.base_dtype) * throw new ArgumentException("Outputs of true_fn and false_fn must have the same type: %s, %s" % (val_x.dtype.name, val_y.dtype.name)); * } * * merges = [merge(pair)[0] for pair in zip(res_f_flat, res_t_flat)]; * merges = _convert_flows_to_tensorarrays(nest.flatten(orig_res_t), merges); * * // Add to collections * ops.add_to_collection(ops.GraphKeys.COND_CONTEXT, context_t); * ops.add_to_collection(ops.GraphKeys.COND_CONTEXT, context_f); * * merges = nest.pack_sequence_as(structure: orig_res_t, flat_sequence: merges); * * // Singleton lists and tuples are automatically unpacked if strict == False. * if (!strict) * merges = _UnpackIfSingleton(merges); * return merges; * } * } */ public static void PreventFetching(this TFGraph g, TFOperation op) { }
private Tensor GetOpMetadata(TFOperation op) { TFStatus status = new TFStatus(); // Query the shape long[] shape = null; var shape_attr = op.GetAttributeMetadata("shape", status); if (!status.Ok || shape_attr.TotalSize <= 0) { Debug.LogWarning("Operation " + op.Name + " does not contain shape attribute or it" + " doesn't contain valid shape data!"); } else { if (shape_attr.IsList) { throw new NotImplementedException("Querying lists is not implemented yet!"); } else { TFStatus s = new TFStatus(); long[] dims = new long[shape_attr.TotalSize]; TF_OperationGetAttrShape(op.Handle, "shape", dims, (int)shape_attr.TotalSize, s.Handle); if (!status.Ok) { throw new FormatException("Could not query model for op shape (" + op.Name + ")"); } else { shape = new long[dims.Length]; for (int i = 0; i < shape_attr.TotalSize; ++i) { if (dims[i] == -1) { // we have to use batchsize 1 shape[i] = 1; } else { shape[i] = dims[i]; } } } } } // Query the data type TFDataType type_value = new TFDataType(); unsafe { TFStatus s = new TFStatus(); TF_OperationGetAttrType(op.Handle, "dtype", &type_value, s.Handle); if (!s.Ok) { Debug.LogWarning("Operation " + op.Name + ": error retrieving dtype, assuming float!"); type_value = TFDataType.Float; } } Tensor.TensorType placeholder_type = Tensor.TensorType.FloatingPoint; switch (type_value) { case TFDataType.Float: placeholder_type = Tensor.TensorType.FloatingPoint; break; case TFDataType.Int32: placeholder_type = Tensor.TensorType.Integer; break; default: Debug.LogWarning("Operation " + op.Name + " is not a float/integer. Proceed at your own risk!"); break; } Tensor t = new Tensor { Data = null, Name = op.Name, Shape = shape, ValueType = placeholder_type }; return(t); }
/// <summary> /// Enqueues a tuple of one or more tensors in this queue. /// </summary> /// <param name="components"> /// One or more tensors from which the enqueued tensors should be taken. /// </param> /// <param name="operationName"> /// If specified, the created operation in the graph will be this one, otherwise it will be named 'QueueEnqueueV2'. /// </param> /// <param name="timeout_ms"> /// Optional argument /// If the queue is full, this operation will block for up to /// timeout_ms milliseconds. /// Note: This option is not supported yet. /// </param> /// <returns> /// Returns the description of the operation /// </returns> /// <remarks> /// The components input has k elements, which correspond to the components of /// tuples stored in the given queue. /// /// N.B. If the queue is full, this operation will block until the given /// element has been enqueued (or 'timeout_ms' elapses, if specified). /// </remarks> public override TFOperation Enqueue(TFOutput [] components, long?timeout_ms = null, string operationName = null) { TFOperation operation = Session.Graph.QueueEnqueueV2(_handle, components, timeout_ms, operationName); return(operation); }