Chapter4.3:Implementing a feed forward network with GELU activations

4 Implementing a GPT model from Scratch To Generate Text

4.3 Implementing a feed forward network with GELU activations

  • 本节即将实现子模块,用于transformer block(变换器块)的一部分。为此,我们需要从激活函数开始。

    深度学习中,ReLU因其简单和有效而被广泛使用。但在大语言模型中,还使用了GELU和SwiGLU这两种更复杂、平滑的激活函数,它们结合了高斯和sigmoid门控,提升了模型性能,与ReLU的简单分段线性不同。

  • GELU(Hendrycks 和 Gimpel,2016)可以通过多种方式实现;其精确版本定义为 GELU(x)=x⋅Φ(x),其中 Φ(x) 是标准高斯分布的累积分布函数。

    在实践中,通常会实现一种计算成本更低的近似版本:
    GELU ( x ) ≈ 0.5 ⋅ x ⋅ ( 1 + tanh ⁡ [ 2 π ⋅ ( x + 0.044715 ⋅ x 3 ) ] ) \text{GELU}(x) \approx 0.5 \cdot x \cdot \left(1 + \tanh\left[\sqrt{\frac{2}{\pi}} \cdot \left(x + 0.044715 \cdot x^3\right)\right]\right) GELU(x)0.5x(1+tanh[π2 (x+0.044715x3)])
    (原始的 GPT-2 模型也是使用此近似版本进行训练的)。

    class GELU(nn.Module):def __init__(self):super().__init__()def forward(self, x):return 0.5 * x * (1 + torch.tanh(torch.sqrt(torch.tensor(2.0 / torch.pi)) * (x + 0.044715 * torch.pow(x, 3))))import matplotlib.pyplot as pltgelu, relu = GELU(), nn.ReLU()# Some sample data
    x = torch.linspace(-3, 3, 100)
    y_gelu, y_relu = gelu(x), relu(x)plt.figure(figsize=(8, 3))
    for i, (y, label) in enumerate(zip([y_gelu, y_relu], ["GELU", "ReLU"]), 1):plt.subplot(1, 2, i)plt.plot(x, y)plt.title(f"{label} activation function")plt.xlabel("x")plt.ylabel(f"{label}(x)")plt.grid(True)plt.tight_layout()
    plt.show()
    

    image-20241229212711708

    如上图所示

    1. ReLU:分段线性函数,正输入直接输出,负输入输出零。

      ReLU的局限性: 零处有尖锐拐角,可能增加优化难度;对负输入输出零,限制了负输入神经元的作用。

    2. GELU:平滑非线性函数,近似 ReLU,对负值具有非零梯度(除了在约-0.75处之外)

      GELU的优势:平滑性带来更好的优化特性;对负输入输出较小的非零值,使负输入神经元仍能贡献学习过程。

  • 接下来让我们使用 GELU 函数来实现小型神经网络模块 FeedForward,稍后我们将在 LLM 的转换器块中使用它:

    class FeedForward(nn.Module):def __init__(self, cfg):super().__init__()self.layers = nn.Sequential(nn.Linear(cfg["emb_dim"], 4 * cfg["emb_dim"]),GELU(),nn.Linear(4 * cfg["emb_dim"], cfg["emb_dim"]),)def forward(self, x):return self.layers(x)
    

    上述的前馈模块是包含两个线性层和一个GELU激活函数的小神经网络,在1.24亿参数的GPT模型中,用于处理嵌入大小为768的令牌批次。

    print(GPT_CONFIG_124M["emb_dim"])"""输出"""
    768
    

    初始化一个新的前馈网络(FeedForward)模块,其 token 嵌入大小为 768,并向其输入一个包含 2 个样本且每个样本有 3 个 token 的批次输入。我们可以看到,输出张量的形状与输入张量的形状相同:

    ffn = FeedForward(GPT_CONFIG_124M)# input shape: [batch_size, num_token, emb_size]
    x = torch.rand(2, 3, 768) 
    out = ffn(x)
    print(out.shape)"""输出"""
    torch.Size([2, 3, 768])
    

    本节的前馈模块对模型学习和泛化至关重要。它通过内部扩展嵌入维度到更高空间,如下图所示,然后应用GELU激活,最后收缩回原维度,以探索更丰富的表示空间。

    前馈神经网络中层输出的扩展和收缩的图示。首先,输入值从 768 个值扩大到 4 倍,达到 3072 个值。然后,第二层将 3072 个值压缩回 768 维表示。

  • 本节至此,现在已经实现了 下图中LLM 的大部分构建块(打勾的部分)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/502975.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

弥散张量分析开源软件 DSI Studio 简体中文汉化版可以下载了

网址: (63条消息) DSIStudio简体中文汉化版(2022年7月)-算法与数据结构文档类资源-CSDN文库

【信号滤波 (补充)】二阶陷波滤波代码推导过程(C++)

目录 二阶陷波滤波器计算实例一、 传递函数的参数推导1. 首先 b 0 , b 1 , b 2 b_0, b_1, b_2 b0​,b1​,b2​是怎么推导出来的?2. 带入实际值求解3. 验证上述的传递函数 二、将传递函数转化成差分方程2.1 传递函数写成输入输出形式2.2 Z域转化为时域 三、将差分方程…

C++进阶——用Hash封装unordered_map和unordered_set

目录 前言 源码怎么说 为什么要兼容? 兼容的具体做法? 为什么要把Key转为整数(HashFcn)? 模拟实现 一、建立框架 二、迭代器 运算符重载 迭代器兼容大法 三、[ ]重载 四、实现不能修改key 实现及测试代码 …

安装MySQL的五种方法(Linux系统和Windows系统)

一.在Linux系统中安装MySQL 第一种方法:在线YUM仓库 首先打开MySQL官网首页 www.mysql.com 找到【DOWNLOADS】选项,点击 下拉,找到 【MySQL Community(GPL) Downloads】 在社区版下载页面中,【 MySQL Yum Repository 】链接为在线仓库安装…

极客说|微软 Phi 系列小模型和多模态小模型

作者:胡平 - 微软云人工智能高级专家 「极客说」 是一档专注 AI 时代开发者分享的专栏,我们邀请来自微软以及技术社区专家,带来最前沿的技术干货与实践经验。在这里,您将看到深度教程、最佳实践和创新解决方案。关注「极客说」&am…

封装/前线修饰符/Idea项目结构/package/impore

目录 1. 封装的情景引入 2. 封装的体现 3. 权限修饰符 4. Idea 项目结构 5. package 关键字 6. import 关键字 7. 练习 程序设计:高内聚,低耦合; 高内聚:将类的内部操作“隐藏”起来,不需要外界干涉&#xff1b…

【C++】P5733 【深基6.例1】自动修正

博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 💯前言💯题目描述💯解题思路概述💯第一种实现方式:直接使用字符ASCII值计算代码实现代码分析 💯第二种实现方式:直接修改…

【Elasticsearch】文档操作:添加、更新和删除

🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,精通Java编…

【insert 插入数据语法合集】.NET开源ORM框架 SqlSugar 系列

系列文章目录 🎀🎀🎀 .NET开源 ORM 框架 SqlSugar 系列 🎀🎀🎀 文章目录 系列文章目录一、前言 🍃二、插入方式 💯2.1 单条插入实体2.2 批量 插入实体2.3 根据字典插入2.4 根据 Dat…

权限掩码umask

1 、 设置新建文件或目录的默认权限 在 Linux 系统中,当用户创建一个新的文件或目录时,系统都会为新建的文件或目录分配默认的权限,该默认权限与umask 值有关,其具体关系是: 新建文件的默认权限 0666-umask 值 新建…

202-01-06 Unity 使用 Tip1 —— UnityHub 模块卸载重装

文章目录 1 卸载模块2 更新配置文件3 重启 UnityHub 起因: ​ WebGL 平台打包程序报错,懒得修复了,因此粗暴地删了重装。但是 UnityHub 不支持卸载模块,因此手动配置。 1 卸载模块 ​ 以 Unity 6000.0.26f1c1 为例,其…

打造三甲医院人工智能矩阵新引擎(二):医学影像大模型篇--“火眼金睛”TransUNet

一、引言 1.1 研究背景与意义 在现代医疗领域,医学影像作为疾病诊断与治疗的关键依据,发挥着不可替代的作用。从传统的X射线、CT(计算机断层扫描)到MRI(磁共振成像)等先进技术,医学影像能够直观呈现人体内部结构,为医生提供丰富的诊断信息,涵盖疾病识别、病灶定位、…

国产编辑器EverEdit - 两种删除空白行的方法

1 使用技巧:删除空白行 1.1 应用场景 用户在编辑文档时,可能会遇到很多空白行需要删除的情况,比如从网页上拷贝文字,可能就会存在大量的空白行要删除。 1.2 使用方法 1.2.1 方法1: 使用编辑主菜单 选择主菜单编辑 …

李宏毅机器学习笔记-Transformer

目录 1. Seq2seq 2. encoder Transformer 中的 Block 结构 3. Decoder 4.Encoder和Decoder间的信息传递 5.Training 6.Tips 1. Seq2seq Transformer 是一个seq2seq的model。Seq2seq指的是input是一个序列,输出也是一个序列,输出的长度是由机器自己…

GitLab集成Runner详细版--及注意事项汇总【最佳实践】

一、背景 看到网上很多用户提出的runner问题其实实际都不是问题,不过是因为对runner的一些细节不清楚导致了误解。本文不系统性的介绍GitLab-Runner,因为这类文章写得好的特别多,本文只汇总一些常几的问题/注意事项。旨在让新手少弯路。 二、…

指针 const 的组合

1、首先来了解一下常量 const int num 5; 那么num的值是5, num的值不可修改 2、来了解一下指针 int value 5; int* p &value; 我喜欢吧指针和类型放一起,来强调p是一个指针类型, 而赋值的时候就得赋值一个int类型的地址…

《C++11》各种初始化方式的详细列举与对比

在 C 中,初始化对象的方式多种多样。随着 C 标准的演进,特别是 C11 的引入,初始化方式得到了显著的扩展和改进。本文将详细列举 C 中的各种初始化方式,并对它们进行对比,帮助开发者更好地理解和应用这些特性。 1. C98…

前端小案例——520表白信封

前言:我们在学习完了HTML和CSS之后,就会想着使用这两个东西去做一些小案例,不过又没有什么好的案例让我们去练手,本篇文章就提供里一个案例——520表白信封 ✨✨✨这里是秋刀鱼不做梦的BLOG ✨✨✨想要了解更多内容可以访问我的主…

【Vim Masterclass 笔记05】第 4 章:Vim 的帮助系统与同步练习(L14+L15+L16)

文章目录 Section 4:The Vim Help System(Vim 帮助系统)S04L14 Getting Help1 打开帮助系统2 退出帮助系统3 查看具体命令的帮助文档4 查看帮助文档中的主题5 帮助文档间的上翻、下翻6 关于 linewise7 查看光标所在术语名词的帮助文档8 关于退…

10-C语言项目池

C语言项目池 《个人通讯录》 《火车订票系统》 管理员用户1录入火车票信息区间查询/购票2显示火车票信息打印购票信息3查询火车票信息退票4修改火车票信息5添加火车票信息 《学生学籍管理系统》 1录入学生信息2添加学生信息3显示学生信息4查找学生信息5删除学生信息6修改学…