引子
23年最出圈的深度学习论文,应该就是这篇新加坡国立大学的模式学习的Text-to-Video的论文了,年初基本横扫了各大视频和文字创作平台。
把大家喜闻乐见的艺人的运球视频通过最先进的T2I扩散模型(模型在图像数据上进行了预训练)通过文字和语句的模式学习,转换成别的人物或者生物与背景。
-
什么是深度学习?
深度学习是机器学习的一个进化分支,旨在通过构建深层神经网络来进行数据建模和处理。它通过模拟人脑神经网络的工作原理,使计算机能够从大量数据中自动学习和提取特征。
深度学习的发展得益于计算机硬件技术的发展,特别是 GPU 等硬件技术的发展,使得深度学习算法能够在大规模数据集上进行训练和处理。同时,深度学习算法的发展也得益于深度学习框架的发展,如 TensorFlow、PyTorch 等,这些框架为深度学习算法的开发和部署提供了便利。
深度学习在计算机视觉、自然语言处理、语音识别等领域取得了显著的突破,成为当前人工智能技术的重要组成部分。然而,深度学习也面临着数据需求量大、计算资源消耗高以及模型的解释性等挑战。不过,随着技术的不断发展,深度学习有望为各种复杂问题的解决提供更加强大的工具和方法。
-
深度学习的方向?
2.1 深度学习是在学习什么?
现在大家见到的深度学习基本上都来自于神经科学和机器学习的结合。更直接一些就是:支持向量机(Support Vector Machines)之类的机器学习的启发,模拟神经网络的分层结构和信息处理方式。
深度学习的核心思想是通过多个隐藏层逐层学习和特征提取,从而解决复杂的非线性关系和大规模数据分析问题。每个隐藏层都会对输入数据进行变换和表示,从较低级别的特征到更高级别的抽象特征。这种层次化的特征提取使得深度学习具有强大的表达能力和泛化能力。
2.2 有哪些经典算法和明星成果?
-
计算机视觉(Computer Vision):
GAN 生成对抗网络 :
GAN(Generative Adversarial Network,生成对抗网络)是一种由生成器和判别器组成的深度学习模型。其中,生成器通过学习数据分布来生成逼真的新样本,而判别器则负责判断生成器生成的样本与真实样本之间的区别。
- 生成器网络 ( Generator ) :生成器接收一个随机噪声向量作为输入,并尝试生成与训练数据类似的新样本。生成器网络通常采用深度神经网络,通过多层非线性变换将输入噪声映射到输出样本空间。
- 判别器网络(Discriminator) :判别器接收生成器生成的样本以及真实训练数据的样本作为输入,并尝试区分它们。判别器也是一个深度神经网络,通过学习将输入样本分类为生成器生成的样本或真实训练数据的样本。
- 对抗训练:在训练过程中,生成器和判别器进行对抗。生成器的目标是生成足够逼真的样本,使得判别器无法区分其与真实样本。而判别器的目标是准确识别生成器生成的样本和真实训练数据的样本。
YOLO(You Only Look Once) 目标检测 算法:
Ultralytics 的YOLOv5 是世界上最受欢迎的视觉 AI,最小模型每次计算只需要4.5 * 640B FLOPs的计算量(目前主流显卡的都有10T FLOPs运算速度了)。截止至8.28日,在github上有41.1k🌟star。
YOLO算法的主要思想是将目标检测任务转化为一个回归问题,并使用单个神经网络同时进行目标定位和分类。下面是YOLO算法的工作流程:
-
分割图像:输入的图像被分割为一个固定大小的网格。每个网格负责检测其中的目标。
-
预测边界框:对于每个网格,YOLO会生成多个候选边界框(bounding box)以包围可能的目标。这些边界框通过预测其中心坐标、宽度和高度来定义。
-
置信度评估:对于每个候选边界框,YOLO会计算其包含目标的概率置信度。该置信度取决于边界框内部是否存在目标以及预测的准确性。
-
类别分类:除了位置信息和置信度外,YOLO还对每个边界框进行类别分类。它通过预测每个类别的概率来确定目标的类别。
-
大数据(Big Data):
股票和期货预测算法(Prediction LSTM ):
arxiv.org/abs/1909.09… Jupyter Notebook:github.com/huseinzol05…
Python:github.com/jaungiers/L…
LSTM(长短期记忆网络)是一种常用的循环神经网络(RNN),被广泛应用于序列数据建模和处理。传统的RNN在处理长序列时会出现梯度消失或梯度爆炸的问题,导致难以捕捉到长期依赖关系。为了解决这个问题,LSTM引入了门控机制来有效地学习和记忆长期信息。
LSTM模型经常被用于各类对冲基金的策略中,如:Quantum Group of Funds,Citron Research,Muddy Waters Research等。
-
自然语言处理(Natural Language Processing):
情感分类和文本分类( Sentiment Analysis and Classification):
可以通过把每个词的情感进行分类,如 好或不好,亢奋或平静,的二维模式对词进行分类。
比如 “好”的坐标就应该是(1,0),不好的坐标应该是(-1,0),兴奋的坐标应该是(1/(2⌃-1),1/(2⌃-1))
eg:一个一维的情感词典⬇️ 这里fuck这个词就是一个极端负面的词语。
文本的消极或者积极就可以通过句子中的所有词的加权平均进行计算,得到的值就是整个文本或者句的情感。
以上是机械的机器学习的方法,但是在深度学习中可以借助rnn,roberta进行分析。
同时也可以进行文本分类任务,如THUCTC。
THUCTC(THU Chinese Text Classification)是由清华大学自然语言处理实验室推出的中文文本分类工具包,能够自动高效地实现用户自定义的文本分类语料的训练、评测、分类功能。文本分类通常包括特征选取、特征降维、分类模型学习三个步骤。如何选取合适的文本特征并进行降维,是中文文本分类的挑战性问题。THUCTC对于开放领域的长文本具有良好的普适性,不依赖于任何中文分词工具的性能,具有准确率高、测试速度快的优点。
目前THUCTC工具包下载次数为:38854
文本摘要任务(summarization)和背后的文本理解任务:
文本摘要任务主要分为抽取式和生成式,其中的代表分别是Google开天辟地的Bert(文本阅读理解能力第一次超过人类)和Facebook的Bart(生成式摘要第一次全面超越抽取式摘要)。引领了整个文本摘要任务的前进,并有力的推动了模型如何理解人类语言的问题,直接影响了大模型的诞生。
BERT(Bidirectional Encoder Representations from Transformers)是由Google AI团队于2018年提出的一种预训练语言模型。BERT的目标是通过预训练来学习通用的语言表示,以便在各种自然语言处理任务中进行微调。
BERT采用了Transformer模型的架构,并通过两个任务来进行预训练:掩码语言建模(masked language modeling)和下一句预测(next sentence prediction)。在掩码语言建模任务中,BERT会将输入的文本中的某些单词掩盖住,然后通过上下文信息预测这些被掩盖的单词。在下一句预测任务中,BERT会判断两个句子是否是连续的。
BERT的一个重要特点是它是双向的,即它能够同时考虑上下文信息。
可以看到自诞生以来BERT和它的衍生模型已经发表了6W+篇论文了(2019-2023)
BART(Bidirectional and AutoRegressive Transformer)是一种预训练语言模型,由Facebook AI Research开发。与BERT不同,BART采用了自回归(autoregressive)和双向(bidirectional)的方法,以更好地处理生成式任务。
BART使用了类似于BERT的Transformer架构,但在预训练阶段采用了不同的策略。BART的预训练有两个阶段:首先是使用无监督方法进行自编码器(autoencoder)训练,然后使用掩码语言建模(masked language modeling)进行有监督的预训练。这使得BART在生成任务中表现出色。
BART的特点之一是它既可以用于生成任务,如摘要生成、机器翻译等,也可以用于理解任务,如文本分类、命名实体识别等。它的双向结构使其能够同时捕捉上下文信息和条件依赖性,从而提高模型在各种任务中的性能。
智能问答任务( QA ):
应该是第一个落地的机器学习QA应用:小黄鸡⬇️
没什么好介绍的,chatgpt出来后这个方向已经不存在了。。。
-
其他:
Alphago等围棋ai
AlphaGo是由DeepMind开发的人工智能程序,它在围棋领域取得了巨大的突破,并且在2016年击败了世界冠军李世石。AlphaGo的成功标志着强化学习在复杂领域中的应用潜力。
AlphaGo的核心算法基于深度强化学习和蒙特卡洛树搜索(Monte Carlo Tree Search)的结合。下面是AlphaGo的工作流程:
-
预训练 阶段:AlphaGo首先通过监督学习来学习游戏的规则和专家级棋谱。这使用了大量的人类对局数据,其中神经网络被训练来预测人类专家所采取的最佳动作。
-
自我对弈训练:通过与自身进行大量对弈,AlphaGo进行了强化学习训练。在每一步中,AlphaGo使用蒙特卡洛树搜索来评估可能的行动,并选择最佳的行动。然后,通过将胜利或失败的结果反向传播回到神经网络,调整权重以优化策略。
-
评估和改进:为了提高AlphaGo的性能,它会定期与其他版本进行对抗,从中选出更好的策略,并用于进一步的自我对弈训练。
蒙特卡洛树搜索 MCTS
落子概率也被称为策略(policy)。有了落子概率,非常简单的方式是直接按照这个概率进行落子。但是事实上这会导致神经网络总是原地踏步。这是因为Policy Network的训练数据是自己和自己下棋(self-play)生成的输出,仅仅自己学习自己是不会有改进的。
所以这里需要有一个办法来利用值函数的信息来优化这个策略。在AlphaGo系列算法里面是使用蒙特卡洛树搜索(MCTS)来进行策略优化的。MCTS的输出pi是依据值函数V得到的一个更优策略,它将被用于通过self-play来生成数据供深度神经网络学习。MCTS也是AlphaGo能够通过self-play不断变强的最重要的原因。
-
业内最前沿:
SAM
Segment Anything是一个用于图像分割的新任务、模型和数据集。它是由Meta AI Research开发的,旨在构建一个可提示的图像分割基础模型,通过提示工程解决新数据分布上的一系列下游分割问题。Segment Anything模型具有强大的泛化能力,可以接受文本提示,并在广泛的数据集上进行预训练。该模型可以通过单击或交互式单击来分割对象,并可以输出多个有效的遮罩以解决模糊性问题。它还可以自动查找并遮罩图像中的所有对象,并在预计算图像嵌入之后实时生成分割遮罩,允许与模型进行实时交互。
SAM将提示(prompt)的概念从 NLP 转化为分割,其中提示可以是一组前景/背景点、粗略的框或掩码(mask)、自由格式的文本,或者一般来说,任何指示要分割内容的信息。 然后,可提示的分割任务是在给定任何提示的情况下返回有效的分割掩码。
Segment Anything 项目试图将图像分割提升到基础模型时代,这篇论文试图使这一飞跃成为可能的新任务(可提示分割)、模型(SAM)和数据集(SA-1B)。
天气预测- 盘古 大模型
盘古气象大模型首次在中长期气象预报上超过了传统数值方法。训练和测试均在ERA5数据集上进行,其包括43年(1979-2021年)的全球实况气象数据。其中,1979-2017年数据作为训练集,2019年数据作为验证集,2018、2020、2021年数据作为测试集。盘古大模型使用的数据,包括垂直高度上13个不同气压层,每层五种气象要素(温度、湿度、位势、经度和纬度方向的风速),以及地球表面的四种气象要素(2米温度、经度和纬度方向的10米风速、海平面气压)。图1展示了盘古气象大模型的一些结果。我们可以看到,盘古气象大模型全方位地超过了现有的数值预报方法(欧洲气象中心的operational IFS)。
例如,盘古气象大模型提供的Z500五天预报均方根误差为296.7,显著低于之前最好的数值预报方法(operational IFS:333.7)和AI方法(FourCastNet:462.5)。同时,盘古气象大模型在一张V100显卡上只需要1.4秒就能完成24小时的全球气象预报,相比传统数值预报提速10000倍以上。
chatgpt 和copliot
感觉没什么好说的,放个论文吧。。。
特斯拉自动驾驶:
特斯拉的自动驾驶系统被称为"Autopilot"(自动驾驶辅助系统),利用计算机视觉、传感器和深度学习等技术,使车辆能够在某些条件下实现部分自主驾驶。自动驾驶系统包括多个传感器,如雷达、摄像头、超声波传感器等,用于感知周围环境。这些传感器收集到的数据通过深度学习算法进行处理和分析,以实现对道路、车辆、行人和其他障碍物的感知和识别。
Midjourney和 Stable Diffusion Model 图像生成:
www.midjourney.com/home/?callb…
docs.midjourney.com/docs/quick-…
其实这种就比较落地了,主要是借助nlp的prompt去给构图足够的提示。
- Stable Diffusion是2022年发布的深度学习文字到图像生成模型。它主要用于根据文字的描述产生详细图像,尽管它也可以应用于其他任务,如内补绘制、外补绘制,以及在提示词指导下产生图生图的翻译。
- 它是一种潜在扩散模型,由慕尼黑大学的CompVis研究团体开发的各种生成性类神经网路。它是由初创公司StabilityAI,CompVis与Runway合作开发的。
- Stable Diffusion的代码和模型权重已公开发布,可以在大多数配备有适度GPU的电脑硬体上运行。而以前的专有文生图模型(如DALL-E和Midjourney)只能通过云端运算服务存取。
- Stable Diffusion模型支援通过使用提示词来产生新的图像,描述要包含或省略的元素,以及重新绘制现有的图像,其中包含提示词中描述的新元素(该过程通常被称为「指导性图像合成」(guided image synthesis))通过使用模型的扩散去噪机制(diffusion-denoising mechanism)。
暂时无法在飞书文档外展示此内容
-
Snow White holding a rifle in the style of Studio Ghibli, Howl's Moving Castle, cel shading, vector, thick outlines
-
Titanic's Fateful Voyage
DLSS 和光线追踪技术:
喜闻乐见的大力水手。
DLSS
暂时无法在飞书文档外展示此内容
光线追踪
暂时无法在飞书文档外展示此内容
AI孙燕姿Sovits4.0:
暂时无法在飞书文档外展示此内容
番外:跨年音乐会的假唱~!www.bilibili.com/video/BV123…
永远的50年:
深度学习约束托卡马克装置。
3.工具和环境推荐
anaconda( 请不要在公司的toC项目中使用 )(不过这玩意是真的好用)
docs.anaconda.com/free/anacon…
- 软件包管理:Anaconda集成了Conda,它是一个强大的包管理器。Conda可以帮助用户轻松地安装、更新和删除各种开源软件包,包括Python及其相关库和工具。Anaconda社区维护了数千个常用的数据科学和机器学习软件包,因此用户可以方便地获取所需的工具。
- 环境管理:使用Anaconda,您可以轻松地创建和管理多个独立的Python环境。每个环境都具有自己的软件包集合,这样可以避免不同项目之间的冲突。您可以根据需要创建新环境,并在环境之间切换,以便于不同项目或实验之间的隔离和管理。
- 跨平台支持:Anaconda可在多个操作系统(包括Windows、macOS和Linux)上运行,并提供与许多常见开发工具和IDE(如Jupyter Notebook、Spyder等)的无缝集成。
- 包括核心工具:Anaconda默认安装了许多数据科学和机器学习常用的核心工具,如NumPy、Pandas、Matplotlib、Scikit-learn等。这些工具组成了强大的基础设施,使用户能够进行数据分析、建模和可视化等任务。
- 易于使用和管理:Anaconda提供了一个直观且易于使用的命令行界面和图形用户界面(Anaconda Navigator),使用户可以方便地浏览、安装和管理软件包、环境和项目。
如果想在公司电脑试用,请使用miniconda,anaconda会直接被SentinelOne扫硬盘删除,试过了已经。
// 创建环境
conda create -n nameWhatYouLike python= pythonVersion
// 切换环境
conda activate envName
// 查看环境
conda env list
// 安装python包
pip install package(推荐
conda install package (不推荐,版本容易有问题,而且可能存在商业法律问题
在pycharm和vscode中也可以使用conda环境,使用自己conda子环境的python解释器。
CUDA 和Cudnn
CUDA(Compute Unified Device Architecture)是由NVIDIA开发的一种并行计算平台和编程模型。它允许开发人员利用NVIDIA GPU的强大并行计算能力来加速各种科学计算、机器学习和深度学习任务。
下面是CUDA的一些重要特点和功能:
- 并行计算能力:CUDA利用了GPU中大量的并行处理单元(CUDA核心),使得开发者可以同时执行大规模的并行计算任务。这对于需要处理大量数据和进行复杂计算的应用非常有用。
- 编程模型:CUDA提供了一种基于C/C++编程语言的编程模型,使开发者能够在GPU上编写并运行自定义的并行计算代码。CUDA编程模型使用了特定的语法和指令集,以便最大程度地发挥GPU的潜力。
- GPU 加速库:CUDA还提供了一系列的GPU加速库,如BLAS(基本线性代数子程序)、cuDNN(CUDA深度神经网络库)等。这些库为常见的科学计算和深度学习任务提供了高效的GPU实现,可显著加速计算过程。
cuDNN(CUDA Deep Neural Network library)是一个专门针对深度学习任务的GPU加速库。它提供了一组优化的算法和函数,用于加速深度神经网络的训练和推理过程。
以下是cuDNN的一些主要特点和功能:
- 高性能优化:cuDNN使用高度优化的算法和实现,针对深度学习任务进行了专门的优化。这些优化使得深度神经网络的训练和推理速度大幅提升。
- 支持多种网络架构:cuDNN支持常见的深度学习框架,如TensorFlow、PyTorch、Caffe等。这使得开发者可以在不同的深度学习框架上获得类似的快速加速效果。
- 便捷的接口:cuDNN提供了简单易用的C语言接口,方便开发者集成并调用cuDNN库中的函数。这样,开发者可以更轻松地利用GPU加速来训练和部署深度学习模型。
CUDA和cuDNN共同为科学计算和深度学习领域的开发者提供了强大的工具和平台,使他们能够充分利用GPU的并行计算能力,并以高效的方式进行各种计算任务。
PyTorch 与 TensorFlow
PyTorch和TensorFlow都是流行的深度学习框架,用于构建、训练和部署神经网络模型。它们在功能、设计理念和生态系统等方面存在一些区别,以下是对它们进行详细介绍:
PyTorch :
pip3 install torch torchvision torchaudio
PyTorch是由Facebook开发并维护的开源深度学习框架。它以Python优雅的API设计为特点,并且强调动态计算图的灵活性。下面是PyTorch的一些关键特点:
- 动态计算图:PyTorch使用动态计算图,允许用户在运行时构建、修改和调试计算图。这种动态图的设计使得模型的开发过程更加灵活和直观。
- 易于调试:因为PyTorch采用了动态计算图,所以开发者可以轻松地使用Python的调试工具和技术对模型进行调试和可视化。
- Pythonic风格:PyTorch的API设计符合Pythonic风格,使得代码简洁、易读、易于理解。这种风格使得快速原型设计变得非常方便。
- 丰富的生态系统:PyTorch拥有庞大而活跃的社区,提供了许多扩展库和预训练模型。此外,PyTorch也被广泛应用于学术界和研究领域。
# Requires the latest pip
pip install --upgrade pip
# Current stable release for CPU and GPU
pip install tensorflow
# Or try the preview build (unstable)
pip install tf-nightly
TensorFlow是由Google Brain团队开发的深度学习框架,具有强大的分布式计算支持。设计上它更加注重静态计算图和优化性能。以下是TensorFlow的一些关键特点:
- 静态计算图:TensorFlow使用静态计算图,允许用户在构建阶段定义计算图,并随后将其编译和优化。这种设计使得TensorFlow在部署和生产环境中表现出色。
- 高性能计算:TensorFlow优化了底层计算,包括自动求导、张量运算和并行计算等,以提供高效的计算性能。它还支持分布式训练和推理,适用于大规模的深度学习任务。
- 工业级部署:由于其强大的分布式支持和良好的性能,TensorFlow在工业界广泛应用于生产环境中的部署。
- 广泛的社区支持:TensorFlow拥有庞大而活跃的社区,提供了丰富的文档、教程和资源。这使得学习和使用TensorFlow更加容易。
总结来说,PyTorch注重灵活性和易用性,适合快速原型设计和研究方向;而TensorFlow注重优化性能和工业级部署,适合大规模深度学习任务和生产环境。选择哪个框架主要取决于个人偏好、应用需求和团队背景。
4.贪吃蛇?
4.1 什么是贪吃蛇?
贪吃蛇是一款经典的电子游戏,最早在20世纪70年代末和80年代初流行起来。游戏的目标是控制一条蛇,在一个有限的区域内移动并吃食物,以使蛇的长度不断增长,同时避免撞到自己的身体或者碰到边界。
贪吃蛇的基本规则和玩法:
- 初始状态:游戏开始时,场地上仅有一条短小的蛇和一个食物。蛇通常位于场地的某一位置,朝向某个方向。
- 蛇的移动:玩家通过键盘或其他输入设备控制蛇的移动方向。蛇按照指定的方向每次移动一个格子的距离。蛇可以在场地中自由移动,但不能倒退或穿过自己的身体。
- 吃食物:当蛇头接触到食物时,它会吃下食物并身体增长一节。新的食物会在场地的其他位置生成,以保持蛇的挑战性。
- 碰撞检测:游戏进行中,蛇需要避免与自身的身体或场地的边界相撞。若蛇头碰到自己的身体或者场地的边界,游戏结束。
- 游戏目标:玩家的目标是尽可能长时间地保持蛇的存活,并使蛇的长度不断增加。通常情况下,蛇的长度越长,游戏难度也会逐渐增加。
贪吃蛇游戏的简单规则和容易上手的操作使其成为一个受欢迎的休闲游戏。同时,开发者还可以根据需求添加其他元素,如障碍物、道具等,以增加游戏的复杂性和挑战性。现在,贪吃蛇游戏已经在各种平台上得到了广泛的传承和演变。
4.2 自己的贪吃蛇
这两周忙里偷闲写了一个的贪吃蛇的简单DQN的深度学习程序。
我这里用的主要库是**pygame** , 架构是pytorch
pygame建立在SDL上,允许实时电子游戏研发而无需被低级语言束缚,所有需要的游戏功能和理念都(主要是图像方面)都完全简化为游戏逻辑本身,所有的资源结构都可以由高级语言提供。
游戏策略和状态:
观测状态(observation) :贪吃蛇头部位置、运动方向、身体的位置、苹果的位置
动作(action) :前,后,左,右
奖励(reward) :每次吃一个苹果,蛇的长度就会增加1,增加奖励。每当蛇与自身碰撞时,碰到板子的边框,或者如果长时间不吃苹果,奖励就会减少。
游戏结束条件(done) :跑完100个episode没有吃到任何苹果,或者撞到墙壁和身体,游戏结束。
4.2.1 贪吃蛇1.0
模型设计:
## model.py
import torch
import torch.nn as nn
## hidden_layer_size = 20
## model = QNetwork(input_dim=10, hidden_dim=20, output_dim=5)
class QNetwork(nn.Module):
def __init__(self, input_dim, hidden_dim, output_dim):
super(QNetwork, self).__init__()
self.fc1 = nn.Linear(input_dim, hidden_dim)
self.fc2 = nn.Linear(hidden_dim, hidden_dim)
self.fc3 = nn.Linear(hidden_dim, hidden_dim)
self.fc4 = nn.Linear(hidden_dim, output_dim)
self.relu = nn.ReLU()
def forward(self, x):
l1 = self.relu(self.fc1(x.float()))
l2 = self.relu(self.fc2(l1))
l3 = self.relu(self.fc3(l2))
l4 = self.fc4(l3)
return l4
def get_network_input(player, apple):
proximity = player.getproximity()
x = torch.cat([torch.from_numpy(player.pos).double(), torch.from_numpy(apple.pos).double(),
torch.from_numpy(player.dir).double(), torch.tensor(proximity).double()])
return
这是一个很简单的4层架构,4层线性结构,分别是输入层,隐藏层,隐藏层,输出层;而且都是使用了最简单的激活函数ReLU。
暂时无法在飞书文档外展示此内容
游戏设计和奖励设计:
## Game.py
import numpy as np
#定义贪吃蛇的动作,
# R表示向右边运动,就在在positon坐标的X轴加1,Y轴坐标不变,可以实现贪吃蛇头部坐标更新。
player_moves = {
'L': np.array([-1.,0.]),
'R': np.array([1.,0.]),
'U': np.array([0.,-1.]),
'D': np.array([0.,1.])
}
initial_playersize = 4
class snakeclass(object):
def __init__(self, gridsize):
self.pos = np.array([gridsize//2, gridsize//2]).astype('float')#初始化贪吃蛇头部position坐标,位于显示区域的中心
self.dir = np.array([1., 0.])#初始化贪吃蛇的运动
self.len = initial_playersize#初始化贪吃蛇的长度
# 建立一个position数据用于存贮贪吃蛇历史轨迹,这些轨迹也是贪吃蛇的身子
self.prevpos = [np.array([gridsize//2, gridsize//2]).astype('float')]
self.gridsize = gridsize
def move(self):
self.pos += self.dir
self.prevpos.append(self.pos.copy())
self.prevpos = self.prevpos[-self.len-1:]
def checkdead(self, pos):#判断贪吃蛇的头部是否到达边界或则碰到自己的身体。
if pos[0] <= -1 or pos[0] >= self.gridsize:
return True
elif pos[1] <= -1 or pos[1] >= self.gridsize:
return True
#判断贪吃蛇头是否碰到了身体
elif list(pos) in [list(item) for item in self.prevpos[:-1]]:
return True
else:
return False
def getproximity(self):#该函数定义了贪吃蛇头部的位置更新
L = self.pos - np.array([1,0])
R = self.pos + np.array([1,0])
U = self.pos - np.array([0,1])
D = self.pos + np.array([0,1])
possdirections = [L, R, U, D]
proximity = [int(self.checkdead(x)) for x in possdirections]
return proximity
def __len__(self):
return self.len + 1
class appleclass(object):#定义苹果出现的地方
def __init__(self, gridsize):
self.pos = np.random.randint(1,gridsize,2)
self.score = 0
self.gridsize = gridsize
def eaten(self):
## generate new apple every time the previous one is eaten
self.pos = np.random.randint(1,self.gridsize,2)
self.score += 1
class GameEnvironment(object):
def __init__(self, gridsize, nothing, dead, apple):
self.snake = snakeclass(gridsize)
self.apple = appleclass(gridsize)
self.game_over = False
self.gridsize = gridsize
self.reward_nothing = nothing
self.reward_dead = dead
self.reward_apple = apple
self.time_since_apple = 0
def resetgame(self):
self.apple.pos = np.random.randint(1, self.gridsize, 2).astype('float')#随机初始化苹果的位置
self.apple.score = 0#初始化score
self.snake.pos = np.random.randint(1, self.gridsize, 2).astype('float')#初始化贪吃蛇出现的位置
self.snake.prevpos = [self.snake.pos.copy().astype('float')]
self.snake.len = initial_playersize
self.game_over = False
def get_boardstate(self):
return [self.snake.pos, self.snake.dir, self.snake.prevpos, self.apple.pos, self.apple.score, self.game_over]
def update_boardstate(self, move):
reward = self.reward_nothing
Done = False
#python 中的all函数用于判断可迭代iterable中所有元素是否都是True,如果是返回Treu,否则False
if move == 0:
if not (self.snake.dir == player_moves['R']).all():
self.snake.dir = player_moves['L']
if move == 1:
if not (self.snake.dir == player_moves['L']).all():
self.snake.dir = player_moves['R']
if move == 2:
if not (self.snake.dir == player_moves['D']).all():
self.snake.dir = player_moves['U']
if move == 3:
if not (self.snake.dir == player_moves['U']).all():
self.snake.dir = player_moves['D']
self.snake.move()
self.time_since_apple += 1
#--
if self.time_since_apple == 100:#episode为100时候结束游戏
self.game_over = True
reward = self.reward_dead
self.time_since_apple = 0
Done = True
#--
if self.snake.checkdead(self.snake.pos) == True:#碰到边缘和身子,结束游戏
self.game_over = True
reward = self.reward_dead
self.time_since_apple = 0
Done = True
elif (self.snake.pos == self.apple.pos).all():#判断是否吃到苹果
self.apple.eaten()
self.snake.len += 1
self.time_since_apple = 0
reward = self.reward_apple
len_of_snake = len(self.snake)
return reward, Done, len_of_snake
#run.py 部分
model = QNetwork(input_dim=10, hidden_dim=20, output_dim=5) #网络参数
epsilon = 0.1 #ε
gridsize = 15 #整个游戏棋盘大小15*15
GAMMA = 0.9 #γ
board = GameEnvironment(gridsize, nothing=0, dead=-1, apple=1)#奖励设置
memory = ReplayMemory(1000)
#学习率lr控制了模型在每次更新时沿着梯度方向更新权重的步长大小。合适的学习率可以帮助模型快速收敛并获得良好的性能。
optimizer = torch.optim.Adam(model.parameters(), lr = 1e-5)
Epsilon(ε) : Epsilon通常用于ε-greedy策略,在强化学习中用于平衡探索(exploration)和利用(exploitation)之间的权衡。这里的探索指的是尝试未知行动以发现更好的策略,而利用则是基于已知的信息选择当前最佳行动。
具体来说,ε-greedy策略在每个决策点上都会以一个小概率ε选择随机策略进行探索,而以1-ε的概率选择目前估值最高的策略进行利用。这样可以在一定程度上保证算法的收敛性,并且在探索和利用之间找到一个平衡点。
GAMMA(γ) : GAMMA是强化学习中的折扣因子,用于平衡当前奖励和未来奖励的重要性。在强化学习任务中,智能体通常在每个时间步骤上都会获得一个即时奖励,但长远来看,未来的奖励也是非常重要的。
GAMMA的取值范围为0到1之间,代表未来奖励的衰减因子。当GAMMA接近1时,智能体会更加重视未来奖励,即更追求长期稳定的回报;而当GAMMA接近0时,智能体更偏向于关注当前即时奖励,对未来奖励的衰减较快。
选择合适的GAMMA值取决于具体任务的特性和目标。对于需要考虑长期收益的问题,如迷宫游戏或棋类游戏,较高的GAMMA值可能更合适;而对于一些需要立即获得奖励反馈的任务,较低的GAMMA值可能更合适。
结果:
发现出来的贪吃蛇虽然有点智力,但是不多,snake_9000。
4.2.2 贪吃蛇2.0
模型设计:
没有什么变化,就是把激活函数调整成leaky_relu,这样可以更好的模拟负反馈以及处理梯度问题。
游戏设计和奖励设计:
感觉1.0的蛇会出现莫名其妙撞墙自杀的问题,所以这里迭代,增加了蛇自己活下去就能加分(0.05分)的正反馈。游戏的反馈维度从:吃苹果、死亡 的二维,化为 吃苹果、活着、死亡的三维。并提高了学习率,防止蛇自己在loss高原无法迭代。
#run.py 部分
model = QNetwork(input_dim=10, hidden_dim=20, output_dim=5) #网络参数
epsilon = 0.1 #ε
gridsize = 15 #整个游戏棋盘大小15*15
GAMMA = 0.9 #γ
board = GameEnvironment(gridsize, nothing=0.05, dead=-1, apple=1)#奖励设置
memory = ReplayMemory(1000)
#学习率lr控制了模型在每次更新时沿着梯度方向更新权重的步长大小。合适的学习率可以帮助模型快速收敛并获得良好的性能。
optimizer = torch.optim.Adam(model.parameters(), lr = 1e-4)
结果:
蛇貌似强了一点,但是还是会撞自己,或者把自己包成团,撞墙少了很多,snake2_9900
4.2.3贪吃蛇3.0
模型设计:
加深了隐藏层,现在是4层隐藏层,一共现在是6层mlp。
class QNetwork(nn.Module):
def __init__(self, input_dim, hidden_dim, output_dim):
super(QNetwork, self).__init__()
self.fc1 = nn.Linear(input_dim, hidden_dim)
self.fc2 = nn.Linear(hidden_dim, hidden_dim)
self.fc3 = nn.Linear(hidden_dim, hidden_dim)
self.fc4 = nn.Linear(hidden_dim, hidden_dim)
self.fc5 = nn.Linear(hidden_dim, hidden_dim)
self.fc6 = nn.Linear(hidden_dim, output_dim)
self.relu = nn.ReLU()
self.leaky_relu = nn.LeakyReLU()
def forward(self, x):
l1 = self.leaky_relu(self.fc1(x.float()))
l2 = self.leaky_relu(self.fc2(l1))
l3 = self.leaky_relu(self.fc3(l2))
l4 = self.leaky_relu(self.fc3(l3))
l5 = self.leaky_relu(self.fc3(l4))
l6= self.fc6(l5)
return l6
暂时无法在飞书文档外展示此内容
游戏设计和奖励设计:
增加了一个关于撞到自己的复杂负反馈,并修改了奖励策略。
class snakeclass(object):
def __init__(self, gridsize):
self.pos = np.array([gridsize // 2, gridsize // 2]).astype('float') # 初始化贪吃蛇头部position坐标,位于显示区域的中心
self.dir = np.array([1., 0.]) # 初始化贪吃蛇的运动
self.len = initial_playersize # 初始化贪吃蛇的长度
# 建立一个position数据用于存贮贪吃蛇历史轨迹,这些轨迹也是贪吃蛇的身子
self.prevpos = [np.array([gridsize // 2, gridsize // 2]).astype('float')]
self.gridsize = gridsize
def move(self):
self.pos += self.dir
self.prevpos.append(self.pos.copy())
self.prevpos = self.prevpos[-self.len - 1:]
def checkdead(self, pos): # 判断贪吃蛇的头部是否到达边界或则碰到自己的身体。
if pos[0] <= -1 or pos[0] >= self.gridsize:
return -1
elif pos[1] <= -1 or pos[1] >= self.gridsize:
return -1
# 判断贪吃蛇头是否碰到了身体
elif list(pos) in [list(item) for item in self.prevpos[:-1]]:
# 判断贪吃蛇头是否碰到了身体
count = 0
x, y = pos[0], pos[1]
if [x + 1, y] in [list(item) for item in self.prevpos[:-1]]:
count -= 0.5
if [x - 1, y] in [list(item) for item in self.prevpos[:-1]]:
count -= 0.5
if [x, y + 1] in [list(item) for item in self.prevpos[:-1]]:
count -= 0.5
if [x, y - 1] in [list(item) for item in self.prevpos[:-1]]:
count -= 0.5
if [x - 1, y - 1] in [list(item) for item in self.prevpos[:-1]]:
count -= 0.25
if [x + 1, y + 1] in [list(item) for item in self.prevpos[:-1]]:
count -= 0.25
if [x - 1, y + 1] in [list(item) for item in self.prevpos[:-1]]:
count -= 0.25
if [x + 1, y - 1] in [list(item) for item in self.prevpos[:-1]]:
count -= 0.25
return count
else:
return 0
model = QNetwork(input_dim=10, hidden_dim=20, output_dim=5)
epsilon = 0.1
gridsize = 15
GAMMA = 0.9
board = GameEnvironment(gridsize, nothing=0.05, dead=-1, apple=1.5)
memory = ReplayMemory(1000)
optimizer = torch.optim.Adam(model.parameters(), lr=1e-4)
结果:
还不错,有6岁小孩水平的了(大概),snake3_9070
贪吃蛇 gitlab :
itrepo.bytedance.net/cuizhixiang…
放这么多链接和源码,其实是希望大家能够找到自己觉得有趣的方向吧,重拾自己对编程的感情和热爱,生活不只有眼前的苟且和CRUD。