/// <inheritdoc /> public virtual object DeepCopy() { Network copy = new Network(Name); copy.Architecture = (INetworkArchitecture)Architecture.DeepCopy(); if (_initialised) { copy.Initialise(_associatedHandler); for (int i = 0; i < _orderedLayerBuffers.Count; i++) { InternalLayerBuffer originalBuffer = _orderedLayerBuffers[i]; InternalLayerBuffer copyBuffer = copy._orderedLayerBuffers[i]; foreach (string parameterIdentifier in originalBuffer.Parameters.Keys.ToArray()) { object value = originalBuffer.Parameters[parameterIdentifier]; IDeepCopyable deepCopyableValue = value as IDeepCopyable; object copiedValue; // copy and copy efficiently by any means possible if (deepCopyableValue == null) { ICloneable cloneableValue = value as ICloneable; copiedValue = cloneableValue?.Clone() ?? value; } else { INDArray asNDArray = value as INDArray; if (asNDArray != null) { _associatedHandler.Fill(asNDArray, copyBuffer.Parameters.Get <INDArray>(parameterIdentifier)); copiedValue = copyBuffer.Parameters.Get <INDArray>(parameterIdentifier); } else { copiedValue = deepCopyableValue.DeepCopy(); } } copyBuffer.Parameters[parameterIdentifier] = copiedValue; } } } copy.UpdateRegistry(); return(copy); }
/// <inheritdoc /> public void Initialise(IComputationHandler handler) { if (handler == null) { throw new ArgumentNullException(nameof(handler)); } if (Architecture == null) { throw new InvalidOperationException("Cannot initialise network before assigning a network architecture."); } _logger.Debug($"Initialising network \"{Name}\" for handler {handler} containing {Architecture.LayerCount} layers..."); _associatedHandler = handler; ITaskObserver prepareTask = SigmaEnvironment.TaskManager.BeginTask(TaskType.Prepare); Architecture.ResolveAllNames(); _orderedLayerBuffers.Clear(); _externalInputsLayerBuffers.Clear(); _externalOutputsLayerBuffers.Clear(); Dictionary <Tuple <LayerConstruct, LayerConstruct>, IRegistry> mappedRegistriesByInOutputs = new Dictionary <Tuple <LayerConstruct, LayerConstruct>, IRegistry>(); foreach (LayerConstruct layerConstruct in Architecture.YieldLayerConstructsOrdered()) { ILayer layer = layerConstruct.InstantiateLayer(handler); Dictionary <string, IRegistry> inputs = new Dictionary <string, IRegistry>(); foreach (string externalInputAlias in layerConstruct.ExternalInputs) { inputs[externalInputAlias] = new Registry(tags: "external_input"); } foreach (string inputAlias in layerConstruct.Inputs.Keys) { inputs[inputAlias] = mappedRegistriesByInOutputs[new Tuple <LayerConstruct, LayerConstruct>(layerConstruct.Inputs[inputAlias], layerConstruct)]; } Dictionary <string, IRegistry> outputs = new Dictionary <string, IRegistry>(); foreach (string externalOutputAlias in layerConstruct.ExternalOutputs) { outputs[externalOutputAlias] = new Registry(tags: "external_output"); } foreach (string outputAlias in layerConstruct.Outputs.Keys) { LayerConstruct outputConstruct = layerConstruct.Outputs[outputAlias]; Tuple <LayerConstruct, LayerConstruct> inOuTuple = new Tuple <LayerConstruct, LayerConstruct>(layerConstruct, outputConstruct); Registry outRegistry = new Registry(tags: "internal"); mappedRegistriesByInOutputs.Add(inOuTuple, outRegistry); outputs[outputAlias] = outRegistry; } InternalLayerBuffer layerBuffer = new InternalLayerBuffer(layer, layerConstruct.Parameters, inputs, outputs, layerConstruct.ExternalInputs, layerConstruct.ExternalOutputs); _orderedLayerBuffers.Add(layerBuffer); if (layerConstruct.ExternalInputs.Length > 0) { _externalInputsLayerBuffers.Add(layerBuffer); } if (layerConstruct.ExternalOutputs.Length > 0) { _externalOutputsLayerBuffers.Add(layerBuffer); } } _orderedLayers = _orderedLayerBuffers.ConvertAll(buffer => buffer.Layer); UpdateRegistry(); SigmaEnvironment.TaskManager.EndTask(prepareTask); _initialised = true; _logger.Debug($"Done initialising network \"{Name}\" for handler {handler} containing {Architecture.LayerCount} layers."); }