天天看點

誰更勝一籌?——随機搜尋 V.S. 網格搜尋

<b>誰更勝一籌?--</b><b>随機搜尋 v.s. </b><b>網格搜尋</b>

我想通過測試來得到自己的答案,我的實驗設定如下。給定空間為(1024,1024)的超參數空間,可由相同形狀的矩陣表示。我們為尋找最佳超參數設定的預算是25個實驗。是以,這将允許我們進行網格搜尋,其中我們設定每個超參數有5個值的組合,或者在該空間中的25個随機搜尋。此外,我設定了一個“批量”版本的随機搜尋,執行5批次每批次5次随機搜尋,優化調整每次批次後的搜尋。生成多個這樣的随機超參數空間後,計算兩種随機搜尋優于網格搜尋的次數。

<b>生成空間</b>

這一步是生成随機2d超參數空間,例如某種地形。

它是一個簡單而優雅的算法。

代碼如下:

 1

 2

 3

 4

 5

 6

 7

 8

 9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

<b>from</b> <b>__future__</b> <b>import</b> division, print_function

<b>import</b> <b>numpy</b> <b>as</b> <b>np</b>

<b>import</b> <b>matplotlib.pyplot</b> <b>as</b> <b>plt</b>

<b>import</b> <b>matplotlib.cm</b> <b>as</b> <b>cm</b>

<b>import</b> <b>operator</b>

%matplotlib inline

size = 1024

num_iterations = 200

terrain = np.zeros((size, size), dtype="float")

mod_iter =

num_iterations // 10

<b>for</b> iter <b>in</b> range(num_iterations):

    <b>if</b> iter % mod_iter == 0:

        <b>print</b>("iteration: {:d}".format(iter))

    r

= int(np.random.uniform(0, 0.2 * size))

xc, yc = np.random.randint(0, size - 1, 2)

    z

= 0

xmin, xmax = int(max(xc - r, 0)), int(min(xc + r,

size))

ymin, ymax = int(max(yc - r, 0)), int(min(yc + r,

    <b>for</b> x <b>in</b> range(xmin, xmax):

<b>for</b> y <b>in</b> range(ymin, ymax):

z = (r ** 2) - ((x - xc)

** 2 + (y - yc) ** 2)

<b>if</b> z &gt; 0:

                terrain[x, y] += z

<b>print</b>("total

iterations: {:d}".format(iter))

# 标準化單元高度

zmin = np.min(terrain)

terrain -=

zmin

zmax = np.max(terrain)

terrain /=

zmax

terrain = np.power(terrain, 2)

# 乘以255以使地形以灰階表示

terrain =

terrain * 255

terrain.astype("uint8")

從上面代碼生成的一個可能的地形如下所示。

我還為它生成了一個等高線圖。

1

2

3

4

5

6

7

8

9

plt.title("terrain")

image = plt.imshow(terrain, cmap="gray")

plt.ylim(max(plt.ylim()), min(plt.ylim()))

plt.colorbar(image,

shrink=0.8)

plt.title("contours")

contour = plt.contour(terrain, linewidths=2)

plt.colorbar(contour,

shrink=0.8, extend='both')

誰更勝一籌?——随機搜尋 V.S. 網格搜尋

<b></b>

網格搜尋

 

如您所見,地形隻是一個形狀矩陣(1024,1024)。

由于我們的預算是25個實驗,我們将在這個地形上進行一次5x5的網格搜尋。

意即在x和y軸上選擇5個等距點,并讀取這些(x,y)位置處的地形矩陣值。

執行此操作的代碼如下所示。

在輪廓圖上的點的最佳值以藍色标示。

# 執行 (5x5)網格搜尋

results = []

<b>for</b> x <b>in</b> np.linspace(0, size-1, 5):

    <b>for</b> y <b>in</b> np.linspace(0, size-1, 5):

xi, yi = int(x), int(y)

results.append([xi, yi, terrain[xi, yi]])

best_xyz = [r <b>for</b> r <b>in</b> sorted(results, key=operator.itemgetter(2))][0]

grid_best =

best_xyz[2]

<b>print</b>(best_xyz)

xvals = [r[0] <b>for</b> r <b>in</b>

results]

yvals = [r[1] <b>for</b> r <b>in</b>

plt.title("grid search")

plt.scatter(xvals,

yvals, color="b", marker="o")

plt.scatter([best_xyz[0]], [best_xyz[1]], color='b', s=200, facecolors='none', edgecolors='b')

plt.colorbar(contour)

<b> </b><b></b>

誰更勝一籌?——随機搜尋 V.S. 網格搜尋

網格搜尋中最優點坐标為(767,767),值為109。

随機搜尋

接下來進行實驗的是純随機搜尋。由于實驗預設為25個,是以這裡僅随機生成x值和y值,然後在這些點中搜尋地形矩陣值。

# 進行随機搜尋

xvals, yvals, zvals = [], [], []

<b>for</b> i <b>in</b> range(25):

    x

= np.random.randint(0, size, 1)[0]

    y

    results.append((x, y, terrain[x, y]))

best_xyz = sorted(results, key=operator.itemgetter(2))[0]

rand_best = best_xyz[2]

xvals = [r[0] <b>for</b> r <b>in</b> results]

yvals = [r[1] <b>for</b> r <b>in</b> results]

plt.title("random search")

誰更勝一籌?——随機搜尋 V.S. 網格搜尋

在該測試中,随機搜尋做得更好一些,找到坐标為(663,618)值為103的點。

批量随機搜尋

在這種方法中,我決定将我的25個實驗預算分成5批,每批5個實驗。

查找(x,y)值在每個批次内是随機的。

同時,在每個批次結束時,優勝者會被挑出來進行特殊處理。

采用對象不是在空間中任何地方生成的點,而是在這些點周圍繪制一個視窗,并且僅從這些空間進行采樣。

在每次疊代時,視窗會進行幾何收縮。我試圖尋找到目前為止找到的最優點的鄰域中的點,希望這個搜尋将産生更多的最優點。

同時,我保留剩餘的實驗探索空間,希望我可能找到另一個最佳點。

其代碼如下所示:

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

<b>def</b> cooling_schedule(n, k):

    """ 每次運作時減少視窗的大小

n – 批次數目

k – 目前批次的索引号

傳回 乘數(0..1) 的大小

"""

    <b>return</b> (n - k) / n

results, winners = [],

[]

<b>for</b> bid <b>in</b> range(5):

    <b>print</b>("batch

#: {:d}".format(bid), end="")

    # 計算視窗大小

window_size = int(0.25 * cooling_schedule(5,

bid) * size)

    # 計算出優勝者并把其值加入結果中

    # 隻保持最優的兩點

    <b>for</b> x, y, _, _ <b>in</b>

winners:

<b>if</b> x &lt;

size // 2:

# 中左區

xleft = max(x - window_size // 2, 0)

xright = xleft +

window_size

<b>else</b>:

# 中右區

xright = min(x + window_size // 2, size)

xleft = xright -

<b>if</b> y &lt;

# 下半區

ybot = max(y - window_size // 2, 0)

ytop = ybot +

# 上半區

ytop = min(y + window_size // 2, 0)

ybot = ytop -

xnew = np.random.randint(xleft, xright, 1)[0]

ynew = np.random.randint(ybot, ytop, 1)[0]

znew = terrain[xnew, ynew]

results.append((xnew, ynew, znew, bid))

    # 添加剩餘随機點

    <b>for</b> i <b>in</b> range(5 - len(winners)):

x = np.random.randint(0, size, 1)[0]

y = np.random.randint(0, size, 1)[0]

z = terrain[x, y]

results.append((x, y, z, 2))

    # 找出最優兩點

winners = sorted(results, key=operator.itemgetter(2))[0:2]

    <b>print</b>("

best: ", winners[0])

plt.title("batched random search")

誰更勝一籌?——随機搜尋 V.S. 網格搜尋

結束時此空間中的全局最小點坐标(707,682),值為20。

顯然,并不是所有的運作都是如此順利的,也很有可能從上述任何方法發現的點隻是一個局部最小值。

此外,沒有理由假定網格搜尋可能不優于随機搜尋,因為随機地形可能在其中一個均勻布置的點下面具有其全局最小點,并且随機搜尋可能錯過該點。

為了檢查這個假設,我對1000個随機地形批量運作上面的代碼。

對于每個地形,我為3種方法中的每一種運作25個實驗,并為每個方法找到最低(最優)點。我這樣做了兩次,以確定結果的客觀性。代碼如下:

terrain_size = 1024

num_hills = 200

num_trials = 1000

num_searches_per_dim = 5

num_winners = 2

nbr_random_wins = 0

nbr_brand_wins = 0

<b>for</b> i <b>in</b> range(num_trials):

terrain = build_terrain(terrain_size, num_hills)

grid_result = best_grid_search(terrain_size,

num_searches_per_dim)

random_result = best_random_search(terrain_size,

num_searches_per_dim**2)

batch_result = best_batch_random_search(terrain_size,

                                            num_searches_per_dim,

num_searches_per_dim,

num_winners)

    <b>print</b>(grid_result, random_result, batch_result)

    <b>if</b> random_result &lt;

grid_result:

 nbr_random_wins += 1

    <b>if</b> batch_result &lt; grid_result:

nbr_brand_wins += 1

<b>print</b>("#

times random search wins: {:d}".format(nbr_random_wins))

times batch random search wins: {:d}".format(nbr_brand_wins))

執行結果如下:

run-1

------

#-times random search wins: 619 ‘随機搜尋優勝次數

run-2

#-times random search wins: 640 ‘随機搜尋優勝次數

#-times batch random search wins: 621随機批量搜尋優勝次數

結果表明随機搜尋似乎比網格搜尋稍好(因為第一個數字超過500)。

此外,批量版本不一定更好,因為純随機搜尋在第二次運作有更好的結果。

<a href="https://promotion.aliyun.com/ntms/act/ambassador/sharetouser.html?usercode=lwju78qa&amp;utm_source=lwju78qa">數十款阿裡雲産品限時折扣中,趕緊點選領劵開始雲上實踐吧!</a>

作者簡介:

sujit pal是一名程式員,在healline

networks擔任技術管理。喜好研究程式設計語言java和python,喜歡從多角度研究和解決問題。

文章原标題《random vs grid search: which

is better?》,作者:sujit pal ,譯者:伍昆