精通 TensorFlow 1.x:11~15(2)https://developer.aliyun.com/article/1426825
- 接下来,训练 Keras 模型 20 个周期,批量大小为 32:
from keras.utils import np_utils batch_size=32 n_epochs=20 total_images = len(x_train_files) n_batches = total_images // batch_size for epoch in range(n_epochs): print('Starting epoch ',epoch) coco.reset_index_in_epoch() for batch in range(n_batches): try: x_batch, y_batch = coco.next_batch(batch_size=batch_size) images=np.array([coco.preprocess_image(x) for x in x_batch]) y_onehot = np_utils.to_categorical(y_batch, num_classes=coco.n_classes) model.fit(x=images,y=y_onehot,verbose=0) except Exception as ex: print('error in epoch {} batch {}'.format(epoch,batch)) print(ex)
- 让我们使用再训练的新模型执行图像分类:
probs = model.predict(images_test)
以下是分类结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cwiJS0XN-1681566540583)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/mastering-tf-1x-zh/img/5e31bad2-c2e8-43e1-9d19-0b5cef8867d6.png)]
Probability 100.00% of [zebra] Probability 0.00% of [dog] Probability 0.00% of [horse] Probability 0.00% of [giraffe] Probability 0.00% of [bear]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XwJlr895-1681566540583)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/mastering-tf-1x-zh/img/4184ac21-2885-47b0-a503-361915a70401.png)]
Probability 96.11% of [horse] Probability 1.85% of [cat] Probability 0.77% of [bird] Probability 0.43% of [giraffe] Probability 0.40% of [sheep]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fs8JwRU3-1681566540583)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/mastering-tf-1x-zh/img/0321b135-32b5-427c-a7a8-39058d197274.png)]
Probability 99.75% of [dog] Probability 0.22% of [cat] Probability 0.03% of [horse] Probability 0.00% of [bear] Probability 0.00% of [zebra]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u1tSE7ju-1681566540584)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/mastering-tf-1x-zh/img/fe76371b-f805-4abf-ac9d-6b4bda36bdff.png)]
Probability 99.88% of [bird] Probability 0.11% of [horse] Probability 0.00% of [giraffe] Probability 0.00% of [bear] Probability 0.00% of [cat]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YIF4xFXr-1681566540584)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/mastering-tf-1x-zh/img/27c1cba9-a04b-44a3-af60-507f73f5e462.png)]
Probability 65.28% of [bear] Probability 27.09% of [sheep] Probability 4.34% of [bird] Probability 1.71% of [giraffe] Probability 0.63% of [dog]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FnCs5aWf-1681566540584)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/mastering-tf-1x-zh/img/dfc094b5-ff7e-4af2-a691-64344d669e6c.png)]
Probability 100.00% of [bear] Probability 0.00% of [sheep] Probability 0.00% of [dog] Probability 0.00% of [cat] Probability 0.00% of [giraffe]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-at67P6F9-1681566540584)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/mastering-tf-1x-zh/img/b89ae721-3a80-458a-ae17-aea4fbf493ef.png)]
Probability 100.00% of [giraffe] Probability 0.00% of [bird] Probability 0.00% of [bear] Probability 0.00% of [sheep] Probability 0.00% of [zebra]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HChRtCvM-1681566540585)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/mastering-tf-1x-zh/img/ddb79a37-37df-4f86-bc7a-2ad4b25f8d45.png)]
Probability 81.05% of [cat] Probability 15.68% of [dog] Probability 1.64% of [bird] Probability 0.90% of [horse] Probability 0.43% of [bear]
除了最后的嘈杂图像外,所有类别都已正确识别。通过适当的超参数调整,也可以进行改进。
到目前为止,您已经看到了使用预训练模型进行分类并对预训练模型进行微调的示例。接下来,我们将使用 InceptionV3 模型显示分类示例。
TensorFlow 中的 InceptionV3
您可以按照 Jupyter 笔记本中的代码ch-12c_InceptionV3_TensorFlow
。
TensorFlow 的 InceptionV3 在 1,001 个标签上训练,而不是 1,000 个。此外,用于训练的图像被不同地预处理。我们在前面的部分中展示了预处理代码。让我们直接深入了解使用 TensorFlow 恢复 InceptionV3 模型。
让我们下载 InceptionV3 的检查点文件:
# load the InceptionV3 model model_name='inception_v3' model_url='http://download.tensorflow.org/models/' model_files=['inception_v3_2016_08_28.tar.gz'] model_home=os.path.join(models_root,model_name) dsu.download_dataset(source_url=model_url, source_files=model_files, dest_dir = model_home, force=False, extract=True)
定义初始模块和变量的常见导入:
### define common imports and variables from tensorflow.contrib.slim.nets import inception image_height=inception.inception_v3.default_image_size image_width=inception.inception_v3.default_image_size
TensorFlow 中的 InceptionV3 的图像分类
图像分类与使用 VGG 16 模型的上一节中说明的相同。 InceptionV3 模型的完整代码如下:
x_p = tf.placeholder(shape=(None, image_height, image_width, 3 ), dtype=tf.float32, name='x_p') with slim.arg_scope(inception.inception_v3_arg_scope()): logits,_ = inception.inception_v3(x_p, num_classes=inet.n_classes, is_training=False ) probabilities = tf.nn.softmax(logits) init = slim.assign_from_checkpoint_fn( os.path.join(model_home, '{}.ckpt'.format(model_name)), slim.get_variables_to_restore()) with tf.Session() as tfs: init(tfs) probs = tfs.run([probabilities],feed_dict={x_p:images_test}) probs=probs[0]
让我们看看我们的模型如何处理测试图像:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pNMMX61b-1681566540585)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/mastering-tf-1x-zh/img/8f8448d0-148c-4f6f-afbc-7dea9073f49f.png)]
Probability 95.15% of [zebra] Probability 0.07% of [ostrich, Struthio camelus] Probability 0.07% of [hartebeest] Probability 0.03% of [sock] Probability 0.03% of [warthog]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CCg2jaBs-1681566540585)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/mastering-tf-1x-zh/img/6dc13766-92b1-4544-88f1-32f26ebb5e0f.png)]
Probability 93.09% of [horse cart, horse-cart] Probability 0.47% of [plow, plough] Probability 0.07% of [oxcart] Probability 0.07% of [seashore, coast, seacoast, sea-coast] Probability 0.06% of [military uniform]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zULW05SS-1681566540585)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/mastering-tf-1x-zh/img/1b39121e-4240-462e-8884-8d77594919d3.png)]
Probability 18.94% of [Cardigan, Cardigan Welsh corgi] Probability 8.19% of [Pembroke, Pembroke Welsh corgi] Probability 7.86% of [studio couch, day bed] Probability 5.36% of [English springer, English springer spaniel] Probability 4.16% of [Border collie]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5B2ntnkx-1681566540585)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/mastering-tf-1x-zh/img/a3bf50cb-2c6b-43fa-82d9-26c12a2bef2c.png)]
Probability 27.18% of [water ouzel, dipper] Probability 24.38% of [junco, snowbird] Probability 6.91% of [chickadee] Probability 0.99% of [magpie] Probability 0.73% of [brambling, Fringilla montifringilla]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i4RTfLzr-1681566540586)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/mastering-tf-1x-zh/img/e669f2b4-5d08-4f8a-bfce-09bf10bff2e5.png)]
Probability 93.00% of [hog, pig, grunter, squealer, Sus scrofa] Probability 2.23% of [wild boar, boar, Sus scrofa] Probability 0.65% of [ram, tup] Probability 0.43% of [ox] Probability 0.23% of [marmot]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AiL9pr6X-1681566540586)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/mastering-tf-1x-zh/img/a35351da-d301-404f-922a-cb48941c706a.png)]
Probability 84.27% of [brown bear, bruin, Ursus arctos] Probability 1.57% of [American black bear, black bear, Ursus americanus, Euarctos americanus] Probability 1.34% of [sloth bear, Melursus ursinus, Ursus ursinus] Probability 0.13% of [lesser panda, red panda, panda, bear cat, cat bear, Ailurus fulgens] Probability 0.12% of [ice bear, polar bear, Ursus Maritimus, Thalarctos maritimus]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Tvrud9J8-1681566540586)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/mastering-tf-1x-zh/img/f1a56a59-9a04-4607-b7d2-7a0a8c9c9b2e.png)]
Probability 20.20% of [honeycomb] Probability 6.52% of [gazelle] Probability 5.14% of [sorrel] Probability 3.72% of [impala, Aepyceros melampus] Probability 2.44% of [Saluki, gazelle hound]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tMRuQ5XP-1681566540586)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/mastering-tf-1x-zh/img/a5bae2ea-89db-4c7e-9e31-1eb86bfc8e47.png)]
Probability 41.17% of [harp] Probability 13.64% of [accordion, piano accordion, squeeze box] Probability 2.97% of [window shade] Probability 1.59% of [chain] Probability 1.55% of [pay-phone, pay-station]
虽然它在与 VGG 模型几乎相同的地方失败了,但并不算太糟糕。现在让我们用 COCO 动物图像和标签再训练这个模型。
TensorFlow 中的再训练 InceptionV3 的图像分类
InceptionV3 的再训练与 VGG16 不同,因为我们使用 softmax 激活层作为输出,tf.losses.softmax_cross_entropy()
作为损耗函数。
- 首先定义占位符:
is_training = tf.placeholder(tf.bool,name='is_training') x_p = tf.placeholder(shape=(None, image_height, image_width, 3 ), dtype=tf.float32, name='x_p') y_p = tf.placeholder(shape=(None,coco.n_classes), dtype=tf.int32, name='y_p')
- 接下来,加载模型:
with slim.arg_scope(inception.inception_v3_arg_scope()): logits,_ = inception.inception_v3(x_p, num_classes=coco.n_classes, is_training=True ) probabilities = tf.nn.softmax(logits)
- 接下来,定义函数以恢复除最后一层之外的变量:
with slim.arg_scope(inception.inception_v3_arg_scope()): logits,_ = inception.inception_v3(x_p, num_classes=coco.n_classes, is_training=True ) probabilities = tf.nn.softmax(logits) # restore except last layer checkpoint_exclude_scopes=["InceptionV3/Logits", "InceptionV3/AuxLogits"] exclusions = [scope.strip() for scope in checkpoint_exclude_scopes] variables_to_restore = [] for var in slim.get_model_variables(): excluded = False for exclusion in exclusions: if var.op.name.startswith(exclusion): excluded = True break if not excluded: variables_to_restore.append(var) init_fn = slim.assign_from_checkpoint_fn( os.path.join(model_home, '{}.ckpt'.format(model_name)), variables_to_restore)
- 定义损失,优化器和训练操作:
tf.losses.softmax_cross_entropy(onehot_labels=y_p, logits=logits) loss = tf.losses.get_total_loss() learning_rate = 0.001 optimizer = tf.train.GradientDescentOptimizer(learning_rate) train_op = optimizer.minimize(loss)
- 训练模型并在同一会话中完成训练后运行预测:
n_epochs=10 coco.y_onehot = True coco.batch_size = 32 coco.batch_shuffle = True total_images = len(x_train_files) n_batches = total_images // coco.batch_size with tf.Session() as tfs: tfs.run(tf.global_variables_initializer()) init_fn(tfs) for epoch in range(n_epochs): print('Starting epoch ',epoch) coco.reset_index() epoch_accuracy=0 epoch_loss=0 for batch in range(n_batches): x_batch, y_batch = coco.next_batch() images=np.array([coco.preprocess_for_inception(x) \ for x in x_batch]) feed_dict={x_p:images,y_p:y_batch,is_training:True} batch_loss,_ = tfs.run([loss,train_op], feed_dict = feed_dict) epoch_loss += batch_loss epoch_loss /= n_batches print('Train loss in epoch {}:{}' .format(epoch,epoch_loss)) # now run the predictions feed_dict={x_p:images_test,is_training: False} probs = tfs.run([probabilities],feed_dict=feed_dict) probs=probs[0]
我们看到每个周期的损失都在减少:
INFO:tensorflow:Restoring parameters from /home/armando/models/inception_v3/inception_v3.ckpt Starting epoch 0 Train loss in epoch 0:2.7896385192871094 Starting epoch 1 Train loss in epoch 1:1.6651896286010741 Starting epoch 2 Train loss in epoch 2:1.2332031989097596 Starting epoch 3 Train loss in epoch 3:0.9912329530715942 Starting epoch 4 Train loss in epoch 4:0.8110128355026245 Starting epoch 5 Train loss in epoch 5:0.7177265572547913 Starting epoch 6 Train loss in epoch 6:0.6175705575942994 Starting epoch 7 Train loss in epoch 7:0.5542363750934601 Starting epoch 8 Train loss in epoch 8:0.523461252450943 Starting epoch 9 Train loss in epoch 9:0.4923107647895813
这次结果正确识别了绵羊,但错误地将猫图片识别为狗:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kE1be6tG-1681566540586)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/mastering-tf-1x-zh/img/701ce0d5-b399-4f4b-b1e9-84e399ae0af9.png)]
Probability 98.84% of [zebra] Probability 0.84% of [giraffe] Probability 0.11% of [sheep] Probability 0.07% of [cat] Probability 0.06% of [dog]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RhPmB39N-1681566540587)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/mastering-tf-1x-zh/img/729c8e7b-f573-4d38-ae0b-1b9eb3ac96b2.png)]
Probability 95.77% of [horse] Probability 1.34% of [dog] Probability 0.89% of [zebra] Probability 0.68% of [bird] Probability 0.61% of [sheep]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MtlXtYuZ-1681566540587)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/mastering-tf-1x-zh/img/db0b9246-ccc2-4c1b-904a-b3dfc799da24.png)]
Probability 94.83% of [dog] Probability 4.53% of [cat] Probability 0.56% of [sheep] Probability 0.04% of [bear] Probability 0.02% of [zebra]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rTkp9MTL-1681566540587)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/mastering-tf-1x-zh/img/0511bc01-7f4d-48f9-a88a-ebb5eca0aab4.png)]
Probability 42.80% of [bird] Probability 25.64% of [cat] Probability 15.56% of [bear] Probability 8.77% of [giraffe] Probability 3.39% of [sheep]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S2TsUeJu-1681566540587)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/mastering-tf-1x-zh/img/6e000739-cba7-4e27-8336-cef9f931629c.png)]
Probability 72.58% of [sheep] Probability 8.40% of [bear] Probability 7.64% of [giraffe] Probability 4.02% of [horse] Probability 3.65% of [bird]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1u7Z5zMH-1681566540587)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/mastering-tf-1x-zh/img/8c50e317-4436-4256-a8d3-f4f48411643b.png)]
Probability 98.03% of [bear] Probability 0.74% of [cat] Probability 0.54% of [sheep] Probability 0.28% of [bird] Probability 0.17% of [horse]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cT2dw8yp-1681566540588)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/mastering-tf-1x-zh/img/8dfafd80-1a4f-4fe7-b806-a18738ff7059.png)]
Probability 96.43% of [giraffe] Probability 1.78% of [bird] Probability 1.10% of [sheep] Probability 0.32% of [zebra] Probability 0.14% of [bear]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dP4sZZGW-1681566540588)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/mastering-tf-1x-zh/img/a344f73f-c858-4134-82ef-541924b1c64a.png)]
Probability 34.43% of [horse] Probability 23.53% of [dog] Probability 16.03% of [zebra] Probability 9.76% of [cat] Probability 9.02% of [giraffe]
总结
迁移学习是一项伟大的发现,它允许我们通过将在较大数据集中训练的模型应用于不同的数据集来节省时间。当数据集很小时,迁移学习也有助于热启动训练过程。在本章中,我们学习了如何使用预训练的模型,如 VGG16 和 InceptionV3,将不同数据集中的图像分类为他们所训练的数据集。我们还学习了如何使用 TensorFlow 和 Keras 中的示例再训练预训练模型,以及如何预处理图像以供给两个模型。
我们还了解到有几种模型在 ImageNet 数据集上进行了训练。尝试查找在不同数据集上训练的其他模型,例如视频数据集,语音数据集或文本/ NLP 数据集。尝试使用这些模型再训练并在您自己的数据集中使用您自己的深度学习问题。
十三、深度强化学习
强化学习是一种学习形式,其中软件智能体观察环境并采取行动以最大化其对环境的奖励,如下图所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Qebfvplz-1681566540588)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/mastering-tf-1x-zh/img/bdd263e7-4be5-4a46-8b91-f5560793473b.png)]
这个比喻可以用来表示现实生活中的情况,如下所示:
- 股票交易智能体观察交易信息,新闻,分析和其他形式信息,并采取行动买入或卖出交易,以便以短期利润或长期利润的形式最大化奖励。
- 保险智能体观察有关客户的信息,然后采取行动确定保险费金额,以便最大化利润并最大限度地降低风险。
- 类人机器人观察环境然后采取行动,例如步行,跑步或拾取物体,以便在实现目标方面最大化奖励。
强化学习已成功应用于许多应用,如广告优化,股票市场交易,自动驾驶汽车,机器人和游戏,仅举几例。
强化学习与监督学习不同,因为预先没有标签来调整模型的参数。该模型从运行中获得的奖励中学习。虽然短期奖励可以立即获得,但只有经过几个步骤才能获得长期奖励。这种现象也称为延迟反馈。
强化学习也与无监督学习不同,因为在无监督学习中没有可用的标签,而在强化学习中,反馈可用于奖励。
在本章中,我们将通过涵盖以下主题来了解强化学习及其在 TensorFlow 和 Keras 中的实现:
- OpenAI Gym 101
- 将简单的策略应用于 Cartpole 游戏
- 强化学习 101
- Q 函数
- 探索和利用
- V 函数
- RL 技术
- RL 的简单神经网络策略
- 实现 Q-Learning
- Q-Learning 的初始化和离散化
- 使用 Q-Table 进行 Q-Learning
- 深度 Q 网络:使用 Q-Network 进行 Q-Learning
我们将在 OpenAI Gym 中演示我们的示例,让我们首先了解一下 OpenAI Gym。
OpenAI Gym 101
OpenAI Gym 是一个基于 Python 的工具包,用于研究和开发强化学习算法。 OpenAI Gym 在撰写本文时提供了 700 多个开源贡献环境。使用 OpenAI,您还可以创建自己的环境。最大的优势是 OpenAI 提供了一个统一的接口来处理这些环境,并在您专注于强化学习算法的同时负责运行模拟。
您可以使用以下命令安装 OpenAI Gym:
pip3 install gym
如果上述命令不起作用,您可以在此链接中找到有关安装的更多帮助。
- 让我们在 OpenAI Gym 中打印可用环境的数量:
您可以按照本书代码包中的 Jupyter 笔记本ch-13a_Reinforcement_Learning_NN
中的代码进行操作。
all_env = list(gym.envs.registry.all()) print('Total Environments in Gym version {} : {}' .format(gym.__version__,len(all_env))) Total Environments in Gym version 0.9.4 : 777
- 让我们打印所有环境的列表:
for e in list(all_env): print(e)
输出的部分列表如下:
EnvSpec(Carnival-ramNoFrameskip-v0) EnvSpec(EnduroDeterministic-v0) EnvSpec(FrostbiteNoFrameskip-v4) EnvSpec(Taxi-v2) EnvSpec(Pooyan-ram-v0) EnvSpec(Solaris-ram-v4) EnvSpec(Breakout-ramDeterministic-v0) EnvSpec(Kangaroo-ram-v4) EnvSpec(StarGunner-ram-v4) EnvSpec(Enduro-ramNoFrameskip-v4) EnvSpec(DemonAttack-ramDeterministic-v0) EnvSpec(TimePilot-ramNoFrameskip-v0) EnvSpec(Amidar-v4)
由env
对象表示的每个环境都有一个标准化的接口,例如:
- 通过传递 ID 字符串,可以使用
env.make()
函数创建env
对象。 - 每个
env
对象包含以下主要函数:
step()
函数将操作对象作为参数并返回四个对象:
- 观察:由环境实现的对象,代表对环境的观察。
- 奖励:一个带符号的浮点值,表示前一个操作的增益(或损失)。
done
:表示方案是否完成的布尔值。info
:表示诊断信息的 Python 字典对象。
render()
函数可创建环境的直观表示。reset()
函数将环境重置为原始状态。
- 每个
env
对象都有明确定义的动作和观察,由action_space
和observation_space
表示。
CartPole 是健身房里最受欢迎的学习强化学习游戏之一。在这个游戏中,连接到推车的杆必须平衡,以便它不会下降。如果杆子倾斜超过 15 度或者推车从中心移动超过 2.4 个单元,则游戏结束。 OpenAI.com 的主页用这些词强调游戏:
这种环境的小尺寸和简单性使得可以进行非常快速的实验,这在学习基础知识时是必不可少的。
游戏只有四个观察和两个动作。动作是通过施加 +1 或 -1 的力来移动购物车。观察结果是推车的位置,推车的速度,杆的角度以及杆的旋转速度。然而,学习观察语义的知识不是学习最大化游戏奖励所必需的。
现在让我们加载一个流行的游戏环境 CartPole-v0,然后用随机控件播放:
- 使用标准
make
函数创建env
对象:
env = gym.make('CartPole-v0')
- 剧集的数量是游戏的数量。我们现在将它设置为一个,表示我们只想玩一次游戏。由于每集都是随机的,因此在实际的制作过程中,您将运行多集并计算奖励的平均值。此外,我们可以初始化一个数组,以便在每个时间步都存储环境的可视化:
n_episodes = 1 env_vis = []
- 运行两个嵌套循环 - 一个用于剧集数量的外部循环和一个用于您要模拟的时间步数的内部循环。您可以继续运行内部循环,直到方案完成或将步数设置为更高的值。
- 在每集开始时,使用
env.reset()
重置环境。 - 在每个时间步的开始,使用
env.render()
捕获可视化。
for i_episode in range(n_episodes): observation = env.reset() for t in range(100): env_vis.append(env.render(mode = 'rgb_array')) print(observation) action = env.action_space.sample() observation, reward, done, info = env.step(action) if done: print("Episode finished at t{}".format(t+1)) break
- 使用辅助函数渲染环境:
env_render(env_vis)
- 辅助函数的代码如下:
def env_render(env_vis): plt.figure() plot = plt.imshow(env_vis[0]) plt.axis('off') def animate(i): plot.set_data(env_vis[i]) anim = anm.FuncAnimation(plt.gcf(), animate, frames=len(env_vis), interval=20, repeat=True, repeat_delay=20) display(display_animation(anim, default_mode='loop'))
运行此示例时,我们得到以下输出:
[-0.00666995 -0.03699492 -0.00972623 0.00287713] [-0.00740985 0.15826516 -0.00966868 -0.29285861] [-0.00424454 -0.03671761 -0.01552586 -0.00324067] [-0.0049789 -0.2316135 -0.01559067 0.28450351] [-0.00961117 -0.42650966 -0.0099006 0.57222875] [-0.01814136 -0.23125029 0.00154398 0.27644332] [-0.02276636 -0.0361504 0.00707284 -0.01575223] [-0.02348937 0.1588694 0.0067578 -0.30619523] [-0.02031198 -0.03634819 0.00063389 -0.01138875] [-0.02103895 0.15876466 0.00040612 -0.3038716 ] [-0.01786366 0.35388083 -0.00567131 -0.59642642] [-0.01078604 0.54908168 -0.01759984 -0.89089036] [ 1.95594914e-04 7.44437934e-01 -3.54176495e-02 -1.18905344e+00] [ 0.01508435 0.54979251 -0.05919872 -0.90767902] [ 0.0260802 0.35551978 -0.0773523 -0.63417465] [ 0.0331906 0.55163065 -0.09003579 -0.95018025] [ 0.04422321 0.74784161 -0.1090394 -1.26973934] [ 0.05918004 0.55426764 -0.13443418 -1.01309691] [ 0.0702654 0.36117014 -0.15469612 -0.76546874] [ 0.0774888 0.16847818 -0.1700055 -0.52518186] [ 0.08085836 0.3655333 -0.18050913 -0.86624457] [ 0.08816903 0.56259197 -0.19783403 -1.20981195] Episode finished at t22
杆子需要 22 个时间步长才能变得不平衡。在每次运行中,我们得到不同的时间步长值,因为我们通过使用env.action_space.sample()
在学术上选择了动作。
由于游戏如此迅速地导致失败,随机选择一个动作并应用它可能不是最好的策略。有许多算法可以找到解决方案,使杆子保持笔直,可以使用更长的时间步长,例如爬山,随机搜索和策略梯度。
解决 Cartpole 游戏的一些算法可通过此链接获得:
https://openai.com/requests-for-research/#cartpole
http://kvfrans.com/simple-algoritms-for-solving-cartpole/
https://github.com/kvfrans/openai-cartpole
将简单的策略应用于 Cartpole 游戏
到目前为止,我们已经随机选择了一个动作并应用它。现在让我们应用一些逻辑来挑选行动而不是随机机会。第三个观察指的是角度。如果角度大于零,则意味着杆向右倾斜,因此我们将推车向右移动(1)。否则,我们将购物车向左移动(0)。我们来看一个例子:
- 我们定义了两个策略函数如下:
def policy_logic(env,obs): return 1 if obs[2] > 0 else 0 def policy_random(env,obs): return env.action_space.sample()
- 接下来,我们定义一个将针对特定数量的剧集运行的实验函数;每一集一直持续到游戏损失,即
done
为True
。我们使用rewards_max
来指示何时突破循环,因为我们不希望永远运行实验:
def experiment(policy, n_episodes, rewards_max): rewards=np.empty(shape=(n_episodes)) env = gym.make('CartPole-v0') for i in range(n_episodes): obs = env.reset() done = False episode_reward = 0 while not done: action = policy(env,obs) obs, reward, done, info = env.step(action) episode_reward += reward if episode_reward > rewards_max: break rewards[i]=episode_reward print('Policy:{}, Min reward:{}, Max reward:{}' .format(policy.__name__, min(rewards), max(rewards)))
- 我们运行实验 100 次,或直到奖励小于或等于
rewards_max
,即设置为 10,000:
n_episodes = 100 rewards_max = 10000 experiment(policy_random, n_episodes, rewards_max) experiment(policy_logic, n_episodes, rewards_max)
我们可以看到逻辑选择的动作比随机选择的动作更好,但不是更好:
Policy:policy_random, Min reward:9.0, Max reward:63.0, Average reward:20.26 Policy:policy_logic, Min reward:24.0, Max reward:66.0, Average reward:42.81
现在让我们进一步修改选择动作的过程 - 基于参数。参数将乘以观察值,并且将基于乘法结果是零还是一来选择动作。让我们修改随机搜索方法,我们随机初始化参数。代码如下:
def policy_logic(theta,obs): # just ignore theta return 1 if obs[2] > 0 else 0 def policy_random(theta,obs): return 0 if np.matmul(theta,obs) < 0 else 1 def episode(env, policy, rewards_max): obs = env.reset() done = False episode_reward = 0 if policy.__name__ in ['policy_random']: theta = np.random.rand(4) * 2 - 1 else: theta = None while not done: action = policy(theta,obs) obs, reward, done, info = env.step(action) episode_reward += reward if episode_reward > rewards_max: break return episode_reward def experiment(policy, n_episodes, rewards_max): rewards=np.empty(shape=(n_episodes)) env = gym.make('CartPole-v0') for i in range(n_episodes): rewards[i]=episode(env,policy,rewards_max) #print("Episode finished at t{}".format(reward)) print('Policy:{}, Min reward:{}, Max reward:{}, Average reward:{}' .format(policy.__name__, np.min(rewards), np.max(rewards), np.mean(rewards))) n_episodes = 100 rewards_max = 10000 experiment(policy_random, n_episodes, rewards_max) experiment(policy_logic, n_episodes, rewards_max)
我们可以看到随机搜索确实改善了结果:
Policy:policy_random, Min reward:8.0, Max reward:200.0, Average reward:40.04 Policy:policy_logic, Min reward:25.0, Max reward:62.0, Average reward:43.03
通过随机搜索,我们改进了结果以获得 200 的最大奖励。平均而言,随机搜索的奖励较低,因为随机搜索会尝试各种不良参数,从而降低整体结果。但是,我们可以从所有运行中选择最佳参数,然后在生产中使用最佳参数。让我们修改代码以首先训练参数:
def policy_logic(theta,obs): # just ignore theta return 1 if obs[2] > 0 else 0 def policy_random(theta,obs): return 0 if np.matmul(theta,obs) < 0 else 1 def episode(env,policy, rewards_max,theta): obs = env.reset() done = False episode_reward = 0 while not done: action = policy(theta,obs) obs, reward, done, info = env.step(action) episode_reward += reward if episode_reward > rewards_max: break return episode_reward def train(policy, n_episodes, rewards_max): env = gym.make('CartPole-v0') theta_best = np.empty(shape=[4]) reward_best = 0 for i in range(n_episodes): if policy.__name__ in ['policy_random']: theta = np.random.rand(4) * 2 - 1 else: theta = None reward_episode=episode(env,policy,rewards_max, theta) if reward_episode > reward_best: reward_best = reward_episode theta_best = theta.copy() return reward_best,theta_best def experiment(policy, n_episodes, rewards_max, theta=None): rewards=np.empty(shape=[n_episodes]) env = gym.make('CartPole-v0') for i in range(n_episodes): rewards[i]=episode(env,policy,rewards_max,theta) #print("Episode finished at t{}".format(reward)) print('Policy:{}, Min reward:{}, Max reward:{}, Average reward:{}' .format(policy.__name__, np.min(rewards), np.max(rewards), np.mean(rewards))) n_episodes = 100 rewards_max = 10000 reward,theta = train(policy_random, n_episodes, rewards_max) print('trained theta: {}, rewards: {}'.format(theta,reward)) experiment(policy_random, n_episodes, rewards_max, theta) experiment(policy_logic, n_episodes, rewards_max)
我们训练了 100 集,然后使用最佳参数为随机搜索策略运行实验:
n_episodes = 100 rewards_max = 10000 reward,theta = train(policy_random, n_episodes, rewards_max) print('trained theta: {}, rewards: {}'.format(theta,reward)) experiment(policy_random, n_episodes, rewards_max, theta) experiment(policy_logic, n_episodes, rewards_max)
我们发现训练参数给出了 200 的最佳结果:
trained theta: [-0.14779543 0.93269603 0.70896423 0.84632461], rewards: 200.0 Policy:policy_random, Min reward:200.0, Max reward:200.0, Average reward:200.0 Policy:policy_logic, Min reward:24.0, Max reward:63.0, Average reward:41.94
我们可以优化训练代码以继续训练,直到我们获得最大奖励。笔记本ch-13a_Reinforcement_Learning_NN
中提供了此优化的代码。
现在我们已经学习了 OpenAI Gym 的基础知识,让我们学习强化学习。
强化学习 101
强化学习由智能体从前一个时间步骤输入观察和奖励并以动作产生输出来描述,目标是最大化累积奖励。
智能体具有策略,值函数和模型:
- 智能体用于选择下一个动作的算法称为策略。在上一节中,我们编写了一个策略,它将采用一组参数
θ
,并根据观察和参数之间的乘法返回下一个动作。该策略由以下等式表示:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Kqg27IjI-1681566540589)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/mastering-tf-1x-zh/img/73c06697-d661-4b7a-82ad-d4bfb078d386.png)]S
是一组状态,A
是一组动作。策略是确定性的或随机性的。
- 确定性策略在每次运行中为相同状态返回相同的操作:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6ditJhzf-1681566540589)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/mastering-tf-1x-zh/img/40b98256-188a-44e6-9aaf-d3b105a28424.png)] - 随机策略为每次运行中的相同状态返回相同操作的不同概率:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MCvqOFYm-1681566540589)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/mastering-tf-1x-zh/img/11dc9c49-c717-4115-b9a5-2015befdef3a.png)]
- 值函数根据当前状态中的所选动作预测长期奖励的数量。因此,值函数特定于智能体使用的策略。奖励表示行动的直接收益,而值函数表示行动的累积或长期未来收益。奖励由环境返回,值函数由智能体在每个时间步骤估计。
- 模型表示智能体在内部保存的环境。该模型可能是环境的不完美表示。智能体使用该模型来估计所选动作的奖励和下一个状态。
智能体的目标还可以是为马尔可夫决策过程(MDP)找到最优策略。 MDP 是从一个州到另一个州的观察,行动,奖励和过渡的数学表示。为简洁起见,我们将省略对 MDP 的讨论,并建议好奇的读者在互联网上搜索更深入 MDP 的资源。
Q 函数(在模型不可用时学习优化)
如果模型不可用,则智能体通过反复试验来学习模型和最优策略。当模型不可用时,智能体使用 Q 函数,其定义如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YLQiBOkR-1681566540590)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/mastering-tf-1x-zh/img/7bdea2f4-cb5e-43ab-b490-5c114303c6cf.png)]
如果状态s
处的智能体选择动作a
,则 Q 函数基本上将状态和动作对映射到表示预期总奖励的实数。
RL 算法的探索与利用
在没有模型的情况下,智能体在每一步都要探索或利用。 探索意味着智能体选择一个未知动作来找出奖励和模型。 利用意味着智能体选择最知名的行动来获得最大奖励。如果智能体总是决定利用它,那么它可能会陷入局部最优值。因此,有时智能体会绕过学到的策略来探索未知的行为。同样,如果智能体总是决定探索,那么它可能无法找到最优策略。因此,在探索和利用之间取得平衡非常重要。在我们的代码中,我们通过使用概率p
来选择随机动作和概率1-p
来选择最优动作来实现这一点。
V 函数(模型可用时学习优化)
如果事先知道模型,则智能体可以执行策略搜索以找到最大化值函数的最优策略。当模型可用时,智能体使用值函数,该函数可以朴素地定义为未来状态的奖励总和:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fv7GHNmM-1681566540590)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/mastering-tf-1x-zh/img/be0e1650-917d-4ff5-b5ca-31ce30f05ed8.png)]
因此,使用策略p
选择操作的时间步t
的值将是:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jNQeYBye-1681566540590)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/mastering-tf-1x-zh/img/1431616e-143f-4d1d-87b8-98d6000e8f31.png)]
V
是值,R
是奖励,值函数估计在未来最多n
个时间步长。
当智能体使用这种方法估计奖励时,它会平等地将所有行为视为奖励。在极点推车示例中,如果民意调查在步骤 50 处进行,则它将把直到第 50 步的所有步骤视为对跌倒的同等责任。因此,不是添加未来奖励,而是估计未来奖励的加权总和。通常,权重是提高到时间步长的折扣率。如果贴现率为零,则值函数变为上面讨论的幼稚函数,并且如果贴现率的值接近 1,例如 0.9 或 0.92,则与当前奖励相比,未来奖励的影响较小。
因此,现在行动a
的时间步t
的值将是:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iL5chU6e-1681566540590)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/mastering-tf-1x-zh/img/607cbf22-522c-4ffd-adc7-8f4ba95fe4ea.png)]
V
是值,R
是奖励,r
是折扣率。
精通 TensorFlow 1.x:11~15(4)https://developer.aliyun.com/article/1426827