Пример #1
0
def runNetPasses(sess, target_placeholder, target_func, net_output,
                 cnp, residual):
  """Runs the net for num_passes.

  Step 3 in the paper.

  Args:
    target_placeholder: (tf.placeholder shape [1, num_samples]) For feeding
      the target function to the net.
    target_func: (np.array of float shape [1, num_samples]) The initial
      target function.
    net_output: (tf.Tensor of float shape [1, num_samples]) The net output, V.
    cnp: The output commands and parameters from each generator, see below.
    residual: target_func - net_output.

  cnp stands for "commands and parameters". cnp[i] is a list
  [commands, multiplier, offset] for generator i.
  commands is a Tensor shape [1, 2] for Phi_i and lambda_i.
  multiplier and offset are each a Tensor shape [1, 1] for A_i and k_i.

  Returns: A list of the computed cnps for each pass.
  """
  predictions = []  # Sum of the net_output from the first i+1 passes.

  # List of cnps for each pass.
  pass_cnps = []

  pass_target = target_func
  for pass_num in range(0, num_passes):
    with sess.as_default():
      net_output_np, cnp_np, residual_np  = sess.run(
          [net_output, cnp, residual],
          feed_dict={target_placeholder: pass_target})
    pass_target = residual_np
    if not predictions:
      predictions.append(net_output_np)
    else:
      predictions.append(net_output_np + predictions[-1])

    pass_cnps.append(cnp_np)

    error = math.sqrt(np.sum(np.square(target_func - predictions[-1])))
    print('Pass %d: error sqrt (sum(error*error)): %f' %
          (pass_num, error))

  utils.graphBatch([target_func[0]],
                   FLAGS.out_dir + '/target.png',
                   title = 'Target',
                   ylim=[-1.5, 1.5])

  utils.graphBatch(
      [target_func[0]] + [p[0] for p in predictions],
      FLAGS.out_dir + '/networkPredictions.png',
      title='Target + Network Predictions with Residuals',
      labels=['Target', 'Network Prediction'] + [
          '+Residual Correction %d' % i for i in range(1, len(predictions))],
      ylim=[-1.5, 1.5])

  return pass_cnps
Пример #2
0
def reweightSampledBases(bases_before_params, target_func):
    """Compute optimal parameters to fit the bases to the target_func.

  Step 5 in the paper.

  Writes graphs comparing the optimized parameters to the target_func
  into --out_dir/refit*.png.

  Args:
    bases_before_params: The sampled bases produced by the commands.
      List of length len(generator_specs) * num_passes since every
      generator in every pass produces one command. Each entry
      is an np.array shape [1, num_samples].
  """
    # Av is shape [num_samples, len(bases_before_params) + 1].
    # As described in Step 5, we compute just one Delta parameter that
    # is the sum of k_i.  The added row of Av computes Delta.
    Av = np.transpose(bases_before_params)
    Av = np.concatenate([Av, np.ones([num_samples, 1])], axis=1)

    # bv is shape [num_samples, 1]
    bv = np.transpose(target_func)

    A = tf.placeholder(tf.float32, Av.shape, name='A')
    b = tf.placeholder(tf.float32, bv.shape, name='b')
    linsol = tf.linalg.lstsq(A, b)

    sess = tf.Session()
    done = False
    while not done:
        try:
            with sess.as_default():
                x = sess.run(linsol, feed_dict={A: Av, b: bv})
            done = True
        except tf.errors.InvalidArgumentError as e:
            print('Cholesky likely failed. Adding miniscule noise.')
            for c in range(Av.shape[1] - 1):
                Av[random.randint(0, Av.shape[0] - 1)][c] *= random.uniform(
                    0.999, 1.001)

    ans = np.matmul(Av, x)
    err = ans - bv
    print('linSolve final error:', math.sqrt(np.sum(err * err)))

    utils.graphBatch([target_func[0], ans],
                     FLAGS.out_dir + '/refit.png',
                     title='After Reweighting',
                     labels=['Target', 'After Reweighting'],
                     ylim=[-1.5, 1.5])
Пример #3
0
def reconstructUsingBases(generator_specs, pass_cnps, target_func):
    """Apply the commands to the basis (rather than generators).

  Step 4 in the paper.

  Writes graphs to --out_dir/extractedCommands*.png comparing the
  target_func to the basis after applying the multiplier and offset.

  pass_cnps contains the commands and parameters for each pass and
  for each generator.

  Returns: (list of np.array shape [1, num_samples]) Each entry is a
    sampled basis for each generator before the parameters are applied.
  """
    # The sampled basis for each function before applying the multiplier
    # and offset. There are num_passes * len(generator_specs) bases in
    # this list.
    bases_before_params = []

    # The sampled function after each pass, including multiplier and
    # offset. Written to the graphs.
    command_fits = []

    for pass_num in range(num_passes):
        current = np.zeros([num_samples])
        for gen_num in range(len(generator_specs)):
            start = pass_cnps[pass_num][gen_num][0][0][0]  # Phi
            period = pass_cnps[pass_num][gen_num][0][0][1]  # lambda
            multiplier = pass_cnps[pass_num][gen_num][1][0][0]  # A
            offset = pass_cnps[pass_num][gen_num][2][0][0]  # k

            print('Pass %d function %d: command (unscaled) (%f, %f),'
                  ' multiplier %f, offset %f' %
                  (pass_num, gen_num, start, period, multiplier, offset))

            sampled_basis = functions.applyFunc(
                start, period, num_samples,
                generator_specs[gen_num].function_name)
            bases_before_params.append(sampled_basis.copy())
            sampled_basis *= multiplier
            sampled_basis += offset

            current += sampled_basis

        if pass_num == 0:
            command_fits.append(current)
        else:
            command_fits.append(current + command_fits[-1])

        err = target_func[0] - command_fits[-1]
        print('recon based on commands iteration: %d : %f' %
              (pass_num, math.sqrt(np.sum(err * err))))

    utils.graphBatch(
        [target_func[0]] + command_fits,
        FLAGS.out_dir + '/extractedCommands.png',
        title='Target + Extracted Commands',
        labels=['Target'] +
        ['Extracted Commands (pass %d)' % i for i in range(len(command_fits))],
        ylim=[-1.5, 1.5])

    return bases_before_params