Пример #1
0
  /**
   * @param samples The number of input vectors the error is sampled over
   * @return Mean-squared error of this origin over randomly selected points
   */
  public float[] getError(int samples) {
    float[] result = new float[getDimensions()];

    if (myNode instanceof NEFEnsemble) {
      NEFEnsemble ensemble = (NEFEnsemble) myNode;

      VectorGenerator vg = new RandomHypersphereVG(false, 1, 0);
      float[][] unscaled = vg.genVectors(samples, ensemble.getDimension());
      float[][] input = new float[unscaled.length][];
      for (int i = 0; i < input.length; i++) {
        input[i] = MU.prodElementwise(unscaled[i], ensemble.getRadii());
      }

      float[][] idealOutput = NEFUtil.getOutput(this, input, SimulationMode.DIRECT);
      float[][] actualOutput = NEFUtil.getOutput(this, input, SimulationMode.CONSTANT_RATE);

      float[][] error = MU.transpose(MU.difference(actualOutput, idealOutput));
      for (int i = 0; i < error.length; i++) {
        result[i] = MU.prod(error[i], error[i]) / error[i].length;
      }
    } else {
      ourLogger.warn(
          "Can't calculate error of a DecodedOrigin unless it belongs to an NEFEnsemble");
    }

    return result;
  }
Пример #2
0
  public DecodedOrigin clone(Node node) throws CloneNotSupportedException {
    if (!(node instanceof DecodableEnsemble)) {
      throw new CloneNotSupportedException("Error cloning DecodedOrigin: Invalid node type");
    }

    try {
      DecodableEnsemble de = (DecodableEnsemble) node;

      DecodedOrigin result = (DecodedOrigin) super.clone();
      result.setDecoders(MU.clone(myDecoders));

      Function[] functions = new Function[myFunctions.length];
      for (int i = 0; i < functions.length; i++) {
        functions[i] = myFunctions[i].clone();
      }
      result.myFunctions = functions;

      result.myNodeOrigin = myNodeOrigin;
      result.myNodes = de.getNodes();
      result.myNode = de;
      result.myOutput = (RealOutput) myOutput.clone();
      if (myNoise != null) {
        result.setNoise(myNoise.clone());
      }
      result.setMode(myMode);
      return result;
    } catch (CloneNotSupportedException e) {
      throw new CloneNotSupportedException("Error cloning DecodedOrigin: " + e.getMessage());
    }
  }
Пример #3
0
  /** @param decoders New decoding vectors (row per Node) */
  public void setDecoders(float[][] decoders) {
    assert MU.isMatrix(decoders);
    assert myDecoders.length == decoders.length;
    assert myDecoders[0].length == decoders[0].length;

    myDecoders = decoders;
  }
Пример #4
0
  /**
   * With this constructor decoding vectors are specified by the caller.
   *
   * @param node The parent Node
   * @param name As in other constructor
   * @param nodes As in other constructor
   * @param nodeOrigin Name of the Origin on each given node from which output is to be decoded
   * @param functions As in other constructor
   * @param decoders Decoding vectors which are scaled by the main output of each Node, and then
   *     summed, to estimate the same function of the ensembles state vector that is defined by the
   *     'functions' arg. The 'functions' arg is still needed, because in DIRECT SimulationMode,
   *     these functions are used directly. The 'decoders' arg allows the caller to provide decoders
   *     that are generated with non-default methods or parameters (eg an unusual number of singular
   *     values). Must be a matrix with one row per Node and one column per function.
   * @throws StructuralException If dimensions.length != neurons.length, decoders is not a matrix
   *     (ie all elements with same length), or if the number of columns in decoders is not equal to
   *     the number of functions
   */
  public DecodedOrigin(
      Node node,
      String name,
      Node[] nodes,
      String nodeOrigin,
      Function[] functions,
      float[][] decoders)
      throws StructuralException {
    checkFunctionDimensions(functions);

    if (!MU.isMatrix(decoders)) {
      throw new StructuralException("Elements of decoders do not all have the same length");
    }

    if (decoders[0].length != functions.length) {
      throw new StructuralException(
          "Number of decoding functions and dimension of decoding vectors must be the same");
    }

    if (decoders.length != nodes.length) {
      throw new StructuralException("Number of decoding vectors and Neurons must be the same");
    }

    myNode = node;
    myName = name;
    myNodes = nodes;
    myNodeOrigin = nodeOrigin;
    myFunctions = functions;
    myDecoders = decoders;
    myMode = SimulationMode.DEFAULT;
    myIntegrator = new EulerIntegrator(.001f);

    reset(false);
  }
Пример #5
0
 private float[] getDynamicDecoder(int i, float input, float startTime, float endTime) {
   float[] result = myDecoders[i];
   if (mySTPDynamicsTemplate
       != null) { // TODO: could use a NullDynamics here instead of null (to allow nulling in
                  // config tree)
     // TODO: could recycle a mutable time series here to avoid object creation
     TimeSeries inputSeries =
         new TimeSeries1DImpl(
             new float[] {startTime, endTime}, new float[] {input, input}, Units.UNK);
     TimeSeries outputSeries = myIntegrator.integrate(mySTPDynamics[i], inputSeries);
     float scaleFactor = outputSeries.getValues()[outputSeries.getValues().length - 1][0];
     mySTPHistory[i] = scaleFactor;
     result = MU.prod(result, scaleFactor);
   }
   return result;
 }
Пример #6
0
  /**
   * With this constructor the target is a signal over time rather than a function.
   *
   * @param node The parent Node
   * @param name As in other constructor
   * @param nodes As in other constructor
   * @param nodeOrigin Name of the Origin on each given node from which output is to be decoded
   * @param targetSignal Signal over time that this origin should produce.
   * @param approximator A LinearApproximator that can be used to approximate new signals as a
   *     weighted sum of the node outputs.
   */
  public DecodedOrigin(
      Node node,
      String name,
      Node[] nodes,
      String nodeOrigin,
      TimeSeries targetSignal,
      LinearApproximator approximator)
      throws StructuralException {

    myNode = node;
    myName = name;
    myNodes = nodes;
    myNodeOrigin = nodeOrigin;
    myFunctions = new FixedSignalFunction[targetSignal.getDimension()];
    for (int i = 0; i < targetSignal.getDimension(); i++) // these are only used in direct mode
    myFunctions[i] = new FixedSignalFunction(targetSignal.getValues(), i);
    myDecoders = findDecoders(nodes, MU.transpose(targetSignal.getValues()), approximator);
    myMode = SimulationMode.DEFAULT;
    myIntegrator = new EulerIntegrator(.001f);

    reset(false);
  }