导入必备的工具包
import torch
# 预定义的网络层torch.nn, 工具开发者已经帮助我们开发好的一些常用层, 比如,卷积层, lstm层, embedding层等, 不需要我们再重新造轮子.
import torch.nn as nn
# 数学计算工具包
import math
# torch中变量封装函数Variable.现在应该使用torch.Tensor了好像??
from torch.autograd import Variable
文本嵌入层
由于 EEG 本身是数值时间相关的序列,因此嵌入是不必要的。所以我们将原来的嵌入修改为标准的线性层。我们没有删除这个函数,因为我们想采用原始代码的架构。
# 定义Embeddings类来实现文本嵌入层,这里s说明代表两个一模一样的嵌入层, 他们共享参数.
# 该类继承nn.Module, 这样就有标准层的一些功能, 这里我们也可以理解为一种模式, 我们自己实现的所有层都这样去写.
class Embeddings(nn.Module):
def __init__(self, d_model, input_d): #(self,d_model,vocab)
"""类的初始化函数, 有两个参数, d_model: 指词嵌入的维度, input_d: 指词表的大小???"""
# 接着就是使用super的方式指明继承nn.Module的初始化函数, 我们自己实现的所有层都会这样去写.
super(Embeddings, self).__init__()
# 之后就是调用nn中的预定义层Linear, 获得一个对象self.proj
self.proj = nn.Linear(input_d, d_model)
# 下边是用于文本时的用法
# 调用nn中的预定义层Embedding, 获得一个词嵌入对象self.lut
# self.lut = nn.Embedding(vocab, d_model)
# 最后就是将d_model传入类中
# self.d_model = d_model
def forward(self, x):
"""可以将其理解为该层的前向传播逻辑,所有层中都会有此函数
当传给该类的实例化对象参数时, 自动调用该类函数
参数x: 因为Embedding层是首层, 所以代表输入给模型的文本通过词汇映射后的张量"""
# 将x传给self.proj并作为结果返回
return self.proj(x)
# return self.lut(x) * math.sqrt(self.d_model)
d_model = 512
vocab = 1000
x = Variable(torch.LongTensor([[1,2,3,4],[5,6,7,8]])) # (2,4)
emb = Embeddings(d_model,vocab)
embr = emb(x)
print('embr:', embr)