संसाधन लोड हो रहा है... लोड करना...

तंत्रिका नेटवर्क और डिजिटल मुद्राओं के लिए क्वांटिफाइड ट्रेडिंग श्रृंखला ((2)) गहन सशक्तिकरण सीखना Bitcoin ट्रेडिंग रणनीतियों को प्रशिक्षित करना

लेखक:घास, बनाया गयाः 2019-07-31 11:13:15, अद्यतनः 2023-10-20 20:10:18

img

1.介绍

पिछले आलेख में बिटकॉइन की कीमत का अनुमान लगाने के लिए LSTM नेटवर्क का उपयोग किया गया थाhttps://www.fmz.com/digest-topic/4035, जैसा कि लेख में उल्लेख किया गया है, आरएनएन और पाइटॉर्च के साथ परिचित होने के लिए एक छोटे से अभ्यासकर्ता प्रोजेक्ट है। इस लेख में एक विधि के बारे में बताया जाएगा जो मजबूत सीखने का उपयोग करता है, सीधे ट्रेडिंग रणनीतियों को प्रशिक्षित करता है। मजबूत सीखने का मॉडल ओपनएआई ओपन सोर्स पीपीओ है, जबकि वातावरण जिम की शैली को संदर्भित करता है। समझने और परीक्षण में आसानी के लिए, एलएसटीएम का पीपीओ मॉडल और पुनर्मूल्यांकन जिम वातावरण दोनों सीधे तैयार किए गए पैकेज का उपयोग नहीं करते हैं। पीपीओ, जिसका पूरा नाम Proximal Policy Optimization है, पॉलिसी ग्रेडिएंट, यानी रणनीति ग्रिडिएंट में एक अनुकूलन सुधार है। जिम भी ओपनएआई द्वारा जारी किया गया है, जो रणनीति नेटवर्क के साथ बातचीत कर सकता है, वर्तमान वातावरण की स्थिति और पुरस्कारों की प्रतिक्रिया कर सकता है, जैसे कि प्रबलित सीखने का अभ्यास। एलएसटीएम का उपयोग करके पीपीओ मॉडल को सीधे बिटकॉइन के बाजार की जानकारी के आधार पर खरीदने, बेचने या निष्क्रिय करने के निर्देशों के लिए उपयोग किया जाता है। इस लेख को पढ़ने के लिए कुछ पायथन, pytorch, DRL डीप रैपिड लर्निंग की नींव की आवश्यकता होती है. लेकिन इससे कोई फर्क नहीं पड़ता, इस लेख में दिए गए कोड के साथ मिलकर, इसे सीखना आसान है.www.fmz.com), QQ समूह में आपका स्वागत हैः 863946592 ।

2.数据和学习参考资料

बिटकॉइन की कीमतों के आंकड़े एफएमजेड के आविष्कारक के क्वांटिफाइड ट्रेडिंग प्लेटफॉर्म से प्राप्त हुए हैंःhttps://www.quantinfo.com/Tools/View/4.htmlएक लेख जो ट्रेडिंग रणनीतियों को प्रशिक्षित करने के लिए DRL + gym का उपयोग करता हैःhttps://towardsdatascience.com/visualizing-stock-trading-agents-using-matplotlib-and-gym-584c992bc6d4यहाँ कुछ उदाहरण दिए गए हैं:https://github.com/yunjey/pytorch-tutorialइस लेख में सीधे इस LSTM-PPO मॉडल के संक्षिप्त कार्यान्वयन का उपयोग किया जाएगाःhttps://github.com/seungeunrho/minimalRL/blob/master/ppo-lstm.pyपीपीओ के बारे में लेखःhttps://zhuanlan.zhihu.com/p/38185553डीआरएल के बारे में और पढ़ेंःhttps://www.zhihu.com/people/flood-sung/postsजिम के बारे में, इस लेख को स्थापित करने की आवश्यकता नहीं है, लेकिन प्रबलित सीखने का उपयोग किया जाता हैःhttps://gym.openai.com/

3.LSTM-PPO

पीपीओ के बारे में गहराई से जानकारी के लिए, आप पहले के संदर्भों को सीख सकते हैं, यहां केवल एक सरल अवधारणा का परिचय है। पिछले चरण में एलएसटीएम नेटवर्क केवल एक मूल्य की भविष्यवाणी करता है, और इस भविष्यवाणी मूल्य के आधार पर खरीदारी और बिक्री लेनदेन को कैसे लागू किया जाए, यह स्वाभाविक रूप से सोचने योग्य है, क्या सीधे आउटपुट खरीद और बिक्री की कार्रवाई अधिक प्रत्यक्ष नहीं है? नीति ग्राइंडेंट ऐसा है, जो इनपुट की गई पर्यावरणीय जानकारी के आधार पर विभिन्न प्रकार की क्रियाओं की कार्रवाई की संभावना देता है। एलएसटीएम का नुकसान अनुमानित मूल्य और वास्तविक मूल्य के बीच का अंतर है, जबकि पीजी का नुकसान - लॉग§*क्यू है, जहां पी आउटपुट की गई किसी क्रिया की संभावना है, और क्यू इस क्रिया के लिए मूल्य है।

निम्न में LSTM-PPO का स्रोत कोड दिया गया है, जो पहले की जानकारी के साथ समझ में आता हैः


import time
import requests
import json
import numpy as np
import pandas as pd
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torch.distributions import Categorical
from itertools import count

#模型的超参数
learning_rate = 0.0005
gamma         = 0.98
lmbda         = 0.95
eps_clip      = 0.1
K_epoch       = 3

device = torch.device('cpu') # 也可以改为GPU版本

class PPO(nn.Module):
    def __init__(self, state_size, action_size):
        super(PPO, self).__init__()
        self.data = []
        self.fc1   = nn.Linear(state_size,10)
        self.lstm  = nn.LSTM(10,10)
        self.fc_pi = nn.Linear(10,action_size)
        self.fc_v  = nn.Linear(10,1)
        self.optimizer = optim.Adam(self.parameters(), lr=learning_rate)

    def pi(self, x, hidden):
        #输出各个动作的概率,由于是LSTM网络还要包含hidden层的信息,可以参考上一期文章
        x = F.relu(self.fc1(x))
        x = x.view(-1, 1, 10)
        x, lstm_hidden = self.lstm(x, hidden)
        x = self.fc_pi(x)
        prob = F.softmax(x, dim=2)
        return prob, lstm_hidden
    
    def v(self, x, hidden):
        #价值函数,用于评价当前局面的好坏,所以只有一个输出
        x = F.relu(self.fc1(x))
        x = x.view(-1, 1, 10)
        x, lstm_hidden = self.lstm(x, hidden)
        v = self.fc_v(x)
        return v
      
    def put_data(self, transition):
        self.data.append(transition)
        
    def make_batch(self):
        #准备训练数据
        s_lst, a_lst, r_lst, s_prime_lst, prob_a_lst, hidden_lst, done_lst = [], [], [], [], [], [], []
        for transition in self.data:
            s, a, r, s_prime, prob_a, hidden, done = transition
            s_lst.append(s)
            a_lst.append([a])
            r_lst.append([r])
            s_prime_lst.append(s_prime)
            prob_a_lst.append([prob_a])
            hidden_lst.append(hidden)
            done_mask = 0 if done else 1
            done_lst.append([done_mask])
            
        s,a,r,s_prime,done_mask,prob_a = torch.tensor(s_lst, dtype=torch.float), torch.tensor(a_lst), \
                                         torch.tensor(r_lst), torch.tensor(s_prime_lst, dtype=torch.float), \
                                         torch.tensor(done_lst, dtype=torch.float), torch.tensor(prob_a_lst)
        self.data = []
        return s,a,r,s_prime, done_mask, prob_a, hidden_lst[0]
        
    def train_net(self):
        s,a,r,s_prime,done_mask, prob_a, (h1,h2) = self.make_batch()
        first_hidden = (h1.detach(), h2.detach())

        for i in range(K_epoch):
            v_prime = self.v(s_prime, first_hidden).squeeze(1)
            td_target = r + gamma * v_prime * done_mask
            v_s = self.v(s, first_hidden).squeeze(1)
            delta = td_target - v_s
            delta = delta.detach().numpy()
            
            advantage_lst = []
            advantage = 0.0
            for item in delta[::-1]:
                advantage = gamma * lmbda * advantage + item[0]
                advantage_lst.append([advantage])
            advantage_lst.reverse()
            advantage = torch.tensor(advantage_lst, dtype=torch.float)

            pi, _ = self.pi(s, first_hidden)
            pi_a = pi.squeeze(1).gather(1,a)
            ratio = torch.exp(torch.log(pi_a) - torch.log(prob_a))  # a/b == log(exp(a)-exp(b))

            surr1 = ratio * advantage
            surr2 = torch.clamp(ratio, 1-eps_clip, 1+eps_clip) * advantage
            loss = -torch.min(surr1, surr2) + F.smooth_l1_loss(v_s, td_target.detach()) #同时训练了价值网络和决策网络

            self.optimizer.zero_grad()
            loss.mean().backward(retain_graph=True)
            self.optimizer.step()

4.比特币回测环境

जिम के प्रारूप की नकल करते हुए, एक रीसेट आरंभिकरण विधि है, कदम इनपुट क्रिया, जिसके परिणामस्वरूप ((अगली स्थिति, क्रिया लाभ, क्या समाप्त हो गया है, अतिरिक्त जानकारी) के रूप में परिणाम लौटाया जाता है), पूरे रीसेट वातावरण में भी 60 पंक्तियां हैं, जो स्वयं को अधिक जटिल संस्करण में संशोधित कर सकते हैं, विशिष्ट कोडः

class BitcoinTradingEnv:
    def __init__(self, df, commission=0.00075,  initial_balance=10000, initial_stocks=1, all_data = False, sample_length= 500):
        self.initial_stocks = initial_stocks #初始的比特币数量
        self.initial_balance = initial_balance #初始的资产
        self.current_time = 0 #回测的时间位置
        self.commission = commission #易手续费
        self.done = False #回测是否结束
        self.df = df
        self.norm_df = 100*(self.df/self.df.shift(1)-1).fillna(0) #标准化方法,简单的收益率标准化
        self.mode = all_data # 是否为抽样回测模式
        self.sample_length = 500 # 抽样长度
        
    def reset(self):
        self.balance = self.initial_balance
        self.stocks = self.initial_stocks
        self.last_profit = 0
        
        if self.mode:
            self.start = 0
            self.end = self.df.shape[0]-1
        else:
            self.start = np.random.randint(0,self.df.shape[0]-self.sample_length)
            self.end = self.start + self.sample_length
            
        self.initial_value = self.initial_balance + self.initial_stocks*self.df.iloc[self.start,4]
        self.stocks_value = self.initial_stocks*self.df.iloc[self.start,4]
        self.stocks_pct = self.stocks_value/self.initial_value
        self.value = self.initial_value
        
        self.current_time = self.start
        return np.concatenate([self.norm_df[['o','h','l','c','v']].iloc[self.start].values , [self.balance/10000, self.stocks/1]])
    
    def step(self, action):
        #action即策略采取的动作,这里将更新账户和计算reward
        done = False
        if action == 0: #持有
            pass
        elif action == 1: #买入
            buy_value = self.balance*0.5
            if buy_value > 1: #余钱不足,不操作账户
                self.balance -= buy_value
                self.stocks += (1-self.commission)*buy_value/self.df.iloc[self.current_time,4]
        elif action == 2: #卖出
            sell_amount = self.stocks*0.5
            if sell_amount > 0.0001:
                self.stocks -= sell_amount
                self.balance += (1-self.commission)*sell_amount*self.df.iloc[self.current_time,4]
                
        self.current_time += 1
        if self.current_time == self.end:
            done = True
        self.value = self.balance + self.stocks*self.df.iloc[self.current_time,4]
        self.stocks_value = self.stocks*self.df.iloc[self.current_time,4]
        self.stocks_pct = self.stocks_value/self.value
        if self.value < 0.1*self.initial_value:
            done = True
            
        profit = self.value - (self.initial_balance+self.initial_stocks*self.df.iloc[self.current_time,4])
        reward = profit - self.last_profit # 每回合的reward是新增收益
        self.last_profit = profit
        next_state = np.concatenate([self.norm_df[['o','h','l','c','v']].iloc[self.current_time].values , [self.balance/10000, self.stocks/1]])
        return (next_state, reward, done, profit)

5.几个值得注意的细节

एक बार जब हम अपने खाते में पैसे जमा करते हैं, तो हम अपने खाते में पैसा क्यों जमा करते हैं?

रीट्वीट वातावरण के लिए रिटर्न की गणना करने का सूत्र हैः वर्तमान रिटर्न = वर्तमान खाता मूल्य - प्रारंभिक खाता वर्तमान मूल्य। इसका मतलब है कि यदि बिटकॉइन की कीमत गिर जाती है, और रणनीति ने सिक्का बेचने का संचालन किया है, तो कुल खाता मूल्य कम हो गया है, भले ही वास्तव में रणनीति को पुरस्कृत किया जाना चाहिए। यदि रीट्वीट का समय लंबा है, तो प्रारंभिक खाता बहुत कम प्रभाव डाल सकता है, लेकिन शुरुआत में बहुत बड़ा प्रभाव डाल सकता है। सापेक्ष रिटर्न की गणना से सुनिश्चित होता है कि हर सही कार्रवाई के लिए सकारात्मक पुरस्कार प्राप्त होता है।

प्रशिक्षण के दौरान नमुने क्यों लिए जाते हैं?

कुल डेटा की मात्रा दस हज़ार से अधिक K-रेखाएं है, यदि प्रत्येक बार पूर्ण मात्रा में एक लूप चलाया जाता है, तो लंबे समय तक समय लगता है, और रणनीति हर बार एक ही स्थिति का सामना करती है, तो इसे ओवरफैट करना आसान हो सकता है। प्रत्येक बार 500 से अधिक डेटा को एक बार में पुनः प्राप्त करने के लिए निकाला जाता है, हालांकि ओवरफैट करना संभव है, लेकिन रणनीति को दस हज़ार से अधिक बार अलग-अलग संभावित शुरुआत का सामना करना पड़ता है।

अगर आपके पास कोई सिक्का या पैसा नहीं है, तो आप क्या करेंगे?

पुनरीक्षण के माहौल में इस स्थिति को ध्यान में नहीं रखा जाता है, यदि सिक्का पहले ही बिक चुका है या न्यूनतम व्यापारिक मात्रा तक नहीं पहुंच पाया है, तो इस समय बिक्री ऑपरेशन को निष्पादित करना वास्तव में निष्पादित नहीं करने के बराबर है, यदि कीमत गिर जाती है, तो सापेक्ष लाभ की गणना के अनुसार, रणनीति अभी भी सकारात्मक पुरस्कार पर आधारित है। इस स्थिति का प्रभाव यह है कि जब रणनीति बाजार को कम करती है और खाता बकाया सिक्का नहीं बेच सकता है, तो बिक्री की कार्रवाई और निष्क्रिय कार्रवाई के बीच अंतर नहीं किया जा सकता है, लेकिन रणनीति के बारे में खुद के निर्णय पर कोई प्रभाव नहीं पड़ता है।

क्यों खाते की जानकारी को वापस करने के लिए?

पीपीओ मॉडल में एक मूल्य नेटवर्क है जिसका उपयोग वर्तमान स्थिति के मूल्य का आकलन करने के लिए किया जाता है, स्पष्ट रूप से यदि रणनीति यह तय करती है कि कीमतें ऊपर जाने वाली हैं, तो केवल वर्तमान खाता बिटकॉइन रखने के दौरान ही पूरे राज्य का सकारात्मक मूल्य होता है, और इसके विपरीत। इसलिए खाता जानकारी मूल्य नेटवर्क निर्णय का एक महत्वपूर्ण आधार है। ध्यान दें कि पिछले गतिविधि जानकारी को स्थिति के रूप में वापस नहीं लौटाया गया है, जो व्यक्तिगत रूप से मूल्य निर्धारण के लिए उपयोगी नहीं है।

क्या आप जानते हैं कि यह कैसे होता है?

जब रणनीति निर्णय खरीद-बिक्री से उत्पन्न होने वाले लाभ को कवर करने में असमर्थ है, तो प्रक्रिया शुल्क वापस नहीं किया जाना चाहिए। हालांकि पहले के विवरण में बार-बार रणनीति निर्णय मूल्य प्रवृत्ति का उपयोग किया गया है, लेकिन यह समझने में आसानी के लिए है कि वास्तव में यह पीपीओ मॉडल बाजार के लिए भविष्यवाणी नहीं करता है, केवल तीन आंदोलनों की संभावनाओं को आउटपुट करता है।

6.数据的获取和训练

पिछले लेख की तरह, डेटा प्राप्त करने का तरीका और प्रारूप इस प्रकार है, Bitfinex एक्सचेंज BTC_USD ट्रेडों के लिए एक घंटे के चक्र K लाइन पर 5/7/2018 से 6/27/2019 तकः

resp = requests.get('https://www.quantinfo.com/API/m/chart/history?symbol=BTC_USD_BITFINEX&resolution=60&from=1525622626&to=1561607596')
data = resp.json()
df = pd.DataFrame(data,columns = ['t','o','h','l','c','v'])
df.index = df['t']
df = df.dropna()
df = df.astype(np.float32)

LSTM नेटवर्क का उपयोग करने के कारण, प्रशिक्षण का समय लंबा था, इसलिए मैंने एक और GPU संस्करण बदल दिया, जो लगभग तीन गुना तेज था।

env = BitcoinTradingEnv(df)
model = PPO()

total_profit = 0 #记录总收益
profit_list = [] #记录每次训练收益
for n_epi in range(10000):
    hidden = (torch.zeros([1, 1, 32], dtype=torch.float).to(device), torch.zeros([1, 1, 32], dtype=torch.float).to(device))
    s = env.reset()
    done = False
    buy_action = 0
    sell_action = 0
    while not done:
        h_input = hidden
        prob, hidden = model.pi(torch.from_numpy(s).float().to(device), h_input)
        prob = prob.view(-1)
        m = Categorical(prob)
        a = m.sample().item()
        if a==1:
            buy_action += 1
        if a==2:
            sell_action += 1
        s_prime, r, done, profit = env.step(a)

        model.put_data((s, a, r/10.0, s_prime, prob[a].item(), h_input, done))
        s = s_prime

    model.train_net()
    profit_list.append(profit)
    total_profit += profit
    if n_epi%10==0:
        print("# of episode :{:<5}, profit : {:<8.1f}, buy :{:<3}, sell :{:<3}, total profit: {:<20.1f}".format(n_epi, profit, buy_action, sell_action, total_profit))

7.训练结果和分析

लंबे इंतजार के बादःimg

सबसे पहले, ट्रेनिंग डेटा की स्थिति को देखें, सामान्य तौर पर, पहले आधे हिस्से में एक लंबा गिरावट आई, जबकि दूसरे आधे हिस्से में एक मजबूत उछाल आया।img

प्रशिक्षण से पहले बहुत सारी खरीद-बिक्री की जाती है, और लाभदायक दौर नहीं होता है। प्रशिक्षण के मध्य में खरीद-बिक्री धीरे-धीरे कम हो जाती है, लाभ की संभावना बढ़ जाती है, लेकिन नुकसान की संभावना बहुत अधिक होती है।img

एक बार जब हम प्रत्येक राउंड के लिए लाभ को समतल करते हैं, तो परिणाम इस प्रकार होता हैःimg

रणनीति ने जल्दी से पहले की नकारात्मक कमाई से छुटकारा पाया, लेकिन उतार-चढ़ाव बड़ा था, और 10,000 राउंड के बाद तक कमाई तेजी से नहीं बढ़ी, और सामान्य तौर पर मॉडल को प्रशिक्षित करना मुश्किल था।

अंतिम प्रशिक्षण के बाद, मॉडल को सभी डेटा को एक बार फिर से चलाने के लिए कहा जाता है, यह देखने के लिए कि यह कैसे काम करता है, इस अवधि के दौरान खाते के कुल बाजार मूल्य, बिटकॉइन की संख्या, बिटकॉइन मूल्य का अनुपात, कुल आय दर्ज की जाती है। सबसे पहले, कुल बाजार मूल्य, कुल लाभ और इसी तरह के, बिना किसी सूचकांक केःimg
कुल बाजार मूल्य में धीमी गति से वृद्धि हुई है, जो पहले के समय में तेजी से बढ़ी है, और बाद के समय में तेजी से बढ़ी है, लेकिन फिर भी चरणबद्ध नुकसान हुआ है।

अंत में, शेयरों के अनुपात को देखें, चार्ट का बाएं अक्ष शेयरों का अनुपात है, दाएं अक्ष बाजार है, यह प्रारंभिक रूप से निर्धारित किया जा सकता है कि मॉडल ओवरफॉर्मेड है, शुरुआती समय में बैर बाजार में शेयरों की संख्या कम है, बाजार के निचले हिस्से में शेयरों की संख्या बहुत अधिक है। यह भी देखा जा सकता है कि मॉडल ने लंबे समय तक स्टॉक रखने के लिए नहीं सीखा है, हमेशा जल्दी से बेच दिया है।img

8.测试数据分析

परीक्षण डेटा प्राप्त होने के समय 2019/06/27 से आज तक बिटकॉइन का एक घंटे का बाजार। चित्र में देखा जा सकता है कि कीमत शुरू में 13,000 डॉलर से गिरकर आज 9,000 डॉलर से अधिक हो गई है, जो मॉडल के लिए एक बड़ी परीक्षा है।img

सबसे पहले, अंततः सापेक्ष लाभ, खराब प्रदर्शन, लेकिन कोई नुकसान नहीं।img

एक बार फिर से होल्डिंग की स्थिति को देखते हुए, यह अनुमान लगाया जा सकता है कि मॉडल तेजी से गिरने के बाद खरीदने और बेचने के लिए झुकाव रखता है, हाल के समय में बिटकॉइन बाजार में बहुत कम उतार-चढ़ाव है, और मॉडल खाली होल्डिंग की स्थिति में रहा है।img

9.总结

इस आलेख में डीपीओ द्वारा एक बिटकॉइन ऑटो ट्रेडिंग रोबोट को प्रशिक्षित करने के बारे में कुछ निष्कर्ष निकाले गए हैं। समय सीमित होने के कारण, मॉडल में कुछ सुधार करने के लिए भी हैं, आप सभी पर चर्चा करने के लिए स्वागत करते हैं। सबसे बड़ा सबक यह है कि डेटा मानकीकृत करने का तरीका है, स्केलिंग जैसे तरीकों का उपयोग न करें, अन्यथा मॉडल जल्दी से मूल्य और बाजार के संबंधों को याद करता है और फिट में गिर जाता है। परिवर्तन दर मानकीकृत होने के बाद सापेक्ष डेटा है, जिससे मॉडल को परिवर्तन दर और उतार-चढ़ाव के संबंधों को याद रखना मुश्किल हो जाता है, और परिवर्तन दर और उतार-चढ़ाव के संबंधों की तलाश करने के लिए मजबूर किया जाता है।

पिछले लेखों में बताया गया हैः FMZ के आविष्कारकों ने अपने क्वांटिफाइंग प्लेटफॉर्म पर कुछ सार्वजनिक रणनीतियों को साझा किया हैःhttps://zhuanlan.zhihu.com/p/64961672NetEase क्लाउड क्लासेस में डिजिटल मुद्राओं के लिए क्वांटिफाइंग ट्रेडिंग का कोर्स, केवल 20 डॉलर मेंःhttps://study.163.com/course/courseMain.htm?courseId=1006074239&share=2&shareId=400000000602076एक बार जब मैंने एक उच्च आवृत्ति रणनीति का खुलासा किया, तो यह बहुत लाभदायक थीःhttps://www.fmz.com/bbs-topic/1211


संबंधित

अधिक

लिसा20231तो आप अपने परीक्षण के परिणामों की तस्वीरों को ऊपर की ओर क्यों कर रहे हैं? क्यों डॉलर की कीमतें बढ़ने पर आपकी आय हमेशा कम होती है?

जैकमाprofit = self.value - (self.initial_balance+self.initial_stocks * self.df.iloc[self.current_time,4]) बग है यह होना चाहिएः लाभ = self.value - (self.initial_balance + self.initial_stocks * self.df.iloc[self.start,4])

जैकमाprofit = self.value - (self.initial_balance+self.initial_stocks*self.df.iloc[self.current_time,4]) बग है यह होना चाहिएः लाभ = self.value - (self.initial_balance+self.initial_stocks*self.df.iloc[self.start,4])

टिमोशेन्कोपहले संस्करण की तुलना में बहुत मजबूत।

xw2021यह बहुत बड़ा है!

एडीघास के देवता!

घासGPU संस्करण `` device = torch.device (('cuda' if torch.cuda.is_available)) else 'सीपीयू') class PPO ((nn.Module): def __init__ ((self): super ((PPO, self).__init__() self.data = [] .. self.fc1 = nn.Linear ((8,64) self.lstm = nn.LSTM ((64,32) self.fc_pi = nn.Linear ((32,3) self.fc_v = nn.Linear ((32,1) self.optimizer = optim.Adam ((self.parameters))) और lr = learning_rate def pi ((self, x, hidden): x = F.relu ((self.fc1 ((x)) x = x.view ((-1, 1, 64) x, lstm_hidden = self.lstm ((x, hidden)) x = self.fc_pi ((x) prob = F.softmax ((x, dim=2) return prob, lstm_hidden .. def v ((self, x, hidden): x = F.relu ((self.fc1 ((x)) x = x.view ((-1, 1, 64) x, lstm_hidden = self.lstm ((x, hidden) v = self.fc_v ((x) return v .. def put_data ((self, transition): self.data.append (transition) .. def make_batch ((self): s_lst, a_lst, r_lst, s_prime_lst, prob_a_lst, hidden_lst, done_lst = [], [], [], [], [], [], [] self.data में संक्रमण के लिएः s, a, r, s_prime, prob_a, hidden, done = संक्रमण .. s_lst.append ((s) a_lst.append (([a]) r_lst.append (([r]) s_prime_lst.append ((s_prime) prob_a_lst.append (([prob_a]) hidden_lst.append (छिपा हुआ) done_mask = 0 if done else 1 अगर किया गया तो done_lst.append (([done_mask]) .. s,a,r,s_prime,done_mask,prob_a = torch.tensor ((s_lst,dtype=torch.float).to(device),torch.tensor ((a_lst).to(device).to(device), \ torch.tensor ((r_lst).to ((device), torch.tensor ((s_prime_lst, dtype=torch.float).to ((device), \ torch.tensor ((done_lst, dtype=torch.float).to ((device), torch.tensor ((prob_a_lst).to ((device) self.data = [] return s,a,r,s_prime, done_mask, prob_a, hidden_lst[0] .. def train_net ((self): s,a,r,s_prime,done_mask, prob_a, (h1,h2) = self.make_batch))) first_hidden = (h1.to(device).detach(), h2.to(device.detach()) for i in range ((K_epoch): v_prime = self.v ((s_prime, first_hidden).squeeze))) td_target = r + गामा * v_prime * done_mask v_s = self.v(s, first_hidden).squeeze ((1) delta = td_target - v_s डेल्टा = डेल्टा.सीपीयू (().detach (().numpy (()) advantage_lst = [] advantage = 0.0 for item in delta [::-1]: advantage = गामा * lmbda * advantage + item[0] advantage_lst.append (([advantage]) advantage_lst.reverse (() advantage = torch.tensor ((advantage_lst, dtype=torch.float).to ((device)) pi, _ = self. pi ((s, first_hidden) pi_a = pi.squeeze ((1).gather ((1,a) ratio = torch.exp ((torch.log ((pi_a) - torch.log ((prob_a)) # a/b == log ((exp ((a) -exp ((b)) surr1 = अनुपात * लाभ surr2 = torch.clamp ((ratio, 1-eps_clip, 1+eps_clip) * लाभ loss = -torch.min ((surr1, surr2) + F.smooth_l1_loss ((v_s, td_target.detach))) self.optimizer.zero_grad ((() loss.mean (().backward ((retain_graph=True)) self.optimizer.step ((() ``