旋转优化器的域名?

时间:2014-12-21 20:21:40

标签: python algorithm optimization parameters

我正在努力弄清楚如何在参数优化方法上设置边界(最小/最大)。 Twiddle是优化算法:https://www.youtube.com/watch?v=2uQ2BSzDvXs。如何确保p(参数)保持在某个域内?下面是我在Python中的Twiddle实现:

def twiddle(objFunction, args, init=0.5, tolerance=0.00001, domain=(0,float("inf"))):
  """Optimize a single parameter given an objective function.

  This is a local hill-climbing algorithm. Here is a simple description of it:
  https://www.youtube.com/watch?v=2uQ2BSzDvXs

  @param args       (tuple)   Arguments necessary for the objective function.

  @param tolerance  (float)   Number used to determine when optimization has
                              converged to a sufficiently good score.

  @param objFunction(function)Objective Function used to quantify how good a
                              particular parameter choice is.

  @param init       (float)   Initial value of the parameter.

  @param domain     (tuple)   Domain of parameter values, as (min, max).

  @return (dict) Contains:
        "parameter" (float)   Threshold that returns the largest score from the
                              Objective function.

        "score"     (float)   The score from the objective function given the
                              threshold.
  """
  pastCalls = {}
  x = init
  delta = 0.1
  bestScore = objFunction(x, args)

  pastCalls[x] = bestScore

  while delta > tolerance: #and x >= domain[0]+tolerance and x <= domain[1]-tolerance:
    x += delta

    if x not in pastCalls:
      score = objFunction(x, args)
      pastCalls[x] = score

    score = pastCalls[x]

    if score > bestScore:
      bestScore = score
      delta *= 2

    else:
      x -= 2*delta

      if x not in pastCalls:
        score = objFunction(x, args)
        pastCalls[x] = score

      score = pastCalls[x]

      if score > bestScore:
        bestScore = score
        delta *= 2
      else:
        x += delta
        delta *= 0.5

    print "Parameter:", x
    print "Best score:", bestScore
    print "delta:", delta
    print

  return {"parameter": x,
          "score": bestScore}

E.g。我想将正弦函数作为objFunction运行,但域名设置为[0,2 * pi]。

1 个答案:

答案 0 :(得分:2)

知道了!与@ AlexMartelli的评论类似,该算法需要防止在每次递增/递减到x时越界。为了保持爬山算法的核心功能,步长delta必须调整到当前位置和外边界之间距离的一半。这样算法仍然倾向于在边界方向上移动,如果最大值在边界处可以到达那里,并且如果需要可以从边界移回。代码如下:

def twiddle(objFunction, args, init=0.5, tolerance=0.00001, domain=(float("-inf"), float("inf"))):
  """Optimize a single parameter given an objective function.

  This is a local hill-climbing algorithm. Here is a simple description of it:
  https://www.youtube.com/watch?v=2uQ2BSzDvXs

  @param args       (tuple)   Arguments necessary for the objective function.

  @param tolerance  (float)   Number used to determine when optimization has
                              converged to a sufficiently good score.

  @param objFunction(function)Objective Function used to quantify how good a
                              particular parameter choice is.

  @param init       (float)   Initial value of the parameter.

  @param domain     (tuple)   Domain of parameter values, as (min, max).

  @return (dict) Contains:
        "parameter" (float)   Threshold that returns the largest score from the
                              Objective function.

        "score"     (float)   The score from the objective function given the
                              threshold.
  """
  pastCalls = {}
  x = init
  delta = 0.1
  bestScore = objFunction(x, args)

  pastCalls[x] = bestScore

  while delta > tolerance:

    # Keep x within bounds
    if x+delta > domain[1]:
      delta = abs(domain[1] - x) / 2
    x += delta

    if x not in pastCalls:
      score = objFunction(x, args)
      pastCalls[x] = score

    score = pastCalls[x]

    if score > bestScore:
      bestScore = score
      delta *= 2

    else:
      # Keep x within bounds
      if x-delta < domain[0]:
        delta = abs(domain[0] - x) / 2
      x -= 2*delta

      if x not in pastCalls:
        score = objFunction(x, args)
        pastCalls[x] = score

      score = pastCalls[x]

      if score > bestScore:
        bestScore = score
        delta *= 2
      else:
        x += delta
        delta *= 0.5

    print "Parameter:", x
    print "Best score:", bestScore
    print "Step size:", delta
    print

  return {"parameter": x,
          "score": bestScore}