ප්රමුඛතාඅත්දැකීම් නැවත ධාවනය කිරීමේ බෆරය

මෙයද්විමය අංශ ගසක් භාවිතා කරමින් කඩදාසි ප්රමුඛතා අත්දැකීම් නැවත ධාවනයකරයි.

Open In Colab View Run

16import random
17
18import numpy as np

ප්රමුඛතාඅත්දැකීම් නැවත ධාවනය සඳහා බෆරය

ප්රමුඛතා අත්දැකීම් සාම්පල නැවත ධාවනය කිරීම වැදගත් සංක්රාන්ති නිතර නිතර. සංක්රාන්ති සඳහා ප්රමුඛතාවය දෙනු ලබන්නේ තාවකාලික වෙනස දෝෂය (td දෝෂය), .

අපිසම්භාවිතාව සමඟ සංක්රාන්තිය නියැදි කරන්නෙමු, ප්රමුඛතාවය කොපමණ ප්රමාණයක් භාවිතා කරනවාද යන්න තීරණය කරන අධි-පරාමිතියක් කොහෙද ? ඒකාකාර නඩුවට අනුරූප වේ. ප්රමුඛතාවය වේ.

සංක්රාන්තියසඳහා තාවකාලික වෙනස කොතැනද සමානුපාතික ප්රමුඛතාවය අපි භාවිතා කරමු .

පාඩුශ්රිතයේ වැදගත්-නියැදීම් (IS) බර භාවිතා කරමින් ප්රමුඛතා නැවත ධාවනය කිරීමෙන් හඳුන්වා දෙන ලද නැඹුරුව අපි නිවැරදි කරමු. මෙය සම්පූර්ණයෙන්ම වන්දි ගෙවන්නේ කවදාද යන්නයි. ස්ථාවරත්වය සඳහා අපි බර සාමාන්යකරණය කරමු. පුහුණුව අවසානයේ අභිසාරීතාව කෙරෙහි අපක්ෂපාතී ස්වභාවය වඩාත් වැදගත් වේ. එබැවින් අපි පුහුණුව අවසන් කිරීම සඳහා වැඩි වෙමු.

ද්විමයඛණ්ඩයේ රුක්

නියැදියසඳහා අවශ්ය වන සමුච්චිත සම්භාවිතාව කාර්යක්ෂමව ගණනය කිරීම සඳහා ද්විමය ඛණ්ඩක ගසක් භාවිතා කරමු. ඒ වගේම අපි සොයා ගැනීමට ද්විමය කොටස ගසක් භාවිතා , සඳහා අවශ්ය වන . මේ සඳහා අපට කුඩා ගොඩක් භාවිතා කළ හැකිය. ද්විමය ඛණ්ඩයේ ගස අපට කාලය තුළ මෙම ගණනය කිරීමට ඉඩ දෙයි, එය බොළඳ ප්රවේශය වඩාත් කාර්යක්ෂම වේ.

ද්විමයඛණ්ඩක ගසක් එකතුව සඳහා ක්රියා කරන ආකාරය මෙයයි; එය අවම වශයෙන් සමාන වේ. අපි නියෝජනය කිරීමට අවශ්ය වටිනාකම් ලැයිස්තුව කරමු . ද්විමය ගසෙහි පේළියේ නෝඩය විය යුතුය. ඒ node එකක් මතම ඊට අදාල දරුවන් දෙදෙනෙකු වන අතර .

පේළියේකොළ නෝඩ් වල අගයන් ඇත . සෑම නෝඩයක්ම ළමා නෝඩ් දෙකේ එකතුව තබා ගනී. එනම්, මූල නෝඩය සමස්ත අගයන්හි එකතුව තබා ගනී. මූල node එකක් මතම ඊට අදාල වම් හා දකුණු දරුවන් පිළිවෙළින් අරාවෙහි පළමු භාගයේ එකතුව සහ දෙවන භාගයේ එකතුව තබා ගන්න. හා එසේ මත...

පේළියේනෝඩ් ගණන , මෙය ඉහත සියලු පේළිවල නෝඩ් එකතුවට සමාන වේ . ඒ නිසා අපට ගස ගබඩා කිරීම සඳහා තනි අරාවක් භාවිතා කළ හැකිය, කොහේද,

එවිටළමා නෝඩ් සහ . එනම්,

ද්විමයගස් නඩත්තු කිරීමේ මෙම ක්රමය ක්රමලේඛනය කිරීම ඉතා පහසුය. අපිසුචිගත කිරීම 1 සිට ආරම්භ වන බව සලකන්න.

අවමගණනය කිරීම සඳහා අපි එකම ව්යුහය භාවිතා කරමු.

21class ReplayBuffer:

ආරම්භකරන්න

91    def __init__(self, capacity, alpha):

අපිධාරිතාව සඳහා බලයක් භාවිතා කරන්නේ එය කේතය සහ නිදොස්කරණය සරල කරන බැවිනි

96        self.capacity = capacity

98        self.alpha = alpha

මුදලක්ගැනීමට සහ පරාසයක් පුරා අවම සොයා ගැනීමට කොටස ද්විමය ගස් පවත්වා

101        self.priority_sum = [0 for _ in range(2 * self.capacity)]
102        self.priority_min = [float('inf') for _ in range(2 * self.capacity)]

වත්මන්උපරිම ප්රමුඛතාවය ,, නව සංක්රාන්ති සඳහා පැවරිය යුතුය

105        self.max_priority = 1.

බෆරයසඳහා අරා

108        self.data = {
109            'obs': np.zeros(shape=(capacity, 4, 84, 84), dtype=np.uint8),
110            'action': np.zeros(shape=capacity, dtype=np.int32),
111            'reward': np.zeros(shape=capacity, dtype=np.float32),
112            'next_obs': np.zeros(shape=(capacity, 4, 84, 84), dtype=np.uint8),
113            'done': np.zeros(shape=capacity, dtype=np.bool)
114        }

දත්තගබඩා කිරීම සඳහා අපි චක්රීය බෆර් භාවිතා කරන අතර ඊළඟ හිස් තට්ටුවේ දර්ශකය next_idx තබා ගනිමු

117        self.next_idx = 0

බෆරයේප්රමාණය

120        self.size = 0

පෝලිමටනියැදිය එක් කරන්න

122    def add(self, obs, action, reward, next_obs, done):

ඊළඟලබාගත හැකි තව් ලබා ගන්න

128        idx = self.next_idx

පෝලිමේගබඩා

131        self.data['obs'][idx] = obs
132        self.data['action'][idx] = action
133        self.data['reward'][idx] = reward
134        self.data['next_obs'][idx] = next_obs
135        self.data['done'][idx] = done

ඊළඟලබා ගත හැකි තව් වැඩි කිරීම

138        self.next_idx = (idx + 1) % self.capacity

ප්රමාණයගණනය කරන්න

140        self.size = min(self.capacity, self.size + 1)

, නව සාම්පල ලබා max_priority

143        priority_alpha = self.max_priority ** self.alpha

එකතුවසහ අවම වශයෙන් කොටස් ගස් දෙක යාවත්කාලීන කරන්න

145        self._set_priority_min(idx, priority_alpha)
146        self._set_priority_sum(idx, priority_alpha)

අවමසඳහා ද්විමය කොටස ගස ප්රමුඛත්වය සකසන්න

148    def _set_priority_min(self, idx, priority_alpha):

ද්විමයගසෙහි කොළ

154        idx += self.capacity
155        self.priority_min[idx] = priority_alpha

මුතුන්මිත්තන් ඔස්සේ ගමන් කිරීමෙන් ගස යාවත්කාලීන කරන්න. ගසේ මුල තෙක් දිගටම කරගෙන යන්න.

159        while idx >= 2:

මව්නෝඩයේ දර්ශකය ලබා ගන්න

161            idx //= 2

මව්node එකක් මතම ඊට අදාල වටිනාකම එය දරුවන් දෙදෙනා අවම වේ

163            self.priority_min[idx] = min(self.priority_min[2 * idx], self.priority_min[2 * idx + 1])

මුදලසඳහා ද්විමය කොටස ගස ප්රමුඛත්වය සකසන්න

165    def _set_priority_sum(self, idx, priority):

ද්විමයගසෙහි කොළ

171        idx += self.capacity

කොළයේප්රමුඛතාවය සකසන්න

173        self.priority_sum[idx] = priority

මුතුන්මිත්තන් ඔස්සේ ගමන් කිරීමෙන් ගස යාවත්කාලීන කරන්න. ගසේ මුල තෙක් දිගටම කරගෙන යන්න.

177        while idx >= 2:

මව්නෝඩයේ දර්ශකය ලබා ගන්න

179            idx //= 2

මව්node එකක් මතම ඊට අදාල වටිනාකම එය දරුවන් දෙදෙනා එකතුව

181            self.priority_sum[idx] = self.priority_sum[2 * idx] + self.priority_sum[2 * idx + 1]

183    def _sum(self):

මූලනෝඩය සියලු අගයන්හි එකතුව තබා ගනී

189        return self.priority_sum[1]

191    def _min(self):

මූලනෝඩය සියලු අගයන්හි අවම වශයෙන් තබා ගනී

197        return self.priority_min[1]

එවැනි විශාලතම සොයා

199    def find_prefix_sum_idx(self, prefix_sum):

මූලසිට ආරම්භ කරන්න

205        idx = 1
206        while idx < self.capacity:

වම්ශාඛාවේ එකතුව අවශ්ය ප්රමාණයට වඩා වැඩි නම්

208            if self.priority_sum[idx * 2] > prefix_sum:

ගසෙහිවම් ශාඛාවට යන්න

210                idx = 2 * idx
211            else:

එසේනොමැතිනම් දකුණු ශාඛාවට ගොස් වම් ශාඛාවේ එකතුව අවශ්ය මුදලින් අඩු කරන්න

214                prefix_sum -= self.priority_sum[idx * 2]
215                idx = 2 * idx + 1

අපිකොළ node එකක් මතම ඊට අදාල වේ. සැබෑ වටිනාකමේ දර්ශකය ලබා ගැනීම සඳහා ගසෙහි දර්ශකය මගින් ධාරිතාව අඩු කිරීම

219        return idx - self.capacity

බෆරයෙන්නියැදිය

221    def sample(self, batch_size, beta):

සාම්පලආරම්භ කරන්න

227        samples = {
228            'weights': np.zeros(shape=batch_size, dtype=np.float32),
229            'indexes': np.zeros(shape=batch_size, dtype=np.int32)
230        }

නියැදිදර්ශක ලබා ගන්න

233        for i in range(batch_size):
234            p = random.random() * self._sum()
235            idx = self.find_prefix_sum_idx(p)
236            samples['indexes'][i] = idx

239        prob_min = self._min() / self._sum()

241        max_weight = (prob_min * self.size) ** (-beta)
242
243        for i in range(batch_size):
244            idx = samples['indexes'][i]

246            prob = self.priority_sum[idx + self.capacity] / self._sum()

248            weight = (prob * self.size) ** (-beta)

සාමාන්යකරණයකරන්න , එමඟින් පදය අවලංගු වේ

251            samples['weights'][i] = weight / max_weight

සාම්පලදත්ත ලබා ගන්න

254        for k, v in self.data.items():
255            samples[k] = v[samples['indexes']]
256
257        return samples

ප්රමුඛතායාවත්කාලීන කරන්න

259    def update_priorities(self, indexes, priorities):
264        for idx, priority in zip(indexes, priorities):

වත්මන්උපරිම ප්රමුඛතාවය සකසන්න

266            self.max_priority = max(self.max_priority, priority)

ගණනයකරන්න

269            priority_alpha = priority ** self.alpha

ගස්යාවත්කාලීන කරන්න

271            self._set_priority_min(idx, priority_alpha)
272            self._set_priority_sum(idx, priority_alpha)

බෆරයපිරී තිබේද

274    def is_full(self):
278        return self.capacity == self.size