文章目录

  • 一、Example(案例)
  • 二、Train an RNN for Text Prediction
  • 三、Training a Text Generator(训练文本生成器)—模型训练
  • 3.1 Prepare Training Data(准备训练数据)
  • 3.2 Character to Vector(字符变为向量)
  • 3.3 Build a Neural Network(设计一个神经网络)
  • 3.4 Train the Neural Network(训练神经网络)
  • 四、Text Generation(文本生成)
  • 4.1 Predict the Next Char(预测下一个字符)
  • 4.2 Text Generation: An Example
  • 五、Summary(总结)
  • 5.1 Train a Neural Network (训练神经网络)
  • 5.2 Text Generation(文本生成)


一、Example(案例)

前提:假设RNN已经训练好了。

  • 输入文本,把文本分割成字符,用one-hot encoding来表示字符,每个字符表示为one-hot 向量,把one-hot向量一次输入RNN,RNN的状态向量h会积累看到的信息,RNN返回最后一个状态向量h,在RNN层上面是一个Softmax分类器,把h与参数矩阵W相乘得到一个向量,经过Softmax函数的变换,最终输入为一个向量,每个元素在(0,1)之间,元素全部相加为1。
  • Softmax的输出为一个概率分布:
  • harmonyos next 关于TextPicker的使用_rnn

  • Input text: “the cat sat on the ma”
  • Question: what is the next char?
  • RNN outputs a distribution over the chars.(Softmax的输出为一个概率分布)
  • Sample a char from it; we may get ‘t’.(假设我们得到字符t)
  • Take "the cat sat on the mat"as input.(把t接入到输入的文本末尾,然后把这句话作为输入,计算下一个字符的概率分布,从而生成下一个字符)
  • Maybe the next char is period “.” .(下一次可能抽到的是一个句号)
    再下次可能抽到一个空格,不停重复下去,可能生成一段话,一篇文章,甚至是一本书
  • harmonyos next 关于TextPicker的使用_Network_02

二、Train an RNN for Text Prediction

How do we train such an RNN?(怎么样训练一个RNN)

训练数据为文本,比如英文维基百科的所有文章

  • Cut text to segments (with overlap) 把文章划分为很多片段,这些片段可以有重叠
  • E.g: seg len_40 and stride=3. (设置片段的长度为40,红色的片段有40个字符;步长为3表示下一个片段会向右平移三个字符的长度)
  • 红色片段作为输入的文本,输入神经网络,神经网络做出的预测是这个蓝色的字符a
  • 蓝色的字符a作为标签
  • harmonyos next 关于TextPicker的使用_Text_03

  • A segment is used as input text.(红色的片段用于神经网络的输入)
  • Its next char is used as label.(蓝色的字符会用作标签)
  • Training data: (segment , next _char ) pairs.(假如文章有3000个字符,文章会切成大约1000个pairs)
  • It is a multi-class classification problem.(它是一个多分类问题)
  • #class = #unique chars.(假如共有50个不同的字符,类别的数量是50,输入一个片段,输出50个概率值)

    训练神经网络的目的:给定输入的片段,神经网络可以预测下一个字符。

If the RNN is trained on Shakespeare’s books, then the generated text is Shakespeare’s style.

三、Training a Text Generator(训练文本生成器)—模型训练

3.1 Prepare Training Data(准备训练数据)

print("Text length:",len(text))            # Text length: 600893

text[0:1000]   # 文本的前1000个字符

3.2 Character to Vector(字符变为向量)

准备好文本,要处理文本,把一个字符变成一个向量,于是一个片段变成一个矩阵。

  • 第一步,建立一个字典,把一个字符映射到一个正整数。用字典把字符变成正整数。
  • 第二步,有了字典,做one-hot encoding。变成数值向量。

    问题:前几次,得到one-hot向量之后,要进行word Embedding,用一个低维词向量来表示一个词,这次不需要Embedding层。

原因:前几次,把一句话分成多个单词,英语里面有10000个常用词,把vocabulary设置成10000,那么one-hot encoding得到的one-hot 向量都是10000维的,维度太高,所以要用word Embedding把高维的one-hot 向量变成低维词向量,而这里我们把一句话切割成很多字符,文本里面通常也就几十个或100个常用字符(比如字母,数字,标点等),所以字典里面的vocabulary顶多100个,做one-hot encoding得到的one-hot 向量顶多100维,维度足够低,因此不需要进一步做Embedding。

  • Vocabulary is V = 57 (including letter, blank, punctuation, etc.) (字典里共有V=57个不同的字符,包括26个小写字母,空格,标点符号等)
  • Segment length is l = 60. (A segment has 60 chars.) (设置每个片段的长度l=60,每个片段里面有60个字符)
  • 于是每个长度为60的片段就变成了60×57的矩阵,每个字符用57维的one-hot向量表示
  • 便签是这个片段的下一个字符,这个字符编码成了57维的one-hot向量
  • Number of segments is n = 200,278. (Number of training samples.)
  • harmonyos next 关于TextPicker的使用_神经网络_04

3.3 Build a Neural Network(设计一个神经网络)

from keras import layers

# 开始搭建网络
model = keras.models.Sequential()     # 建立Sequential()模型
# LSTM层状态向量h的维度设为128,输入是60×57的矩阵,seg_len=60,vocabulary=57,每个片段编码成60×57的矩阵
# 这里面只能用单向LSTM,不能用双向LSTM,文本生成需要预测下一个字符,必须从前往后
model.add(layers.LSTM(128,input_shape=(seg_len,vocabulary)))
# 上面加载一个全连接层,加一个激活函数softmax,输出是v=57的向量,向量的每个元素是字符的概率值
# 字典里面有57个不同的字符,输出的向量是57维的
model.add(layers.Dense(vocabulary,activation="softmax"))
model.summary()

harmonyos next 关于TextPicker的使用_神经网络_05

3.4 Train the Neural Network(训练神经网络)

编译模型
# 指定优化算法为 RMSprop,loss为损失函数,
optimizer= keras.optimizers.RMSprop(lr=0.01)
model.compile(loss="categorical_cossentropy",optimizer=optimizer)

# 用训练数据来拟合模型,训练数据用x,y表示
model.fit(x,y,batch_size=128,epochs=1)

harmonyos next 关于TextPicker的使用_Network_06

四、Text Generation(文本生成)

4.1 Predict the Next Char(预测下一个字符)

harmonyos next 关于TextPicker的使用_Network_07


Question: Given the distribution, what will be the next char? (知道每个字符的概率值怎样生成下一个字符)

方法一:greedy selection.(哪个字符的概率大,选择哪个字符)

next_index = np.argmax(pred)
  • It is determipistic.(这种方法是确定性的,没有随机性)
  • Empirically not good.(从经验上讲不好。我们希望生成的文本尽量多元化)

方法二:sampling from the multinomial distrihution(多项式分布中随机抽取)

next_onehot = np.random.multinomial(1,pred,1)
next_index = np.argmax(next_onehot)
  • Maybe too random.(这种抽样太随机,生成的文本会有很多拼写和语法错误)

方法三:adjusting the multinomial distribution.(调整概率)

pred = pred ** (1 / temperature)
pred = pred / np.sum(pred)  # 归一化,大的概率值变大,小的概率值变小
  • Sample according to pred.
  • Between greedy and multinomial (controlled temperature).

harmonyos next 关于TextPicker的使用_神经网络_08

4.2 Text Generation: An Example

harmonyos next 关于TextPicker的使用_Text_09

五、Summary(总结)

5.1 Train a Neural Network (训练神经网络)

  1. Partition text to (segment, next_char) pairs. (把文本划分成片段)
  2. One-hot encode the characters.(把字符编码成向量)
  • Character V x 1 vector. (每个字符用 V x 1的向量表示)
  • Segment LxV matrix. (每个片段用 LxV 的矩阵表示)
  1. Build and train a neural network.
    Lxv matrix ==> LSTM ==> Dense ==> vx1 vector.

5.2 Text Generation(文本生成)

  1. Propose a seed segment.
  2. Repeat the followings:
  • Feed the segment (with one-hot) to the neural network.
  • The neural network outputs probabilities.
  • next_char <——Sample from the probabilities.(根据概率值做抽样,得到下一个字符)
  • Append next char to the segment.(把新生成的字符接到片段的后面,作为神经网络新的输入,开始下一轮循环)