驗(yàn)回放的強(qiáng)化學(xué)習(xí)實(shí)戰(zhàn))
1. 先搞懂 hindsight 的一體兩面心理偏差和 AI 算法1.1 認(rèn)知科學(xué)里的后見之明偏差估計(jì)每個人都有過這種經(jīng)歷白天和同事討論方案的時候死活想不到關(guān)鍵點(diǎn)下班路上突然一拍腦袋哎呀明明該用那個參數(shù)啊。英文里有個詞特別精準(zhǔn)地描述這種感覺hindsight中文一般翻譯成后見之明。心理學(xué)里更嚴(yán)格的說法叫 hindsight bias后見之明偏差也叫我早就知道了效應(yīng)。這個效應(yīng)的經(jīng)典定義很簡單當(dāng)你知道某件事的結(jié)果之后你會高估自己事前猜到結(jié)果的可能性??荚噷Υ鸢傅臅r候覺得每道題都會比賽看完回放覺得教練換人換得不明智項(xiàng)目復(fù)盤的時候覺得當(dāng)時的所有信號都已經(jīng)指向了正確方向——這些都是后見之明偏差在起作用。它本質(zhì)上是一種認(rèn)知重構(gòu)大腦為了維持我是理性且善于預(yù)測的自我形象會把已經(jīng)知道的結(jié)果悄悄植入記憶讓你誤以為我之前的判斷其實(shí)很接近正確答案。從神經(jīng)科學(xué)的角度看這種記憶扭曲幾乎是自動發(fā)生的。大腦在編碼新信息的時候并不是把當(dāng)時的判斷原封不動存下來而是在事后反復(fù)修改。你以為自己保留了當(dāng)時的預(yù)期其實(shí)那個預(yù)期已經(jīng)被后來的結(jié)果污染了。所以很多嚴(yán)肅的復(fù)盤方法都強(qiáng)調(diào)一個原則必須在行動之前留下書面判斷否則你回憶出來的事前判斷大概率是假的。1.2 AI 領(lǐng)域里的 Hindsight從后悔變算法有意思的是hindsight 這個詞在機(jī)器學(xué)習(xí)領(lǐng)域被打造成了完全不同的含義。2017 年Andrychowicz 等人在論文 Hindsight Experience Replay 中提出了一種強(qiáng)化學(xué)習(xí)算法直接取名為事后經(jīng)驗(yàn)回放簡稱 HER。作者給算法取這個名字明顯是借用后見之明偏差的靈感但取的不是后悔或誤判而是事后視角可以重新解讀過去這個正面含義。HER 的核心思想用一句話說就是如果一條經(jīng)驗(yàn)按照原定目標(biāo)來看是失敗的那不如換個目標(biāo)讓它變成成功的經(jīng)驗(yàn)。這就像你復(fù)盤的時候發(fā)現(xiàn)雖然沒搞定客戶 A但我摸清了整個行業(yè)的報(bào)價邏輯這個認(rèn)知本身就是價值。HER 讓 AI 也擁有這種能力——它不用改變真實(shí)發(fā)生過的事情只需要在回放經(jīng)驗(yàn)的時候把原來的目標(biāo)替換成實(shí)際達(dá)到的狀態(tài)原本價值極低的失敗樣本立刻擁有了訓(xùn)練價值。這篇文章后面要講的就是這個事后視角在強(qiáng)化學(xué)習(xí)里到底怎么落地。我會把它拆成原理、代碼、調(diào)參、問題排查四個部分對做機(jī)器人控制、操作類 RL 任務(wù)的人尤其有參考價值。如果只是想了解后見之明這個概念讀完第一第二部分也會有收獲。2. 稀疏獎勵為什么這么難解從機(jī)械臂抓取說起2.1 一個讓 AI 崩潰的經(jīng)典場景想象一下你讓一個機(jī)械臂去抓桌面上的杯子。任務(wù)定義很簡單只要夾爪碰到杯子并提起就算成功獎勵 1沒抓到獎勵 0??雌饋砗芎侠淼嬲脧?qiáng)化學(xué)習(xí)訓(xùn)練的時候這個問題會讓絕大多數(shù)算法原地打轉(zhuǎn)。原因不復(fù)雜初始狀態(tài)下機(jī)械臂連杯子在哪個方向都不知道它隨機(jī)動一下成功率無限接近 0。訓(xùn)練 1000 個回合可能 999 個回合都是獎勵 0。在 Q 函數(shù)和目標(biāo)狀態(tài)的視角里所有失敗樣本的回報(bào)幾乎一模一樣網(wǎng)絡(luò)根本區(qū)分不出稍微靠近了一點(diǎn)和完全沒動之間誰更好。缺乏梯度策略就學(xué)不進(jìn)去表現(xiàn)為訓(xùn)練曲線從頭到尾平平的一條線沒有任何上升趨勢。這就像讓一個從來沒摸過籃球的孩子練習(xí)投籃規(guī)則是投進(jìn)了才給一顆糖投不進(jìn)去什么都沒有。他試了兩小時一次都沒投進(jìn)完全不知道調(diào)整手型、力度、瞄準(zhǔn)點(diǎn)哪個動作方向是對的。沒有中間反饋只有二元結(jié)果學(xué)習(xí)效率趨近于零。2.2 獎勵稀疏的根源差信號不等于無信號許多人都認(rèn)為解決辦法是加過程獎勵比如靠近杯子 0.01碰到桌子 -0.01用密集合成獎勵引導(dǎo)機(jī)械臂一步步走。這類做法叫 reward shaping確實(shí)有效但工程上很脆。你很難設(shè)計(jì)一套既不誤導(dǎo)、又足夠稠密的獎勵函數(shù)而且 agent 經(jīng)常能鉆空子找到一條獎勵高但任務(wù)沒完成的捷徑訓(xùn)練出來的行為完全不是你要的。更本質(zhì)的問題在于稀疏獎勵環(huán)境并不是沒有信息而是信息密度太低。傳統(tǒng)的經(jīng)驗(yàn)回放Experience Replay把整段失敗軌跡丟進(jìn)緩沖區(qū)但這些軌跡在目標(biāo)定義下全是負(fù)樣本價值趨同。HER 提出的關(guān)鍵觀察是失敗并不是絕對的它取決于你用什么目標(biāo)去衡量。同一個狀態(tài)轉(zhuǎn)移相對于目標(biāo) A 是失敗的相對于目標(biāo) B 可能就成功了。2.3 為什么我們不能直接丟給 AI 一本事后總結(jié)有人會問既然事后知道實(shí)際抓到了什么位置為什么不直接告訴 AI你去學(xué)那個位置這就牽涉到強(qiáng)化學(xué)習(xí)的動態(tài)特性。AI 在訓(xùn)練過程中看到的并不是實(shí)際操作后的總結(jié)報(bào)告而是大量帶獎勵的轉(zhuǎn)移樣本 (state, action, reward, next_state, goal)。HER 的聰明之處在于它把事后視角作為一種數(shù)據(jù)增強(qiáng)手段在訓(xùn)練過程中動態(tài)生成新目標(biāo)而不是在 episode 結(jié)束時做一次性的總結(jié)。所以 HER 從來不改變真實(shí)環(huán)境中的行為策略也不偽造機(jī)械臂曾經(jīng)成功過。它只是改變了經(jīng)驗(yàn)池里樣本的解釋方式同一個轉(zhuǎn)移用原始目標(biāo)存一份實(shí)際達(dá)到的狀態(tài)當(dāng)新目標(biāo)再存一份。off-policy 算法之后采樣時兩份樣本都能用網(wǎng)絡(luò)就有了更多可學(xué)習(xí)的正樣本。這個方法不需要手工設(shè)計(jì)獎勵函數(shù)也不需要改變探索策略因此被稱為免費(fèi)午餐——至少在這個特定場景下它的性價比高得驚人。3. HER 核心原理拆解怎樣用事后視野重構(gòu)訓(xùn)練樣本3.1 目標(biāo)重標(biāo)注是怎么發(fā)生的在正式講流程前得先把 HER 的數(shù)學(xué)表示說清楚。一個帶目標(biāo)目標(biāo)的馬爾可夫決策過程里每一條經(jīng)驗(yàn)可以寫成四元組 (s, a, r, s′, g)g 是這條經(jīng)驗(yàn)對應(yīng)的目標(biāo)。HER 在 episode 結(jié)束后會額外生成一條偽經(jīng)驗(yàn)把 g 替換成這個 episode 中某個未來狀態(tài) s_future然后重新計(jì)算獎勵 r′ reward(s_future, g′)。舉個例子機(jī)械臂的目標(biāo) g 是夾爪到達(dá)位置 (x1, y1, z1)一次 episode 結(jié)束后夾爪停在 (x2, y2, z2)。原始目標(biāo)下(x2, y2, z2) 不算成功reward 0HER 會把 g′ 設(shè)置成 (x2, y2, z2)此時定義成功條件變成了夾爪到達(dá) (x2, y2, z2)而機(jī)械臂最后確實(shí)到達(dá)了那里reward 就是 1。這條經(jīng)驗(yàn)從負(fù)樣本變成了正樣本。但這里有個關(guān)鍵細(xì)節(jié)不是用最終狀態(tài)當(dāng)唯一目標(biāo)。原版論文對比了四種采樣策略final用最終狀態(tài)、episode同一 episode 中隨機(jī)選一個狀態(tài)、random從整個 buffer 里隨機(jī)選狀態(tài)、future在當(dāng)前轉(zhuǎn)移之后的未來狀態(tài)里隨機(jī)選。實(shí)驗(yàn)結(jié)果是 future 策略效果最好。原因在于future 目標(biāo)與當(dāng)前轉(zhuǎn)移在時間上相關(guān)性強(qiáng)更接近近期可以實(shí)現(xiàn)的子目標(biāo)能讓 agent 學(xué)到漸進(jìn)式的技能分解。3.2 完整流程與經(jīng)驗(yàn)池結(jié)構(gòu)HER 的完整流程可以拆成六步采樣任務(wù)目標(biāo) g 并初始化狀態(tài) s0。讓 agent 與環(huán)境交互記錄每一步轉(zhuǎn)移信息直到 episode 結(jié)束。把整條軌跡按原始目標(biāo) g 存入 replay buffer。對每個狀態(tài)轉(zhuǎn)移隨機(jī)選取同一軌跡中、時間步在當(dāng)前之后的未來狀態(tài)作為新目標(biāo) g′。根據(jù) g′ 重新計(jì)算獎勵 r′生成偽轉(zhuǎn)移 (s, a, r′, s′, g′)也放入 buffer。訓(xùn)練時從 buffer 中等概率采樣原始目標(biāo)和偽目標(biāo)更新 actor 和 critic。經(jīng)驗(yàn)池的結(jié)構(gòu)因此比普通 replay buffer 要復(fù)雜一點(diǎn)它不能只存單條 transition至少要緩存一條完整的 episode這樣在回放時才能抽取未來狀態(tài)。工程實(shí)現(xiàn)上一般用一個臨時列表收集當(dāng)前 episode等到結(jié)束后統(tǒng)一拆分成 transition 寫入主 buffer。偽代碼層面長這樣# 注意這是一個簡化示意 episode_transitions [] for t in range(max_steps): action actor.select_action(state, goal) next_state, reward, done, info env.step(action) episode_transitions.append((state, action, reward, next_state, done, goal)) state next_state if done: break # episode 結(jié)束后原始目標(biāo)樣本直接入池 for transition in episode_transitions: replay_buffer.store(transition) # 額外重標(biāo)注未來目標(biāo) for t, transition in enumerate(episode_transitions): for _ in range(k): future_t random.randint(t, len(episode_transitions) - 1) future_achieved_goal episode_transitions[future_t][achieved_goal] new_goal future_achieved_goal new_reward compute_reward(new_goal, transition[achieved_goal]) replay_buffer.store((transition[state], transition[action], new_reward, transition[next_state], transition[done], new_goal))這里的 k 是每個原始轉(zhuǎn)移額外生成的目標(biāo)數(shù)量OpenAI 在 baselines 里常用的 k 是 4。k 越大正樣本比例越高但也會增加經(jīng)驗(yàn)池中的相關(guān)性一般來說 4 到 8 之間是合理范圍。3.3 為什么 off-policy 是 HER 的前提HER 能成立靠的是強(qiáng)化學(xué)習(xí)里 off-policy 算法對數(shù)據(jù)來源的寬容。DDPG、SAC、TD3 這類算法更新網(wǎng)絡(luò)的時候可以從任意舊策略產(chǎn)生的經(jīng)驗(yàn)中采樣只要 reward 和 transition 是合法數(shù)據(jù)就行。HER 額外生成的偽轉(zhuǎn)移等于把一條真實(shí)轉(zhuǎn)移重新標(biāo)記成了另一個目標(biāo)下的合法經(jīng)驗(yàn)這對 off-policy 算法來說完全合法。如果換成 on-policy 算法比如 PPO它要求訓(xùn)練數(shù)據(jù)必須來源于當(dāng)前策略HER 這種偽造目標(biāo)的做法就沒法直接用。因?yàn)?PPO 的梯度估計(jì)依賴行為策略和目標(biāo)策略的一致性直接把重標(biāo)注后的樣本拿來算 importance ratio 會導(dǎo)致嚴(yán)重偏差。所以你在做技術(shù)選型的時候別看到 HER 就想往 PPO 里塞它天然就是搭配 off-policy 算法的。3.4 邊界條件HER 不是萬能的HER 容易給人一種有了它所有稀疏獎勵都能解決的錯覺。實(shí)際上它有個硬性前提目標(biāo)必須可以從狀態(tài)中推斷出來即存在一個 achieved_goal 的觀測。機(jī)械臂抓取滿足這個條件因?yàn)閵A爪坐標(biāo)就是狀態(tài)的一部分。但如果任務(wù)是按順序完成三個動作這種過程型目標(biāo)獎勵只來自最后是否按序完成HER 就很難重標(biāo)注因?yàn)閱我蛔罱K狀態(tài)并不能表達(dá)順序這個信息。另外HER 也不太適合目標(biāo)狀態(tài)完全不在狀態(tài)空間里的任務(wù)。比如讓空調(diào)把室溫調(diào)到人體舒適溫度如果狀態(tài)空間只有當(dāng)前溫度和功率你無法定義實(shí)際達(dá)成目標(biāo)對應(yīng)的狀態(tài)表示HER 無從下手。所以實(shí)際工程中用 HER 前先回答兩個問題這個任務(wù)的成敗能由狀態(tài)唯一決定嗎我能從狀態(tài)中提取一個可計(jì)算的 achieved goal 嗎答案一旦是否定的就老實(shí)做 reward shaping 或者換模型。4. 手把手實(shí)現(xiàn)一個 HER 基準(zhǔn)流程代碼與調(diào)參4.1 環(huán)境準(zhǔn)備兩種路線最正統(tǒng)的 HER 實(shí)驗(yàn)環(huán)境是 OpenAI Gym 里的 Fetch 系列FetchReach、FetchPush、FetchPickAndPlace。這套環(huán)境自帶 achieved_goalreward 默認(rèn)就是稀疏的 0/1配合 MuJoCo 物理引擎跑起來能非常直觀地看到 HER 的效果。如果你沒有 MuJoCo 授權(quán)也不用灰心可以先在自定義的網(wǎng)格世界或簡單的二維連續(xù)控制環(huán)境里驗(yàn)證 HER 思想。我自己調(diào)代碼時的習(xí)慣是先在玩具環(huán)境里跑通 HER 的數(shù)據(jù)流再切到 Fetch 環(huán)境調(diào)超參。因?yàn)?HER 的難點(diǎn)不在算法本身而在經(jīng)驗(yàn)池的目標(biāo)重標(biāo)注邏輯玩具環(huán)境能幫你把邏輯里的 bug 快速暴露出來。環(huán)境安裝以 Fetch 為例conda create -n her python3.8 conda activate her pip install gymnasium-robotics注意 gymnasium-robotics 需要額外配置 MuJoCo不同版本的依賴差異比較大建議老老實(shí)實(shí)按官方 README 走別圖省事直接 pip 裝老 gym后面會踩一堆版本兼容坑。4.2 寫一個可復(fù)用的 HER ReplayBuffer工程上 HER 最容易被寫錯的地方是經(jīng)驗(yàn)池。我見過不少新手把單條 transition 直接堆進(jìn) buffer結(jié)果重標(biāo)注的時候找不到未來狀態(tài)。正確的設(shè)計(jì)是有一個臨時緩沖區(qū)專門攢 episode結(jié)束后再把原始轉(zhuǎn)移和偽轉(zhuǎn)移都寫進(jìn)主 buffer。一個精簡的 Python 類可以這樣組織class HerReplayBuffer: def __init__(self, capacity, k4): self.capacity capacity self.k k self.buffer deque(maxlencapacity) self.episode_transitions [] def add_transition(self, transition): self.episode_transitions.append(transition) def end_episode(self): # 原始目標(biāo)入池 for trans in self.episode_transitions: self.buffer.append(trans) # 重標(biāo)注未來目標(biāo)入池 episode_len len(self.episode_transitions) for t in range(episode_len): obs_t, action, reward, obs_tp1, done, goal self.episode_transitions[t] achieved_t obs_t[achieved_goal] for _ in range(self.k): future_t np.random.randint(t, episode_len) new_goal self.episode_transitions[future_t][obs][achieved_goal].copy() new_reward reward_fn(achieved_goalnew_goal, goalnew_goal) new_transition (obs_t, action, new_reward, obs_tp1, done, new_goal) self.buffer.append(new_transition) self.episode_transitions.clear() def sample(self, batch_size): batch random.sample(self.buffer, batch_size) return batch這個實(shí)現(xiàn)里最關(guān)鍵的一行是future_t np.random.randint(t, episode_len)它保證了新目標(biāo)永遠(yuǎn)來自當(dāng)前時間步之后的未來狀態(tài)符合原論文 future 策略。另一個重點(diǎn)是new_reward reward_fn(achieved_goalnew_goal, goalnew_goal)此時 achieved_goal 已經(jīng)等于 new_goal所以對稀疏 0/1 獎勵來說這條偽轉(zhuǎn)移大概率是正樣本。4.3 訓(xùn)練循環(huán)DDPG HER 的組合有了重放緩沖區(qū)剩下的訓(xùn)練循環(huán)就和普通 DDPG 很接近。這里以 DDPG 為例因?yàn)樗Y(jié)構(gòu)簡單、好調(diào)試。訓(xùn)練循環(huán)大致是初始化 actorcritictarget actortarget critic。每個 episode 開始前隨機(jī)采樣一個目標(biāo)。agent 與環(huán)境交互把每一步 transition 喂進(jìn) HerReplayBuffer。episode 結(jié)束后調(diào)用 end_episode() 完成重標(biāo)注。從 buffer 采樣 batch更新 critic 和 actor。周期性 soft update 目標(biāo)網(wǎng)絡(luò)。DDPG 的 critic 更新邏輯是action_next target_actor(next_obs, next_goal) target_q reward gamma * (1 - done) * target_critic(next_obs, action_next, next_goal) critic_loss F.mse_loss(critic(obs, action, goal), target_q)這里有個容易被忽略的細(xì)節(jié)在重標(biāo)注偽轉(zhuǎn)移里面obs和next_obs仍然來自真實(shí)轉(zhuǎn)移只有g(shù)oal變了。DDPG 計(jì)算 target_q 時使用的是替換后的目標(biāo)而不是原始目標(biāo)。這一點(diǎn)必須寫對否則 HER 就變成了普通的普通 buffer。4.4 調(diào)參經(jīng)驗(yàn)我踩過哪些坑超參方面原論文和 OpenAI baselines 里比較穩(wěn)的配置是buffer size 1e6actor 和 critic 各 3 層 256 個神經(jīng)元的 MLP學(xué)習(xí)率 1e-3gamma 0.98k 4。fetch 系列任務(wù)一般 50 到 100 萬步能看出明確趨勢。我自己實(shí)際調(diào)的時候發(fā)現(xiàn)幾個容易讓人崩潰的點(diǎn)第一網(wǎng)絡(luò)不要太大。HER 本身已經(jīng)通過重標(biāo)注擴(kuò)充了正樣本比例網(wǎng)絡(luò)越大反而越難收斂還容易過擬合到 buffer 里的舊樣本。256×3 在小規(guī)模任務(wù)里完全夠用。第二獎勵函數(shù)要穩(wěn)定。Fetch 稀疏獎勵用的是距離小于閾值給 1的判定閾值設(shè)置在 0.05 左右。如果你改用負(fù)距離獎勵需要先做標(biāo)準(zhǔn)化不然不同維度的目標(biāo)差距會把 Q 值炸飛。第三隨便調(diào) gamma 可能毀掉整個訓(xùn)練。HER 特別依賴長期信用分配gamma 太小會削弱未來目標(biāo)帶來的信號我試過從 0.98 調(diào)到 0.9失敗率直接從 15% 漲到 60%。建議保持在 0.95 到 0.99 之間別亂動。5. 常見問題與排查技巧實(shí)錄別讓 HER 訓(xùn)練白跑5.1 訓(xùn)練不收斂——先看正樣本比例很多人在 FetchPush 上跑了兩百萬步成功率還是 0。我遇到這種問題第一件事不是改網(wǎng)絡(luò)結(jié)構(gòu)而是打印 replay buffer 里正樣本的比例。HER 生效的標(biāo)志是 buffer 里應(yīng)該有相當(dāng)數(shù)量的偽正樣本如果end_episode()里的目標(biāo)替換寫錯了這些正樣本根本不會出現(xiàn)整個訓(xùn)練就退化成了普通稀疏獎勵 DDPG不收斂是必然的。檢查方法很簡單在重標(biāo)注入池后統(tǒng)計(jì)reward 1的比例。FetchReach 這類簡單任務(wù)里這個比例應(yīng)該至少達(dá)到 20% 到 30%。如果低于 5%大概率是你對achieved_goal的索引取錯了或者 future_t 采樣范圍寫成了[0, t)導(dǎo)致新目標(biāo)來自過去狀態(tài)語義完全不成立。5.2 重標(biāo)注后的經(jīng)驗(yàn)會不會污染策略這個問題我在剛開始做 HER 時也糾結(jié)過把本來沒完成的目標(biāo)強(qiáng)行改成已完成不是讓 AI 學(xué)壞嗎后來我想明白一個關(guān)鍵點(diǎn)重標(biāo)注后的偽樣本并不是告訴 agent你成功了而是告訴它如果目標(biāo)是這個狀態(tài)那么你剛才的動作就是正確的。這是兩個完全不同的語義。HER 改變的不是行為策略的探索過程而是目標(biāo)分布。agent 在同一個真實(shí)轉(zhuǎn)移上既能看到原始目標(biāo)下的負(fù)樣本也能看到未來目標(biāo)下的正樣本網(wǎng)絡(luò)被迫去理解同一個動作在不同目標(biāo)語境下有不同的價值。這本質(zhì)上是一種多任務(wù)學(xué)習(xí)不會讓 agent 學(xué)出投機(jī)取巧的行為反而讓它的目標(biāo)表征更豐富。5.3 成功率忽高忽低——隨機(jī)種子和評估陷阱HER 在 Fetch 任務(wù)上的方差比普通 DDPG 小很多但如果你的成功率曲線像心電圖一樣跳先別懷疑算法看看評估方式。強(qiáng)化學(xué)習(xí)訓(xùn)練時如果你用訓(xùn)練期的 buffer 里的臨時策略做評估結(jié)果天然不穩(wěn)定。正確做法是固定一個評估專用的隨機(jī)種子每隔固定步數(shù)跑固定次數(shù)的 rollout取平均成功率。另外MuJoCo 環(huán)境里同一個 seed 在不同的物理庫版本下結(jié)果可能不一樣。訓(xùn)練腳本里最好把隨機(jī)種子顯式傳給 env并且在換環(huán)境版本時重新跑一輪 baseline否則你記錄的提升 30%可能只是版本差異造成的幻覺。5.4 快速診斷清單正樣本比例是否達(dá)標(biāo)goal維度是否與 actor/critic 輸入層的期望一致achieved_goal是否在 obs 字典里正確取到未來狀態(tài)的采樣區(qū)間是否為[t, episode_len)gamma 是否在 0.95 到 0.99 區(qū)間是否使用 off-policy 算法訓(xùn)練步數(shù)和學(xué)習(xí)率是否匹配步數(shù)太少時HER 優(yōu)勢還沒完全顯現(xiàn)。6. 從算法到日常后見之明真正的復(fù)利6.1 復(fù)盤的三種姿勢別把Hindsight用反了如果只把 hindsight 當(dāng)成事后的聰明那它一點(diǎn)用都沒有但如果把它理解成重新選擇衡量標(biāo)準(zhǔn)的能力它的價值就完全不同了。我常用 HER 的思路做項(xiàng)目復(fù)盤傳統(tǒng)復(fù)盤是目標(biāo)沒達(dá)成找原因HER 式復(fù)盤是目標(biāo)沒達(dá)成那我實(shí)際達(dá)成了什么這個新成就值不值得被當(dāng)作下一步的目標(biāo)拿一次沒能按期上線的版本舉例。按原始目標(biāo)看這是失敗。但如果你把目標(biāo)換成摸清了線上問題的容量瓶頸那整個過程積累了非常多的真實(shí)流量數(shù)據(jù)這本身就是一個可復(fù)用的成果。把這個成果作為下一步的起點(diǎn)比單純懊悔沒上線要有用得多。當(dāng)然這不能變成自我安慰的借口否則就是后見之明偏差的負(fù)面版本。具體操作上我建議在項(xiàng)目啟動時寫一行原始預(yù)期存起來復(fù)盤時先不看結(jié)論只看事實(shí)再對照原始預(yù)期。這個習(xí)慣能很好壓制大腦的記憶重構(gòu)傾向讓復(fù)盤不再依賴你美化后的記憶。6.2 一個詞背后的擴(kuò)展空間HER 思路還能用到哪回頭看 HER 本身它已經(jīng)不是一個孤立算法?,F(xiàn)在的多目標(biāo)強(qiáng)化學(xué)習(xí)、機(jī)器人技能學(xué)習(xí)、甚至離線強(qiáng)化學(xué)習(xí)的數(shù)據(jù)增強(qiáng)都在沿用重寫目標(biāo)這個思路。比如機(jī)器人領(lǐng)域有一個常見玩法先讓機(jī)械臂隨機(jī)亂動收集大量沒有明確目標(biāo)但狀態(tài)變化豐富的軌跡再用 HER 類方法給這些軌跡標(biāo)出實(shí)際可達(dá)的目標(biāo)把它們變成訓(xùn)練數(shù)據(jù)。這比手工設(shè)計(jì)課程任務(wù)要省力得多。還有人在推薦系統(tǒng)里做類似的事用戶沒有點(diǎn)擊某個推薦項(xiàng)就把沒有點(diǎn)擊看作失敗但如果換一個目標(biāo)維度比如用戶在該物品上停留時間超過兩秒這個樣本就能變成正樣本。這種視角遷移不限于強(qiáng)化學(xué)習(xí)任何帶目標(biāo)評價的系統(tǒng)都可以試試。我在實(shí)際調(diào) HER 時最深的體會是算法層面的驚喜反而不是性能提升而是它對失敗的重新定義足夠溫和。它沒有否定過去的失敗也沒有假裝失敗不存在只是把失敗放到了一個能產(chǎn)生新價值的坐標(biāo)里。這個思路放在代碼里是幾行重標(biāo)注邏輯放在做事方法里就是真正意義上的復(fù)盤能力。最后再分享一個小技巧訓(xùn)練 HER 時不要一上來就開著可視化看機(jī)械臂你看到的幾乎全是沒抓到的畫面。先盯成功率曲線等到曲線抬頭了再開可視化那時候你才看得見后見之明到底給 agent 帶來了什么改變。