第1關(guān):邁出第一步----數(shù)據(jù)預(yù)處理
代碼文件
import numpy as np
test_point = input()
with open('cmn.txt', 'r', encoding='utf-8') as f:
data = f.read()
data = data.split('\n')
data = data[:100]
#########begin#########
en_data = [line.split('\t')[0] for line in data]
ch_data = ['\t' + line.split('\t')[1] + '\n' for line in data]
#########end#########
print('英文數(shù)據(jù):\n', en_data[:5])
print('\n中文數(shù)據(jù):\n', ch_data[:5])
print('數(shù)據(jù)讀取完成')
# 分別生成中英文字典
#########begin#########
en_vocab = set(''.join(en_data))
en_vocab = sorted(en_vocab)
id2en = {i: char for i, char in enumerate(en_vocab)}
en2id = {char: i for i, char in enumerate(en_vocab)}
ch_vocab = set(''.join(ch_data))
ch_vocab = sorted(ch_vocab)
id2ch = {i: char for i, char in enumerate(ch_vocab)}
ch2id = {char: i for i, char in enumerate(ch_vocab)}
#########end#########
print('\n英文字典:\n', en2id)
print('\n中文字典\n:', ch2id)
print('字典構(gòu)建完成')
en_num_data = [[en2id[en] for en in line] for line in en_data]
ch_num_data = [[ch2id[ch] for ch in line] for line in ch_data]
de_num_data = [[ch2id[ch] for ch in line][1:] for line in ch_data]
import numpy as np
# 獲取輸入輸出端的最大長度
max_encoder_seq_length = max([len(txt) for txt in en_num_data])
max_decoder_seq_length = max([len(txt) for txt in ch_num_data])
#########begin#########
# 將數(shù)據(jù)進(jìn)行onehot處理
# 將數(shù)據(jù)進(jìn)行onehot處理
encoder_input_data = np.zeros(
(len(en_num_data), max_encoder_seq_length, len(en2id)), dtype='float32')
decoder_input_data = np.zeros(
(len(ch_num_data), max_decoder_seq_length, len(ch2id)), dtype='float32')
decoder_target_data = np.zeros(
(len(ch_num_data), max_decoder_seq_length, len(ch2id)), dtype='float32')
for i, (input_text, target_text) in enumerate(zip(en_num_data, ch_num_data)):
for t, char in enumerate(input_text):
encoder_input_data[i, t, char] = 1.
for t, char in enumerate(target_text):
decoder_input_data[i, t, char] = 1.
# 注意:target_text是從索引1開始,因?yàn)樗饕?是'\t'開始標(biāo)記
if t > 0:
# decoder_target_data是從索引0開始,結(jié)束標(biāo)記是'\n'
decoder_target_data[i, t - 1, char] = 1.
#########end#########
print(encoder_input_data[int(test_point)])
print(decoder_input_data[int(test_point)])
print(decoder_target_data[int(test_point)])
print('向量化完成')
題目描述
任務(wù)描述
本關(guān)任務(wù):基于機(jī)器學(xué)習(xí)的思想,是一種數(shù)據(jù)驅(qū)動的研究思想,因此首先要對準(zhǔn)備研究的數(shù)據(jù)進(jìn)行處理。對于機(jī)器翻譯模型,數(shù)據(jù)預(yù)處理主要分為兩個方面:
- 標(biāo)準(zhǔn)化自然語言語句的格式
- 構(gòu)建訓(xùn)練所用的語言詞典
- 將語詞轉(zhuǎn)化為向量
相關(guān)知識
為了完成本關(guān)任務(wù),你需要掌握:
- 讀取原始數(shù)據(jù)并對其進(jìn)行標(biāo)準(zhǔn)化整理
- 根據(jù)自然語言語句數(shù)據(jù),構(gòu)建英語和法語兩個詞典。
- 將自然語言向量化
數(shù)據(jù)整理
本實(shí)訓(xùn)提供20,000個英語句子和其相對應(yīng)的20,000個翻譯好的法語句子。數(shù)據(jù)的原始格式如下:
每一行包含一句英語句子和其對應(yīng)的法語句子,它們中間用\t
隔開?,F(xiàn)在希望將英語和法語句子分割開來,將英語句子存入en_data
,將法語句子存入ch_data
,并且為了后續(xù)模型訓(xùn)練,規(guī)定英語句子保持不變,而法語每個句子都以\t
開頭,并以\n
結(jié)尾。
#英文句子
line.split('\t')[0]
#中文句子
'\t' + line.split('\t')[1] + '\n'
構(gòu)建詞典
所謂詞典,就是指在整個數(shù)據(jù)集中出現(xiàn)的所有token
所構(gòu)成的集合。該token
可以是單詞,也可以是字母。本文以字母作為token
。所有的英文字符存儲在en_vocab
中,中文字符存儲在ch_vocab
中。詞典一般使用dictionary
數(shù)據(jù)類型,以英文為例子,英文的詞典分為兩個:
-
id2en
,其中的key
為詞典的index
,而value
對應(yīng)相應(yīng)的英文字母 -
en2id
,其中key
為英文字母,而value
為對應(yīng)的詞典index
?例如:id2en[0]
# out: a
en2id['a']
# out: 0
自然語言向量化
向量化后的自然語言語句,將被用于模型的輸入。對自然語言的向量化,一種常用的方法是one-hot編碼。 one-hot編碼,又稱“獨(dú)熱編碼”。其實(shí)就是用N位狀態(tài)寄存器編碼N個狀態(tài),每個狀態(tài)都有獨(dú)立的寄存器位,且這些寄存器位中只有一位有效。 例如一個特征“性別”,性別有“男性”、“女性”,這個特征有兩個特征值,也只有兩個特征值,如果這個特征進(jìn)行one-hot編碼,則特征值為“男性”的編碼為“10”,“女性”的編碼為“01” 在代碼片段中,使用encoder_input_data
,decoder_input_data
和decoder_target_data
,分別來存儲向量化的英文、中文和目標(biāo)語言句子。以encoder_input_data
為例:
# 三維數(shù)組,第一維度是數(shù)據(jù)集中的總句子數(shù),第二維度為最長的
# 句子長度,最后一維度為字典的長度
encoder_input_data = np.zeros((len(en_num_data), max_encoder_seq_length, len(en2id)), dtype='float32')
# 向量化時,根據(jù)詞典將0向量的相應(yīng)位置置為1
for i in range(len(ch_num_data)):
for t, j in enumerate(en_num_data[i]):
encoder_input_data[i, t, j] = 1.
編程要求
根據(jù)提示,在右側(cè)編輯器補(bǔ)充代碼。完成數(shù)據(jù)的標(biāo)準(zhǔn)化處理、構(gòu)建訓(xùn)練所用的語言詞典并將語詞轉(zhuǎn)化為向量。
測試說明
平臺會對你編寫的代碼進(jìn)行測試: 測試輸入: 1 預(yù)期輸出(會輸出對應(yīng)測試輸入的向量化數(shù)據(jù)):
英文數(shù)據(jù):
['Hi.', 'Hi.', 'Run.', 'Wait!', 'Hello!']
中文數(shù)據(jù):
['\t嗨。\n', '\t你好。\n', '\t你用跑的。\n', '\t等等!\n', '\t你好。\n']
數(shù)據(jù)讀取完成
英文字典:
{' ': 0, '!': 1, "'": 2, '.': 3, '?': 4,...
中文字典:
{'\t': 0, '\n': 1, '!': 2, '。':...
字典構(gòu)建完成
[[0. 0. 0. 0.....
向量化完成
開始你的任務(wù)吧,祝你成功!文章來源地址http://www.zghlxwxcb.cn/news/detail-827131.html
第2關(guān):?模型訓(xùn)練----搭建seq2seq訓(xùn)練模型
代碼文件
import data_prepare
from keras.models import Model
from keras.layers import Input, LSTM, Dense, Embedding,concatenate,TimeDistributed,RepeatVector,Bidirectional
from keras.optimizers import Adam
EN_VOCAB_SIZE = 47
CH_VOCAB_SIZE = 147
HIDDEN_SIZE = 256
LEARNING_RATE = 0.003
BATCH_SIZE = 100
EPOCHS = 200
encoder_input_data, decoder_input_data,decoder_target_data,_,_,_ = data_prepare.getdata()
# ==============encoder=============
#########begin#########
# Encoder
encoder_inputs = Input(shape=(None, EN_VOCAB_SIZE))
encoder_LSTM = LSTM(HIDDEN_SIZE, return_sequences=True, return_state=True, name='encoder')
encoder_outputs, state_h, state_c = encoder_LSTM(encoder_inputs)
encoder_states = [state_h, state_c]
#########end#########
# # ==============decoder=============
#########begin#########
# Decoder
decoder_inputs = Input(shape=(None, CH_VOCAB_SIZE))
decoder_LSTM = LSTM(HIDDEN_SIZE, return_sequences=True, return_state=True, name='decoder')
decoder_outputs, _, _ = decoder_LSTM(decoder_inputs, initial_state=encoder_states)
decoder_dense = Dense(CH_VOCAB_SIZE, activation='softmax', name='dense')
decoder_outputs = decoder_dense(decoder_outputs)
#########end#########
#
#
model = Model([encoder_inputs, decoder_inputs], decoder_outputs)
opt = Adam(lr=LEARNING_RATE, beta_1=0.9, beta_2=0.999, epsilon=1e-08)
model.compile(optimizer=opt, loss='categorical_crossentropy', metrics=['accuracy'])
model.summary()
# model.fit([encoder_input_data, decoder_input_data], decoder_target_data,
# batch_size=BATCH_SIZE,
# epochs=EPOCHS,
# validation_split=0.2)
題目描述
任務(wù)描述
本關(guān)任務(wù):準(zhǔn)備好數(shù)據(jù)后,就要著手搭建訓(xùn)練模型了。本關(guān)將完成seq2seq模型的搭建和模型的訓(xùn)練。
相關(guān)知識
為了完成本關(guān)任務(wù),你需要掌握: 1.seq2seq模型基本原理 2.搭建seq2seq模型 3.訓(xùn)練seq2seq模型
seq2seq模型基本原理
Seq2Seq模型是RNN最重要的一個變種,這種結(jié)構(gòu)又叫Encoder-Decoder模型。 由于我們遇到的大部分問題序列都是不等長的,如機(jī)器翻譯中,源語言和目標(biāo)語言的句子往往并沒有相同的長度。
為此,Encoder-Decoder結(jié)構(gòu)先將輸入數(shù)據(jù)編碼成一個上下文向量,該上下文向量通常是Encoder的最后一個隱藏狀態(tài)。 Decoder將該上下文向量作為輸入,對其進(jìn)行解碼,輸出相應(yīng)的目標(biāo)序列。 由于Encoder-Decoder結(jié)構(gòu)不限制輸入和輸出的序列長度,因此應(yīng)用的范圍非常廣泛,比如:機(jī)器翻譯、文本摘要、閱讀理解、語音識別等。
搭建seq2seq模型
Encoder模型
首先對模型的Encoder部分進(jìn)行搭建,為此我們需要考慮3個方面:
- Encoder模型的輸入是什么樣子?
- Encoder模型使用怎樣的RNN單元?
- 模型的哪部分作為Decoder的輸入?
模型的輸入可以使用Input來設(shè)定,輸入的形狀要與字典長度相同:
encoder_input = Input(shape=(None,len(vocabulary)))
本關(guān)模型使用LSTM單元,維度設(shè)置為HIDDEN_SIZE
,return_sequences
字段用來決控制是否需要每一步的輸出,return_states
用來控制是否輸出隱藏層狀態(tài)。
encoder_LSTM = LTM(HIDDEN_SIZE, return_sequences=True, return_state=True,name='encoder')
Encoder使用最后一層的隱藏狀態(tài),即encoder_state_h
和 encoder_state_c
作為Decoder的輸入:
encoder_h, encoder_state_h, encoder_state_c = encoder_LSTM (encoder_input)
Decoder模型
對Decoder部分進(jìn)行搭建,我們需要考慮3個方面:
- Decoder模型的輸入是什么樣子?
- Decoder模型使用怎樣的RNN單元?
- 模型的輸出是怎樣的結(jié)構(gòu)?
前兩步與Encoder相似,對于Decoder的輸出,我們使用一個全連接層,并使用softmax
激活函數(shù)將輸出的向量映射到目標(biāo)語言的字典上。
lstm = LSTM(HIDDEN_SIZE, return_sequences=True, return_state=True,name='decoder')
decoder_h, _, _ = lstm(decoder_inputs, initial_state=[encoder_state_h, encoder_state_c])
decoder_dense = Dense(CH_VOCAB_SIZE, activation='softmax',name='dense')
decoder_outputs = decoder_dense(decoder_h)
Decoder部分還可以使用注意力機(jī)制:
該方法通過一個attention
層,將Encoder
部分的每一步的輸出與decoder_inputs
聯(lián)系起來作為decoder
的輸入。相當(dāng)于根據(jù)序列的每個時間步將編碼器編碼為不同隱藏向量c
,在解碼時,結(jié)合每個不同的c
進(jìn)行解碼輸出,這樣得到的結(jié)果會更加準(zhǔn)確。在本實(shí)訓(xùn)中,請先掌握較為簡單的普通Decoder
結(jié)構(gòu)。
訓(xùn)練seq2seq模型
訓(xùn)練模型時,我們用Model模塊將Encoder和Decoder封裝,并通過optimizer
選擇優(yōu)化器,loss
選擇損失函數(shù)。
model = Model([encoder_inputs, decoder_inputs], decoder_outputs)
opt = Adam(lr=LEARNING_RATE, beta_1=0.9, beta_2=0.999, epsilon=1e-08)
model.compile(optimizer=opt, loss='categorical_crossentropy', metrics=['accu\fracy'])
模型在訓(xùn)練時,將之前預(yù)處理好的數(shù)據(jù)輸入模型,并設(shè)置相應(yīng)參數(shù)即可。
model.fit([encoder_input_data, decoder_input_data], decoder_target_data,
batch_size=BATCH_SIZE,
epochs=EPOCHS,
validation_split=0.2)
其中x
為輸入的數(shù)據(jù),y
為輸出的數(shù)據(jù)。batch_size
為每一批處理的序列數(shù),epochs
為訓(xùn)練的迭代次數(shù),validation_split
為訓(xùn)練集和驗(yàn)證集的比例。 ####編程要求
根據(jù)提示,在右側(cè)編輯器補(bǔ)充代碼,完成seq2seq模型的搭建和訓(xùn)練。
測試說明
平臺會對你編寫的代碼進(jìn)行測試:
模型結(jié)構(gòu)與要求相符即可通過本關(guān)。
開始你的任務(wù)吧,祝你成功!
第3關(guān):模型實(shí)踐----搭建seq2seq推斷模型
代碼文件
import data_prepare
from keras.models import Model
from keras.layers import Input, LSTM, Dense, Embedding, concatenate, TimeDistributed, RepeatVector, Bidirectional
from keras.optimizers import Adam
import numpy as np
# Existing code for setting up the model
EN_VOCAB_SIZE = 47
CH_VOCAB_SIZE = 147
HIDDEN_SIZE = 256
LEARNING_RATE = 0.003
BATCH_SIZE = 100
EPOCHS = 100
encoder_input_data, decoder_input_data, decoder_target_data, ch2id, id2ch, en_data = data_prepare.getdata()
# ==============encoder=============
encoder_inputs = Input(shape=(None, EN_VOCAB_SIZE))
encoder_h, encoder_state_h, encoder_state_c = LSTM(HIDDEN_SIZE, return_sequences=True, return_state=True, name='encoder')(encoder_inputs)
# ==============decoder=============
decoder_inputs = Input(shape=(None, CH_VOCAB_SIZE))
decoder = LSTM(HIDDEN_SIZE, return_sequences=True, return_state=True, name='decoder')
decoder_dense = Dense(CH_VOCAB_SIZE, activation='softmax', name='dense')
decoder_h, _, _ = decoder(decoder_inputs, initial_state=[encoder_state_h, encoder_state_c])
decoder_outputs = decoder_dense(decoder_h)
model = Model([encoder_inputs, decoder_inputs], decoder_outputs)
opt = Adam(lr=LEARNING_RATE, beta_1=0.9, beta_2=0.999, epsilon=1e-08)
model.compile(optimizer=opt, loss='categorical_crossentropy', metrics=['accuracy'])
model.fit([encoder_input_data, decoder_input_data], decoder_target_data, batch_size=BATCH_SIZE, epochs=EPOCHS, validation_split=0.2, verbose=0)
# Encoder Inference Model
encoder_model = Model(encoder_inputs, [encoder_state_h, encoder_state_c])
# Decoder Inference Model
decoder_state_input_h = Input(shape=(HIDDEN_SIZE,))
decoder_state_input_c = Input(shape=(HIDDEN_SIZE,))
decoder_h, state_h, state_c = decoder(decoder_inputs, initial_state=[decoder_state_input_h, decoder_state_input_c])
decoder_outputs = decoder_dense(decoder_h)
decoder_model = Model([decoder_inputs, decoder_state_input_h, decoder_state_input_c], [decoder_outputs, state_h, state_c])
for k in range(40, 50):
test_data = encoder_input_data[k:k + 1]
h, c = encoder_model.predict(test_data)
target_seq = np.zeros((1, 1, CH_VOCAB_SIZE))
target_seq[0, 0, ch2id['\t']] = 1
outputs = []
while True:
output_tokens, h, c = decoder_model.predict([target_seq, h, c])
sampled_token_index = np.argmax(output_tokens[0, -1, :])
outputs.append(sampled_token_index)
if sampled_token_index == ch2id['\n'] or len(outputs) > 20:
break
target_seq = np.zeros((1, 1, CH_VOCAB_SIZE))
target_seq[0, 0, sampled_token_index] = 1
print(en_data[k])
print(''.join([id2ch[i] for i in outputs if i not in [ch2id['\t'], ch2id['\n']]])+'\n')
題目描述
任務(wù)描述
本關(guān)任務(wù):本關(guān)將使用訓(xùn)練好的翻譯模型,對英文句子進(jìn)行翻譯。
相關(guān)知識
為了完成本關(guān)任務(wù),你需要掌握: 1.如何建立推斷模型。 2.如何將模型的輸出整理成最終翻譯的結(jié)果
建立推斷模型
推斷模型的建立也分為兩部分,模型Encoder部分的結(jié)構(gòu)與訓(xùn)練時完全相同,因此只需要將原來的encoder
部分封裝起來即可:
# Encoder inference model
encoder_model = Model(encoder_inputs, [encoder_state_h, encoder_state_c])
而Decoder部分,需要將每一步的輸出作為下一步的輸入:
因此需要對Decoder部分重新設(shè)計(jì)。 首先確定Decoder部分的輸入與輸出,輸入部分的大小應(yīng)與Encoder輸出的大小相同。
decoder_state_input_h = Input(shape=(HIDDEN_SIZE,))
decoder_state_input_c = Input(shape=(HIDDEN_SIZE,))
由于我們需要每一步的輸出作為下一步的輸入,因此需要將Decoder的隱藏狀態(tài)和輸出向量都存下來以備用。
decoder_h, state_h, state_c = decoder(decoder_inputs, initial_state=[decoder_state_input_h, decoder_state_input_c])
decoder_outputs = decoder_dense(decoder_h)
最后將Decoder的部分封裝:
decoder_model = Model([decoder_inputs, decoder_state_input_h, decoder_state_input_c], [decoder_outputs, state_h, state_c])
輸出整理
Decoder部分的輸出是一個概率向量,它的每一位對應(yīng)著字典中相應(yīng)位置的概率,通常我們將輸出向量中概率值最高的一位,作為預(yù)測的結(jié)果:
output_tokens, h, c= decoder_model.predict([target_seq, h, c])
sampled_token_index = np.argmax(output_tokens[0, -1, :])
在獲得Encoder部分的輸出后,我們需要設(shè)計(jì)一個程序結(jié)構(gòu),使得Decoder部分將每一步的輸出送入下一步之中,并且當(dāng)輸出了終止符號或者超過最長輸出序列長度(本實(shí)訓(xùn)中設(shè)置為20)時,停止程序。
while True:
output_tokens, h, c= decoder_model.predict([target_seq, h, c])
#...
target_seq = np.zeros((1, 1, CH_VOCAB_SIZE))
target_seq[0, 0, sampled_token_index] = 1
if sampled_token_index == ch2id['\n'] or len(outputs) > 20: break
編程要求
根據(jù)提示,在右側(cè)編輯器補(bǔ)充代碼,搭建推斷模型,完成英語到法語的翻譯模型。 ####測試說明
平臺會對你編寫的代碼進(jìn)行測試: 輸入英文,輸出相應(yīng)的中文語句。 注意:本關(guān)需要運(yùn)行模型,因此評測可能較慢,請耐心等待1-2分鐘。文章來源:http://www.zghlxwxcb.cn/news/detail-827131.html
開始你的任務(wù)吧,祝你成功!
到了這里,關(guān)于廣西民族大學(xué)高級人工智能課程—頭歌實(shí)踐教學(xué)實(shí)踐平臺—機(jī)器翻譯--English to Chinese的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!