2020-03-11 18:41:39 aaronjny 阅读数 212
  • 实用主义学Python(小白也容易上手的Python实用案例)

    原价169,早鸟价仅需99元 系统掌握Python核心语法16点,轻松应对工作中80%以上的Python使用场景! 99元=72讲+源码+社群答疑+讲师社群分享会  【哪些人适合学习这门课程?】 1)大学生,平时只学习了Python理论,并未接触Python实战问题; 2)对Python实用技能掌握薄弱的人,自动化、爬虫、数据分析能让你快速提高工作效率; 3)想学习新技术,如:人工智能、机器学习、深度学习等,这门课程是你的必修课程; 4)想修炼更好的编程内功,优秀的工程师肯定不能只会一门语言,Python语言功能强大、使用高效、简单易学。 【超实用技能】 从零开始 自动生成工作周报 职场升级 豆瓣电影数据爬取 实用案例 奥运冠军数据分析 自动化办公 :通过Python自动化分析Excel数据并自动操作Word文档,最终获得一份基于Excel表格的数据分析报告。 豆瓣电影爬虫: 通过Python自动爬取豆瓣电影信息并将电影图片保存到本地。 奥运会数据分析实战 简介:通过Python分析120年间奥运会的数据,从不同角度入手分析,从而得出一些有趣的结论。 【超人气老师】 二两 中国人工智能协会高级会员 生成对抗神经网络研究者 《深入浅出生成对抗网络:原理剖析与TensorFlow实现》一书作者 阿里云大学云学院导师 前大型游戏公司后端工程师 【超丰富实用案例】 0)图片背景去除案例 1)自动生成工作周报案例 2)豆瓣电影数据爬取案例 3)奥运会数据分析案例 4)自动处理邮件案例 5)github信息爬取/更新提醒案例 6)B站百大UP信息爬取与分析案例 7)构建自己的论文网站案例

    2573 人正在学习 去看看 廖茂文

前言

前阵子使用RNN写了个古体诗生成器(有趣的深度学习——使用TensorFlow 2.0 + RNN 实现一个古体诗生成器)的NLP小Demo玩玩。而现在说到NLP,就很难绕开Transformers系列模型,譬如BERT、GPT-2、RoBERTa、ALBERT、XLNet等等。Transformers系列模型不断刷新着NLP任务得分记录,在绝大多数任务下都远胜于传统的、基于RNN的NLP任务。

那么,既然之前用RNN写了个古体诗生成器,我们不妨也用BERT写一个吧,正好对比一下效果。

转载请注明来源:https://blog.csdn.net/aaronjny/article/details/104802847

解读

代码结构和功能与有趣的深度学习——使用TensorFlow 2.0 + RNN 实现一个古体诗生成器(https://blog.csdn.net/aaronjny/article/details/103806954)基本上相同,只是将模型从RNN换成了BERT,注释也很详细,感觉没有解读的必要了。

对照着这两份文档就能搞清楚:

基于RNN的模型的详细文档:使用TensorFlow 2.0 + RNN 实现一个古体诗生成器

基于BERT模型的项目源码(即本项目的源码):DeepLearningExamples/keras-bert-poetry-generator

演示

随机生成一首古体诗:

不见山头寺,唯闻竹下僧。
白云生寺远,青壁入山深。
夜宿高楼月,秋眠白阁钟。
不缘山下路,何事见僧踪。
千里彩云千里别,再来还访玉京师。
三年不负青云志,此地终须见汝时。

续写一首古体诗(以"床前明月光,"为例):

床前明月光,无端出曙寒。
夜来应不寐,头白露沾袍。
床前明月光,不见到天涯。
寂寞海云外,寥寥孤烛前。

随机生成一首藏头诗(以"海阔天空"为例):

海燕朝朝去,
阔鸥还远居。
天寒疑水势,
空见见鱼行。
海上苍须插锦鳞,
阔无心计似文君。
天涯本是无心物,
空解将人学钓鳌。

BERT 模型使用的是苏剑林大佬封装的 bert4keras,开发过程中参考了 bert4keras 的 demo

模型参数使用的是 Google 官方在中文语料上的预训练权重 BERT-Base, Chinese,下载地址为 https://storage.googleapis.com/bert_models/2018_11_03/chinese_L-12_H-768_A-12.zip

分析

对比可以发现,预训练的BERT模型在此任务下确实表现良好,远胜于RNN模型。模型在简单的迭代后,很快就能生成还算不错的内容。仔细观察输出的内容,可以发现,在大部分语句中,模型是遵守仄起平收的(一个还算客观的评价标准?)。然后主观上来看,意境上也要稍优于RNN模型?(个人看法,这里就见仁见智啦。虽然严格来说,都是基于概率统计的生搬硬凑……)

结语

嘛,就目前来看,Transformers系列模型是大势所趋咯。作为预训练的模型,对于在小公司工作、或个人兴趣开发者来说,真的是个很好的消息。因为你不需要准备一大堆数据,然后在一大批昂贵的GPU、TPU设备上训练长达数周乃至数月的时间,只需要下载某个大公司(Google、华为等)花费较大代价训练好的预训练模型数据,经过简单的fine-tune,即可在你要处理的NLP任务上取得较好的结果,节省大量的时间和资金。

当然啦,如果你的任务追求极致,那就另说啦。

如果你喜欢这篇文章的话,麻烦给点个赞呗~谢谢大佬~

文中如有错漏之处,还请大佬们指正哈~

2017-04-07 22:13:44 CoderPai 阅读数 7237
  • 实用主义学Python(小白也容易上手的Python实用案例)

    原价169,早鸟价仅需99元 系统掌握Python核心语法16点,轻松应对工作中80%以上的Python使用场景! 99元=72讲+源码+社群答疑+讲师社群分享会  【哪些人适合学习这门课程?】 1)大学生,平时只学习了Python理论,并未接触Python实战问题; 2)对Python实用技能掌握薄弱的人,自动化、爬虫、数据分析能让你快速提高工作效率; 3)想学习新技术,如:人工智能、机器学习、深度学习等,这门课程是你的必修课程; 4)想修炼更好的编程内功,优秀的工程师肯定不能只会一门语言,Python语言功能强大、使用高效、简单易学。 【超实用技能】 从零开始 自动生成工作周报 职场升级 豆瓣电影数据爬取 实用案例 奥运冠军数据分析 自动化办公 :通过Python自动化分析Excel数据并自动操作Word文档,最终获得一份基于Excel表格的数据分析报告。 豆瓣电影爬虫: 通过Python自动爬取豆瓣电影信息并将电影图片保存到本地。 奥运会数据分析实战 简介:通过Python分析120年间奥运会的数据,从不同角度入手分析,从而得出一些有趣的结论。 【超人气老师】 二两 中国人工智能协会高级会员 生成对抗神经网络研究者 《深入浅出生成对抗网络:原理剖析与TensorFlow实现》一书作者 阿里云大学云学院导师 前大型游戏公司后端工程师 【超丰富实用案例】 0)图片背景去除案例 1)自动生成工作周报案例 2)豆瓣电影数据爬取案例 3)奥运会数据分析案例 4)自动处理邮件案例 5)github信息爬取/更新提醒案例 6)B站百大UP信息爬取与分析案例 7)构建自己的论文网站案例

    2573 人正在学习 去看看 廖茂文

更大的标注数据集和更多可用的计算能力是AI革命的基石。在本文中,我列出了我们最近为数据科学家发现的一些非常好玩的深度学习数据集。

1. EMNIST: An Extension of MNIST to Handwritten Letters

MNIST is a very popular dataset for people getting started with Deep Learning in particular and Machine Learning on images in general. MNIST has images of digits which are to be mapped to the digits themselves. EMNIST extends this to images of letters as well. The dataset can be downloaded here . There is an alternative dataset we discovered as well on Reddit. It’s called HASYv2 and can be downloaded here

2. HICO & HICO-DET

HICO has images containing multiple objects and these objects have been tagged along with their relationships. The proposed problem is for algorithms to be able to dig out objects in an image and relationship between them after being trained on this dataset. I expect multiple papers to come out of this dataset in future.

3. CLEVR: A Diagnostic Dataset for Compositional Language and Elementary Visual Reasoning

CLEVR is an attempt by Fei-Fei Li’s group, the same scientist who developed the revolutionary ImageNet dataset. It has objects and questions asked about those objects along with their answers specified by humans. The aim of the project is to develop machines with common sense about what they see. So for example, the machine should be able to find “an odd one out” in an image automatically. You can download the dataset here.

4. HolStep: A Machine Learning Dataset for Higher-order Logic Theorem Proving

This dataset is tagged in a way so that algorithms trained on it can be used for automatic theorem proving . The download link is here.

5. The Parallel Meaning Bank: Towards a Multilingual Corpus of Translations Annotated with Compositional Meaning Representations

The Parallel Meaning Bank (PMB), developed at the University of Groningen, comprises sentences and texts in raw and tokenised format, tags for part of speech, named entities and lexical categories, and formal meaning representations. The download link is here.

6. JFLEG: A Fluency Corpus and Benchmark for Grammatical Error Correction

JFLEG dataset is an aim to tag sentences with nominal grammatical corrections and smart grammatical corrections. This dataset aims to build machines that can correct grammar automatically for people making mistakes. The dataset can be downloaded here.

7. Introducing VQA v2.0: A More Balanced and Bigger VQA Dataset!

This dataset has images, questions asked on them and their answers tagged. The aim is to train machines to answer questions asked about images (and in continuation about the real world they are seeing). Visual QA is an old dataset but its 2.0 version came out just this december.

8. Google Cloud & YouTube-8M Video Understanding Challenge

Probably the largest dataset available for training in the open. This is a dataset of 8 Million Youtube videos tagged with the objects within them. There is also a running Kaggle competition on the dataset with a bounty of 1,00,000 dollars.

9. Data Science Bowl 2017

This turns out to be the largest bounty offered to crack a Data Science problem. There are prizes of $1 Million to be grabbed by Data Scientists who can detect lung cancer using this dataset of tagges CT-Scans.

10. Exoplanets Dataset

Today, a team that includes MIT and is led by the Carnegie Institution for Science has released the largest collection of observations made with a technique called radial velocity, to be used for hunting exoplanets. The dataset can be downloaded here.

11. End-to-End Interpretation of the French Street Name Signs Dataset

This is a huge dataset of French Street signs labeled with what they denote. The dataset is easily readable by everyone’s favorite Tensorflow and can be downloaded here.

12. A Realistic Dataset for the Smart Home Device Scheduling Problem for DCOPs

An upcoming dataset for IoT and AI interface. You can download it here.

13. RepEval 2017 Shared Task

From Sam Bowman’s team, the creators of the famous SNLI dataset, this dataset about understanding the meaning of the text is going to be out soon as a competition. The dataset is expected by 15th March. You can find it here once it’s live.

14. Driver Speed Dataset

A 200 Gb huge dataset, which is aimed to calculate speed of moving vehicles. Can be downloaded here.

15. NWPU-RESISC45 Remote sensing images dataset

A huge dataset of remote sensing images covering a wide array of landscapes which can be seen through sattelites. Potential technology that can be developed includes satellite surveys, monitoring, and surveillance. Unfortunately, we are still waiting for the download link here.

16. Recipe to create your own free datasets from the open web

This is probably the most interesting of the datasets. This dataset has not been tagged by humans but by machines. Also, the authors make things clear about what is to be done if we want to create a similar dataset from the millions of images which are already available on the web.

17. The LIP Dataset

This large-scale data set focuses on the semantic understanding of a person. The download link for the dataset is here.

18. WikiReading Data

This dataset is a large-scale natural language understanding task and publicly-available dataset with 18 million instances. The downlaod link is here.

19. MUSCIMA++

MUSCIMA++ is a dataset of handwritten music notation for musical symbol detection. Here is the download link.

20. DeScript (Describing Script Structure)

DeScript is a crowdsourced corpus of event sequence descriptions (ESDs) for different scenarios crowdsourced via Amazon Mechanical Turk. Here is the download link.


Reference:

http://blog.paralleldots.com/data-scientist/new-deep-learning-datasets-data-scientists/


如果觉得内容有用,帮助多多分享哦 :)

长按或者扫描如下二维码,关注 “CoderPai” 微信号(coderpai)。添加底部的 coderpai 小助手,添加小助手时,请备注 “算法” 二字,小助手会拉你进算法群。如果你想进入 AI 实战群,那么请备注 “AI”,小助手会拉你进AI实战群。

2020-03-15 15:21:38 aaronjny 阅读数 1563
  • 实用主义学Python(小白也容易上手的Python实用案例)

    原价169,早鸟价仅需99元 系统掌握Python核心语法16点,轻松应对工作中80%以上的Python使用场景! 99元=72讲+源码+社群答疑+讲师社群分享会  【哪些人适合学习这门课程?】 1)大学生,平时只学习了Python理论,并未接触Python实战问题; 2)对Python实用技能掌握薄弱的人,自动化、爬虫、数据分析能让你快速提高工作效率; 3)想学习新技术,如:人工智能、机器学习、深度学习等,这门课程是你的必修课程; 4)想修炼更好的编程内功,优秀的工程师肯定不能只会一门语言,Python语言功能强大、使用高效、简单易学。 【超实用技能】 从零开始 自动生成工作周报 职场升级 豆瓣电影数据爬取 实用案例 奥运冠军数据分析 自动化办公 :通过Python自动化分析Excel数据并自动操作Word文档,最终获得一份基于Excel表格的数据分析报告。 豆瓣电影爬虫: 通过Python自动爬取豆瓣电影信息并将电影图片保存到本地。 奥运会数据分析实战 简介:通过Python分析120年间奥运会的数据,从不同角度入手分析,从而得出一些有趣的结论。 【超人气老师】 二两 中国人工智能协会高级会员 生成对抗神经网络研究者 《深入浅出生成对抗网络:原理剖析与TensorFlow实现》一书作者 阿里云大学云学院导师 前大型游戏公司后端工程师 【超丰富实用案例】 0)图片背景去除案例 1)自动生成工作周报案例 2)豆瓣电影数据爬取案例 3)奥运会数据分析案例 4)自动处理邮件案例 5)github信息爬取/更新提醒案例 6)B站百大UP信息爬取与分析案例 7)构建自己的论文网站案例

    2573 人正在学习 去看看 廖茂文

前言

这也是一个重写的项目,之前用Python 2.7 + TensorFlow 1.4写的图片神经风格迁移的项目(TensorFlow 练手项目三:使用 VGG19 迁移学习实现图像风格迁移)直到现在还有很多朋友问我相关问题,毕竟环境太过古老,如今很难顺利跑起来,可能要做不少兼容性的调整(除非照装一样的环境……)。于是,我抽时间用TensorFlow 2.0重写了一下。

先做一下简单演示(所有演示图片来源于网络,侵删),风格图片统一使用《星夜》:

在这里插入图片描述

示例1:

输入图片

在这里插入图片描述

输出图片

在这里插入图片描述

示例2:

输入图片

在这里插入图片描述

输出图片

在这里插入图片描述

项目 GitHub 地址:

DeepLearningExamples/tf2-neural-style-transfer : https://github.com/AaronJny/DeepLearningExamples/tree/master/tf2-neural-style-transfer

转载请注明来源:https://blog.csdn.net/aaronjny/article/details/104879258

代码解读

这是一个重写项目,原理上和TensorFlow 练手项目三:使用 VGG19 迁移学习实现图像风格迁移没有任何区别,可以直接参考原博文了解细节。只是部分细节上有所差异,我会分别进行说明。公式原理方面请参考老博文,就不赘述了。

1.迁移学习

项目仍然使用在imagenet上预训练的vgg19网络做迁移学习。区别在于,本次我们直接使用tf.keras.applications模块加载预训练的vgg19网络,更加方便。

2.进度提示

为了方便观察训练进度,使用tqdm做了进度提示,并实时输出最新的loss。下面是一次执行的示例:

Epoch 1/20: 100%|██████████| 100/100 [00:09<00:00, 10.37it/s, loss=22066.4688]
Epoch 2/20: 100%|██████████| 100/100 [00:07<00:00, 13.09it/s, loss=12479.9658]
Epoch 3/20: 100%|██████████| 100/100 [00:07<00:00, 13.06it/s, loss=9065.9258]
Epoch 4/20: 100%|██████████| 100/100 [00:07<00:00, 13.06it/s, loss=6993.3652]
Epoch 5/20: 100%|██████████| 100/100 [00:07<00:00, 13.02it/s, loss=5558.0947]
Epoch 6/20: 100%|██████████| 100/100 [00:07<00:00, 13.03it/s, loss=4526.5439]
Epoch 7/20: 100%|██████████| 100/100 [00:07<00:00, 13.01it/s, loss=3777.7947]
Epoch 8/20: 100%|██████████| 100/100 [00:07<00:00, 13.00it/s, loss=3228.8064]
Epoch 9/20: 100%|██████████| 100/100 [00:07<00:00, 12.98it/s, loss=2821.5425]
Epoch 10/20: 100%|██████████| 100/100 [00:07<00:00, 12.98it/s, loss=2515.5208]
Epoch 11/20: 100%|██████████| 100/100 [00:07<00:00, 12.97it/s, loss=2278.1858]
Epoch 12/20: 100%|██████████| 100/100 [00:07<00:00, 12.96it/s, loss=2090.5942]
Epoch 13/20: 100%|██████████| 100/100 [00:07<00:00, 12.95it/s, loss=1939.2296]
Epoch 14/20: 100%|██████████| 100/100 [00:07<00:00, 12.95it/s, loss=1813.9688]
Epoch 15/20: 100%|██████████| 100/100 [00:07<00:00, 12.94it/s, loss=1708.0551]
Epoch 16/20: 100%|██████████| 100/100 [00:07<00:00, 12.93it/s, loss=1628.9713]
Epoch 17/20: 100%|██████████| 100/100 [00:07<00:00, 12.93it/s, loss=1545.6821]
Epoch 18/20: 100%|██████████| 100/100 [00:07<00:00, 12.93it/s, loss=1917.6001]
Epoch 19/20: 100%|██████████| 100/100 [00:07<00:00, 12.91it/s, loss=1416.0177]
Epoch 20/20: 100%|██████████| 100/100 [00:07<00:00, 12.91it/s, loss=1359.5453]

Process finished with exit code 0

3.加速计算

TensorFlow 2.0 默认使用动态图模式,性能上还是有影响的。所以在单次迭代过程中,使用了tf.function利用AutoGraph技术,将迭代过程构造成静态图,加速计算。经测试,在本任务中,不使用tf.function训练花费的时间约为使用tf.function的两倍。

我的计算设备为GTX 1060,共训练20个epoch,每个epoch训练100次。单个epoch训练约花费7秒。

4.学习率

为了快速降低loss,且我只训练20个epoch,所以选择了比较大的学习率。我不要求loss足够低,生成的图片满意就行,在此学习率下训练20个epoch还不至于出现在局部最优解周围秘技*反复横跳的情况,但继续训练下去应该会遇到此问题。如果想要把loss降到足够低,可以在增大训练epoch数的同时,选择较小的学习率,或者使用学习率衰减。但需要明白,这么做需要花费更多的时间,我觉得在这个任务上是没有必要的。

使用说明

下面说明如何使用此项目,快速开始体验。

我的开发环境是Python 3.7,通过Anaconda安装的,所以下面指令中的python和pip请酌情替换成python3和pip3。

1.clone 项目:

git clone https://github.com/AaronJny/DeepLearningExamples.git

2.切换到子项目根目录:

cd DeepLearningExamples/tf2-neural-style-transfer

3.安装依赖环境:

pip install -r requirements.txt

4.根据个人需求,修改settings.py中的配置参数。

5.运行训练脚本:

python train.py

运行成功则会输出训练进度,训练完成后在输出目录(默认./output)下能看到生成的图片,默认每个epoch保存一次生成的图片。

下面给出一次训练过程中生成的20张图片,它们直观地展示了神经风格迁移的过程。在这渐进式的过程中,观察两张相邻epoch的图片时,不细看很难看出两张图片的区别。但如果直接对比第一张生成图片和最后一张,感受还是挺明显的:

Epoch 1:

在这里插入图片描述

Epoch 2:

在这里插入图片描述

Epoch 3:

在这里插入图片描述

Epoch 4:

在这里插入图片描述

Epoch 5:

在这里插入图片描述

Epoch 6:

在这里插入图片描述

Epoch 7:

在这里插入图片描述

Epoch 8:

在这里插入图片描述

Epoch 9:

在这里插入图片描述

Epoch 10:

在这里插入图片描述

Epoch 11:

在这里插入图片描述

Epoch 12:

在这里插入图片描述

Epoch 13:

在这里插入图片描述

Epoch 14:

在这里插入图片描述

Epoch 15:

在这里插入图片描述

Epoch 16:

在这里插入图片描述

Epoch 17:

在这里插入图片描述

Epoch 18:

在这里插入图片描述

Epoch 19:

在这里插入图片描述

Epoch 20:

在这里插入图片描述

结语

好了,以上就是这篇文章的全部内容,感谢您的阅读~

如果你喜欢这篇文章的话,麻烦给点个赞呗 ~谢谢大佬 ~

文中如有错漏之处,还请大佬们指正哈 ~

2019-05-17 11:18:52 hgy413 阅读数 57
  • 实用主义学Python(小白也容易上手的Python实用案例)

    原价169,早鸟价仅需99元 系统掌握Python核心语法16点,轻松应对工作中80%以上的Python使用场景! 99元=72讲+源码+社群答疑+讲师社群分享会  【哪些人适合学习这门课程?】 1)大学生,平时只学习了Python理论,并未接触Python实战问题; 2)对Python实用技能掌握薄弱的人,自动化、爬虫、数据分析能让你快速提高工作效率; 3)想学习新技术,如:人工智能、机器学习、深度学习等,这门课程是你的必修课程; 4)想修炼更好的编程内功,优秀的工程师肯定不能只会一门语言,Python语言功能强大、使用高效、简单易学。 【超实用技能】 从零开始 自动生成工作周报 职场升级 豆瓣电影数据爬取 实用案例 奥运冠军数据分析 自动化办公 :通过Python自动化分析Excel数据并自动操作Word文档,最终获得一份基于Excel表格的数据分析报告。 豆瓣电影爬虫: 通过Python自动爬取豆瓣电影信息并将电影图片保存到本地。 奥运会数据分析实战 简介:通过Python分析120年间奥运会的数据,从不同角度入手分析,从而得出一些有趣的结论。 【超人气老师】 二两 中国人工智能协会高级会员 生成对抗神经网络研究者 《深入浅出生成对抗网络:原理剖析与TensorFlow实现》一书作者 阿里云大学云学院导师 前大型游戏公司后端工程师 【超丰富实用案例】 0)图片背景去除案例 1)自动生成工作周报案例 2)豆瓣电影数据爬取案例 3)奥运会数据分析案例 4)自动处理邮件案例 5)github信息爬取/更新提醒案例 6)B站百大UP信息爬取与分析案例 7)构建自己的论文网站案例

    2573 人正在学习 去看看 廖茂文

风格迁移

windows安装

1.下载Miniconda,并安装。

2.打开Anaconda Prompt,并输入以下命令:

conda create -n style-transfer python=2.7.9
source activate style-transfer
pip install tensorflow
conda install scipy pillow

第一行创建一个新的环境,其中存储了格式迁移代码所需的程序包。第二行 (source activate style-transfer) 进入该环境,你应该会在提示符窗口的开头看到环境名称。接下来的两行负责安装 TensorFlow、Scipy 和 Pillow(一种图像处理库)。

安装时间有点久。

迁移风格

1.从fast-style-transfer资源库中下载 Zip 归档文件并解压。你可以通过点击右侧的亮绿色按钮进行下载。
2.从此处下载 Rain Princess 检查点,将其放在 fast-style-transfer 文件夹中。检查点文件是已经调谐参数的模型。使用此检查点文件后我们不需要再训练该模型,可以直接使用。
3.将你要调整格式的图片放到 fast-style-transfer 文件夹,就叫input.jpg
4.进入你之前创建的 Conda 环境(如果不在里面的话)。
5.在终端里,转到 fast-style-transfer 文件夹并输入:

python evaluate.py --checkpoint ./rain-princess.ckpt --in-path ./input.jpg --out-path ./output_image.jpg

如果提示No module named 'scipy'错误,就先运行一下pip install scipy安装即可,最终效果图如下:

在这里插入图片描述

特别注意:输入图片的大小不能太大,不然会花费相当长的时间

DeepTraffic

使用神经网络的交通模拟游戏:https://selfdrivingcars.mit.edu/deeptraffic/:
在这里插入图片描述
在这里插入图片描述

Flappy Bird

1.打开Anaconda Prompt,并输入以下命令:

conda create --name=flappybird python=3.5
activate flappybird
conda install -c menpo opencv3
pip install pygame
pip install tensorflow
git clone https://github.com/yenchenlin/DeepLearningFlappyBird.git
cd DeepLearningFlappyBird
python deep_q_network.py

其中git clone https://github.com/yenchenlin/DeepLearningFlappyBird.git 如果报错,你可以单独使用git bash下载
我在运行时,还遇到一个错误,就是Check failed: PyBfloat16_Type.tp_base != nullptr,解决方案是升级numpy:

python -m pip install --upgrade numpy

如果一切正常,你应该会看到一个基于深度学习的代理在玩 Flappy Bird!最终效果如下:
在这里插入图片描述

2020-01-02 16:46:29 aaronjny 阅读数 1623
  • 实用主义学Python(小白也容易上手的Python实用案例)

    原价169,早鸟价仅需99元 系统掌握Python核心语法16点,轻松应对工作中80%以上的Python使用场景! 99元=72讲+源码+社群答疑+讲师社群分享会  【哪些人适合学习这门课程?】 1)大学生,平时只学习了Python理论,并未接触Python实战问题; 2)对Python实用技能掌握薄弱的人,自动化、爬虫、数据分析能让你快速提高工作效率; 3)想学习新技术,如:人工智能、机器学习、深度学习等,这门课程是你的必修课程; 4)想修炼更好的编程内功,优秀的工程师肯定不能只会一门语言,Python语言功能强大、使用高效、简单易学。 【超实用技能】 从零开始 自动生成工作周报 职场升级 豆瓣电影数据爬取 实用案例 奥运冠军数据分析 自动化办公 :通过Python自动化分析Excel数据并自动操作Word文档,最终获得一份基于Excel表格的数据分析报告。 豆瓣电影爬虫: 通过Python自动爬取豆瓣电影信息并将电影图片保存到本地。 奥运会数据分析实战 简介:通过Python分析120年间奥运会的数据,从不同角度入手分析,从而得出一些有趣的结论。 【超人气老师】 二两 中国人工智能协会高级会员 生成对抗神经网络研究者 《深入浅出生成对抗网络:原理剖析与TensorFlow实现》一书作者 阿里云大学云学院导师 前大型游戏公司后端工程师 【超丰富实用案例】 0)图片背景去除案例 1)自动生成工作周报案例 2)豆瓣电影数据爬取案例 3)奥运会数据分析案例 4)自动处理邮件案例 5)github信息爬取/更新提醒案例 6)B站百大UP信息爬取与分析案例 7)构建自己的论文网站案例

    2573 人正在学习 去看看 廖茂文

一、前言

很早之前,我曾经写过一个古体诗生成器(详情可以戳TensorFlow练手项目二:基于循环神经网络(RNN)的古诗生成器),那个时候用的还是Python 2.7和TensorFlow 1.4。

随着框架的迭代,API 的变更,老项目已经很难无障碍运行起来了。有不少朋友在老项目下提出了各种问题,于是,我就萌生了使用TensorFlow 2.0重写项目的想法。

这不,终于抽空,重写了这个项目。

完整的项目已经放到了GitHub上:

AaronJny/DeepLearningExamples/tf2-rnn-poetry-generator (https://github.com/AaronJny/DeepLearningExamples/tree/master/tf2-rnn-poetry-generator)

先对项目做个简单展示。项目主要包含如下功能:

  • 使用唐诗数据集训练模型。
  • 使用训练好的模型,随机生成一首古体诗。
  • 使用训练好的模型,续写一首古体诗。
  • 使用训练好的模型,随机生成一首藏头诗。

随机生成一首古体诗:

金鹤有僧心,临天寄旧身。
石松惊枕树,红鸟发禅新。
不到风前远,何人怨夕时。
明期多尔处,闲此不依迟。
水泉临鸟声,北去暮空行。
林阁多开雪,楼庭起洞城。
夜来疏竹外,柳鸟暗苔清。
寂寂重阳里,悠悠一钓矶。

续写一首古体诗(以"床前明月光,"为例):

床前明月光,翠席覆银丝。
岁气分龙阁,无人入鸟稀。
圣明无泛物,云庙逐雕旗。
永夜重江望,南风正送君。
床前明月光,清水入寒云。
远景千山雨,萧花入翠微。
影云虚雪润,花影落云斜。
独去江飞夜,谁能作一花。

随机生成一首藏头诗(以"海阔天空"为例):

海口多无定,
阔庭何所难。
天山秋色上,
空石昼尘连。
海庭愁不定,
阔处到南关。
天阙青秋上,
空城雁渐催。

下面开始讲解项目实现过程。

转载请注明来源:https://blog.csdn.net/aaronjny/article/details/103806954

二、数据集处理

跟老项目一样,我们仍然使用四万首唐诗的文本作为训练集(已经上传,可以直接从GitHub上下载)。我们打开文本,看一下数据格式:

在这里插入图片描述

能够看到,文本中每行是一首诗,且使用冒号分割,前面是标题,后面是正文,且诗的长度不一。

我们对数据的处理流程大致如下:

  1. 读取文本,按行切分,构成古诗列表。
  2. 将全角、半角的冒号统一替换成半角的。
  3. 按冒号切分诗的标题和内容,只保留诗的内容。
  4. 考虑到模型的大小,我们只保留内容长度小于一定长度的古诗。
  5. 统计保留的诗中的词频,去掉低频词,构建词汇表。

代码如下:

# -*- coding: utf-8 -*-
# @File    : dataset.py
# @Author  : AaronJny
# @Time    : 2019/12/30
# @Desc    : 构建数据集
from collections import Counter
import math
import numpy as np
import tensorflow as tf
import settings

# 禁用词
disallowed_words = settings.DISALLOWED_WORDS
# 句子最大长度
max_len = settings.MAX_LEN
# 最小词频
min_word_frequency = settings.MIN_WORD_FREQUENCY
# mini batch 大小
batch_size = settings.BATCH_SIZE

# 加载数据集
with open(settings.DATASET_PATH, 'r', encoding='utf-8') as f:
    lines = f.readlines()
    # 将冒号统一成相同格式
    lines = [line.replace(':', ':') for line in lines]
# 数据集列表
poetry = []
# 逐行处理读取到的数据
for line in lines:
    # 有且只能有一个冒号用来分割标题
    if line.count(':') != 1:
        continue
    # 后半部分不能包含禁止词
    __, last_part = line.split(':')
    ignore_flag = False
    for dis_word in disallowed_words:
        if dis_word in last_part:
            ignore_flag = True
            break
    if ignore_flag:
        continue
    # 长度不能超过最大长度
    if len(last_part) > max_len - 2:
        continue
    poetry.append(last_part.replace('\n', ''))

# 统计词频
counter = Counter()
for line in poetry:
    counter.update(line)
# 过滤掉低频词
_tokens = [(token, count) for token, count in counter.items() if count >= min_word_frequency]
# 按词频排序
_tokens = sorted(_tokens, key=lambda x: -x[1])
# 去掉词频,只保留词列表
_tokens = [token for token, count in _tokens]

# 将特殊词和数据集中的词拼接起来
_tokens = ['[PAD]', '[UNK]', '[CLS]', '[SEP]'] + _tokens
# 创建词典 token->id映射关系
token_id_dict = dict(zip(_tokens, range(len(_tokens))))
# 使用新词典重新建立分词器
tokenizer = Tokenizer(token_id_dict)
# 混洗数据
np.random.shuffle(poetry)

代码很简单,注释也很清晰,就不一行一行说了。有几点需要注意一下:

  • 我们需要一些特殊字符,以完成特定的功能。这里使用的特殊字符有四个,为’[PAD]’, ‘[UNK]’, ‘[CLS]’, ‘[SEP]’,它们分别代表填充字符、低频词、古诗开始标记、古诗结束标记。
  • 代码中出现了一个类——Tokenizer,这是为了方便我们完成字符转编号、编号转字符、字符串转编号序列、编号序列转字符串等操作而编写的一个辅助类。它的代码也很简单,我们来看一下。
class Tokenizer:
    """
    分词器
    """

    def __init__(self, token_dict):
        # 词->编号的映射
        self.token_dict = token_dict
        # 编号->词的映射
        self.token_dict_rev = {value: key for key, value in self.token_dict.items()}
        # 词汇表大小
        self.vocab_size = len(self.token_dict)

    def id_to_token(self, token_id):
        """
        给定一个编号,查找词汇表中对应的词
        :param token_id: 带查找词的编号
        :return: 编号对应的词
        """
        return self.token_dict_rev[token_id]

    def token_to_id(self, token):
        """
        给定一个词,查找它在词汇表中的编号
        未找到则返回低频词[UNK]的编号
        :param token: 带查找编号的词
        :return: 词的编号
        """
        return self.token_dict.get(token, self.token_dict['[UNK]'])

    def encode(self, tokens):
        """
        给定一个字符串s,在头尾分别加上标记开始和结束的特殊字符,并将它转成对应的编号序列
        :param tokens: 待编码字符串
        :return: 编号序列
        """
        # 加上开始标记
        token_ids = [self.token_to_id('[CLS]'), ]
        # 加入字符串编号序列
        for token in tokens:
            token_ids.append(self.token_to_id(token))
        # 加上结束标记
        token_ids.append(self.token_to_id('[SEP]'))
        return token_ids

    def decode(self, token_ids):
        """
        给定一个编号序列,将它解码成字符串
        :param token_ids: 待解码的编号序列
        :return: 解码出的字符串
        """
        # 起止标记字符特殊处理
        spec_tokens = {'[CLS]', '[SEP]'}
        # 保存解码出的字符的list
        tokens = []
        for token_id in token_ids:
            token = self.id_to_token(token_id)
            if token in spec_tokens:
                continue
            tokens.append(token)
        # 拼接字符串
        return ''.join(tokens)

我的注释都写得很细,阅读起来应该不存在问题。上面的代码中引用了一些配置项,这些配置项被我统一提取到了settings.py里,贴出来以供查阅:

# -*- coding: utf-8 -*-
# @File    : settings.py
# @Author  : AaronJny
# @Time    : 2019/12/25
# @Desc    :

# 禁用词,包含如下字符的唐诗将被忽略
DISALLOWED_WORDS = ['(', ')', '(', ')', '__', '《', '》', '【', '】', '[', ']']
# 句子最大长度
MAX_LEN = 64
# 最小词频
MIN_WORD_FREQUENCY = 8
# 训练的batch size
BATCH_SIZE = 16
# 数据集路径
DATASET_PATH = './poetry.txt'
# 每个epoch训练完成后,随机生成SHOW_NUM首古诗作为展示
SHOW_NUM = 5
# 共训练多少个epoch
TRAIN_EPOCHS = 20
# 最佳权重保存路径
BEST_MODEL_PATH = './best_model.h5'

好的,我们已经对数据进行了处理,并构建了分词器。为了方便训练,我们还需要再编写一个生成器,对数据集进行封装:

class PoetryDataGenerator:
    """
    古诗数据集生成器
    """

    def __init__(self, data, random=False):
        # 数据集
        self.data = data
        # batch size
        self.batch_size = batch_size
        # 每个epoch迭代的步数
        self.steps = int(math.floor(len(self.data) / self.batch_size))
        # 每个epoch开始时是否随机混洗
        self.random = random

    def sequence_padding(self, data, length=None, padding=None):
        """
        将给定数据填充到相同长度
        :param data: 待填充数据
        :param length: 填充后的长度,不传递此参数则使用data中的最大长度
        :param padding: 用于填充的数据,不传递此参数则使用[PAD]的对应编号
        :return: 填充后的数据
        """
        # 计算填充长度
        if length is None:
            length = max(map(len, data))
        # 计算填充数据
        if padding is None:
            padding = tokenizer.token_to_id('[PAD]')
        # 开始填充
        outputs = []
        for line in data:
            padding_length = length - len(line)
            # 不足就进行填充
            if padding_length > 0:
                outputs.append(np.concatenate([line, [padding] * padding_length]))
            # 超过就进行截断
            else:
                outputs.append(line[:length])
        return np.array(outputs)

    def __len__(self):
        return self.steps

    def __iter__(self):
        total = len(self.data)
        # 是否随机混洗
        if self.random:
            np.random.shuffle(self.data)
        # 迭代一个epoch,每次yield一个batch
        for start in range(0, total, self.batch_size):
            end = min(start + self.batch_size, total)
            batch_data = []
            # 逐一对古诗进行编码
            for single_data in self.data[start:end]:
                batch_data.append(tokenizer.encode(single_data))
            # 填充为相同长度
            batch_data = self.sequence_padding(batch_data)
            # yield x,y
            yield batch_data[:, :-1], tf.one_hot(batch_data[:, 1:], tokenizer.vocab_size)
            del batch_data

    def for_fit(self):
        """
        创建一个生成器,用于训练
        """
        # 死循环,当数据训练一个epoch之后,重新迭代数据
        while True:
            # 委托生成器
            yield from self.__iter__()

写成生成器的形式,主要出于内存方面的考虑。训练时需要对数据进行填充、转one-hot形式等操作,会占用较多内存。如果提前对全部数据都进行处理,内存可能会溢出。而以生成器的形式,可以只在要进行训练的时候,处理相应batch size的数据即可。

另外,注意这一句:

yield batch_data[:, :-1], tf.one_hot(batch_data[:, 1:], tokenizer.vocab_size)

前面部分是数据x,后面部分是标签y。将诗的内容错开一位分别作为数据和标签,举个例子,假设有诗是“[CLS]床前明月光,疑是地上霜。举头望明月,低头思故乡。[SEP]”,则数据为“[CLS]床前明月光,疑是地上霜。举头望明月,低头思故乡。”,标签为“床前明月光,疑是地上霜。举头望明月,低头思故乡。[SEP]”,两者一一对应,y是x中每个位置的下一个字符。

当然了,以字符的形式举例是为了方便理解,实际上不论是数据还是标签,都是使用tokenizer编码后的编号序列。

还有一点不同的是,标签部分使用了one-hot进行处理,而数据部分没有使用。原因在于,数据部分准备输入词嵌入层,而词嵌入层的输入不需要进行one-hot;而标签部分,需要和模型的输出计算交叉熵,输出层的激活函数是softmax,所以标签部分也要转成相应的shape,故使用one-hot形式。

三、构建模型

数据处理完成后,该着手构建模型了。因为不涉及自定义程度比较高的层,所以我选择使用TensorFlow 2.0的高级接口tf.keras构建模型。

使用tf.keras构建模型非常简单快捷,估计使用过Keras的朋友都深有体会:

# -*- coding: utf-8 -*-
# @File    : model.py
# @Author  : AaronJny
# @Time    : 2020/01/01
# @Desc    :
import tensorflow as tf
from dataset import tokenizer

# 构建模型
model = tf.keras.Sequential([
    # 不定长度的输入
    tf.keras.layers.Input((None,)),
    # 词嵌入层
    tf.keras.layers.Embedding(input_dim=tokenizer.vocab_size, output_dim=128),
    # 第一个LSTM层,返回序列作为下一层的输入
    tf.keras.layers.LSTM(128, dropout=0.5, return_sequences=True),
    # 第二个LSTM层,返回序列作为下一层的输入
    tf.keras.layers.LSTM(128, dropout=0.5, return_sequences=True),
    # 对每一个时间点的输出都做softmax,预测下一个词的概率
    tf.keras.layers.TimeDistributed(tf.keras.layers.Dense(tokenizer.vocab_size, activation='softmax')),
])

# 查看模型结构
model.summary()
# 配置优化器和损失函数
model.compile(optimizer=tf.keras.optimizers.Adam(), loss=tf.keras.losses.categorical_crossentropy)

使用tf.keras.Sequential构建了一个顺序的模型,选择Adam作为优化器,交叉熵作为损失函数。让我们看一下模型的结构:

Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
embedding (Embedding)        (None, None, 128)         439552    
_________________________________________________________________
lstm (LSTM)                  (None, None, 128)         131584    
_________________________________________________________________
lstm_1 (LSTM)                (None, None, 128)         131584    
_________________________________________________________________
time_distributed (TimeDistri (None, None, 3434)        442986    
=================================================================
Total params: 1,145,706
Trainable params: 1,145,706
Non-trainable params: 0

模型参数数量在1M左右,挺小的一个模型。

四、训练模型

数据和模型都已就位,可以开始训练了。在这之前,先考虑一个问题,如何评价训练结果呢?除了loss以外,人工观察模型生成的古体诗的质量也是一个选择。让我们先编写几个工具方法,用于使用模型随机生成古体诗。

# -*- coding: utf-8 -*-
# @File    : utils.py
# @Author  : AaronJny
# @Time    : 2019/12/30
# @Desc    :
import numpy as np
import settings


def generate_random_poetry(tokenizer, model, s=''):
    """
    随机生成一首诗
    :param tokenizer: 分词器
    :param model: 用于生成古诗的模型
    :param s: 用于生成古诗的起始字符串,默认为空串
    :return: 一个字符串,表示一首古诗
    """
    # 将初始字符串转成token
    token_ids = tokenizer.encode(s)
    # 去掉结束标记[SEP]
    token_ids = token_ids[:-1]
    while len(token_ids) < settings.MAX_LEN:
        # 进行预测,只保留第一个样例(我们输入的样例数只有1)的、最后一个token的预测的、不包含[PAD][UNK][CLS]的概率分布
        _probas = model.predict([token_ids, ])[0, -1, 3:]
        # print(_probas)
        # 按照出现概率,对所有token倒序排列
        p_args = _probas.argsort()[::-1][:100]
        # 排列后的概率顺序
        p = _probas[p_args]
        # 先对概率归一
        p = p / sum(p)
        # 再按照预测出的概率,随机选择一个词作为预测结果
        target_index = np.random.choice(len(p), p=p)
        target = p_args[target_index] + 3
        # 保存
        token_ids.append(target)
        if target == 3:
            break
    return tokenizer.decode(token_ids)


def generate_acrostic(tokenizer, model, head):
    """
    随机生成一首藏头诗
    :param tokenizer: 分词器
    :param model: 用于生成古诗的模型
    :param head: 藏头诗的头
    :return: 一个字符串,表示一首古诗
    """
    # 使用空串初始化token_ids,加入[CLS]
    token_ids = tokenizer.encode('')
    token_ids = token_ids[:-1]
    # 标点符号,这里简单的只把逗号和句号作为标点
    punctuations = [',', '。']
    punctuation_ids = {tokenizer.token_to_id(token) for token in punctuations}
    # 缓存生成的诗的list
    poetry = []
    # 对于藏头诗中的每一个字,都生成一个短句
    for ch in head:
        # 先记录下这个字
        poetry.append(ch)
        # 将藏头诗的字符转成token id
        token_id = tokenizer.token_to_id(ch)
        # 加入到列表中去
        token_ids.append(token_id)
        # 开始生成一个短句
        while True:
            # 进行预测,只保留第一个样例(我们输入的样例数只有1)的、最后一个token的预测的、不包含[PAD][UNK][CLS]的概率分布
            _probas = model.predict([token_ids, ])[0, -1, 3:]
            # 按照出现概率,对所有token倒序排列
            p_args = _probas.argsort()[::-1][:100]
            # 排列后的概率顺序
            p = _probas[p_args]
            # 先对概率归一
            p = p / sum(p)
            # 再按照预测出的概率,随机选择一个词作为预测结果
            target_index = np.random.choice(len(p), p=p)
            target = p_args[target_index] + 3
            # 保存
            token_ids.append(target)
            # 只有不是特殊字符时,才保存到poetry里面去
            if target > 3:
                poetry.append(tokenizer.id_to_token(target))
            if target in punctuation_ids:
                break
    return ''.join(poetry)

两个方法,一个用于随机生成古体诗,另一个用于随机生成藏头诗。在训练时,我们只用随机生成古体诗的方法观察效果。在Keras里,可以通过回调(callback)执行测试方法。

# -*- coding: utf-8 -*-
# @File    : train.py
# @Author  : AaronJny
# @Time    : 2020/01/01
# @Desc    :
import tensorflow as tf
from dataset import PoetryDataGenerator, poetry, tokenizer
from model import model
import settings
import utils


class Evaluate(tf.keras.callbacks.Callback):
    """
    在每个epoch训练完成后,保留最优权重,并随机生成settings.SHOW_NUM首古诗展示
    """

    def __init__(self):
        super().__init__()
        # 给loss赋一个较大的初始值
        self.lowest = 1e10

    def on_epoch_end(self, epoch, logs=None):
        # 在每个epoch训练完成后调用
        # 如果当前loss更低,就保存当前模型参数
        if logs['loss'] <= self.lowest:
            self.lowest = logs['loss']
            model.save(settings.BEST_MODEL_PATH)
        # 随机生成几首古体诗测试,查看训练效果
        print()
        for i in range(settings.SHOW_NUM):
            print(utils.generate_random_poetry(tokenizer, model))


# 创建数据集
data_generator = PoetryDataGenerator(poetry, random=True)
# 开始训练
model.fit_generator(data_generator.for_fit(), steps_per_epoch=data_generator.steps, epochs=settings.TRAIN_EPOCHS,
                    callbacks=[Evaluate()])

通过执行train.py脚本,即可完成模型的训练。观察模型在每个epoch结束后的表现是一件很有意思的事。

刚开始训练,模型的输出有些乱七八糟的。字、标点胡乱的混在一起,完全没有格式。比如(每行是一首):

门长风,黄有秋尽天天白。门为还下长,去人上独。寒开入行水。时还客。莫月不鸟尽前,远
知白酒上,风青白中。无无风,春山白知,不如,雨新玉归,,知来知来。中月秋流。家何玉。,不山欲知难,空
玉知初归去,水酒尽如,欲长不未。林边还城,朝未无水,愁月思不,归烟声白。酒
风知家君子,秋客叶不,草生花此中,,林时下见长。烟天深何,时客,谁水雨时,白生雨不白。不向归闻。更玉远马。烟知满去。未见行有,
处风去阳,水西向水朝。行叶风水。空南天飞有。是今不白鸟。高有此得,应来日远道。万,将自秋水,人

从第二、三个epoch开始,模型的输出有些格式了。但还是有些很明显的问题,比如标点用错,上下句子长度不同。比如:

三行山此日,清朝不客人。寒知自一,似子夜,开城春身。云风雪天,不云客过。松未入无,千入里月。

再几个epoch之后,意境和用词先且不谈,模型算是成功学到了句式:

白竹芳人别,江云云云乡。野山连山鸟,深来上有心。夜时何时月,江马几路朝。何日能前客,青为复自情。
清人多三重,年上一未时。自云中有月,诗树风人泉。寒风非阳外,为影水未烟。到乡已何苦,留家不时明。
闲林山溪下,清花楚过时。花人自长去,窗树旧不时。水知远见花,愁此长云波。此中不声鹤,风雨亦更看。
下雨花山客,初开是有西。孤山无古后,青头到几乡。楚日时下路,天山松天秋。且来犹人下,何游白如诗。有君相几归,重泪不长开。
花高江水老,风向到花台。月山自日石,故叶雪海间。

随着迭代次数的增加,模型的输出看起来也变得像模像样了。我们在下一个小节使用训练了20个epoch后的权重,演示一下对模型的测试。

五、测试模型

逻辑很简单,加载训练好的模型,通过工具方法生成古体诗和藏头诗,两个工具方法前面都给出了,没什么好说的,直接看代码吧:

# -*- coding: utf-8 -*-
# @File    : eval.py
# @Author  : AaronJny
# @Time    : 2020/01/01
# @Desc    :
import tensorflow as tf
from dataset import tokenizer
import settings
import utils

# 加载训练好的模型
model = tf.keras.models.load_model(settings.BEST_MODEL_PATH)
# 随机生成一首诗
print(utils.generate_random_poetry(tokenizer, model))
# 给出部分信息的情况下,随机生成剩余部分
print(utils.generate_random_poetry(tokenizer, model, s='床前明月光,'))
# 生成藏头诗
print(utils.generate_acrostic(tokenizer, model, head='海阔天空'))

执行脚本:

新安不忍赋,名步亦悠悠。夜向云沙雪,城连塞井边。潮销千雨入,云过露荷鲜。尽日相逢处,应怜别路遥。
床前明月光,声洒绿苔轻。惊梦知何事,春中亦相逢。绿云含露发,月月出铜罍。又共红脂袖,花香意欲同。
海前多道长,阔地为行游。天汉一家疾,空林应自秋。

再来一次:

江郭茫茫径复霜,月明帆落半相思。莫伤白日犹深笑,明月同来见五京。
床前明月光,水在紫楼长。水晓风犹尽,山从雪暮霜。风枝回枕急,湖树向流塘。早日知同客,沧溟满谷川。
海上长初入,阔山谁独同。天开天际里,空尽一声声。

六、结语

好了,如上就是本篇文章的全部内容,希望对你有所帮助。

如果你喜欢这篇文章的话,麻烦给点个赞呗~

菜鸟一只,如有纰漏之处,请大佬们指正,欢迎各位大佬拍砖~

参考

bojone/bert4keras

没有更多推荐了,返回首页