Eager Execution, tf.GradientTape возвращает только None

Я пытаюсь рассчитать градиент с помощью tf.GradientTape. Когда я пытаюсь сделать это, используя в качестве входных данных потерю и результат Model.trainable_weights (tf.keras.Model), который возвращает мне массив None. Что я делаю неправильно? Я использую версию тензорного потока 1.13.0.

Реализованный алгоритм представляет собой OnPolicy DQN (не обычный DQN), поэтому я не использую целевую сеть (которая используется в качестве поведенческой сети в обычном коде DQN). Итак, я хотел дифференцировать ошибку, которая определяется как мини-пакет MSE Y (который равен R + gamma * max_a Q (s', a')) и Q (s, a) в приведенном ниже коде.

import gym
import numpy as np
import tensorflow as tf
from collections import deque

# ==== import below from my repo ====
from common.wrappers import MyWrapper   # just a wrapper to set a reward at the terminal state -1
from common.params import Parameters    # params for training
from common.memory import ReplayBuffer  # Experience Replay Buffer

tf.enable_eager_execution()

class Model(tf.keras.Model):
    def __init__(self, num_action):
        super(Model, self).__init__()
        self.dense1 = tf.keras.layers.Dense(16, activation='relu')
        self.dense2 = tf.keras.layers.Dense(16, activation='relu')
        self.dense3 = tf.keras.layers.Dense(16, activation='relu')
        self.pred = tf.keras.layers.Dense(num_action, activation='softmax')

    def call(self, inputs):
        x = self.dense1(inputs)
        x = self.dense2(x)
        x = self.dense3(x)
        pred = self.pred(x)
        return pred


class DQN:
    """
    On policy DQN

    """

    def __init__(self, num_action):
        self.num_action = num_action
        self.model = Model(num_action)
        self.optimizer = tf.train.AdamOptimizer()

    def predict(self, state):
        return self.model(tf.convert_to_tensor(state[None, :], dtype=tf.float32)).numpy()[0]

    def update(self, state, action, target):
        # target: R + gamma * Q(s',a')
        # calculate Q(s,a)
        q_values = self.predict(state)
        actions_one_hot = tf.one_hot(action, self.num_action, 1.0, 0.0)
        action_probs = tf.reduce_sum(actions_one_hot * q_values, reduction_indices=-1)

        # Minibatch MSE => (1/batch_size) * (R + gamma * Q(s',a') - Q(s,a))^2
        loss = tf.reduce_mean(tf.squared_difference(target, action_probs))
        return loss


if __name__ == '__main__':
    reward_buffer = deque(maxlen=5)
    env = MyWrapper(gym.make("CartPole-v0"))
    replay_buffer = ReplayBuffer(5000)
    params = Parameters(mode = "CartPole")
    agent = DQN(env.action_space.n)

    for i in range(2000):
        state = env.reset()

        total_reward = 0
        for t in range(210):
            # env.render()
            action = np.argmax(agent.predict(state)) # behave greedily
            next_state, reward, done, info = env.step(action)
            replay_buffer.add(state, action, reward, next_state, done)

            total_reward += reward
            state = next_state

            if done:
                print("Episode {0} finished after {1} timesteps".format(i, t + 1))

                if i > 10:
                    print("Update")
                    with tf.GradientTape() as tape:
                        states, actions, rewards, next_states, dones = replay_buffer.sample(params.batch_size)
                        next_Q = agent.predict(next_states)
                        Y = rewards + params.gamma * np.max(next_Q, axis=1) * np.logical_not(dones)
                        loss = agent.update(states, actions, Y)
                        print(loss)

                    grads = tape.gradient(loss, agent.model.trainable_weights)

                    # ==== THIS RETURNS ONLY NONE ====
                    print(grads)
                    agent.optimizer.apply_gradients(zip(grads, agent.model.trainable_weights))
                break

        # store the episode reward
        reward_buffer.append(total_reward)

        # check the stopping condition
        if np.mean(reward_buffer) > 195:
            print("GAME OVER!!")
            break

    env.close()
import gym
import numpy as np
import tensorflow as tf
from collections import deque

# ==== import below from my repo ====
from common.wrappers import MyWrapper   # just a wrapper to set a reward at the terminal state -1
from common.params import Parameters    # params for training
from common.memory import ReplayBuffer  # Experience Replay Buffer

tf.enable_eager_execution()

class Model(tf.keras.Model):
    def __init__(self, num_action):
        super(Model, self).__init__()
        self.dense1 = tf.keras.layers.Dense(16, activation='relu')
        self.dense2 = tf.keras.layers.Dense(16, activation='relu')
        self.dense3 = tf.keras.layers.Dense(16, activation='relu')
        self.pred = tf.keras.layers.Dense(num_action, activation='softmax')

    def call(self, inputs):
        x = self.dense1(inputs)
        x = self.dense2(x)
        x = self.dense3(x)
        pred = self.pred(x)
        return pred


class DQN:
    """
    On policy DQN

    """

    def __init__(self, num_action):
        self.num_action = num_action
        self.model = Model(num_action)
        self.optimizer = tf.train.AdamOptimizer()

    def predict(self, state):
        return self.model(tf.convert_to_tensor(state[None, :], dtype=tf.float32)).numpy()[0]

    def update(self, state, action, target):
        # target: R + gamma * Q(s',a')
        # calculate Q(s,a)
        q_values = self.predict(state)
        actions_one_hot = tf.one_hot(action, self.num_action, 1.0, 0.0)
        action_probs = tf.reduce_sum(actions_one_hot * q_values, reduction_indices=-1)

        # Minibatch MSE => (1/batch_size) * (R + gamma * Q(s',a') - Q(s,a))^2
        loss = tf.reduce_mean(tf.squared_difference(target, action_probs))
        return loss


if __name__ == '__main__':
    reward_buffer = deque(maxlen=5)
    env = MyWrapper(gym.make("CartPole-v0"))
    replay_buffer = ReplayBuffer(5000)
    params = Parameters(mode = "CartPole")
    agent = DQN(env.action_space.n)

    for i in range(2000):
        state = env.reset()

        total_reward = 0
        for t in range(210):
            # env.render()
            action = np.argmax(agent.predict(state)) # behave greedily
            next_state, reward, done, info = env.step(action)
            replay_buffer.add(state, action, reward, next_state, done)

            total_reward += reward
            state = next_state

            if done:
                print("Episode {0} finished after {1} timesteps".format(i, t + 1))

                if i > 10:
                    print("Update")
                    with tf.GradientTape() as tape:
                        states, actions, rewards, next_states, dones = replay_buffer.sample(params.batch_size)
                        next_Q = agent.predict(next_states)
                        Y = rewards + params.gamma * np.max(next_Q, axis=1) * np.logical_not(dones)
                        loss = agent.update(states, actions, Y)
                        print(loss)

                    grads = tape.gradient(loss, agent.model.trainable_weights)

                    # ==== THIS RETURNS ONLY NONE ====
                    print(grads)
                    agent.optimizer.apply_gradients(zip(grads, agent.model.trainable_weights))
                break

        # store the episode reward
        reward_buffer.append(total_reward)

        # check the stopping condition
        if np.mean(reward_buffer) > 195:
            print("GAME OVER!!")
            break

    env.close()
import gym
import numpy as np
import tensorflow as tf
from collections import deque

# ==== import below from my repo ====
from common.wrappers import MyWrapper   # just a wrapper to set a reward at the terminal state -1
from common.params import Parameters    # params for training
from common.memory import ReplayBuffer  # Experience Replay Buffer

tf.enable_eager_execution()

class Model(tf.keras.Model):
    def __init__(self, num_action):
        super(Model, self).__init__()
        self.dense1 = tf.keras.layers.Dense(16, activation='relu')
        self.dense2 = tf.keras.layers.Dense(16, activation='relu')
        self.dense3 = tf.keras.layers.Dense(16, activation='relu')
        self.pred = tf.keras.layers.Dense(num_action, activation='softmax')

    def call(self, inputs):
        x = self.dense1(inputs)
        x = self.dense2(x)
        x = self.dense3(x)
        pred = self.pred(x)
        return pred


class DQN:
    """
    On policy DQN

    """

    def __init__(self, num_action):
        self.num_action = num_action
        self.model = Model(num_action)
        self.optimizer = tf.train.AdamOptimizer()

    def predict(self, state):
        return self.model(tf.convert_to_tensor(state[None, :], dtype=tf.float32)).numpy()[0]

    def update(self, state, action, target):
        # target: R + gamma * Q(s',a')
        # calculate Q(s,a)
        q_values = self.predict(state)
        actions_one_hot = tf.one_hot(action, self.num_action, 1.0, 0.0)
        action_probs = tf.reduce_sum(actions_one_hot * q_values, reduction_indices=-1)

        # Minibatch MSE => (1/batch_size) * (R + gamma * Q(s',a') - Q(s,a))^2
        loss = tf.reduce_mean(tf.squared_difference(target, action_probs))
        return loss


if __name__ == '__main__':
    reward_buffer = deque(maxlen=5)
    env = MyWrapper(gym.make("CartPole-v0"))
    replay_buffer = ReplayBuffer(5000)
    params = Parameters(mode = "CartPole")
    agent = DQN(env.action_space.n)

    for i in range(2000):
        state = env.reset()

        total_reward = 0
        for t in range(210):
            # env.render()
            action = np.argmax(agent.predict(state)) # behave greedily
            next_state, reward, done, info = env.step(action)
            replay_buffer.add(state, action, reward, next_state, done)

            total_reward += reward
            state = next_state

            if done:
                print("Episode {0} finished after {1} timesteps".format(i, t + 1))

                if i > 10:
                    print("Update")
                    with tf.GradientTape() as tape:
                        states, actions, rewards, next_states, dones = replay_buffer.sample(params.batch_size)
                        next_Q = agent.predict(next_states)
                        Y = rewards + params.gamma * np.max(next_Q, axis=1) * np.logical_not(dones)
                        loss = agent.update(states, actions, Y)
                        print(loss)

                    grads = tape.gradient(loss, agent.model.trainable_weights)

                    # ==== THIS RETURNS ONLY NONE ====
                    print(grads)
                    agent.optimizer.apply_gradients(zip(grads, agent.model.trainable_weights))
                break

        # store the episode reward
        reward_buffer.append(total_reward)

        # check the stopping condition
        if np.mean(reward_buffer) > 195:
            print("GAME OVER!!")
            break

    env.close()
import gym
import numpy as np
import tensorflow as tf
from collections import deque

# ==== import below from my repo ====
from common.wrappers import MyWrapper   # just a wrapper to set a reward at the terminal state -1
from common.params import Parameters    # params for training
from common.memory import ReplayBuffer  # Experience Replay Buffer

tf.enable_eager_execution()

class Model(tf.keras.Model):
    def __init__(self, num_action):
        super(Model, self).__init__()
        self.dense1 = tf.keras.layers.Dense(16, activation='relu')
        self.dense2 = tf.keras.layers.Dense(16, activation='relu')
        self.dense3 = tf.keras.layers.Dense(16, activation='relu')
        self.pred = tf.keras.layers.Dense(num_action, activation='softmax')

    def call(self, inputs):
        x = self.dense1(inputs)
        x = self.dense2(x)
        x = self.dense3(x)
        pred = self.pred(x)
        return pred


class DQN:
    """
    On policy DQN

    """

    def __init__(self, num_action):
        self.num_action = num_action
        self.model = Model(num_action)
        self.optimizer = tf.train.AdamOptimizer()

    def predict(self, state):
        return self.model(tf.convert_to_tensor(state[None, :], dtype=tf.float32)).numpy()[0]

    def update(self, state, action, target):
        # target: R + gamma * Q(s',a')
        # calculate Q(s,a)
        q_values = self.predict(state)
        actions_one_hot = tf.one_hot(action, self.num_action, 1.0, 0.0)
        action_probs = tf.reduce_sum(actions_one_hot * q_values, reduction_indices=-1)

        # Minibatch MSE => (1/batch_size) * (R + gamma * Q(s',a') - Q(s,a))^2
        loss = tf.reduce_mean(tf.squared_difference(target, action_probs))
        return loss


if __name__ == '__main__':
    reward_buffer = deque(maxlen=5)
    env = MyWrapper(gym.make("CartPole-v0"))
    replay_buffer = ReplayBuffer(5000)
    params = Parameters(mode = "CartPole")
    agent = DQN(env.action_space.n)

    for i in range(2000):
        state = env.reset()

        total_reward = 0
        for t in range(210):
            # env.render()
            action = np.argmax(agent.predict(state)) # behave greedily
            next_state, reward, done, info = env.step(action)
            replay_buffer.add(state, action, reward, next_state, done)

            total_reward += reward
            state = next_state

            if done:
                print("Episode {0} finished after {1} timesteps".format(i, t + 1))

                if i > 10:
                    print("Update")
                    with tf.GradientTape() as tape:
                        states, actions, rewards, next_states, dones = replay_buffer.sample(params.batch_size)
                        next_Q = agent.predict(next_states)
                        Y = rewards + params.gamma * np.max(next_Q, axis=1) * np.logical_not(dones)
                        loss = agent.update(states, actions, Y)
                        print(loss)

                    grads = tape.gradient(loss, agent.model.trainable_weights)

                    # ==== THIS RETURNS ONLY NONE ====
                    print(grads)
                    agent.optimizer.apply_gradients(zip(grads, agent.model.trainable_weights))
                break

        # store the episode reward
        reward_buffer.append(total_reward)

        # check the stopping condition
        if np.mean(reward_buffer) > 195:
            print("GAME OVER!!")
            break

    env.close()

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
0
1 192
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Попробуйте изменить функцию обновления на:

def update(self, state, action, target):
        # target: R + gamma * Q(s',a')
        # calculate Q(s,a)
        q_values = self.model(tf.convert_to_tensor(state[None, :], dtype=tf.float32))
        actions_one_hot = tf.one_hot(action, self.num_action, 1.0, 0.0)
        action_probs = tf.reduce_sum(actions_one_hot * q_values, reduction_indices=-1)

        # Minibatch MSE => (1/batch_size) * (R + gamma * Q(s',a') - Q(s,a))^2
        loss = tf.reduce_mean(tf.squared_difference(target, action_probs))
        return loss

Я думаю, что с вызовом .numpy() в функции прогнозирования лента теряет ссылку на веса. (я не проверял свой ответ)

Теперь я протестировал функцию обновления с моими изменениями, и это работает для меня. Я думаю, что с вызовом .numpy() сеть теряет ссылку на веса.

tk338 29.04.2019 17:04

Большое спасибо!! честно говоря, это было решено немного раньше... но я очень ценю ваше расследование и ответ!!

Rowing0914 30.04.2019 11:33

Вы решили это так же? Если да, можете ли вы отметить мой ответ?

tk338 30.04.2019 16:48

Другие вопросы по теме

Ошибка при обучении нейросети с помощью TensorFlow
Tensorflow: сигмовидная перекрестная потеря энтропии не заставляет сетевые выходы быть равными 0 или 1
Tensorflow: невозможно поделиться плотной/ядрой - ValueError: попытка поделиться переменной плотной/ядром, но указанная форма (100, 160) и найденная форма (9, 100)
Установка Tensorflow зависает на 100%
Как исправить ошибку «импортировать тензорный поток как tf» в Windows при использовании ноутбука Jupyter
Как применить один полносвязный слой к каждой точке изображения
Tensorflow: подсчитайте количество примеров в файле TFRecord — без использования устаревшего `tf.python_io.tf_record_iterator`
Почему эта ошибка: Неизвестная функция потери: DSSIMObjective возникает после добавления пользовательской функции потери?
TensorFlow не может передать значение формы (538, 1) для тензора «Placeholder_21: 0», который имеет форму «(?, 8)»?
Как использовать tf.gather в пакетном режиме?