指针生成网络(PGN)详细指南(引入)

news2025/1/24 6:21:42

一、Seq2Seq模型:编码-解码框架的开山之作

我们首先要了解的是seq2seq(Sequence-to-Sequence)模型。它最早由Google在2014年的一篇论文中提出,是第一个真正意义上的端到端的编码器-解码器(Encoder-Decoder)框架。

seq2seq模型主要由两部分组成:

  1. 编码器(Encoder):通常是一个RNN(循环神经网络),用于将输入序列编码为一个固定长度的向量表示,即所谓的“语义向量”。你可以把编码器看作一位尽职的秘书,他会认真阅读你给他的所有材料(输入序列),然后为你写一份精炼的内容摘要(语义向量)。
  2. 解码器(Decoder):同样是一个RNN,接收编码器输出的语义向量,从中解码出目标输出序列。解码器就像一位创意写手,他会根据秘书提供的摘要(语义向量),创作出一篇全新的文章(输出序列)。

然而,传统的seq2seq模型也存在一些局限性:

  • 编码器需要将整个输入序列压缩为一个固定大小的向量,对于较长的输入序列,这样做会损失很多信息。就像秘书写摘要,输入内容太多的话,摘要就不可能面面俱到。
  • 解码器只能利用编码器最后一个时间步的状态,无法充分利用编码器中间产生的语义信息。秘书的摘要再好,也只是对原始材料的高度概括,写手创作时无法参考材料的细节。

二、注意力机制:让写手"只选对的,不选多的"

为了克服上述问题,研究者提出了注意力机制(Attention Mechanism)。它的核心思想是:解码器在生成每个词时,都可以有选择地参考编码器不同时间步的输出,自动决定应该重点关注哪些部分。这个过程有点像写手在创作时翻阅秘书整理的资料,重点参考与当前内容最相关的部分。

在实现上,注意力机制会为编码器的每个时间步的输出分配一个权重,然后基于这些权重计算一个上下文向量(Context Vector),作为解码器的附加输入。权重的计算通常基于解码器当前的隐藏状态和编码器各时间步的输出。直观地说,权重越大,说明编码器该时间步的输出对解码器当前预测越重要,需要被重点"关注"。

引入注意力机制后,模型变得更加灵活和高效:

  • 不再需要将整个输入序列压缩为固定长度的向量,缓解了长序列的信息损失问题。秘书不用再提供"一言以蔽之"的摘要,而是可以整理一份完整的材料供写手参考。
  • 解码过程可以参考编码器各个时间步的输出,充分利用了输入序列的细节信息。写手可以有的放矢地参考材料,写出更精彩的内容。

首先导入库

import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F

# 使用PyTorch的Transformer模块来简化编码器和解码器的实现
from torch.nn import Transformer

定义编码器类

编码器使用了PyTorch的TransformerEncoder模块,它由多个TransformerEncoderLayer堆叠而成。每个编码器层包含一个多头自注意力机制和一个前馈神经网络。此外,为了让模型能够区分输入序列中不同位置的词,我们还使用了位置编码(Positional Encoding)。位置编码与词嵌入相加,得到最终的输入表示。

class Encoder(nn.Module):
    def __init__(self, input_dim, hid_dim, n_layers, n_heads, pf_dim, dropout):
        super().__init__()

        # 定义Transformer编码器层        
        self.encoder_layer = nn.TransformerEncoderLayer(
            d_model=hid_dim, 
            nhead=n_heads, 
            dim_feedforward=pf_dim,
            dropout=dropout
        )
        
        # 编码器由n_layers个编码器层堆叠而成
        self.transformer_encoder = nn.TransformerEncoder(self.encoder_layer, num_layers=n_layers)
        
        # 位置编码,用于为输入序列的每个位置添加位置信息
        self.pos_embedding = nn.Embedding(1000, hid_dim)
        
        # 输入嵌入层,将离散的输入token转换为连续的向量表示  
        self.embedding = nn.Embedding(input_dim, hid_dim)
        
        # Dropout层,用于防止过拟合
        self.dropout = nn.Dropout(dropout)
        
    def forward(self, src):
        # src的形状: (src_len, batch_size)
        
        # 生成位置编码
        src_pos = torch.arange(0, src.shape[0]).unsqueeze(0).repeat(src.shape[1], 1).permute(1, 0)
        
        # 将输入序列转换为嵌入向量,并加上位置编码
        src = self.embedding(src) + self.pos_embedding(src_pos)
        
        # 通过Dropout层
        src = self.dropout(src)
        
        # 通过Transformer编码器获取最终的编码结果
        # src的形状: (src_len, batch_size, hid_dim)
        src = self.transformer_encoder(src)

        return src

定义注意力层

class Attention(nn.Module):
    def __init__(self, hid_dim):
        super().__init__()
        
        self.attn = nn.Linear(hid_dim * 2, hid_dim)
        self.v = nn.Linear(hid_dim, 1, bias=False)
        
    def forward(self, hidden, encoder_outputs):
        # hidden的形状: (batch_size, hid_dim)  
        # encoder_outputs的形状: (src_len, batch_size, hid_dim)
        
        src_len = encoder_outputs.shape[0]
        
        # 将hidden扩展为encoder_outputs的长度,以便拼接
        hidden = hidden.unsqueeze(1).repeat(1, src_len, 1)
  
        # 将hidden和encoder_outputs按最后一维拼接
        energy = torch.tanh(self.attn(torch.cat((hidden, encoder_outputs), dim=2))) 
        
        # 计算注意力权重
        attention = self.v(energy).squeeze(2)
        
        return F.softmax(attention, dim=1)

定义解码器类

解码器的核心也是一个TransformerDecoder模块,它由多个TransformerDecoderLayer组成。每个解码器层包含一个self-attention、一个cross-attention和一个前馈神经网络。其中,self-attention用于处理已生成的输出序列,cross-attention用于根据编码器的输出计算注意力权重。

在每个时间步,解码器首先将上一步的输出通过一个嵌入层和dropout层,然后用注意力层计算当前隐藏状态对编码器输出的注意力权重。接着,将注意力权重与编码器输出加权求和,得到一个上下文向量。这个上下文向量会与当前步的嵌入输入拼接,再通过一个线性层,作为transformer解码器的输入。最后,将transformer解码器的输出通过一个线性层和softmax层,得到当前步的词表分布。

class Decoder(nn.Module):
    def __init__(self, output_dim, hid_dim, n_layers, n_heads, pf_dim, dropout, attention):
        super().__init__()

        self.output_dim = output_dim
        self.hid_dim = hid_dim
        self.n_layers = n_layers
        self.n_heads = n_heads
        self.pf_dim = pf_dim
        self.dropout = dropout

        # 注意力层
        self.attention = attention
        
        # 解码器层
        self.decoder_layer = nn.TransformerDecoderLayer(
            d_model=hid_dim, 
            nhead=n_heads,
            dim_feedforward=pf_dim, 
            dropout=dropout
        )
        
        # 解码器由n_layers个解码器层堆叠而成 
        self.transformer_decoder = nn.TransformerDecoder(self.decoder_layer, num_layers=n_layers)
        
        # 输出层,将transformer的输出转换为预测的词表分布
        self.out = nn.Linear(hid_dim, output_dim)
        
        # 输出词嵌入层
        self.output_embedding = nn.Embedding(output_dim, hid_dim)
        
        # Dropout层
        self.dropout = nn.Dropout(dropout)
        
    def forward(self, input, hidden, encoder_outputs):
        # input的形状: (batch_size)
        # hidden的形状: (batch_size, hid_dim)
        # encoder_outputs的形状: (src_len, batch_size, hid_dim)
        
        # 将输入转换为词嵌入
        input = self.output_embedding(input.unsqueeze(0))
        
        # 通过Dropout层
        input = self.dropout(input)
        
        # 通过注意力层,根据hidden和encoder_outputs计算注意力权重
        a = self.attention(hidden, encoder_outputs)
                
        # 将注意力权重与编码器输出相乘,得到注意力加权的上下文向量
        # a的形状: (batch_size, src_len)
        # encoder_outputs的形状: (src_len, batch_size, hid_dim)
        # 将两者相乘得到 (batch_size, src_len, hid_dim)
        # 然后在src_len维度求和,得到 (batch_size, hid_dim)
        weighted = torch.bmm(a.unsqueeze(1), encoder_outputs.permute(1, 0, 2)).squeeze(1)
        
        # 将加权的上下文向量与输入拼接,作为transformer解码器的输入
        # input的形状: (1, batch_size, hid_dim)
        # weighted的形状: (batch_size, hid_dim)
        # 将两者拼接得到 (1, batch_size, 2*hid_dim)
        input = torch.cat((input, weighted.unsqueeze(0)), dim=2)
        
        # 将拼接后的输入通过线性层,将维度还原为hid_dim
        input = F.relu(self.attn_combine(input))
        
        # 通过transformer解码器
        # input的形状: (1, batch_size, hid_dim)
        # hidden的形状: (n_layers, batch_size, hid_dim)
        # 注意我们这里只传入了encoder_outputs,因为解码器的self-attention会自动计算decoded_outputs
        output, hidden = self.transformer_decoder(input, hidden, encoder_outputs)

        # 将输出通过线性层转换为词表空间
        output = self.out(output.squeeze(0))
        
        # 应用softmax得到最终的词表分布
        output = F.softmax(output, dim=1)
        
        # 返回 output和新的隐藏状态
        return output, hidden

我们将编码器和解码器组合成完整的seq2seq模型:

在每个时间步,解码器根据上一步的输出、当前的隐藏状态和编码器的输出计算注意力权重,然后将注意力权重与编码器输出加权求和,得到一个上下文向量。这个上下文向量会作为transformer解码器的一部分输入,用于预测当前步的输出词。

class Seq2Seq(nn.Module):
    def __init__(self, encoder, decoder, device):
        super().__init__()
        
        self.encoder = encoder
        self.decoder = decoder
        self.device = device
        
    def forward(self, src, trg, teacher_forcing_ratio = 0.5):
        
        # src的形状: (src_len, batch_size)
        # trg的形状: (trg_len, batch_size)
        # teacher_forcing_ratio是使用正确目标词的概率
                
        batch_size = trg.shape[1]
        trg_len = trg.shape[0]
        trg_vocab_size = self.decoder.output_dim
        
        # 存储解码器的输出序列
        outputs = torch.zeros(trg_len, batch_size, trg_vocab_size).to(self.device)
        
        # 编码输入序列
        encoder_outputs = self.encoder(src)
                
        # 初始化解码器的隐藏状态
        hidden = encoder_outputs[-1,:,:]
                
        # 解码器的第一个输入是 <sos> 标记
        input = trg[0,:]
        
        for t in range(1, trg_len):
            
            # 根据当前的输入、隐藏状态和编码器输出,获取预测结果
            output, hidden = self.decoder(input, hidden, encoder_outputs)
            
            # 保存当前的输出
            outputs[t] = output
            
            # 根据teacher_forcing_ratio决定使用正确答案还是模型预测的词作为下一步的输入  
            teacher_force = random.random() < teacher_forcing_ratio
            top1 = output.argmax(1) 
            input = trg[t] if teacher_force else top1
            
        return outputs

 我们可以打印一下完整的model来看一下内部结构:

# 创建一些示例输入数据
src = torch.tensor([[1, 3, 4, 2]])  # 形状: (src_len, batch_size)
trg = torch.tensor([[1, 3, 4, 2]])  # 形状: (trg_len, batch_size)

# 定义模型参数
input_dim = len(input_vocab)
output_dim = len(output_vocab)
hid_dim = 256
n_layers = 3
n_heads = 8
pf_dim = 512
dropout = 0.1

# 实例化模型组件
attention = Attention(hid_dim)
encoder = Encoder(input_dim, hid_dim, n_layers, n_heads, pf_dim, dropout)
decoder = Decoder(output_dim, hid_dim, n_layers, n_heads, pf_dim, dropout, attention)
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

# 实例化Seq2Seq模型
model = Seq2Seq(encoder, decoder, device).to(device)
print(model)

 输出:

Seq2Seq(
  (encoder): Encoder(
    (encoder_layer): TransformerEncoderLayer(
      (self_attn): MultiheadAttention(
        (out_proj): NonDynamicallyQuantizableLinear(in_features=256, out_features=256, bias=True)
      )
      (linear1): Linear(in_features=256, out_features=512, bias=True)
      (dropout): Dropout(p=0.1, inplace=False)
      (linear2): Linear(in_features=512, out_features=256, bias=True)
      (norm1): LayerNorm((256,), eps=1e-05, elementwise_affine=True)
      (norm2): LayerNorm((256,), eps=1e-05, elementwise_affine=True)
      (dropout1): Dropout(p=0.1, inplace=False)
      (dropout2): Dropout(p=0.1, inplace=False)
    )
    (transformer_encoder): TransformerEncoder(
      (layers): ModuleList(
        (0-2): 3 x TransformerEncoderLayer(
          (self_attn): MultiheadAttention(
            (out_proj): NonDynamicallyQuantizableLinear(in_features=256, out_features=256, bias=True)
          )
          (linear1): Linear(in_features=256, out_features=512, bias=True)
          (dropout): Dropout(p=0.1, inplace=False)
          (linear2): Linear(in_features=512, out_features=256, bias=True)
          (norm1): LayerNorm((256,), eps=1e-05, elementwise_affine=True)
          (norm2): LayerNorm((256,), eps=1e-05, elementwise_affine=True)
          (dropout1): Dropout(p=0.1, inplace=False)
          (dropout2): Dropout(p=0.1, inplace=False)
        )
      )
    )
    (pos_embedding): Embedding(1000, 256)
    (embedding): Embedding(5, 256)
    (dropout): Dropout(p=0.1, inplace=False)
  )
  (decoder): Decoder(
    (attention): Attention(
      (attn): Linear(in_features=512, out_features=256, bias=True)
      (v): Linear(in_features=256, out_features=1, bias=False)
    )
    (decoder_layer): TransformerDecoderLayer(
      (self_attn): MultiheadAttention(
        (out_proj): NonDynamicallyQuantizableLinear(in_features=256, out_features=256, bias=True)
      )
      (multihead_attn): MultiheadAttention(
        (out_proj): NonDynamicallyQuantizableLinear(in_features=256, out_features=256, bias=True)
      )
      (linear1): Linear(in_features=256, out_features=512, bias=True)
      (dropout): Dropout(p=0.1, inplace=False)
      (linear2): Linear(in_features=512, out_features=256, bias=True)
      (norm1): LayerNorm((256,), eps=1e-05, elementwise_affine=True)
      (norm2): LayerNorm((256,), eps=1e-05, elementwise_affine=True)
      (norm3): LayerNorm((256,), eps=1e-05, elementwise_affine=True)
      (dropout1): Dropout(p=0.1, inplace=False)
      (dropout2): Dropout(p=0.1, inplace=False)
      (dropout3): Dropout(p=0.1, inplace=False)
    )
    (transformer_decoder): TransformerDecoder(
      (layers): ModuleList(
        (0-2): 3 x TransformerDecoderLayer(
          (self_attn): MultiheadAttention(
            (out_proj): NonDynamicallyQuantizableLinear(in_features=256, out_features=256, bias=True)
          )
          (multihead_attn): MultiheadAttention(
            (out_proj): NonDynamicallyQuantizableLinear(in_features=256, out_features=256, bias=True)
          )
          (linear1): Linear(in_features=256, out_features=512, bias=True)
          (dropout): Dropout(p=0.1, inplace=False)
          (linear2): Linear(in_features=512, out_features=256, bias=True)
          (norm1): LayerNorm((256,), eps=1e-05, elementwise_affine=True)
          (norm2): LayerNorm((256,), eps=1e-05, elementwise_affine=True)
          (norm3): LayerNorm((256,), eps=1e-05, elementwise_affine=True)
          (dropout1): Dropout(p=0.1, inplace=False)
          (dropout2): Dropout(p=0.1, inplace=False)
          (dropout3): Dropout(p=0.1, inplace=False)
        )
      )
    )
    (out): Linear(in_features=256, out_features=5, bias=True)
    (output_embedding): Embedding(5, 256)
    (dropout): Dropout(p=0.1, inplace=False)
  )
)

三、指针生成网络:在"写原创"和"纯搬运"间找平衡

尽管有了注意力机制,传统的seq2seq模型在一些任务上的表现仍不尽如人意,尤其是在文本摘要领域。想象一下,如果让一个小说家去写新闻摘要,他很可能会添加一些原文中没有的内容。这在文学创作中是才华,在文本摘要里却是Bug。我们希望摘要模型既能准确抓取原文的关键信息,又能生成流畅自然的句子。

于是,斯坦福大学的研究者在2017年提出了指针生成网络(PGN)。它在传统的seq2seq+注意力框架的基础上,添加了一种新的混合生成方式:

  • 生成模式:根据当前的解码器状态和注意力语境,从固定词表中生成新词。这一部分与普通的seq2seq没有区别,对应着摘要写手的“创作”能力。
  • 拷贝模式:直接从输入序列中选择某个词,原封不动地"指针"到输出中。这一部分让模型有了"直接引用"的能力,对应着摘要写手的"摘抄"功能。

PGN通过一个可学习的"生成概率"来控制每一步应该选择生成模式还是拷贝模式。生成概率同时取决于解码器状态、注意力语境和当前输入,可以自动调节生成和拷贝的比例。打个比方,生成概率就像写手的思路开关:什么时候该发挥创造力,什么时候该直接引用原文,全凭她自己拿捏。

PGN在文本摘要、阅读理解等任务上取得了显著的效果提升。它成功地找到了"创作"与"摘编"的平衡:

  • 在关键信息的提取和复述上更加准确,避免了关键细节的遗漏和僭改。写手知道什么地方该直接"照抄"。
  • 生成的摘要更加自然流畅,可读性大大提高。写手也能适时发挥"文学才华",润色文字。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Tailscale 配置 subnet 实现访问 Openwrt 路由器下的子网

Openwrt 安装 Tailscale 参考 OpenWrt 配置 Tailscale 内网穿透。 tailscale两台openwrt(双lan)网对网(site to site)互通OpenWrt安装配置Tailscale 在 OpenWrt 上使用 Tailscale 使用 tailscale subnet 在openwrt terminal 执行 tailscale up --advertise-routes192.168.…

低代码可视化-转盘小游戏可视化-代码生成器

转盘小程序是一种互动工具&#xff0c;它通过模拟真实的转盘抽奖或决策体验&#xff0c;为用户提供了一种有趣且公平的选择方式。以下是对转盘小程序的详细介绍&#xff1a; 转盘小程序的应用场景 日常决策&#xff1a;转盘小程序可以帮助用户解决日常生活中的选择困难问题&a…

【Uniapp-Vue3】uni-icons的安装和使用

一、uni-icon的安装 进入到如下页面中&#xff0c;点击“点击下载&安装”。 uni-icons 图标 | uni-app官网 点击“下载插件并导入HBuilder”&#xff0c;如果没有登录就登陆一下 网页中会打开Hbuilder&#xff0c;进入Hbuilder以后&#xff0c;选择需要使用该插件的项目进…

【橘子ES】Kibana的分析能力Analytics简易分析

一、kibana是啥&#xff0c;能干嘛 我们经常会用es来实现一些关于检索&#xff0c;关于分析的业务。但是es本身并没有UI,我们只能通过调用api来完成一些能力。而kibana就是他的一个外置UI&#xff0c;你完全可以这么理解。 当我们进入kibana的主页的时候你可以看到这样的布局。…

一、引论,《组合数学(第4版)》卢开澄 卢华明

零、前言 发现自己数数题做的很烂&#xff0c;重新学一遍组合数学吧。 参考卢开澄 卢华明 编著的《组合数学(第4版)》&#xff0c;只打算学前四章。 通过几个经典问题来了解组合数学所研究的内容。 一、幻方问题 据说大禹治水之前&#xff0c;河里冒出来一只乌龟&#xff0c…

LabVIEW太阳能照明监控系统

在公共照明领域&#xff0c;传统的电力照明系统存在高能耗和维护不便等问题。利用LabVIEW开发太阳能照明监控系统&#xff0c;通过智能控制和实时监测&#xff0c;提高能源利用效率&#xff0c;降低维护成本&#xff0c;实现照明系统的可持续发展。 ​ 项目背景 随着能源危机…

5. 马科维茨资产组合模型+政策意图AI金融智能体(Qwen-Max)增强方案(理论+Python实战)

目录 0. 承前1. AI金融智能体1.1 What is AI金融智能体1.2 Why is AI金融智能体1.3 How to AI金融智能体 2. 数据要素&计算流程2.1 参数集设置2.2 数据获取&预处理2.3 收益率计算2.4 因子构建与预期收益率计算2.5 协方差矩阵计算2.6 投资组合优化2.7 持仓筛选2.8 AI金融…

【华为路由的arp配置】

华为路由的arp配置 ARP&#xff1a;IP地址与MAC地址的映射。 R1: g0/0/0:10.1.1.254/24 g0/0/1:10.1.2.254/24 PC1: 10.1.1.1/16 PC2: 10.1.1.2/16 PC3: 10.1.2.3/16 动态ARP 查看PC1的arp表&#xff0c;可以看到&#xff0c;列表为空。 查看R1的arp表 在PC3上ping命令测…

U3D的.Net学习

Mono&#xff1a;这是 Unity 最初采用的方式&#xff0c;它将 C# 代码编译为中间语言 (IL)&#xff0c;然后在目标平台上使用虚拟机 (VM) 将其转换为本地机器码执行。 IL2CPP&#xff1a;这是一种较新的方法&#xff0c;它会将 C# 代码先编译为 C 代码&#xff0c;再由 C 编译器…

机器学习-线性回归(简单回归、多元回归)

这一篇文章&#xff0c;我们主要来理解一下&#xff0c;什么是线性回归中的简单回归和多元回归&#xff0c;顺便掌握一下特征向量的概念。 一、简单回归 简单回归是线性回归的一种最基本形式&#xff0c;它用于研究**一个自变量&#xff08;输入&#xff09;与一个因变量&…

智能体的核心技能之插件,插件详解和实例 ,扣子免费系列教程(11)

欢迎来到滔滔讲AI&#xff0c;今天我们来学习智能体的核心功能点之一的插件。 插件是通过API连接集成各种平台和服务&#xff0c;它扩展了智能体的能力。平台内置了丰富的插件&#xff0c;我们可以直接调用。 一、什么是插件 首先&#xff0c;插件其实就像一个工具箱。 每个插…

Spring Security(maven项目) 3.0.2.6版本—总

通过实践而发现真理&#xff0c;又通过实践而证实真理和发展真理。从感性认识而能动地发展到理性认识&#xff0c;又从理性认识而能动地指导革命实践&#xff0c;改造主观世界和客观世界。实践、认识、再实践、再认识&#xff0c;这种形式&#xff0c;循环往复以至无穷&#xf…

超强推理大模型 QVQ-32B-preview 一键部署

QwQ-32B-Preview 是 Qwen 团队于 2024 年开发的实验研究模型&#xff0c;专注于提高 AI 推理能力。这个模型在多个基准测试中展现了卓越的性能&#xff0c;特别是在 GPQA、AIME、MATH-500 和 LiveCodeBench 等测试中&#xff0c;准确率分别达到了 65.2%、50.0%、90.6% 和 50.0%…

数据结构(Java)——二叉树

1.概念 二叉树是一种树形数据结构&#xff0c;其中每个节点最多有两个子节点&#xff0c;通常被称为左子节点和右子节点。二叉树可以是空的&#xff08;即没有节点&#xff09;&#xff0c;或者由一个根节点以及零个或多个左子树和右子树组成&#xff0c;其中左子树和右子树也分…

谷粒商城——商品服务-三级分类

1.商品服务-三级分类 1.1三级分类介绍 1.2查询三级分类查询-递归树型结构数据获取 1.2.1导入数据pms_catelog.sql到数据表pms_category 1.2.2一次性查出所有分类及子分类 1.2.2.1修改CategoryController.java /*** 查出所有分类以及子分类&#xff0c;以树形结构组装起来*/R…

AviatorScript用法

AviatorScript的介绍&#xff0c;网上有很多&#xff0c;这里就不啰嗦了。这里介绍下传参的用法 应用场景&#xff1a;如果不想频繁的打包升级&#xff0c;而是想只更新某些规则脚本重启服务就可以升级的话&#xff0c;AviatorScript无疑是最佳选择。比如说&#xff0c;今天制…

云计算和服务器

一、云计算概述 ICT是世界电信协会在2001年的全球性会议上提出的综合性概念&#xff0c;ICT分为IT和CT&#xff0c;IT(information technology)信息技术&#xff0c;负责对数据生命周期的管理&#xff1b;CT(communication technology)&#xff0c;负责数据的传输管理。 CT技术…

论文:深度可分离神经网络存内计算处理芯片

引言&#xff1a;SRAM - CIM芯片在处理深度可分离神经网络时面临的挑战 深度可分离卷积&#xff08;Depthwise separable convolution, DSC&#xff09;由逐深度卷积&#xff08;DW&#xff09;和逐点卷积&#xff08;PW)组成&#xff0c;逐深度卷积用于提取空间特征&#xff…

代码随想录刷题day14(1)|(链表篇)142.环形链表 II

目录 一、链表理论基础 二、环形链表思路 1.如何判断有环&#xff1f; 2.如何找出环的入口&#xff1f; 3.其他疑问 三、相关算法题目 四、总结 一、链表理论基础 代码随想录 (programmercarl.com) 二、环形链表思路 1.如何判断有环&#xff1f; 使用快慢指针法&…

运算放大器应用电路设计笔记(六)

6.1输出失调电压发生的原因与计算 6.1.1用噪声增益进行评价 若运算放大器两个输入端接地&#xff0c;则理想运放输出为零&#xff0c;但实际的运放输出不为零&#xff0c;有一定的直流输出电压。这种直流电压称为输出失调电压。发生的原因是&#xff0c;运算放大器内部元件尤…