import sys
import random
import numpy as np
import math
import torch
from torch import nn
#[B,C,L],一个序列100条交易,一条交易200个特征,即使用200个 维度/列 描述一条交易
seq_len=100
in_feature= 200
data = torch.randn(64,seq_len,in_feature)
data.shape
#统一转换到指定维度计算
embedding_dim=256
w = torch.randn(in_feature,embedding_dim)
(data@w).shape # torch.Size([64, 100, 256])
# 位置编码层
class PositionEmbedding(nn.Module):
def __init__(self,seq_len=100, in_feature=200, embedding_dim=256):
super().__init__()
self.w = nn.Parameter(torch.ones(in_feature, embedding_dim, dtype=torch.float32),requires_grad=True)
self.norm = torch.nn.LayerNorm(normalized_shape=embedding_dim,
elementwise_affine=True)
# pos是第几个词,i是第几个维度,d_model是维度总数
def get_pe(pos, i, d_model):
temp = 1e4 ** (i / d_model)
pe = pos / temp
if i % 2 == 0:
return math.sin(pe)
return math.cos(pe)
# 初始化位置编码矩阵
pe = torch.empty(seq_len, embedding_dim)
for i in range(seq_len):#第几个序列
for j in range(embedding_dim):#第几个维度
pe[i, j] = get_pe(i, j, embedding_dim)
pe = pe.unsqueeze(0)
# 定义为不更新的常量
self.register_buffer('pe', pe)
# 初始化参数
# self.w.weight.data.normal_(0, 0.1)
def forward(self, x):
# [B, C, seq_len] -> [B, C, embedding_dim]
embed = x@self.w
# 特征维度归一化
x = self.norm(embed)
# 词编码和位置编码相加
# [B, C, embedding_dim] + [1, C, embedding_dim] -> [B, C, embedding_dim]
embed = x + self.pe
return embed
embed = PositionEmbedding(seq_len=100, embedding_dim=256)
res = embed(data)
特征维度从200转换到256
res.shape #torch.Size([64, 100, 256])
|