分类网站 模板,凡客诚品 v官网,如何做网络推广人员,大连建设网官网网上办公大厅视频指路 参考博客笔记 参考笔记二 文章目录 上课笔记基于RNNCell实现总代码 基于RNN实现总代码 含嵌入层的RNN网络嵌入层的作用含嵌入层的RNN网络架构总代码 其他RNN扩展基本注意力机制自注意力机制#xff08;Self-Attention#xff09;自注意力计算多头注意力机制#xf… 视频指路 参考博客笔记 参考笔记二 文章目录 上课笔记基于RNNCell实现总代码 基于RNN实现总代码 含嵌入层的RNN网络嵌入层的作用含嵌入层的RNN网络架构总代码 其他RNN扩展基本注意力机制自注意力机制Self-Attention自注意力计算多头注意力机制Multi-Head AttentionTransformer模型简单的Transformer编码器 上课笔记
例子每天若干特征若干天作为输出
使用cnn的时候要明确全连接层占的权重比例特别大是训练的瓶颈通过权重共享的概念来减少需要训练的权重的数量
RNN cell本质就是一个线性层但是这个线性层是共享的如下图每次把hi和xi1计算得到的hi1传送到下一层进行计算同时xi1还需要通过某种运算融合xi的信息比如求和、求乘积等h0是先验知识比如对于图像生成文本可以先通过cnnfc生成h0也可以把h0设成和h1等统一维度的向量值都设成0。所有的rnnc都处于同一个线性层 RNN网络最大的特点就是可以处理序列特征就是我们的一组动态特征。比如我们可以通过将前三天每天的特征是否下雨是否有太阳等输入到网络从而来预测第四天的天气。
知识点RNN处理数据维度两种构建RNN的方法
问题描述对于序列数据采用循环神经网络
11.1 RNNCell 主要内容随机生成seq_size个句子通过h0为全零的RNN网络探究输入输出以及隐层的维度
代码实现利用RNNCell处理单个运算RNNCell只是RNN的一个单元用于处理一个时间步的输入数据需要在循环中手动处理时间步。
seqLen:每个句子所含词的个数
batchSize每次处理词的批数
InputSize每个词嵌入向量的位数
dataset: (seq_size, batch_size, input_size)——整个数据集维度
input: (batch_size, input_size)——每个时间步处理的输入input in dataset
hidden: (batch_size, output_size)——每次处理的隐层(即为output)import torchbatch_size 1
seq_len 3
input_size 4
hidden_size 2# Construction of RNNCell
cell torch.nn.RNNCell(input_sizeinput_size, hidden_sizehidden_size)
# Wrapping the sequence into:(seqLen,batchSize,InputSize)
dataset torch.randn(seq_len, batch_size, input_size) # (3,1,4)
# Initializing the hidden to zero
hidden torch.zeros(batch_size, hidden_size) # (1,2)for idx, input in enumerate(dataset):print( * 20, idx, * 20)print(Input size:, input.shape) # (batch_size, input_size)# 按序列依次输入到cell中seq_len3故循环3次hidden cell(input, hidden) # 返回的hidden是下一次的输入之一循环使用同一个cellprint(output size:, hidden.shape) # (batch_size, hidden_size)print(hidden.data)
Wih的size应该是(hidden * input)whh的size应该是(hidden * hidden)输入 * 一个权重和上一个隐藏层 * 一个权重。w1 * h w2 * x [w1 w2] [h x]^T也就是(h * (hi)) * (h i) * 1 h * 1的矩阵 然后丢到tanh()里去计算 写成下面公式 h t t a n h ( W i h x t b i h W h h h t − 1 b h h ) h_ttanh(W_{ih}x_tb_{ih}W_{hh}h_{t-1}b_{hh}) httanh(WihxtbihWhhht−1bhh)
如果使用rnncell主要用下面代码需要输入维度和隐藏层维度作为函数输入 import torchbatch_size 1
seq_len 3
input_size 4
hidden_size 2cell torch.nn.RNNCell(input_sizeinput_size, hidden_sizehidden_size)
# #(seqLen, batchSize, inputSize)
datasets torch.randn(seq_len, batch_size, input_size)
hidden torch.zeros(batch_size, hidden_size)for idx, input in enumerate(datasets):print( * 20, idx, * 20)print(input size:, input.shape)hidden cell(input, hidden)print(output size:, hidden.shape)print(hidden)Train a model to learn: “hello” - “ohlol”
基于RNNCell实现 先给每个字母编号索引然后对于’hello’序列写出其对应的序列表将表展开成一个独热向量出现的位置是1其他位置是0 每个字母相当于一个独热向量送进去输出是一个四维向量经过softmax输出概率最大的值在本题里应该是ohlol -》 “31232” 总代码
import torch# 输入样本特征数
input_size 4
# 隐藏层样本特征数分类数
hidden_size 4
# batch大小
batch_size 1idx2char [e, h, l, o]
# hello
x_data [1, 0, 2, 2, 3]#输入字典
# ohlol
y_data [3, 1, 2, 3, 2]#输出词典# 将x_data转换为one_hot表示torch.eye()
参数
n (int ) – 行数
m (int, optional) – 列数.如果为None,则默认为n
out (Tensor, optinal) - Output tensorx_one_hot torch.eye(n4)[x_data, :]
y_one_hot torch.eye(n4)[y_data, :]# x_data转换维度为(seqlen, batch_size, input_size),此维度为RNN的输入
inputs x_one_hot.view(-1, batch_size, input_size)
# y_data转换维度为(seqlen1)
labels torch.LongTensor(y_data).view(-1, 1)# 构建神经网络模型
class Model(torch.nn.Module):def __init__(self):super(Model, self).__init__()self.input_size input_sizeself.batch_size batch_sizeself.hidden_size hidden_size# 对于RNNCell输入为(batch_size, input_size)隐层为(batch_size, hidden_size)self.rnncell torch.nn.RNNCell(input_sizeself.input_size, hidden_sizeself.hidden_size)def forward(self, input, hidden):# h_tCell(x_t, h_t-1)hidden self.rnncell(input, hidden)return hidden# 初始化隐层h_0def init_hidden(self):return torch.zeros(self.batch_size, self.hidden_size)model Model()# 构建损失函数和优化器
criterion torch.nn.CrossEntropyLoss()
optimizer torch.optim.Adam(model.parameters(), lr0.01)# 训练
for epoch in range(60):loss 0optimizer.zero_grad()# h_0hidden model.init_hidden()print(Predicted string:, end)for input, label in zip(inputs, labels):hidden model(input, hidden)loss criterion(hidden, label)_, idx hidden.max(dim1)print(idx2char[idx.item()], end)loss.backward()optimizer.step()print(, epoch[%d/60] loss%.4f % (epoch1, loss.item()))
基于RNN实现
RNN需要输入三个参数input_size, hidden_size, num_layers 输入input的shape(seqSize, batch, input_size)
hidden的shape(numLayers, batch, hidden_size)
输出output的shape(seqSize, batch, hidden_size)
hidden的shape(numLayers, batch, hidden_size) import torchbatch_size 1
seq_len 3
input_size 4
hidden_size 2
num_layers 1cell torch.nn.RNN(input_sizeinput_size, hidden_sizehidden_size, num_layersnum_layers, batch_firstTrue)#(seqLen, batchSize, inputSize)
inputs torch.randn(batch_size, seq_len, input_size)
hidden torch.zeros(num_layers, batch_size, hidden_size)out, hidden cell(inputs, hidden)
print(output size:, out.shape)
print(output:, out)
print(hidden size:, hidden.shape)
print(hidden:, hidden)总代码
import torch# 1.参数设置
seq_len 5
input_size 4
hidden_size 4
batch_size 1# 2.数据准备
index2char [e, h, l, o]
x_data [1, 0, 2, 2, 3]
y_data [3, 1, 2, 3, 2]
one_hot_lookup [[1, 0, 0, 0],[0, 1, 0, 0],[0, 0, 1, 0],[0, 0, 0, 1]]
x_one_hot [one_hot_lookup[x] for x in x_data]
inputs torch.Tensor(x_one_hot).view(-1, batch_size, input_size)
labels torch.LongTensor(y_data)# 3.模型构建
class Model(torch.nn.Module):def __init__(self, input_size, hidden_size, batch_size, num_layers1): # 需要指定输入隐层批super(Model, self).__init__()self.batch_size batch_sizeself.input_size input_sizeself.hidden_size hidden_sizeself.num_layers num_layersself.rnn torch.nn.RNN(input_sizeself.input_size, hidden_sizeself.hidden_size, num_layersself.num_layers)def forward(self, input):hidden torch.zeros(self.num_layers,self.batch_size,self.hidden_size)out, _ self.rnn(input, hidden) # out: tensor of shape (seq_len, batch, hidden_size)return out.view(-1, self.hidden_size) # 将输出的三维张量转换为二维张量,(×,)net Model(input_size, hidden_size, batch_size)# 4.损失和优化器
criterion torch.nn.CrossEntropyLoss()
optimizer torch.optim.Adam(net.parameters(), lr0.5)# 5.训练
for epoch in range(15):optimizer.zero_grad()outputs net(inputs)print(outputs.shape)loss criterion(outputs, labels)loss.backward()optimizer.step()_, idx outputs.max(dim1)idx idx.data.numpy()print(Predicted string: , .join([index2char[x] for x in idx]), end)print(,Epoch [%d / 15] loss:%.4f % (epoch1, loss.item()))
one-hot的缺点高维、稀疏、硬编码
需求低维、稠密、从数据中学习
实现方法embedding
含嵌入层的RNN网络
from gpt4o
含嵌入层的RNN网络是结合嵌入层Embedding Layer和循环神经网络RNN的一种神经网络架构常用于自然语言处理NLP任务。嵌入层的主要作用是将离散的词汇映射到连续的向量空间中从而为RNN提供密集的、低维的输入表示这比直接使用稀疏的one-hot编码更为高效。
嵌入层的作用
嵌入层将词汇表中的每个词映射到一个固定维度的向量。它的主要优点包括
降低维度从高维的one-hot编码词汇表大小转换为低维的密集向量表示。捕捉语义关系相似的词在嵌入空间中往往具有相近的向量表示从而能够捕捉词与词之间的语义关系。
含嵌入层的RNN网络架构
一个典型的含嵌入层的RNN网络架构包括以下几个部分
嵌入层将输入的词汇索引序列转换为嵌入向量序列。RNN层处理嵌入向量序列捕捉序列中的时序依赖关系。输出层根据任务的不同可以是分类层、回归层等用于生成最终的预测结果。
以下是一个含嵌入层的RNN网络的具体代码示例和详细解释
import torch
import torch.nn as nn# 定义超参数
vocab_size 10 # 词汇表大小
embed_size 8 # 嵌入向量的维度
hidden_size 16 # RNN隐藏层的维度
output_size 5 # 输出层的大小例如类别数
num_layers 1 # RNN的层数# 定义含嵌入层的RNN模型
class RNNModelWithEmbedding(nn.Module):def __init__(self, vocab_size, embed_size, hidden_size, output_size, num_layers1):super(RNNModelWithEmbedding, self).__init__()self.embedding nn.Embedding(vocab_size, embed_size) # 嵌入层self.rnn nn.RNN(embed_size, hidden_size, num_layers, batch_firstTrue)self.fc nn.Linear(hidden_size, output_size) # 全连接层输出最终结果def forward(self, x):embedded self.embedding(x) # 输入序列通过嵌入层out, hidden self.rnn(embedded) # 嵌入向量序列通过RNN层out self.fc(out[:, -1, :]) # 取RNN的最后一个时间步的输出经过全连接层return out# 创建模型实例
model RNNModelWithEmbedding(vocab_size, embed_size, hidden_size, output_size, num_layers)# 打印模型结构
print(model)# 创建随机输入形状为(batch_size, seq_len)
input_data torch.randint(0, vocab_size, (2, 3)) # 例如 batch_size2, seq_len3# 前向传播
output model(input_data)print(输入:, input_data)
print(输出:, output)
嵌入层self.embedding nn.Embedding(vocab_size, embed_size)
vocab_size词汇表的大小即词汇数量。embed_size每个词的嵌入向量的维度。嵌入层的作用是将输入的词汇索引序列如[1, 2, 3]转换为嵌入向量序列。
RNN层self.rnn nn.RNN(embed_size, hidden_size, num_layers, batch_firstTrue)
embed_sizeRNN的输入维度即嵌入向量的维度。hidden_sizeRNN隐藏层的维度。num_layersRNN的层数。batch_firstTrue输入和输出的形状为(batch_size, seq_len, feature_size)。
全连接层self.fc nn.Linear(hidden_size, output_size)
hidden_sizeRNN隐藏层的维度。output_size输出层的大小例如分类任务中的类别数。全连接层的作用是将RNN的输出转换为最终的预测结果。
前向传播函数def forward(self, x)
输入x是词汇索引序列形状为(batch_size, seq_len)。通过嵌入层将输入序列转换为嵌入向量序列embedded。嵌入向量序列通过RNN层得到输出out和隐藏状态hidden。取RNN层最后一个时间步的输出out[:, -1, :]通过全连接层得到最终输出out。
gpt结束
在下面加一层embed层
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
torch.nn.Embedding(num_embeddings, embedding_dim, padding_idxNone, max_normNone, norm_type2.0, scale_grad_by_freqFalse, sparseFalse)参数解释
num_embeddings嵌入字典的大小即词汇表的大小。比如如果有 10000 个不同的单词那么 num_embeddings 就是 10000。
embedding_dim每个嵌入向量的维度。比如如果希望每个单词表示为 128 维的向量那么 embedding_dim 就是 128。
padding_idx (可选)如果指定了这个参数那么这个索引将在计算梯度时总是返回零向量并且其对应的嵌入向量不会更新。这个通常用于处理填充padding。
max_norm (可选)如果指定了这个参数每个嵌入向量的范数norm将不会超过这个值。如果某个嵌入向量的范数超过了 max_norm那么它将被重新缩放到 max_norm。
norm_type (可选)用于计算范数的类型。默认为2L2范数。
scale_grad_by_freq (可选)如果设为 True则根据单词在小批量中的频率来缩放梯度。
sparse (可选)如果设为 True则使用稀疏更新。当使用嵌入层torch.nn.Embedding作为 RNN 的输入时输入张量通常需要是长整型torch.LongTensor因为嵌入层的输入是索引索引通常以长整型表示。嵌入层将这些索引映射到相应的嵌入向量然后这些嵌入向量可以作为 RNN 的输入。 总代码
import torch# 1、确定参数
num_class 4
input_size 4
hidden_size 8
embedding_size 10
num_layers 2
batch_size 1
seq_len 5# 2、准备数据
index2char [e, h, l, o] # 字典
x_data [[1, 0, 2, 2, 3]] # (batch_size, seq_len) 用字典中的索引数字表示来表示hello
y_data [3, 1, 2, 3, 2] # (batch_size * seq_len) 标签ohlolinputs torch.LongTensor(x_data) # (batch_size, seq_len)
labels torch.LongTensor(y_data) # (batch_size * seq_len)# 3、构建模型
class Model(torch.nn.Module):def __init__(self):super(Model, self).__init__()self.emb torch.nn.Embedding(num_class, embedding_size)self.rnn torch.nn.RNN(input_sizeembedding_size, hidden_sizehidden_size, num_layersnum_layers,batch_firstTrue)self.fc torch.nn.Linear(hidden_size, num_class)def forward(self, x):hidden torch.zeros(num_layers, x.size(0), hidden_size) # (num_layers, batch_size, hidden_size)x self.emb(x) # 返回(batch_size, seq_len, embedding_size)x, _ self.rnn(x, hidden) # 返回(batch_size, seq_len, hidden_size)x self.fc(x) # 返回(batch_size, seq_len, num_class)return x.view(-1, num_class) # (batch_size * seq_len, num_class)net Model()# 4、损失和优化器
criterion torch.nn.CrossEntropyLoss()
optimizer torch.optim.Adam(net.parameters(), lr0.05) # Adam优化器# 5、训练
for epoch in range(15):optimizer.zero_grad()outputs net(inputs)loss criterion(outputs, labels)loss.backward()optimizer.step()_, idx outputs.max(dim1)idx idx.data.numpy()print(Predicted string: , .join([index2char[x] for x in idx]), end)print(, Epoch [%d/15] loss: %.4f % (epoch 1, loss.item()))其他RNN扩展
LSTM长短期记忆网络 LSTM通过引入细胞状态和门控机制输入门、遗忘门和输出门来保留和控制长期依赖信息。解决了标准RNN在处理长序列时的梯度消失问题。
import torch
import torch.nn as nnclass LSTMModel(nn.Module):def __init__(self, input_size, hidden_size, batch_size, num_layers1):super(LSTMModel, self).__init__()self.hidden_size hidden_sizeself.num_layers num_layersself.lstm nn.LSTM(input_size, hidden_size, num_layers)def forward(self, input):h0 torch.zeros(self.num_layers, input.size(1), self.hidden_size)c0 torch.zeros(self.num_layers, input.size(1), self.hidden_size)out, _ self.lstm(input, (h0, c0))return out.view(-1, self.hidden_size)GRU门控循环单元
GRU是LSTM的简化版本使用更新门和重置门来控制信息的流动。与LSTM相比GRU的参数较少因此计算效率更高。
import torch
import torch.nn as nnclass GRUModel(nn.Module):def __init__(self, input_size, hidden_size, batch_size, num_layers1):super(GRUModel, self).__init__()self.hidden_size hidden_sizeself.num_layers num_layersself.gru nn.GRU(input_size, hidden_size, num_layers)def forward(self, input):h0 torch.zeros(self.num_layers, input.size(1), self.hidden_size)out, _ self.gru(input, h0)return out.view(-1, self.hidden_size)Bidirectional RNN双向RNN
双向RNN在输入序列的两个方向正向和反向上进行训练从而捕获更多的上下文信息。可以用于LSTM和GRU。
python复制代码import torch
import torch.nn as nnclass BidirectionalLSTMModel(nn.Module):def __init__(self, input_size, hidden_size, batch_size, num_layers1):super(BidirectionalLSTMModel, self).__init__()self.hidden_size hidden_sizeself.num_layers num_layersself.lstm nn.LSTM(input_size, hidden_size, num_layers, bidirectionalTrue)def forward(self, input):h0 torch.zeros(self.num_layers * 2, input.size(1), self.hidden_size)c0 torch.zeros(self.num_layers * 2, input.size(1), self.hidden_size)out, _ self.lstm(input, (h0, c0))return out.view(-1, self.hidden_size * 2)Attention Mechanism注意力机制
注意力机制用于在处理序列时动态地关注重要部分。常用于提高序列到序列模型如机器翻译的性能。
python复制代码import torch
import torch.nn as nnclass AttentionModel(nn.Module):def __init__(self, input_size, hidden_size, batch_size, num_layers1):super(AttentionModel, self).__init__()self.hidden_size hidden_sizeself.num_layers num_layersself.lstm nn.LSTM(input_size, hidden_size, num_layers)self.attention nn.Linear(hidden_size, hidden_size)def forward(self, input):h0 torch.zeros(self.num_layers, input.size(1), self.hidden_size)c0 torch.zeros(self.num_layers, input.size(1), self.hidden_size)out, _ self.lstm(input, (h0, c0))attn_weights torch.softmax(self.attention(out), dim1)out torch.bmm(attn_weights.transpose(1, 2), out)return out.view(-1, self.hidden_size)这些RNN变体在不同的应用中各有优势选择适当的变体可以显著提高模型的性能。
注意力机制Attention Mechanism是深度学习中一种强大的技术尤其在自然语言处理NLP任务中。它允许模型在处理序列数据时动态地关注序列的不同部分从而捕捉更丰富的上下文信息。以下是一些关于注意力机制的详细信息和其主要变体。
基本注意力机制
基本的注意力机制可以用在编码器-解码器结构中以动态地聚焦在输入序列的不同部分。下面是一个简单的注意力机制示例
python复制代码import torch
import torch.nn as nnclass BasicAttention(nn.Module):def __init__(self, hidden_size):super(BasicAttention, self).__init__()self.attention nn.Linear(hidden_size, hidden_size)def forward(self, encoder_outputs, decoder_hidden):# 计算注意力权重attn_weights torch.bmm(encoder_outputs, decoder_hidden.unsqueeze(2)).squeeze(2)attn_weights torch.softmax(attn_weights, dim1)# 用注意力权重加权平均编码器输出context torch.bmm(attn_weights.unsqueeze(1), encoder_outputs).squeeze(1)return context, attn_weights自注意力机制Self-Attention
自注意力机制用于捕获序列中各位置之间的关系尤其适用于序列到序列任务。它是Transformer模型的核心组件。
自注意力计算
自注意力计算涉及三个矩阵查询矩阵Query、键矩阵Key和值矩阵Value。下面是自注意力计算的公式 Attention ( Q , K , V ) softmax ( Q K T d k ) V \text{Attention}(Q, K, V) \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V Attention(Q,K,V)softmax(dk QKT)V
python复制代码import torch
import torch.nn as nnclass SelfAttention(nn.Module):def __init__(self, input_size, hidden_size):super(SelfAttention, self).__init__()self.query nn.Linear(input_size, hidden_size)self.key nn.Linear(input_size, hidden_size)self.value nn.Linear(input_size, hidden_size)self.scale torch.sqrt(torch.FloatTensor([hidden_size]))def forward(self, x):Q self.query(x)K self.key(x)V self.value(x)attention_weights torch.bmm(Q, K.transpose(1, 2)) / self.scaleattention_weights torch.softmax(attention_weights, dim-1)context torch.bmm(attention_weights, V)return context, attention_weights多头注意力机制Multi-Head Attention
多头注意力机制是自注意力的扩展它通过多个注意力头head来捕获不同的特征子空间。每个头独立地执行自注意力然后将所有头的输出连接起来。
import torch
import torch.nn as nnclass MultiHeadAttention(nn.Module):def __init__(self, input_size, hidden_size, num_heads):super(MultiHeadAttention, self).__init__()self.num_heads num_headsself.hidden_size hidden_sizeself.query nn.Linear(input_size, hidden_size * num_heads)self.key nn.Linear(input_size, hidden_size * num_heads)self.value nn.Linear(input_size, hidden_size * num_heads)self.fc nn.Linear(hidden_size * num_heads, hidden_size)def forward(self, x):batch_size x.size(0)Q self.query(x).view(batch_size, -1, self.num_heads, self.hidden_size).transpose(1, 2)K self.key(x).view(batch_size, -1, self.num_heads, self.hidden_size).transpose(1, 2)V self.value(x).view(batch_size, -1, self.num_heads, self.hidden_size).transpose(1, 2)attention_weights torch.matmul(Q, K.transpose(-2, -1)) / torch.sqrt(torch.FloatTensor([self.hidden_size]))attention_weights torch.softmax(attention_weights, dim-1)context torch.matmul(attention_weights, V).transpose(1, 2).contiguous().view(batch_size, -1, self.hidden_size * self.num_heads)output self.fc(context)return output, attention_weightsTransformer模型
Transformer模型是基于自注意力和多头注意力机制的架构。它广泛应用于NLP任务并通过引入位置编码Positional Encoding解决了序列位置问题。
简单的Transformer编码器
class TransformerEncoder(nn.Module):def __init__(self, input_size, hidden_size, num_heads, num_layers):super(TransformerEncoder, self).__init__()self.layers nn.ModuleList([nn.TransformerEncoderLayer(hidden_size, num_heads) for _ in range(num_layers)])self.embedding nn.Linear(input_size, hidden_size)def forward(self, src):src self.embedding(src)for layer in self.layers:src layer(src)return src