您好,登錄后才能下訂單哦!
這篇文章主要介紹“怎么利用PyTorch實現(xiàn)爬山算法”,在日常操作中,相信很多人在怎么利用PyTorch實現(xiàn)爬山算法問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”怎么利用PyTorch實現(xiàn)爬山算法”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!
在隨機搜索策略中,每個回合都是獨立的。因此,隨機搜索中的所有回合都可以并行運行,最終選擇能夠得到最佳性能的權(quán)重。我們還通過繪制總獎勵隨回合增加的變化情況進行驗證,可以看到獎勵并沒有上升的趨勢。在本節(jié)中,我們將實現(xiàn)爬山算法 (hill-climbing algorithm
),以將在一個回合中學(xué)習(xí)到的知識轉(zhuǎn)移到下一個回合中。
在爬山算法中,我們同樣從隨機選擇的權(quán)重開始。但是,對于每個回合,我們都會為權(quán)重添加一些噪聲數(shù)據(jù)。如果總獎勵有所改善,我們將使用新的權(quán)重來更新原權(quán)重;否則,將保持原權(quán)重。通過這種方法,隨著回合的增加,權(quán)重也會逐步修改,而不是在每個回合中隨機改變。
接下來,我們使用 PyTorch
實現(xiàn)爬山算法。首先,導(dǎo)入所需的包,創(chuàng)建一個 CartPole
環(huán)境實例,并計算狀態(tài)空間和動作空間的尺寸。重用 run_episode
函數(shù),其會根據(jù)給定權(quán)重,模擬一個回合后返回總獎勵:
import gym import torch from matplotlib import pyplot as plt env = gym.make('CartPole-v0') n_state = env.observation_space.shape[0] print(n_state) n_action = env.action_space.n print(n_action) def run_episode(env, weight): state = env.reset() total_reward = 0 is_done = False while not is_done: state = torch.from_numpy(state).float() action = torch.argmax(torch.matmul(state, weight)) state, reward, is_done, _ = env.step(action.item()) total_reward += reward return total_reward
模擬 1000
個回合,并初始化變量用于跟蹤最佳的總獎勵以及相應(yīng)的權(quán)重。同時,初始化一個空列表用于記錄每個回合的總獎勵:
n_episode = 1000 best_total_reward = 0 best_weight = torch.randn(n_state, n_action) total_rewards = []
正如以上所述,我們在每個回合中為權(quán)重添加一些噪音,為了使噪聲不會覆蓋原權(quán)重,我們還將對噪聲進行縮放,使用 0.01
作為噪聲縮放因子:
noise_scale = 0.01
然后,就可以運行 run_episode
函數(shù)進行模擬。
隨機選擇初始權(quán)重之后,在每個回合中執(zhí)行以下操作:
為權(quán)重增加隨機噪音
智能體根據(jù)線性映射采取動作
回合終止并返回總獎勵
如果當(dāng)前獎勵大于到目前為止獲得的最佳獎勵,更新最佳獎勵和權(quán)重;否則,最佳獎勵和權(quán)重將保持不變
記錄每回合的總獎勵
for e in range(n_episode): weight = best_weight + noise_scale * torch.rand(n_state, n_action) total_reward = run_episode(env, weight) if total_reward >= best_total_reward: best_total_reward = total_reward best_weight = weight total_rewards.append(total_reward) print('Episode {}: {}'.format(e + 1, total_reward))
計算使用爬山算法所獲得的平均總獎勵:
print('Average total reward over {} episode: {}'.format(n_episode, sum(total_rewards) / n_episode)) # Average total reward over 1000 episode: 62.421
為了評估使用爬山算法的訓(xùn)練效果,多次重復(fù)訓(xùn)練過程,使用循環(huán)語句多次執(zhí)行爬山算法,可以觀察到平均總獎勵的波動變化較大:
for i in range(10): best_total_reward = 0 best_weight = torch.randn(n_state, n_action) total_rewards = [] for e in range(n_episode): weight = best_weight + noise_scale * torch.rand(n_state, n_action) total_reward = run_episode(env, weight) if total_reward >= best_total_reward: best_total_reward = total_reward best_weight = weight total_rewards.append(total_reward) # print('Episode {}: {}'.format(e + 1, total_reward)) print('Average total reward over {} episode: {}'.format(n_episode, sum(total_rewards) / n_episode))
以下是我們運行10次后得到的結(jié)果:
Average total reward over 1000 episode: 200.0
Average total reward over 1000 episode: 9.846
Average total reward over 1000 episode: 82.1
Average total reward over 1000 episode: 9.198
Average total reward over 1000 episode: 9.491
Average total reward over 1000 episode: 9.073
Average total reward over 1000 episode: 149.421
Average total reward over 1000 episode: 49.584
Average total reward over 1000 episode: 8.827
Average total reward over 1000 episode: 9.369
產(chǎn)生如此差異的原因是什么呢?如果初始權(quán)重較差,則添加的少量噪聲只會小范圍改變權(quán)重,且對改善性能幾乎沒有影響,導(dǎo)致算法收斂性能不佳。另一方面,如果初始權(quán)重較為合適,則添加大量噪聲可能會大幅度改變權(quán)重,使得權(quán)重偏離最佳權(quán)重并破壞算法性能。為了使爬山算法的訓(xùn)練更穩(wěn)定,我們可以使用自適應(yīng)噪聲縮放因子,類似于梯度下降中的自適應(yīng)學(xué)習(xí)率,隨著模型性能的提升改變噪聲縮放因子的大小。
為了使噪聲具有自適應(yīng)性,執(zhí)行以下操作:
指定初始噪聲縮放因子
如果回合中的模型性能有所改善,則減小噪聲縮放因子,本節(jié)中,每次將噪聲縮放因子減小為原來的一半,同時設(shè)置縮放因子最小值為 0.0001
而如果回合中中的模型性能下降,則增大噪聲縮放因子,本節(jié)中,每次將噪聲縮放因子增大為原來的 2
倍,同時設(shè)置縮放因子最大值為 2
noise_scale = 0.01 best_total_reward = 0 best_weight = torch.randn(n_state, n_action) total_rewards = [] for e in range(n_episode): weight = best_weight + noise_scale * torch.rand(n_state, n_action) total_reward = run_episode(env, weight) if total_reward >= best_total_reward: best_total_reward = total_reward best_weight = weight noise_scale = max(noise_scale/2, 1e-4) else: noise_scale = min(noise_scale*2, 2) total_rewards.append(total_reward) print('Episode {}: {}'.format(e + 1, total_reward))
可以看到,獎勵隨著回合的增加而增加。訓(xùn)練過程中,當(dāng)一個回合中可以運行 200
個步驟時,模型的性能可以得到保持,平均總獎勵也得到了極大的提升:
print('Average total reward over {} episode: {}'.format(n_episode, sum(total_rewards) / n_episode)) # Average total reward over 1000 episode: 196.28
接下來,為了更加直觀的觀察,我們繪制每個回合的總獎勵的變化情況,如下所示,可以看到總獎勵有明顯的上升趨勢,然后穩(wěn)定在最大值處:
plt.plot(total_rewards, label='search') plt.xlabel('episode') plt.ylabel('total_reward') plt.legend() plt.show()
多次運行訓(xùn)練過程過程,可以發(fā)現(xiàn)與采用恒定噪聲縮放因子進行學(xué)習(xí)相比,自適應(yīng)噪聲縮放因子可以得到穩(wěn)定的訓(xùn)練結(jié)果。
接下來,我們測試所得到的模型策略在 1000 個新回合中的性能表現(xiàn):
n_episode_eval = 1000 total_rewards_eval = [] for episode in range(n_episode_eval): total_reward = run_episode(env, best_weight) print('Episode {}: {}'.format(episode+1, total_reward)) total_rewards_eval.append(total_reward) print('Average total reward over {} episode: {}'.format(n_episode_eval, sum(total_rewards_eval)/n_episode_eval)) # Average total reward over 1000 episode: 199.98
可以看到在測試階段的平均總獎勵接近 200
,即 CartPole
環(huán)境中可以獲得的最高獎勵。通過多次運行評估,可以獲得非常一致的結(jié)果。
到此,關(guān)于“怎么利用PyTorch實現(xiàn)爬山算法”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。