文章目录
- 一、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的输出为一个概率分布:
- 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 “.” .(下一次可能抽到的是一个句号)
再下次可能抽到一个空格,不停重复下去,可能生成一段话,一篇文章,甚至是一本书
二、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作为标签
- 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.)
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()
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)
四、Text Generation(文本生成)
4.1 Predict the Next Char(预测下一个字符)
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).
4.2 Text Generation: An Example
五、Summary(总结)
5.1 Train a Neural Network (训练神经网络)
- Partition text to (segment, next_char) pairs. (把文本划分成片段)
- One-hot encode the characters.(把字符编码成向量)
- Character V x 1 vector. (每个字符用 V x 1的向量表示)
- Segment LxV matrix. (每个片段用 LxV 的矩阵表示)
- Build and train a neural network.
Lxv matrix ==> LSTM ==> Dense ==> vx1 vector.
5.2 Text Generation(文本生成)
- Propose a seed segment.
- 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.(把新生成的字符接到片段的后面,作为神经网络新的输入,开始下一轮循环)