TongHTP2.0集成MQTT从原理到实战:构建实时消息通道
2026/9/26 13:53:24
注:后续技术类文章会同步到我的公众号里,搜索公众号小志的博客感兴趣的读友可以去找来看看。
我们先准备训练数据,可以在网上找公开的翻译数据集,我们用的是 AIchallenger 2017,这个数据集有 1000 万对中英文数据,不过因为电脑配置问题,我直接从里面中文和英文的部分各取了 10000 条进行训练。数据集名称是 train_1w.zh和 train_1w.en。
cn_sentences=[]zh_file_path="train_1w.zh"# 使用Python的文件操作逐行读取文件,并将每一行的内容添加到列表中withopen(zh_file_path,"r",encoding="utf-8")as file:forline in file:# 去除行末的换行符并添加到列表中 cn_sentences.append(line.strip())en_sentences=[]en_file_path="train_1w.en"# 使用Python的文件操作逐行读取文件,并将每一行的内容添加到列表中withopen(en_file_path,"r",encoding="utf-8")as file:forline in file:# 去除行末的换行符并添加到列表中 en_sentences.append(line.strip())接下来,基于训练数据集构建中文和英文的词汇表,将每个词映射到一个唯一的索引(integer)。
# cn_sentences 和 en_sentences 分别包含了所有的中文和英文句子 cn_vocab=build_vocab(cn_sentences,tokenize_cn,max_size=10000,min_freq=2)en_vocab=build_vocab(en_sentences,tokenize_en,max_size=10000,min_freq=2)我们再来看 biild_vocab 的源码。
defbuild_vocab(sentences,tokenizer,max_size,min_freq):token_freqs=Counter()forsentence in sentences:tokens=tokenizer(sentence)token_freqs.update(tokens)vocab={token:idx+4foridx,(token,freq)inenumerate(token_freqs.items())iffreq>=min_freq}vocab['<unk>']=0vocab['<pad>']=1vocab['<sos>']=2vocab['<eos>']=3returnvocab思路就是把所有的句子读进去,循环分词,放入字典,放的时候要判断一下是否大于等于 min_freq,用来过滤掉出现频率较低的词汇,最后构建出来的词汇表如下:
vocab={'<unk>':0,'<pad>':1,'<sos>':2,'<eos>':3,'i':4,'like':5,'learning':6,'machine':7,'is':8,'very':9,'interesting':10,...}我们来看一下里面比较重要的几个部分。
< unk >:未知单词,表示在训练数据中没有出现过的单词。当模型在处理输入文本时遇到未知单词时,会用这个标记来表示。
< pad>:填充单词,用于将不同长度的序列填充到相同的长度。在处理批次数据时,由于不同序列的长度可能不同,因此需要用这个标记把短序列填充到与最长序列相同的长度,以便进行批次处理。
< sos>:句子起始标记,表示句子的开始位置。在 Seq2Seq 模型中,通常会在目标句子的开头添加这个标记,以指示解码器开始生成输出。
< eos>:句子结束标记,表示句子的结束位置。在 Seq2Seq 模型中,通常会在目标句子的末尾添加该标记,以指示解码器生成结束。
创建训练数据集,将数据处理成方便训练的格式:语言序列,比如 [1,2,3,4]。
dataset=TranslationDataset(cn_sentences,en_sentences,cn_vocab,en_vocab,tokenize_cn,tokenize_en)train_loader=DataLoader(dataset,batch_size=32,collate_fn=collate_fn)然后检测是否有显卡:
# 检查是否有可用的GPU,如果没有,则使用CPUdevice=torch.device("cuda"iftorch.cuda.is_available()else"cpu")print("训练设备为:",device)创建模型,参数的解释可以参考代码注释。
# 定义一些超参数 INPUT_DIM=10000# 输入语言的词汇量 OUTPUT_DIM=10000# 输出语言的词汇量 ENC_EMB_DIM=256# 编码器嵌入层大小,也就是编码器词向量维度 DEC_EMB_DIM=256# 解码器嵌入层大小,解码器词向量维度 HID_DIM=512# 隐藏层维度 N_LAYERS=2# RNN层的数量 ENC_DROPOUT=0.5# 编码器神经元输出的数据有50%会被随机丢掉 DEC_DROPOUT=0.5# 解码器同上 enc=Encoder(INPUT_DIM,ENC_EMB_DIM,HID_DIM,N_LAYERS,ENC_DROPOUT)dec=Decoder(OUTPUT_DIM,DEC_EMB_DIM,HID_DIM,N_LAYERS,DEC_DROPOUT)model=Seq2Seq(enc,dec,device).to(device)# 假定模型已经被实例化并移到了正确的设备上 model.to(device)# 定义优化器和损失函数 optimizer=optim