李宏毅-hw5-translation-有关transformer、seq2seq的探索

这篇具有很好参考价值的文章主要介绍了李宏毅-hw5-translation-有关transformer、seq2seq的探索。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、ppt研读:

1.关于这个 input Embedding 的内容:

李宏毅-hw5-translation-有关transformer、seq2seq的探索,人工智能,transformer,深度学习,人工智能

李宏毅-hw5-translation-有关transformer、seq2seq的探索,人工智能,transformer,深度学习,人工智能

2.关于Positional Encoding:

李宏毅-hw5-translation-有关transformer、seq2seq的探索,人工智能,transformer,深度学习,人工智能

李宏毅-hw5-translation-有关transformer、seq2seq的探索,人工智能,transformer,深度学习,人工智能

二、慢慢积累,一点点阅读代码:

虽然这次的模块挺多的,但是,这样也就意味着,把这个内化为自己的,就可以获得更大的进步了

1.关于使用git命令获取到源代码:

李宏毅-hw5-translation-有关transformer、seq2seq的探索,人工智能,transformer,深度学习,人工智能

2.Fix Random Seed部分都是相同的,就是为了结果可以复现:
seed = 73
random.seed(seed)
torch.manual_seed(seed)
if torch.cuda.is_available():
    torch.cuda.manual_seed(seed)
    torch.cuda.manual_seed_all(seed)  
np.random.seed(seed)  
torch.backends.cudnn.benchmark = False
torch.backends.cudnn.deterministic = True
3.定义一个字符类型转换函数:
def strQ2B(ustring):
    """Full width -> half width"""
    # reference:https://ithelp.ithome.com.tw/articles/10233122
    ss = []
    for s in ustring:
        rstring = ""
        for uchar in s:
            inside_code = ord(uchar)
            if inside_code == 12288:  # Full width space: direct conversion
                inside_code = 32
            elif (inside_code >= 65281 and inside_code <= 65374):  # Full width chars (except space) conversion
                inside_code -= 65248
            rstring += chr(inside_code)
        ss.append(rstring)
    return ''.join(ss)

李宏毅-hw5-translation-有关transformer、seq2seq的探索,人工智能,transformer,深度学习,人工智能

4.字符处理函数:
def clean_s(s, lang):
    if lang == 'en':
        s = re.sub(r"\([^()]*\)", "", s) # remove ([text])
        s = s.replace('-', '') # remove '-'
        s = re.sub('([.,;!?()\"])', r' \1 ', s) # keep punctuation
    elif lang == 'zh':
        s = strQ2B(s) # Q2B
        s = re.sub(r"\([^()]*\)", "", s) # remove ([text])
        s = s.replace(' ', '')
        s = s.replace('—', '')
        s = s.replace('“', '"')
        s = s.replace('”', '"')
        s = s.replace('_', '')
        s = re.sub('([。,;!?()\"~「」])', r' \1 ', s) # keep punctuation
    s = ' '.join(s.strip().split())
    return s

李宏毅-hw5-translation-有关transformer、seq2seq的探索,人工智能,transformer,深度学习,人工智能

5.python中的string.split()分割函数:

李宏毅-hw5-translation-有关transformer、seq2seq的探索,人工智能,transformer,深度学习,人工智能

6.定义整个文字串的处理函数:
```python
def clean_corpus(prefix, l1, l2, ratio=9, max_len=1000, min_len=1):
    # 检查已经存在的清洗后文件,如果存在则跳过清洗步骤
    if Path(f'{prefix}.clean.{l1}').exists() and Path(f'{prefix}.clean.{l2}').exists():
        print(f'{prefix}.clean.{l1} & {l2} exists. skipping clean.')
        return
    
    # 打开原始语料文件和清洗后的输出文件
    with open(f'{prefix}.{l1}', 'r') as l1_in_f:
        with open(f'{prefix}.{l2}', 'r') as l2_in_f:
            with open(f'{prefix}.clean.{l1}', 'w') as l1_out_f:
                with open(f'{prefix}.clean.{l2}', 'w') as l2_out_f:
                    # 逐行读取原始语料文件
                    for s1 in l1_in_f:
                        s1 = s1.strip()  # 去除首尾空格
                        s2 = l2_in_f.readline().strip()
                        s1 = clean_s(s1, l1)  # 清洗句子 s1
                        s2 = clean_s(s2, l2)  # 清洗句子 s2
                        s1_len = len_s(s1, l1)  # 计算句子 s1 的长度
                        s2_len = len_s(s2, l2)  # 计算句子 s2 的长度
                        
                        if min_len > 0:  # 判断句子长度是否满足最小长度要求,如果不满足则跳过
                            if s1_len < min_len or s2_len < min_len:
                                continue
                        
                        if max_len > 0:  # 判断句子长度是否超过最大长度,如果超过则跳过
                            if s1_len > max_len or s2_len > max_len:
                                continue
                                
                        if ratio > 0:  # 判断句子长度比例是否满足要求,如果不满足则跳过
                            if s1_len/s2_len > ratio or s2_len/s1_len > ratio:
                                continue
                                
                        # 将清洗后的句子写入输出文件
                        print(s1, file=l1_out_f)
                        print(s2, file=l2_out_f)
```

以上是一个用于清洗语料的函数,函数将两个语料文件 `prefix.l1` 和 `prefix.l2` 清洗后保存到 `prefix.clean.l1` 和 `prefix.clean.l2` 文件中。

注释已经逐行添加在代码中。

总的来说呢,就是将 太长 或者 太短的 句子进行处理,并且进行一些符号的处理,使得最终得到的句子是比较合理的那种

7.转换为subword units进行处理:

import sentencepiece as spm
vocab_size = 8000
if (prefix/f'spm{vocab_size}.model').exists():
    print(f'{prefix}/spm{vocab_size}.model exists. skipping spm_train.') #如果这段文字已经被subword过了,pass
else:
    spm.SentencePieceTrainer.train( #否则,就要设置这个SentencePieceTrainer模块的参数的具体数值了
        input=','.join([f'{prefix}/train.clean.{src_lang}',
                        f'{prefix}/valid.clean.{src_lang}',
                        f'{prefix}/train.clean.{tgt_lang}',
                        f'{prefix}/valid.clean.{tgt_lang}']),
        model_prefix=prefix/f'spm{vocab_size}',
        vocab_size=vocab_size,
        character_coverage=1,
        model_type='unigram', # 'bpe' works as well
        input_sentence_size=1e6,
        shuffle_input_sentence=True,
        normalization_rule_name='nmt_nfkc_cf',
    )
spm_model = spm.SentencePieceProcessor(model_file=str(prefix/f'spm{vocab_size}.model')) #初始化上述模块
in_tag = {
    'train': 'train.clean',
    'valid': 'valid.clean',
    'test': 'test.raw.clean',
}
#反正下面这里就是利用subword进行文字串的处理
for split in ['train', 'valid', 'test']:
    for lang in [src_lang, tgt_lang]:
        out_path = prefix/f'{split}.{lang}'
        if out_path.exists():
            print(f"{out_path} exists. skipping spm_encode.")
        else:
            with open(prefix/f'{split}.{lang}', 'w') as out_f:
                with open(prefix/f'{in_tag[split]}.{lang}', 'r') as in_f:
                    for line in in_f:
                        line = line.strip()
                        tok = spm_model.encode(line, out_type=str)
                        print(' '.join(tok), file=out_f)
8.将上述的字符串利用fairseq处理:
binpath = Path('./DATA/data-bin', dataset_name)
if binpath.exists():
    print(binpath, "exists, will not overwrite!")
else:
    !python -m fairseq_cli.preprocess \
        --source-lang {src_lang}\
        --target-lang {tgt_lang}\
        --trainpref {prefix/'train'}\
        --validpref {prefix/'valid'}\
        --testpref {prefix/'test'}\
        --destdir {binpath}\
        --joined-dictionary\
        --workers 2

李宏毅-hw5-translation-有关transformer、seq2seq的探索,人工智能,transformer,深度学习,人工智能

9.原来真的需要些log实验日志:
logging.basicConfig(
    format="%(asctime)s | %(levelname)s | %(name)s | %(message)s",
    datefmt="%Y-%m-%d %H:%M:%S",
    level="INFO", # "DEBUG" "WARNING" "ERROR"
    stream=sys.stdout,
)
proj = "hw5.seq2seq"
logger = logging.getLogger(proj)
if config.use_wandb:
    import wandb
    wandb.init(project=proj, name=Path(config.savedir).stem, config=config)

李宏毅-hw5-translation-有关transformer、seq2seq的探索,人工智能,transformer,深度学习,人工智能

10.关于fairseq(facebook AI Research Sequence to Sequence Toolkit)这个库的初探

(1)概念:它基于PyTorch开发,提供了多种自然语言处理任务的模型,包括神经机器翻译、语音识别、文本生成等

(2)功能分块李宏毅-hw5-translation-有关transformer、seq2seq的探索,人工智能,transformer,深度学习,人工智能

(3)使用方式:(我感觉就是一种别具一格形式的函数调用)

李宏毅-hw5-translation-有关transformer、seq2seq的探索,人工智能,transformer,深度学习,人工智能

李宏毅-hw5-translation-有关transformer、seq2seq的探索,人工智能,transformer,深度学习,人工智能

http://t.csdn.cn/d8dpn

也可以参考这一篇文章

11.torch.bmm(tensor1,tensor2)这种批量的矩阵乘法运算:

李宏毅-hw5-translation-有关transformer、seq2seq的探索,人工智能,transformer,深度学习,人工智能

12.了解一下,什么叫做RNN(Recurrent Neural Network):

李宏毅-hw5-translation-有关transformer、seq2seq的探索,人工智能,transformer,深度学习,人工智能

二、下面重点研读 encoder 、 attention 和 decoder部分的代码(目前来说其他部分有些吃力,等我够强大了,再回来报仇!!!虽迟未晚)
1.Encoder部分的代码:
class RNNEncoder(FairseqEncoder): #通过继承来自FairseqEncoder的这个类模型
    def __init__(self, args, dictionary, embed_tokens): #_init_初始化函数:参数:arg参数数组中包含着embed_dim、hidden_dim、num_layers等参数,dictionary字符集,embed_tokens这个算是字符还是embedding之后的向量呢?
        super().__init__(dictionary) #用字符初始化父类的_init_函数
        self.embed_tokens = embed_tokens #把embed_tokens参数传进去
        
        self.embed_dim = args.encoder_embed_dim #原来arg中就有dim等参数
        self.hidden_dim = args.encoder_ffn_embed_dim #中间层的dim
        self.num_layers = args.encoder_layers  #layer的层数
        
        self.dropout_in_module = nn.Dropout(args.dropout) #args中的dropout概率参数也要传递进去
        self.rnn = nn.GRU(        #定义这个模型的rnn结构,
            self.embed_dim,      #传参:embed_dim就是embed时的dim维度
            self.hidden_dim,      #hidden_dim就是中间层的dim维度
            self.num_layers,      #num_layers层数
            dropout=args.dropout,   #dropout概率参数
            batch_first=False, 
            bidirectional=True
        )
        self.dropout_out_module = nn.Dropout(args.dropout)
        
        self.padding_idx = dictionary.pad()  #pad()又是这个用来对不够长的文段进行pad,然后返回索引
        
    def combine_bidir(self, outs, bsz: int):
        out = outs.view(self.num_layers, 2, bsz, -1).transpose(1, 2).contiguous()
        return out.view(self.num_layers, bsz, -1) #就是对outs结构的重新排布

    def forward(self, src_tokens, **unused): #定义encoder的运行函数了
        bsz, seqlen = src_tokens.size() #获取tokens的数量
        
        # get embeddings
        x = self.embed_tokens(src_tokens) #对tokens字符进行embedding得到向量序列
        x = self.dropout_in_module(x)   #经过一次dropout,防止overfit

        # B x T x C -> T x B x C
        x = x.transpose(0, 1)       
        
        # pass thru bidirectional RNN
        h0 = x.new_zeros(2 * self.num_layers, bsz, self.hidden_dim) #创建一个多维向量
        x, final_hiddens = self.rnn(x, h0) #将x数据 和 h0传进到rnn模型中,得到输出x和final_hiddens
        outputs = self.dropout_out_module(x) #再将x通过一个dropout得到outputs
        # outputs = [sequence len, batch size, hid dim * directions]
        # hidden =  [num_layers * directions, batch size  , hid dim]
        
        # Since Encoder is bidirectional, we need to concatenate the hidden states of two directions
        final_hiddens = self.combine_bidir(final_hiddens, bsz)
        # hidden =  [num_layers x batch x num_directions*hidden]
        
        encoder_padding_mask = src_tokens.eq(self.padding_idx).t()
        return tuple(
            (
                outputs,  # seq_len x batch x hidden
                final_hiddens,  # num_layers x batch x num_directions*hidden
                encoder_padding_mask,  # seq_len x batch
            )
        )
    
    def reorder_encoder_out(self, encoder_out, new_order): #用于beam_search,反正不重要
        # This is used by fairseq's beam search. How and why is not particularly important here.
        return tuple(
            (
                encoder_out[0].index_select(1, new_order),
                encoder_out[1].index_select(1, new_order),
                encoder_out[2].index_select(1, new_order),
            )
        )
2.attention函数的设计:
class AttentionLayer(nn.Module): #用nn.Module设计一个self-attention的网络结构
    def __init__(self, input_embed_dim, source_embed_dim, output_embed_dim, bias=False): #定义初始化函数
        super().__init__()

        self.input_proj = nn.Linear(input_embed_dim, source_embed_dim, bias=bias) #第一个Linear层-input
        self.output_proj = nn.Linear(
            input_embed_dim + source_embed_dim, output_embed_dim, bias=bias  #第二个Linear层-output
        )

    def forward(self, inputs, encoder_outputs, encoder_padding_mask): #定义运行函数
        # inputs: T, B, dim
        # encoder_outputs: S x B x dim
        # padding mask:  S x B
        
        # convert all to batch first
        #通过transpose将这些数据都转化为第零维的是batch
        inputs = inputs.transpose(1,0) # B, T, dim
        encoder_outputs = encoder_outputs.transpose(1,0) # B, S, dim
        encoder_padding_mask = encoder_padding_mask.transpose(1,0) # B, S
        
        # project to the dimensionality of encoder_outputs
        x = self.input_proj(inputs) #调用input_linear函数

        # compute attention
        # (B, T, dim) x (B, dim, S) = (B, T, S) #这里说的就是批量的矩阵乘法运算
        attn_scores = torch.bmm(x, encoder_outputs.transpose(1,2)) 

        # cancel the attention at positions corresponding to padding
        if encoder_padding_mask is not None:
            # leveraging broadcast  B, S -> (B, 1, S)
            encoder_padding_mask = encoder_padding_mask.unsqueeze(1)
            attn_scores = (
                attn_scores.float()
                .masked_fill_(encoder_padding_mask, float("-inf"))
                .type_as(attn_scores)
            )  # FP16 support: cast to float and back

        # softmax on the dimension corresponding to source sequence
        attn_scores = F.softmax(attn_scores, dim=-1)  #将attn_scores通过一个softmax

        # shape (B, T, S) x (B, S, dim) = (B, T, dim) weighted sum
        x = torch.bmm(attn_scores, encoder_outputs) #再次进行矩阵乘法

        # (B, T, dim)
        x = torch.cat((x, inputs), dim=-1) #沿着最后一维进行向量的拼接
        x = torch.tanh(self.output_proj(x)) # concat + linear + tanh(双曲正切值)
        
        # restore shape (B, T, dim) -> (T, B, dim)
        return x.transpose(1,0), attn_scores  #返回x,和对应的attn_scores分数
3.Decoder的结构设计:
class RNNDecoder(FairseqIncrementalDecoder): #继承来自FairseqIncrementalDecoder,有点d
    def __init__(self, args, dictionary, embed_tokens): #初始化参数:和encoder那边一样的基本
        super().__init__(dictionary) 
        self.embed_tokens = embed_tokens 
        
        #2个断言,不用管
        assert args.decoder_layers == args.encoder_layers, f"""seq2seq rnn requires that encoder 
        and decoder have same layers of rnn. got: {args.encoder_layers, args.decoder_layers}"""
        assert args.decoder_ffn_embed_dim == args.encoder_ffn_embed_dim*2, f"""seq2seq-rnn requires 
        that decoder hidden to be 2*encoder hidden dim. got: {args.decoder_ffn_embed_dim, args.encoder_ffn_embed_dim*2}"""
        
        #把参数传进去
        self.embed_dim = args.decoder_embed_dim
        self.hidden_dim = args.decoder_ffn_embed_dim
        self.num_layers = args.decoder_layers
        
        
        self.dropout_in_module = nn.Dropout(args.dropout)
        self.rnn = nn.GRU( #取nn.GRU模板作为rnn结构
            self.embed_dim, 
            self.hidden_dim, 
            self.num_layers, 
            dropout=args.dropout, 
            batch_first=False, 
            bidirectional=False
        )
        self.attention = AttentionLayer(  #把上面定义的那个attentionLayer涌过来
            self.embed_dim, self.hidden_dim, self.embed_dim, bias=False
        ) 
        # self.attention = None
        self.dropout_out_module = nn.Dropout(args.dropout)
        
        if self.hidden_dim != self.embed_dim: #是否需要Linear层的问题
            self.project_out_dim = nn.Linear(self.hidden_dim, self.embed_dim) 
        else:
            self.project_out_dim = None
        
        if args.share_decoder_input_output_embed:
            self.output_projection = nn.Linear(
                self.embed_tokens.weight.shape[1],
                self.embed_tokens.weight.shape[0],
                bias=False,
            )
            self.output_projection.weight = self.embed_tokens.weight
        else:
            self.output_projection = nn.Linear(
                self.output_embed_dim, len(dictionary), bias=False
            )
            nn.init.normal_(
                self.output_projection.weight, mean=0, std=self.output_embed_dim ** -0.5
            )
        
    def forward(self, prev_output_tokens, encoder_out, incremental_state=None, **unused): #定义整个Decoder的运行过程
        # extract the outputs from encoder
        encoder_outputs, encoder_hiddens, encoder_padding_mask = encoder_out #从encoder那里取到数据
        # outputs:          seq_len x batch x num_directions*hidden
        # encoder_hiddens:  num_layers x batch x num_directions*encoder_hidden
        # padding_mask:     seq_len x batch
        
        if incremental_state is not None and len(incremental_state) > 0:
            # if the information from last timestep is retained, we can continue from there instead of starting from bos
            prev_output_tokens = prev_output_tokens[:, -1:]
            cache_state = self.get_incremental_state(incremental_state, "cached_state")
            prev_hiddens = cache_state["prev_hiddens"]
        else:
            # incremental state does not exist, either this is training time, or the first timestep of test time
            # prepare for seq2seq: pass the encoder_hidden to the decoder hidden states
            prev_hiddens = encoder_hiddens
        
        bsz, seqlen = prev_output_tokens.size()
        
        #主要的操作都在下面了哇!
        # embed tokens
        x = self.embed_tokens(prev_output_tokens) #对tokens进行embedding得到向量序列
        x = self.dropout_in_module(x)       #通过一次dropout

        # B x T x C -> T x B x C
        x = x.transpose(0, 1)
                
        # decoder-to-encoder attention
        if self.attention is not None:
            x, attn = self.attention(x, encoder_outputs, encoder_padding_mask) #有attention就进行attention
                        
        # pass thru unidirectional RNN
        x, final_hiddens = self.rnn(x, prev_hiddens)  #通过rnn结构
        # outputs = [sequence len, batch size, hid dim]
        # hidden =  [num_layers * directions, batch size  , hid dim]
        x = self.dropout_out_module(x)
                
        # project to embedding size (if hidden differs from embed size, and share_embedding is True, 
        # we need to do an extra projection)
        if self.project_out_dim != None:
            x = self.project_out_dim(x)
        
        # project to vocab size
        x = self.output_projection(x)
        
        # T x B x C -> B x T x C
        x = x.transpose(1, 0)
        
        # if incremental, record the hidden states of current timestep, which will be restored in the next timestep
        cache_state = {
            "prev_hiddens": final_hiddens,
        }
        self.set_incremental_state(incremental_state, "cached_state", cache_state)
        
        return x, None
    
    def reorder_incremental_state( #下面就是用来进行beam_search的内容,暂时不管了
        self,
        incremental_state,
        new_order,
    ):
        # This is used by fairseq's beam search. How and why is not particularly important here.
        cache_state = self.get_incremental_state(incremental_state, "cached_state")
        prev_hiddens = cache_state["prev_hiddens"]
        prev_hiddens = [p.index_select(0, new_order) for p in prev_hiddens]
        cache_state = {
            "prev_hiddens": torch.stack(prev_hiddens),
        }
        self.set_incremental_state(incremental_state, "cached_state", cache_state)
        return

目前实力还不足以让我完成hw5,君子报仇,十年不晚文章来源地址https://www.toymoban.com/news/detail-703810.html

到了这里,关于李宏毅-hw5-translation-有关transformer、seq2seq的探索的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 李宏毅机器学习 hw2 boss baseline 解析

    Multiclass Classification ,让你判断给定的向量是属于哪一个 phoneme ,由于一个 phoneme 可能包含好多个向量,所以要对数据进行处理,对向量进行拼接。 不同baseline 要求 先给出我最终使用的过boss baseline的方法,后面再介绍我一步步的思考过程。 助教提示过boss baseline要使用RNN模型

    2023年04月09日
    浏览(38)
  • 李宏毅机器学习 hw7 boss baseline分享

    使用bert来做问答任务 答案是都是可以在 Document 找到的,输入 Document 和 Query 输出两个数字分别表示答案在Document中的开始和结束位置。 输入格式如下: doc stride ,初始时 Doc stride 等于 max_paragraph_len ,这样会导致在测试时如果答案在边界附近就会被切割到两个不同的 window 中

    2024年02月06日
    浏览(40)
  • 2023李宏毅机器学习HW05样例代码中文注释版

    这里只是 2023 李宏毅机器学习 HW05 样例代码的中文注释版的分享,下面的内容绝大部分是样例代码,补充了小部分函数的功能解释,没有做函数功能上的修改,是 Simple baseline 版本。 notebook 代码下载: [EN] [ZH] 进阶阅读:李宏毅2023机器学习作业HW05解析和代码分享 英译中(繁体

    2024年02月05日
    浏览(87)
  • 李宏毅-21-hw3:对11种食物进行分类-CNN

    一、代码慢慢阅读理解+总结内化: 1.关于torch.nn.covd2d()的参数含义、具体用法、功能: (1)参数含义: 注意,里面的“padding”参数:《both》side所以是上下左右《四》边都会加一个padding数量的0列: 证明如下: 运行结果:torch.Size([3, 4, 5, 4] (2)具体用法: 输入:x[ batch_size,

    2024年02月09日
    浏览(36)
  • 李宏毅 2022机器学习 HW2 strong baseline 上分路线

    baseline 增加concat_nframes (提升明显) 增加batchnormalization 和 dropout 增加hidden layer宽度至512 (提升明显) 提交文件命名规则为 prediction_{concat_nframes} [{n_hidden_layers} {dropout}_bn].csv (2%) Implement 2 models with approximately the same number of parameters, (A) one narrower and deeper (e.g. hidden_layers=6, hidden

    2024年02月10日
    浏览(43)
  • 李宏毅_机器学习_作业4(详解)_HW4 Classify the speakers

    本次作业需要学习完transformer后完成! 做语者辨识任务,一共有600个语者,给了每一个语者的语音feature进行训练,然后通过test_feature进行语者辨识。(本质上还是分类任务Classification) Simple(0.60824):run sample code and know how to use transformer Medium(0.70375):know how to adjust parameters of tra

    2024年02月01日
    浏览(42)
  • 李宏毅-机器学习hw4-self-attention结构-辨别600个speaker的身份

    一、慢慢分析+学习pytorch中的各个模块的参数含义、使用方法、功能: 1.encoder编码器中的nhead参数: self.encoder_layer = nn.TransformerEncoderLayer( d_model=d_model, dim_feedforward=256, nhead=2) 所以说,这个nhead的意思,就是有window窗口的大小,也就是一个b由几个a得到 2.tensor.permute改变维度的用

    2024年02月09日
    浏览(42)
  • 物体的移动Transform.Translate函数

    Transform.Translate通过设置下一步移动的矢量方向和大小进行移动。 有两种移动方式: 1.ADWS控制游戏对象上下左右移动,不涉及旋转; 2.AD通过旋转控制方向,WS控制前后移动,也可以实现受控位移。 无论哪种方式,首先都要获取键盘响应,可以通过Input.GetKey获取,也可以通过

    2024年02月03日
    浏览(36)
  • 【深度学习】Transformer、GPT、BERT、Seq2Seq什么区别?

    请看vcr:https://transformers.run/back/transformer/

    2024年02月08日
    浏览(43)
  • 基于transformer的Seq2Seq机器翻译模型训练、预测教程

    机器翻译(Machine Translation, MT)是一类将某种语言(源语言,source language)的句子 x x x 翻译成另一种语言(目标语言,target language)的句子 y y y 的任务。机器翻译的相关研究早在上世纪50年代美苏冷战时期就开始了,当时的机器翻译系统是基于规则的,利用两种语言的单词、

    2024年02月03日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包