작가 : 함원
요약
"심층 강화 학습으로 Atari 플레이"는 강화 학습과 딥 러닝을 결합한 최초의 고전적인 심층 강화 학습 논문으로 DeepMind 팀이 설계하고 개발했으며, 알고리즘은 Atari 2600 게임 환경에서 테스트되었습니다. 일부 게임은 휴먼 플레이어보다 나았습니다.
논문 URL: https://paperswithcode.com/paper/playing-atari-with-deep-reinforcement
01
Pycharm으로 가상 환경 프로젝트 만들기
프로젝트 코드 및 교육 결과는 Baidu Netdisk에 업로드되어 있으며 먼저 다운로드할 수 있습니다. 그러나 가상 환경이 너무 크기 때문에 직접 다운로드하여 설치해야 합니다. 아래에.
링크: https://pan.baidu.com/s/1zoh0glqH4xcNSbOUuR2r7g?pwd=00wd
추출 코드: 00wd
먼저 Pycharm을 사용하여 새 프로젝트를 생성한 후 아래와 같이 설정에 가상 환경을 추가합니다.
가상 환경 프로젝트를 생성하는 목적은 현재 프로젝트의 실행 환경을 자체 Python 환경과 분리하는 것입니다. 그런 다음 이전 Python 환경에 영향을 미치지 않도록 가상 환경에 필요한 패키지를 설치합니다. 제가 사용하는 Pycharm 버전은 2019 버전입니다. Pycharm 새 버전의 설정도 각자의 상황에 맞춰서 하시면 됩니다. 모든 사람의 Anaconda 경로는 다르므로 설치 위치에 따라 기본 인터프리터를 선택해야 합니다.
가상 환경 구성에 대해서는 CSDN 문서: Pycharm이 가상 환경을 생성하고 관리함을 참조하십시오.
가상 환경이 생성된 후에도 설정에서 터미널 프로그램을 설정해야 합니다.
이때 Pycharm에서 터미널 탭을 열면 터미널 앞에 프롬프트(venv)가 보이는데, 이는 현재 터미널이 가상 환경에 있음을 나타냅니다.
이때 필요한 모든 패키지는 이 터미널에서 pip를 통해 설치할 수 있습니다.
Baidu Cloud에서 다운로드한 세 개의 폴더 코드, Imgs 및 모델을 현재 프로젝트 폴더에 복사하는 것을 잊지 마세요. 프로젝트에 필요한 Python 패키지는 코드 폴더 아래의 요구 사항.tx 파일에 이미 포함되어 있습니다 . Pycharm의 터미널 탭을 열고 cd 명령을 통해 코드 폴더를 입력하세요.
cd code
그런 다음 pip는 필요한 패키지를 설치합니다.
pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
일반적으로 위의 환경을 구성한 후에는 코드 폴더에 있는 코드가 정상적으로 실행될 수 있어야 합니다. 정상적으로 실행되지 않으면 Atari의 게임 환경에 문제가 있을 수 있습니다. 자세한 내용은 CSDN 문서: [gym] 새 버전 설치(0.21 이상) 및 Atari 환경 구성, 매우 간단함(Windows)을 참조하세요.
02
종이 모델 설명
간단히 말하면 , 이 논문은 84X84로 잘린 게임 이미지의 연속 4프레임을 4X84X84 입력으로 쌓은 다음 convolution + ReLU, convolution + ReLU, Flatten, full 연결 + ReLU 및 full 연결을 사용하는 DQN 네트워크를 설계합니다. 행동 차원에 해당하는 출력. 여기서는 주로 BreakOut(핀볼 및 블록) 게임을 훈련하고 테스트합니다. 이 게임에 해당하는 동작 유형은 4가지이므로 출력 차원은 4입니다.
출력된 4차원 배열은 각각 4개의 동작에 해당하는 Q(s,a) 값을 나타냅니다. 가장 큰 Q 값에 해당하는 숫자가 네트워크에서 출력되는 동작 코드로 선택됩니다.
0: 움직임이 없음을 의미
1: 게임 시작을 나타냅니다(게임이 이미 시작된 경우 1은 여전히 움직이지 않습니다).
2: 오른쪽 이동을 나타냅니다.
3: 왼쪽 시프트를 나타냅니다.
컨볼루션 크기 계산:
출력 크기 = (입력 크기 - 컨볼루션 커널 크기 + 2 x 패딩) / 스트라이드 + 1
위의 DQN 네트워크를 에이전트 에이전트로 사용하면 에이전트와 게임 환경 간의 상호 작용이 실현될 수 있습니다. 네트워크는 현재 관찰을 기반으로 작업을 생성
하고 하단의 슬라이더를 제어하며 환경의 변화가 새로운 관찰을 생성합니다
. 슬라이더가 성공적으로 공을 움직여 위의 블록을 칩니다. 각 블록에 대해 보상 = 1을 받게 되며, 그렇지 않으면 보상 = 0이 없습니다.
다음으로 해결해야 할 문제는 강화 학습 알고리즘이 에이전트와 환경 간의 상호 작용을 통해 에이전트의 DQN 네트워크 매개 변수를 지속적으로 업데이트하여 에이전트가 게임을 학습하도록 하는 방법입니다.
강화학습 알고리즘은 에이전트와 환경 간의 상호작용 경험을 저장하고 논문의 작성 방법에 따라 일련의 경험 튜플(현재 관찰, 행동, 다음 관찰, 보상, 종료 표시)을 얻을 수 있습니다. 다음과 같이 표현될 수 있습니다:
우리는 경험 튜플의 현재 관찰을 네트워크에 입력하고, 네트워크의 출력은 현재 관찰에서 취한 4가지 행동의 값에 해당하는 4차원 배열입니다. 경험 튜플에서 현재 관찰이 취한 실제 행동에 따르면 ,
이 배열에서 현재 관찰이
취한 행동
에 해당하는 값을 얻을 수 있습니다
. 이 값은 분명히 네트워크의 현재 매개변수 θ와 관련이 있습니다.
실제로 강화학습의 기반이 되는 Bellman 방정식에 따르면, 행동을 취한 후 얻은 보상을 통해 현재 값
과 해당 다음 관찰의 기대 값도 추정할 수 있습니다.
게임 종료 상황의 경우 행동을 취한 후 얻는 보상만 있고 다음 관찰은 없으므로 현재 가치 추정이 보상입니다.
게임이 끝나지 않은 상황의 경우 현재 가치 추정에는 획득한 보상에 다음 관찰에서 수행된 4가지 조치 중 가장 큰 추정 값에 할인 계수 γ를 곱한 값이 포함됩니다. 후속 값 사이의 연결이 닫혀 있습니까? 0이면 현재 값은 현재 보상에만 의존한다는 의미입니다. γ가 클수록 연결이 더 가까워집니다.
이제 우리는:
DQN 네트워크를 사용하여 얻은 현재 관찰에 의해 수행된 조치
에 해당하는 추정값입니다
.
현재 값은 보상과 다음 관찰의 최대 추정 값에 할인 요소를 곱하여 추정됩니다 . Bellman 방정식에 따르면 두 추정치는 동일해야 하지만 네트워크의 값 추정이 정확하지 않기 때문에 두 추정치 간에 차이가 있습니다.
네트워크 훈련을 위한 심층 강화 학습 알고리즘의 목표는 두 추정치의 차이를 줄여 DQN 네트워크 전략이 벨만 방정식을 만족시켜 DQN 네트워크가 이 게임의 최적 전략을 학습할 수 있도록 하는 것입니다. 에이전트 DQN 네트워크가 환경과 상호 작용하는 과정에서 위의 목적은 저장된 경험 튜플을 사용하여 위의 손실을 계산한 다음 경사하강법을 사용하여 DQN 네트워크의 매개변수를 업데이트함으로써 달성할 수 있습니다.
다음은 Python 환경에서 MindSpore 프레임워크를 사용하여 구체적인 코드 구현을 제공하고 해당 설명을 제공합니다.
03
Shengsi MindSpore 코드 구현
코드 폴더에 있는 Playing_atari.py 파일을 엽니다. 코드의 구체적인 의미는 다음과 같습니다.
3.1 게임 환경 조성
해당 라이브러리를 가져온 후 먼저 게임 환경 환경을 만듭니다.
env = gym.make("BreakoutNoFrameskip-v4") # 游戏环境
env = gym.wrappers.RecordEpisodeStatistics(env)
env = gym.wrappers.ResizeObservation(env, (84, 84)) # 设置图片放缩
env = gym.wrappers.GrayScaleObservation(env) # 设置图片为灰度图
env = gym.wrappers.FrameStack(env, 4) # 4帧图片堆叠在一起作为一个观测
env = MaxAndSkipEnv(env, skip=4) # 跳帧,一个动作维持4帧
환경은 여기에 캡슐화되었으며
env
출력 이미지는 전처리되었습니다. 각 관찰 출력은 4X84X84 누적 회색조 이미지입니다.
3.2 DQN 네트워크 정의
Sengsi MindSpore를 사용하여 DQN 네트워크를 정의하고 nn.SequentialCell()을 직접 사용하여 설계된 네트워크에 따라 정의합니다.
class DQN(nn.Cell):
def __init__(self, nb_actions):
super().__init__()
self.network = nn.SequentialCell(
nn.Conv2d(in_channels=4, out_channels=16, kernel_size=8, stride=4, pad_mode='valid'),
nn.ReLU(),
nn.Conv2d(in_channels=16, out_channels=32, kernel_size=4, stride=2, pad_mode='valid'),
nn.ReLU(),
nn.Flatten(),
nn.Dense(in_channels=2592, out_channels=256),
nn.ReLU(),
nn.Dense(in_channels=256, out_channels=nb_actions),
)
def construct(self, x):
return self.network(x / 255.)
constructor()는 Pytorch 프레임워크의forward()와 유사하게 네트워크의 출력을 나타냅니다.
3.3 디자인 경험 저장 풀
class ReplayBuffer():
def __init__(self, replay_memory_size):
def add(self, obs, next_obs, action, reward, done):
def sample(self, sample_num):
...
return Tensor(temp_obs, ms.float32), Tensor(temp_next_obs, ms.float32), Tensor(temp_action, ms.int32), Tensor(temp_reward, ms.float32), Tensor(temp_done, ms.float32)
특정 코드는 여기에 게시되지 않습니다. 간단히 말해서, 경험 튜플 저장과 배치 샘플링을 실현하여 후속 신경망 훈련을 용이하게 합니다.
3.4 손실함수, 옵티마이저, 훈련함수의 정의
먼저 정의된 DQN 클래스에 대한 네트워크를 인스턴스화한
q_network
다음 최적화 프로그램을 다음과 같이 정의하고nn.Adam
손실 함수를 다음과 같이 정의합니다.nn.HuberLOss()
q_network = DQN(nb_actions=env.action_space.n) # 网络实例化
optimizer = nn.Adam(params=q_network.trainable_params(), learning_rate=1.25e-4) # 优化器
loss_fn = nn.HuberLoss() # 损失函数
다음은 기능적 자동 차별화라고 불리는 네트워크 훈련을 정의할 때 MindSpore만의 고유한 단계입니다. 공식 웹사이트에서 기능적 자동 차별화에 대한 튜토리얼을 참조할 수 있습니다 . 구체적으로 먼저 손실 계산 함수를 정의한 forward_fn
다음 손실 계산 함수를 기반으로 기울기 계산 함수를 생성한 grad_fn
다음 기울기 계산 함수를 사용하여 네트워크 훈련의 한 단계에 대한 함수를 정의합니다 train_step
. 이런 식으로 train_step
함수를 사용하면 필요한 데이터만 입력하면 되며, 네트워크 매개변수를 한 번 업데이트하고 원스텝 훈련을 완료할 수 있습니다.
# 损失值计算函数
def forward_fn(observations, actions, y):
current_q_value = q_network(observations).gather_elements(dim=1, index=actions).squeeze() # 把经验对中这个动作对应的q_value给提取出来
loss = loss_fn(current_q_value, y)
return loss
함수 에서
forward_fn
추정값 계산이 완료됩니다. 코드에서
current_q_value
DQN 네트워크는 이 함수의 Q 값을 계산해야 하며 이 계산 프로세스에서 손실의 후속 기울기가 DQN 네트워크 매개변수로 역전파됩니다. . 신경망 업데이트.
y
함수의 입력은함수 외부에서 계산된 후에 입력됩니다. 왜냐하면
about의 계산에도 DQN 네트워크가 필요하고 Loss의 기울기가
about의 계산 프로세스로 역전파되어서는 안 되기 때문입니다. 그렇지 않으면 네트워크 매개변수 가 업데이트되지 않습니다. 따라서
에 대한 계산은 함수 외부에서 계산하여 에 입력해야 합니다
forward_fn
.
# 损失梯度函数
grad_fn = ms.ops.value_and_grad(forward_fn, None, optimizer.parameters)
# 参考:https://www.mindspore.cn/tutorials/zh-CN/r2.1/beginner/autograd.html
# 训练一步的函数
def train_step(observations, actions, y):
loss, grads = grad_fn(observations, actions, y)
optimizer(grads)
return loss
ms.ops.value_and_grad
정의된 손실 계산 함수를 사용하면forward_fn
기울기 계산 함수 grad_fn이 반환될 수 있습니다.그런 다음 훈련 함수에서 기울기를 계산한 다음 최적화 프로그램을 사용하여
train_step
기울기 역전파를 수행하고 네트워크 매개변수를 업데이트하고 1단계 훈련을 완료할 수 있습니다.grad_fn
optimizer
3.4 네트워크 훈련
다음으로 네트워크를 훈련할 수 있습니다. 주요 키 코드에 대한 설명은 다음과 같습니다.
def Deep_Q_Learning(env, replay_memory_size=100_000, nb_epochs=40000_000, update_frequency=4, batch_size=32,
discount_factor=0.99, replay_start_size=5000, initial_exploration=1, final_exploration=0.01,
exploration_steps=100_000):
먼저 경험 풀 용량 크기 100_000, 총 훈련 epoch = 40000_000, 네트워크 매개 변수는 4 epoch마다 업데이트되고 할인 계수는 0.99이며 경험 풀이 5000이 가득 차면 훈련이 시작되는 등 훈련에 필요한 관련 매개 변수를 정의합니다. , 초기 탐사 확률은 1입니다. 총 탐사 에포크는 100_000입니다.
여기서 탐색은 DQN이 더 나은 전략을 학습하기 위해 훈련 전에 탐색을 위한 작업을 무작위로 생성하고 탐색 확률이 점차 감소하며 이 전략을 ε-탐욕이라고 합니다. 전략.
훈련하기 전에 네트워크를 훈련 모드로 설정하십시오.
q_network.set_train() # 设置网络为训练模式
그런 다음 DQN이 게임과 상호 작용하도록 하고 작업을 생성하는 해당 코드는 다음과 같습니다(DQN에서 생성된 작업 또는 무작위 탐색).
if random.random() < epsilon: # With probability ε select a random action a
action = np.array(env.action_space.sample())
else: # Otherwise select a = max_a Q∗(φ(st), a; θ)
temp_input = Tensor(obs, ms.float32).unsqueeze(0)
q_values = q_network(temp_input)
action = q_values.argmax(axis=1).item().asnumpy()
각 경험 튜플을 경험 풀에 저장합니다.
rb.add(obs, real_next_obs, action, reward, done)
경험 풀에서 경험 튜플 배치를 선택하고, 값을 계산하고,
train_step
기능을 사용하여 네트워크 매개변수를 업데이트합니다.
data_obs, data_next_obs, data_action, data_reward, data_done = rb.sample(batch_size)
# 这一部分不用求梯度,所以写在forward_fn和train_step函数之外
max_q_value = q_network(data_next_obs).max(1)
y = data_reward.flatten() + discount_factor * max_q_value * (1 - data_done.flatten())
loss = train_step(data_obs, data_action, y)
계산 프로세스에 그래디언트 역전파가 필요하지 않기 때문에 여기서 계산된다는 점에 유의하세요.
따라서 여기에서 먼저 계산한 다음 이전에 정의한
train_step
함수에 입력하여 훈련 세션을 완료합니다.
다음은 내 노트북을 사용하여 약 10일 동안 진행되는 긴 교육 과정입니다. 노트북에서 훈련 속도를 테스트했는데 Pytorch와 거의 같습니다. Ascend MindSpore는 Huawei Ascend 910(Huawei에서 개발한 AI 칩)을 사용하여 훈련을 가속화할 수 있지만, 가난한 학생으로서 생각하기 때문에 vivo50(`・Ω・´)으로 시험해보고 싶습니다.
훈련 곡선은 다음과 같습니다. Pytorch를 사용하여 github에서 상사가 훈련한 결과는 약 200개입니다. 노트북 메모리 16g으로 제한되어 현재 경험 풀 용량에서 훈련할 수 있는 최상의 결과는 약 150개입니다.
04
실험 결과
훈련 후 DQN이 이 게임을 학습한 것을 볼 수 있습니다. 일반적으로 운이 좋으면 다음과 같이 300점을 얻을 수 있습니다.
1990년대에 태어난 프로그래머가 비디오 포팅 소프트웨어를 개발하여 1년도 안 되어 700만 개 이상의 수익을 올렸습니다. 결말은 매우 처참했습니다! Google은 Flutter, Dart 및 Python 팀의 중국 코더의 "35세 저주"와 관련된 정리해고를 확인했습니다 . | Daily Windows 1.0용 Arc Browser가 3개월 만에 공식적으로 GA Windows 10 시장 점유율이 70%에 도달했으며 Windows 11 GitHub는 AI 기본 개발 도구 GitHub Copilot Workspace JAVA를 계속 해서 출시했습니다 . OLTP+OLAP을 처리할 수 있는 유일한 강력한 유형의 쿼리입니다. 우리는 너무 늦게 만났습니다 .