Hiểu chính sách Gradient


19

Tôi đang cố gắng tạo lại ví dụ rất đơn giản về Gradient chính sách, từ tài nguyên gốc của blog Andrej Karpathy . Trong articale đó, bạn sẽ tìm thấy ví dụ với CartPole và Gradient chính sách với danh sách trọng số và kích hoạt Softmax. Dưới đây là ví dụ được tạo lại và rất đơn giản của tôi về gradient chính sách CartPole, hoạt động hoàn hảo .

import gym
import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import PolynomialFeatures
import copy

NUM_EPISODES = 4000
LEARNING_RATE = 0.000025
GAMMA = 0.99


# noinspection PyMethodMayBeStatic
class Agent:
    def __init__(self):
        self.poly = PolynomialFeatures(1)
        self.w = np.random.rand(5, 2)

    def policy(self, state):
        z = state.dot(self.w)
        exp = np.exp(z)
        return exp/np.sum(exp)

    def __softmax_grad(self, softmax):
        s = softmax.reshape(-1,1)
        return np.diagflat(s) - np.dot(s, s.T)

    def grad(self, probs, action, state):
        dsoftmax = self.__softmax_grad(probs)[action,:]
        dlog = dsoftmax / probs[0,action]
        grad = state.T.dot(dlog[None,:])
        return grad

    def update_with(self, grads, rewards):

        for i in range(len(grads)):
            # Loop through everything that happend in the episode
            # and update towards the log policy gradient times **FUTURE** reward

            total_grad_effect = 0
            for t, r in enumerate(rewards[i:]):
                total_grad_effect += r * (GAMMA ** r)
            self.w += LEARNING_RATE * grads[i] * total_grad_effect
            print("Grads update: " + str(np.sum(grads[i])))



def main(argv):
    env = gym.make('CartPole-v0')
    np.random.seed(1)

    agent = Agent()
    complete_scores = []

    for e in range(NUM_EPISODES):
        state = env.reset()[None, :]
        state = agent.poly.fit_transform(state)

        rewards = []
        grads = []
        score = 0

        while True:

            probs = agent.policy(state)
            action_space = env.action_space.n
            action = np.random.choice(action_space, p=probs[0])

            next_state, reward, done,_ = env.step(action)
            next_state = next_state[None,:]
            next_state = agent.poly.fit_transform(next_state.reshape(1, 4))
            grad = agent.grad(probs, action, state)

            grads.append(grad)
            rewards.append(reward)

            score += reward
            state = next_state

            if done:
                break

        agent.update_with(grads, rewards)
        complete_scores.append(score)

    env.close()
    plt.plot(np.arange(NUM_EPISODES),
             complete_scores)
    plt.savefig('image1.png')


if __name__ == '__main__':
    main(None)

nhập mô tả hình ảnh ở đây

.

.

Câu hỏi

Tôi đang cố gắng thực hiện, gần như cùng một ví dụ nhưng với kích hoạt Sigmoid (chỉ để đơn giản). Đó là tất cả những gì tôi cần làm. Chuyển đổi kích hoạt trong mô hình từ softmaxsang sigmoid. Mà nên làm việc cho chắc chắn (dựa trên giải thích dưới đây). Nhưng mô hình Gradient Chính sách của tôi không học được gì và giữ ngẫu nhiên. Bất cứ đề nghị nào?

import gym
import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import PolynomialFeatures

NUM_EPISODES = 4000
LEARNING_RATE = 0.000025
GAMMA = 0.99


# noinspection PyMethodMayBeStatic
class Agent:
    def __init__(self):
        self.poly = PolynomialFeatures(1)
        self.w = np.random.rand(5, 1) - 0.5

    # Our policy that maps state to action parameterized by w
    # noinspection PyShadowingNames
    def policy(self, state):
        z = np.sum(state.dot(self.w))
        return self.sigmoid(z)

    def sigmoid(self, x):
        s = 1 / (1 + np.exp(-x))
        return s

    def sigmoid_grad(self, sig_x):
        return sig_x * (1 - sig_x)

    def grad(self, probs, action, state):
        dsoftmax = self.sigmoid_grad(probs)
        dlog = dsoftmax / probs
        grad = state.T.dot(dlog)
        grad = grad.reshape(5, 1)
        return grad

    def update_with(self, grads, rewards):
        if len(grads) < 50:
            return
        for i in range(len(grads)):
            # Loop through everything that happened in the episode
            # and update towards the log policy gradient times **FUTURE** reward

            total_grad_effect = 0
            for t, r in enumerate(rewards[i:]):
                total_grad_effect += r * (GAMMA ** r)
            self.w += LEARNING_RATE * grads[i] * total_grad_effect


def main(argv):
    env = gym.make('CartPole-v0')
    np.random.seed(1)

    agent = Agent()
    complete_scores = []

    for e in range(NUM_EPISODES):
        state = env.reset()[None, :]
        state = agent.poly.fit_transform(state)

        rewards = []
        grads = []
        score = 0

        while True:

            probs = agent.policy(state)
            action_space = env.action_space.n
            action = np.random.choice(action_space, p=[1 - probs, probs])

            next_state, reward, done, _ = env.step(action)
            next_state = next_state[None, :]
            next_state = agent.poly.fit_transform(next_state.reshape(1, 4))

            grad = agent.grad(probs, action, state)
            grads.append(grad)
            rewards.append(reward)

            score += reward
            state = next_state

            if done:
                break

        agent.update_with(grads, rewards)
        complete_scores.append(score)

    env.close()
    plt.plot(np.arange(NUM_EPISODES),
             complete_scores)
    plt.savefig('image1.png')


if __name__ == '__main__':
    main(None)

Âm mưu tất cả các học tập giữ ngẫu nhiên. Không có gì giúp điều chỉnh các thông số siêu. Dưới hình ảnh mẫu.

nhập mô tả hình ảnh ở đây

Tài liệu tham khảo :

1) Học tập củng cố sâu: Pông từ Pixels

2) Giới thiệu về sinh viên chính sách với Cartpole và Doom

3) Học sinh chính sách xuất phát và triển khai TÁI TẠO

4) Thủ thuật học máy trong ngày (5): Thủ thuật ghi nhật ký 12


CẬP NHẬT

Có vẻ như câu trả lời dưới đây có thể thực hiện một số công việc từ đồ họa. Nhưng đó không phải là xác suất đăng nhập và thậm chí không phải là độ dốc của chính sách. Và thay đổi toàn bộ mục đích của Chính sách Gradient RL. Vui lòng kiểm tra tài liệu tham khảo ở trên. Theo hình ảnh chúng tôi tuyên bố tiếp theo.

nhập mô tả hình ảnh ở đây

Tôi cần lấy một Gradient của chức năng Nhật ký trong Chính sách của mình (đơn giản là trọng lượng và sigmoidkích hoạt).


4
Tôi đề nghị bạn nên đăng câu hỏi này lên Data Science Stack Exchange vì đây chủ yếu là một câu hỏi lý thuyết (Stack Overflow chủ yếu dành cho các câu hỏi mã hóa). Bạn cũng sẽ tiếp cận được nhiều người có kiến ​​thức hơn trong lĩnh vực này.
Gilles-Philippe Paillé

@ Gilles-PhilippePaillé Tôi đã thêm mã, đại diện cho vấn đề. Những gì tôi cần làm, đó chỉ là sửa một số phần với kích hoạt. Vui lòng kiểm tra câu trả lời cập nhật.
GensaGames

1
Đối với sinh viên chính sách phái sinh, đây là bài viết tham khảo với ví dụ hoạt động cùng loại sắp xếp, Hy vọng bạn sẽ tìm hiểu chi tiết: Medium.com/@thechrisyoon/ Lỗi .
Muhammad Usman

@MuhammadUsman. Cảm ơn thông tin. Tôi đỏ nguồn đó. Ngay bây giờ, ví dụ rõ ràng và mẫu ở trên, tôi đang cố gắng thay đổi kích hoạt từ softmaxsang signmoid. Đó chỉ là một điều tôi cần làm trong ví dụ trên.
GensaGames

2
@JasonChia sigmoid xuất số thực trong phạm vi [0, 1]có thể được hiểu là xác suất của hành động tích cực (ví dụ rẽ phải trong CartPole). Khi đó xác suất của hành động tiêu cực (rẽ trái) là 1 - sigmoid. Tổng xác suất này là 1. Có, đây là môi trường thẻ cực độc.
Pavel Tyshevskyi

Câu trả lời:


8

Vấn đề là với gradphương pháp.

def grad(self, probs, action, state):
    dsoftmax = self.sigmoid_grad(probs)
    dlog = dsoftmax / probs
    grad = state.T.dot(dlog)
    grad = grad.reshape(5, 1)
    return grad

Trong mã ban đầu, Softmax đã được sử dụng cùng với chức năng mất CrossEntropy. Khi bạn chuyển đổi kích hoạt sang Sigmoid, chức năng mất thích hợp sẽ trở thành Binary CrossEntropy. Bây giờ, mục đích của gradphương thức là tính toán độ dốc của hàm mất wrt. trọng lượng. Bỏ qua các chi tiết, độ dốc thích hợp được đưa ra bởi(probs - action) * state thuật ngữ của chương trình của bạn. Điều cuối cùng là thêm dấu trừ - chúng tôi muốn tối đa hóa âm của hàm mất.

gradPhương pháp đúng như vậy:

def grad(self, probs, action, state):
    grad = state.T.dot(probs - action)
    return -grad

Một thay đổi khác mà bạn có thể muốn thêm là tăng tỷ lệ học tập. LEARNING_RATE = 0.0001NUM_EPISODES = 5000sẽ tạo ra cốt truyện sau:

Phần thưởng trung bình đúng so với số tập

Sự hội tụ sẽ nhanh hơn nhiều nếu các trọng số được khởi tạo bằng phân phối Gaussian với giá trị trung bình bằng không và phương sai nhỏ:

def __init__(self):
    self.poly = PolynomialFeatures(1)
    self.w = np.random.randn(5, 1) * 0.01

nhập mô tả hình ảnh ở đây

CẬP NHẬT

Đã thêm mã hoàn chỉnh để tạo lại kết quả:

import gym
import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import PolynomialFeatures

NUM_EPISODES = 5000
LEARNING_RATE = 0.0001
GAMMA = 0.99


# noinspection PyMethodMayBeStatic
class Agent:
    def __init__(self):
        self.poly = PolynomialFeatures(1)
        self.w = np.random.randn(5, 1) * 0.01

    # Our policy that maps state to action parameterized by w
    # noinspection PyShadowingNames
    def policy(self, state):
        z = np.sum(state.dot(self.w))
        return self.sigmoid(z)

    def sigmoid(self, x):
        s = 1 / (1 + np.exp(-x))
        return s

    def sigmoid_grad(self, sig_x):
        return sig_x * (1 - sig_x)

    def grad(self, probs, action, state):
        grad = state.T.dot(probs - action)
        return -grad

    def update_with(self, grads, rewards):
        if len(grads) < 50:
            return
        for i in range(len(grads)):
            # Loop through everything that happened in the episode
            # and update towards the log policy gradient times **FUTURE** reward

            total_grad_effect = 0
            for t, r in enumerate(rewards[i:]):
                total_grad_effect += r * (GAMMA ** r)
            self.w += LEARNING_RATE * grads[i] * total_grad_effect


def main(argv):
    env = gym.make('CartPole-v0')
    np.random.seed(1)

    agent = Agent()
    complete_scores = []

    for e in range(NUM_EPISODES):
        state = env.reset()[None, :]
        state = agent.poly.fit_transform(state)

        rewards = []
        grads = []
        score = 0

        while True:

            probs = agent.policy(state)
            action_space = env.action_space.n
            action = np.random.choice(action_space, p=[1 - probs, probs])

            next_state, reward, done, _ = env.step(action)
            next_state = next_state[None, :]
            next_state = agent.poly.fit_transform(next_state.reshape(1, 4))

            grad = agent.grad(probs, action, state)
            grads.append(grad)
            rewards.append(reward)

            score += reward
            state = next_state

            if done:
                break

        agent.update_with(grads, rewards)
        complete_scores.append(score)

    env.close()
    plt.plot(np.arange(NUM_EPISODES),
             complete_scores)
    plt.savefig('image1.png')


if __name__ == '__main__':
    main(None)

Cảm ơn rât nhiều. Tôi sẽ thử giải pháp này sau.
GensaGames

Tôi không chắc chắn, nơi bạn lấy dẫn xuất như vậy cho chức năng của tôi. Như bạn có thể kiểm tra hình ảnh ở trên. Tôi sẽ cần phải lấy độ dốc của nhật ký của chính sách . Trường hợp chính sách trong trường hợp của tôi chỉ đơn giản là trọng lượng với sigmoid. Nhưng gradient của bạn trong câu trả lời sẽ không có gì để làm với gradient của tôi. Đúng?
GensaGames

Lưu ý rằng bạn không kết hợp bất kỳ thông tin nào về hành động được thực hiện. Theo bài giảng về Grad Grad Chính sách (slide 13) , cập nhật sẽ như thế nào (action - probs) * sigmoid_grad(probs), nhưng tôi đã bỏ qua sigmoid_gradvì vấn đề biến mất với độ dốc sigmoid.
Pavel Tyshevskyi

Mấu chốt ở đây là chỉ ra hướng mà chúng ta muốn thay đổi trọng lượng. Nếu action = 1, chúng tôi muốn probsgần hơn 1, tăng trọng số (độ dốc dương). Nếu action=0, chúng tôi muốn probsgần hơn 0, do đó giảm trọng lượng (độ dốc âm).
Pavel Tyshevskyi

1
Trong mọi trường hợp, những thay đổi ở trên hoàn toàn không hoạt động, bạn có thể chia sẻ toàn bộ tệp không? Đồng thời, tôi muốn làm cho mẫu rõ ràng và không quan tâm đến vấn đề biến mất trong trường hợp này. Và (action - probs)đó chỉ là một cách khác để thay đổi các cuộc chiến tương tự.
GensaGames
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.