簡體   English   中英

Pytorch修改的DQN算法錯誤“未實現''的導數”

[英]Pytorch modified DQN algorithm error “the derivative for ' ' is not implemented”

我正在嘗試構建新的觀察並將其應用於DQN。 我在觀察代碼中使用pytorch DQN算法。 尚未完成,因此數據尚不清楚。

我在整個代碼中更改了以下幾行。

import sys, math
import random as rd
import numpy as np
import matplotlib
import matplotlib.pyplot as plt

######################################
from collections import namedtuple
from itertools import count
from PIL import Image

import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
from torch.autograd import Variable
import torchvision.transforms as T


Transition = namedtuple('Transition',
                    ('state', 'action', 'next_state', 'reward'))

class ReplayMemory(object):

def __init__(self, capacity):
    self.capacity = capacity
    self.memory = []
    self.position = 0

def push(self, *args):
    """Saves a transition."""
    if len(self.memory) < self.capacity:
        self.memory.append(None)
    self.memory[self.position] = Transition(*args)
    self.position = (self.position + 1) % self.capacity

def sample(self, batch_size):
    return rd.sample(self.memory, batch_size)

def __len__(self):
    return len(self.memory)


class DQN(nn.Module):

def __init__(self):
    super(DQN, self).__init__()
    self.l1 = nn.Linear(5, 16)
    self.l2 = nn.Linear(16, 12)
    self.l3 = nn.Linear(12, 20)
    self.head = nn.Linear(20, 1)
def forward(self, x):
    x = F.relu(self.l1(x))
    x = F.relu(self.l2(x))
    x = F.relu(self.l3(x))
    return self.head(x.view(x.size(0), -1))

BATCH_SIZE = 5
GAMMA = 0.999
EPS_START = 0.9
EPS_END = 0.05
EPS_DECAY = 200
TARGET_UPDATE = 5
policy_net = DQN()
target_net = DQN()
target_net.load_state_dict(policy_net.state_dict())
target_net.eval()

optimizer = optim.RMSprop(policy_net.parameters())
memory = ReplayMemory(10000)

def optimize_model():
if len(memory) < BATCH_SIZE:
    return
transitions = memory.sample(BATCH_SIZE)
# Transpose the batch (see http://stackoverflow.com/a/19343/3343043 for
# detailed explanation).
batch = Transition(*zip(*transitions))
print("batch = ", batch, "\n")
# Compute a mask of non-final states and concatenate the batch elements


state_batch = Variable(torch.cat(batch.state))
print("state_batch = ", state_batch)
action_batch = Variable(torch.cat(batch.action))
print("action_batch = ", action_batch)
reward_batch = Variable(torch.cat(batch.reward), requires_grad = False)
print("reward_batch = ", reward_batch)
next_state_batch = Variable(torch.cat(batch.next_state), requires_grad = False)

# Compute Q(s_t, a) - the model computes Q(s_t), then we select the
# columns of actions taken
state_action_values = policy_net(state_batch)
print("state_action_values = ", state_action_values)

# Compute V(s_{t+1}) for all next states.
next_state_values = target_net(next_state_batch)
print("next_state_values = ", next_state_values)

# Compute the expected Q values
expected_state_action_values = (next_state_values * GAMMA) + reward_batch
print("expected next state values = ", expected_state_action_values)

# Compute Huber loss
loss = F.smooth_l1_loss(state_action_values, expected_state_action_values, reduce = False)

# Optimize the model
optimizer.zero_grad()
loss.backward()
for param in policy_net.parameters():
    param.grad.data.clamp_(-1, 1)
optimizer.step()



num_episodes = 5
for i_episode in range(num_episodes):
    # Initialize the environment and state
    drive = AutoDrive(20, 20, 0, 16, 0) # x/y/yaw/velocity/heading
    drive._make_observation(0, -1, -1, -1, -1, -1) random other vehicle     location, parameters

    stand = 3

    # exploit 1
    e = 1. / ((i_episode // 100) + 1) # conditioon for choosing action
    optimizer.zero_grad()

    for t in range(stand):
        # Select and perform an action

#         exploit 2
        if np.random.rand(1) > e:
            action = rd.randint(1, 4)
        else:
            action = np.argmax(drive._select_action(0.5, 0.5)) + 1 #index + 1
        print("state = ", drive.state, ", action = ", action, ", yaw = ",     drive.yaw, ", mag = ", drive.mag)
    state = drive.state
    drive._step(action)
    drive._calc_reward(0.5, 0.5)
    print(drive.reward)
    if (drive.reward == -10):
        break


    # Store the transition in memory
    state1 = torch.FloatTensor(state).view(1, 5)
    state2 = torch.FloatTensor(drive.state).view(1, 5)
    action = torch.FloatTensor([float(action)]).view(1, 1)
    reward = torch.FloatTensor([drive.reward]).view(1, 1)
    memory.push(state1, action\
                , state2, reward)

    # Perform one step of the optimization (on the target network)
    optimize_model()
    if done:
        episode_durations.append(t + 1)
        plot_durations()
        break
# Update the target network
if i_episode % TARGET_UPDATE == 0:
    target_net.load_state_dict(policy_net.state_dict())

錯誤發生在損失函數中

  File "<ipython-input-190-29dcdbbf0383>", line 1, in <module>
    runfile('C:/Users/desktop/.spyder-py3/temp.py',     wdir='C:/Users/desktop/.spyder-py3')

  File "C:\ProgramData\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 705, in runfile
execfile(filename, namespace)

  File "C:\ProgramData\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 102, in execfile
exec(compile(f.read(), filename, 'exec'), namespace)

  File "C:/Users/desktop/.spyder-py3/temp.py", line 441, in <module>
optimize_model()

  File "C:/Users/desktop/.spyder-py3/temp.py", line 362, in optimize_model
loss = F.smooth_l1_loss(state_action_values, expected_state_action_values, reduce = False)

RuntimeError: the derivative for 'target' is not implemented

函數中的輸入如下。

expected next state values =  Variable containing:
  8.9615
 12.0198
 12.0488
 12.2920
 13.9062
[torch.FloatTensor of size 5x1]

state_action_values =  Variable containing:
 0.3765
 0.5196
 0.4587
 0.3765
 0.5636
[torch.FloatTensor of size 5x1]

我該怎么辦? 我真的是初學者,歡迎提供有用的建議

可能是因為您試圖通過調用.eval()的網絡進行反向傳播。 相反,將目標變量與其計算圖分離:

loss = F.smooth_l1_loss(state_action_values, expected_state_action_values.detach(), reduce = False)

現在,當您對丟失調用.backward()時,PyTorch將不會嘗試使用目標網絡參數來計算派生類。

看一下損失函數smooth_l1_loss(input, target) ,第二個參數target應該是一個沒有梯度的張量。 target.requires_grad應該為False。

Expected_state_action_values =(next_state_values * GAMMA)+獎勵批次

我可以看到你的expected_state_action_values被計算next_state_values在你的代碼。 但是next_state_values = target_net(next_state_batch) ,所以expected_state_action_values具有grad屬性,因為next_state_values具有grad屬性。 所以你應該:

loss = F.smooth_l1_loss(state_action_values, expected_state_action_values.detach(), reduce = False)

要么:

loss = F.smooth_l1_loss(state_action_values, expected_state_action_values.data, reduce = False)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM