1.Parameter 是torch.autograd.Variable的一个子类,也可以理解为一种类型转换函数,其可将一个固定不可训练的tensor转换成可以训练的类型parameter,并将这个parameter绑定到这个module
里面;
2.一般来说,pytorch 的Parameter是一个tensor,但是跟通常意义上的tensor有区别:通常意义上的tensor 仅仅是数据,而Parameter所对应的tensor 除了包含数据之外,还包含一个属性:requires_grad(=True/False)
3.parameter.data 可得到tensor数据 ;parameter.requires_grad 默认为True, BP过程中会求导
4.Parameter一般是在Modules中作为权重和偏置,自动加入参数列表,可以进行保存恢复。和Variable具有相同的运算。
5.实际用法:
self.v = torch.nn.Parameter(torch.FloatTensor(hidden_size))
在注意力机制中,权值V
是不断学习且优化的,所以应是parameter
类型,不直接使用tensor类替换。
引入词嵌入可以直接调用torch.nn.Embedding(m, n) ,其中m 表示单词的总数目,n 表示词嵌入的维度,这里举例它的两种用法:
import torch
import torch.utils.data as Data
import torch.nn as nn
import torch.nn.functional as F
from torch.autograd import Variable
word_to_id = {'hello':0, 'world':1}
embeds = nn.Embedding(2, 10)
hello_idx = torch.LongTensor([word_to_id['hello']])
# hello_idx = Variable(hello_idx)
hello_embed = embeds(hello_idx)
print(hello_embed)
if __name__ == '__main__':
pass
from torchtext.vocab import Vectors
#1.引入自己的词向量路径
vector = Vectors(name='./vector_cache/sgns.weibo.word')
#2.根据词向量建立词表
text_field.build_vocab(train, dev, test, vectors=vector)
#3.获得word embedding
word_embedding = text_field.vocab.vectors
####在模型中使用word embedding
class textClassification(nn.Module):
def __init__(self, args):
super(textClassification,self).__init__()
V = args.embed_num#单词数
D = args.embed_dim#词向量维度
self.embed = nn.Embedding(V, D)
#将前面得到的word embedding代入
self.embed.weight = nn.Parameter(args.word_embedding, requires_grad=False)
...
def forward(self, x):
x = self.embed(x) # (batch,seq_len,embed_size)
....
1.ModuleList是将子Module作为一个List来保存的,可以通过下标进行访问,类似于Python中的List,但是该类需要手动实现forward函数。
2.Sequential内部自动实现了forward函数,可以在forward函数里直接调用定义的Sequentila结构体。
这里涉及pytorch底层的设计原理,理解比较复杂,这里参考contiguous的理解中的内容。
narrow(),view(),expand(),transpose(),permute()
这几个操作不改变tensor的内容,只是重新定义下标与元素的对应关系;即这种操作不改变数据也不进行数据拷贝,变的是元数据。
例如:在使用transpose()
进行转置操作时,pytorch并不会创建新的、转置后的tensor,而是修改了tensor中的一些属性(也就是元数据),使得此时的offset和stride是与转置tensor相对应的。转置的tensor和原tensor的内存是共享的!
我们看一下下面的代码:
x = torch.randn(3, 2)
y = x.transpose(x, 0, 1)
x[0, 0] = 233
print(y[0, 0])
# print 233
我们可以看到,改变了y的元素的值的同时,x的元素的值也发生了变化。
也就是说,经过上述操作后得到的tensor,它内部数据的布局方式和从头开始创建一个这样的常规的tensor的布局方式是不一样的!于是…这就有contiguous()
的用武之地了。
在上面的例子中,x是contiguous的,但y不是(因为内部数据不是通常的布局方式)。注意不要被contiguous的字面意思“连续的”误解,tensor中数据还是在内存中一块区域里,只是布局的问题!
当调用contiguous()
时,会强制拷贝一份tensor,让它的布局和从头创建的一模一样。
当我们遇到提示
RuntimeError: input is not contiguous
只需要加上contiguous()就可以了。
torch.view
等方法操作需要连续的Tensor呢?可以参考PyTorch中的contiguous
对传入数据应用线性变换:y = A x+ b
参数:
in_features - 每个输入样本的大小
out_features - 每个输出样本的大小
bias - 如果设置为False,则图层不会学习附加偏差。默认值:True
mm只能进行矩阵乘法,也就是输入的两个tensor维度只能是和
bmm是两个三维张量相乘, 两个输入tensor维度是 和,第一维b代表batch size,输出为
matmul可以进行张量乘法, 输入可以是高维.