惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - Franky
D
Docker
Jina AI
Jina AI
The GitHub Blog
The GitHub Blog
博客园 - 聂微东
B
Blog RSS Feed
大猫的无限游戏
大猫的无限游戏
M
MIT News - Artificial intelligence
Vercel News
Vercel News
Microsoft Security Blog
Microsoft Security Blog
博客园 - 叶小钗
爱范儿
爱范儿
D
DataBreaches.Net
Hugging Face - Blog
Hugging Face - Blog
IT之家
IT之家
Recent Announcements
Recent Announcements
U
Unit 42
腾讯CDC
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
宝玉的分享
宝玉的分享
量子位
Stack Overflow Blog
Stack Overflow Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Microsoft Azure Blog
Microsoft Azure Blog

极客兔兔

Go sync.Cond | Go 语言高性能编程 Go 死码消除与调试(debug)模式 | Go 语言高性能编程 Go sync.Once | Go 语言高性能编程 Go 逃逸分析 | Go 语言高性能编程 2020 年终总结 | 极客兔兔 Go struct 内存对齐 | Go 语言高性能编程 Go 空结构体 struct{} 的使用 | Go 语言高性能编程 控制协程(goroutine)的并发数量 | Go 语言高性能编程 | 极客兔兔 如何退出协程 goroutine (其他场景) | Go 语言高性能编程 如何退出协程 goroutine (超时场景) | Go 语言高性能编程 Go 语言陷阱 - 数组和切片 | Go 语言高性能编程 减小 Go 代码编译后的二进制体积 | Go 语言高性能编程 Go Reflect 提高反射性能 | Go 语言高性能编程 读写锁和互斥锁的性能比较 | Go 语言高性能编程 | 极客兔兔 for 和 range 的性能比较 | Go 语言高性能编程 切片(slice)性能及陷阱 | Go 语言高性能编程 | 极客兔兔 字符串拼接性能及原理 | Go 语言高性能编程 | 极客兔兔 pprof 性能分析 | Go 语言高性能编程 benchmark 基准测试 | Go 语言高性能编程 Go 语言高性能编程 | 极客兔兔 Go 接口型函数的使用场景 | 极客兔兔 Python 简明教程 | 快速入门 | 极客兔兔 Go 语言笔试面试题(代码输出) | 极客面试 | 极客兔兔 动手写RPC框架 - GeeRPC第七天 服务发现与注册中心(registry) | 极客兔兔 动手写RPC框架 - GeeRPC第六天 负载均衡(load balance) 动手写RPC框架 - GeeRPC第五天 支持HTTP协议 | 极客兔兔 动手写RPC框架 - GeeRPC第四天 超时处理(timeout) | 极客兔兔 动手写RPC框架 - GeeRPC第三天 服务注册(service register) 动手写RPC框架 - GeeRPC第二天 支持并发与异步的客户端 | 极客兔兔 动手写RPC框架 - GeeRPC第一天 服务端与消息编码 | 极客兔兔
TensorFlow 2.0 (六) - 监督学习玩转 OpenAI gym game
2019-06-21 · via 极客兔兔

源代码/数据集已上传到 Github - tensorflow-tutorial-samples

gym cartpole-v0 failed

这篇文章是 TensorFlow 2.0 Tutorial 入门教程的第六篇文章,介绍如何使用 TensorFlow 2.0 搭建神经网络(Neural Network, NN),使用纯监督学习(Supervised Learning)的方法,玩转 OpenAI gym game。示例代码基于 Python 3 和 TensorFlow 2.0 。

OpenAI gym是一个开源的游戏模拟环境,主要用来开发和比较强化学习(Reinforcement Learning, RL)的算法。这篇文章是 Tensorflow 2.0 系列使用 gym 的第一篇文章,网上介绍强化学习玩 gym 的文章比较多,而纯监督学习的文章极少。我们先使用纯监督学习的算法,一起感受 gym 的魅力吧。

如何安装

1
2
3
4
5
pip install tensorflow==2.0.0-beta0
pip install gym



OpenAI gym 初尝试

我们先对 OpenAI 的 gym 库的几个核心概念作个简单介绍。

想象一下你在玩贪吃蛇,你需要分析当前游戏的状态(State),例如你所处的位置,周围的障碍物等,才能够决定下一步的动作(Action),上下左右。那你每走一步,就会得到一个奖励(Reward)。这个奖励可能是正向奖励(Positive Reward),也可能是负向奖励(Negative Reward),比如撞到了障碍物。重复N次这样的过程,直到游戏结束(Done)

从整个例子中,可以总结出几个重要的概念,接下来的示例将会使用 OpenAI gym 库提供的 CartPole Game 环境,一起来熟悉CartPole 游戏中的这几个概念的含义吧。先直接给一个可以运行看效果的示例,这个示例中,Action 是随机选择的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20


import gym
import random
import time

env = gym.make("CartPole-v0")

state = env.reset()
score = 0
while True:
time.sleep(0.1)
env.render()
action = random.randint(0, 1)
state, reward, done, _ = env.step(action)
score += reward
if done:
print('score: ', score)
break
env.close()
1
2
$ python3 try_gym.py
score: 14.0
概念 解释 示例
State list:状态,[车位置, 车速度, 杆角度, 杆速度] 0.02,0.95,-0.07,-1.53
Action int:动作(0向左/1向右) 1
Reward float:奖励(每走一步得1分) 1.0
Done bool:是否结束(True/False),上限200回合 False

游戏上限是200回合,但是如果是随机选择 Action,就只得了14分,游戏就结束了。

搭建神经网络

我们的目的就是将随机选择 Action 的部分,变为由神经网络模型来选择。神经网络的输入是State,输出是Action。在这里,Action 用独热编码来表示,即 [1, 0] 表示向左,**[0, 1]** 表示向右。这样我们可以方便地使用np.argmax()获取预测的 Action 的值。

1
2
np.argmax([0.3, 0.7]) 
np.argmax([0.8, 0.2])

接下来我们搭建一个 4 x 64 x 20 x 2 的网络,输入层为4,输出层为2。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16


import random
import gym
import numpy as np
from tensorflow.keras import models, layers

env = gym.make("CartPole-v0")

STATE_DIM, ACTION_DIM = 4, 2
model = models.Sequential([
layers.Dense(64, input_dim=STATE_DIM, activation='relu'),
layers.Dense(20, activation='relu'),
layers.Dense(ACTION_DIM, activation='linear')
])
model.summary()

训练数据从哪里来?

神经网络的模型搭好了,那训练数据呢?

随机产生的数据,得分很低,如果不过滤,数据集质量是很低的。

最终的办法:试,一百次不行,就试一万次

简而言之,我们在过程中计算Score,如果最终得分达到设定的标准,这个分数所对应的所有StateAction就可以作为我们的训练数据了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

def generate_data_one_episode():
'''生成单次游戏的训练数据'''
x, y, score = [], [], 0
state = env.reset()
while True:
action = random.randrange(0, 2)
x.append(state)
y.append([1, 0] if action == 0 else [0, 1])
state, reward, done, _ = env.step(action)
score += reward
if done:
break
return x, y, score

def generate_training_data(expected_score=100):
'''# 生成N次游戏的训练数据,并进行筛选,选择 > 100 的数据作为训练集'''
data_X, data_Y, scores = [], [], []
for i in range(10000):
x, y, score = generate_data_one_episode()
if score > expected_score:
data_X += x
data_Y += y
scores.append(score)
print('dataset size: {}, max score: {}'.format(len(data_X), max(scores)))
return np.array(data_X), np.array(data_Y)

这样,我们就可以使用generate_training_data函数生成训练集了。

训练并保存模型

神经网络和数据集都准备好了,训练就非常简单了。

1
2
3
4
5

data_X, data_Y = generate_training_data()
model.compile(loss='mse', optimizer='adam', epochs=5)
model.fit(data_X, data_Y)
model.save('CartPole-v0-nn.h5')

从运行的结果看,我们最终得到的训练集大小为213,最大分数是108分。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
$ python train.py
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param
=================================================================
dense (Dense) (None, 64) 320
_________________________________________________________________
dense_1 (Dense) (None, 20) 1300
_________________________________________________________________
dense_2 (Dense) (None, 2) 42
=================================================================
Total params: 1,662
Trainable params: 1,662
Non-trainable params: 0
_________________________________________________________________
dataset size: 213, max score: 108.0
Train on 213 samples
Epoch 1/5
213/213 [==============================] - 0s 713us/sample - loss: 0.4701
Epoch 2/5
213/213 [==============================] - 0s 35us/sample - loss: 0.3920
Epoch 3/5
213/213 [==============================] - 0s 38us/sample - loss: 0.3370
Epoch 4/5
213/213 [==============================] - 0s 39us/sample - loss: 0.2985
Epoch 5/5
213/213 [==============================] - 0s 38us/sample - loss: 0.2745

模型测试/预测

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24


import time
import numpy as np
import gym
from tensorflow.keras import models


saved_model = models.load_model('CartPole-v0-nn.h5')
env = gym.make("CartPole-v0")

for i in range(5):
state = env.reset()
score = 0
while True:
time.sleep(0.01)
env.render()
action = np.argmax(saved_model.predict(np.array([state]))[0])
state, reward, done, _ = env.step(action)
score += reward
if done:
print('using nn, score: ', score)
break
env.close()
1
2
3
4
5
6
$ python predict.py
using nn, score: 200.0
using nn, score: 200.0
using nn, score: 200.0
using nn, score: 200.0
using nn, score: 200.0

模型的结果很不错,每一次都达到了200的满分。

看看效果吧~

gym cartpole-v0 success

Github - tensorflow-tutorial-samples上提供了.py.ipynb2种格式的代码。

附 推荐



上一篇 « 博客折腾记(二) - 对搜索引擎的理解 下一篇 » 博客折腾记(三) - 主题设计、彩蛋与阅读量翻倍