如何建立深度学习模型,从几个不同的包中挑选单词并形成一个有意义的句子
How to build deep learning model that picks words from serval distinct bags and forms a meaningful sentence
Image of Bags and how to choose from them
假设我有 10 个包,在 other.ie Bag 1,Bag 2 之后订购了一个......... Bag n.
每个袋子都有不同的单词集。
为了了解包是什么,
假设我们有 10,000 个单词的词汇量。
第一个包包含单词 Hello , India , Manager.
即 Bag 1 的单词索引处为 1。
ex:Bag 1 的大小为 10000*1
如果 Hello 的指数为 1 India 的指数为 2 而 Manager 的指数为 4
这将是
[0 , 1, 1, 0 , 1 ,0,0,0,0 ......]
*我还没有模型。
*我想用故事书,但对我来说还是有点抽象。
必须从每个包中选择一个单词并分配一个数字 word 1(word from bag 1)
单词 2(袋子 2 中的单词),它们必须按照数字顺序组成一个有意义的句子。!
首先,我们需要一种计算机可以识别单词的方法,否则它无法选择正确的单词。这意味着在这个阶段,我们需要决定我们要教计算机从什么开始(即什么是动词、名词、语法),但我假设我们会将字典倒入其中,除了单词本身之外不提供任何信息。
为了让计算机可以计算出句子是什么,我们需要将它们转换为数字(一种方法是从 1 开始按字母顺序工作,将它们用作字典的键(这次是数字(!))和词作为值)。现在我们可以将相同的线性代数技术应用于这个问题,就像任何其他问题一样。
所以我们需要将生成的权值矩阵乘到字典的键中,然后去掉所有超出字典键范围的权值,剩下的可以用来取字典中的值,使一句话。或者,您还可以使用阈值来减去矩阵乘法的所有输出
现在是困难的部分:学习。一旦你有了一些(比如 100 个)矩阵,我们需要 "breed" 最好的(这是需要人工干预的地方),你需要选择 50 个最有意义的句子(一开始可能很难)并使用它们以你的下一个 100 为基础(最简单的方法是随机加权 50 个矩阵以获得加权平均值 100 次)。
还有无聊的一点,一遍又一遍地保持 运行 几代人,直到你的句子大部分时间都有意义(当然不能保证它总是有意义但是这就是 ANN 的本质)
如果您发现它不起作用,您可以使用更多层(更多矩阵)and/or 我最近听说了一种动态改变网络的不同技术,但我对此无能为力。
有 database
个 thousands/millions 个有效句子。
创建一个字典,其中每个单词代表一个数字(为 "nothing" 保留 0,为 "start of sentence" 保留 1,为 "end of sentence" 保留 2)。
word_dic = { "_nothing_": 0, "_start_": 1, "_end_": 2, "word1": 3, "word2": 4, ...}
reverse_dic = {v:k for k,v in word_dic.items()}
记得在数据库中所有句子的开头和结尾加上"_start_"
和"_end_"
,在结尾后面加上"_nothing_"
来完成想要的能够包含所有句子的长度. (理想情况下,使用 10 个或更少单词的句子,这样您的模型就不会尝试创建更大的句子)。
将你所有的句子转换成索引序列:
#supposing you have an array of shape (sentences, length) as string:
indices = []
for word in database.reshape((-1,)):
indices.append(word_dic[word])
indices = np.array(indices).reshape((sentences,length))
使用 keras 函数将其转换为分类词 to_categorical()
cat_sentences = to_categorical(indices) #shape (sentences,length,dictionary_size)
Hint: keras has lots of useful text preprocessing functions here.
分离训练输入和输出数据:
#input is the sentences except for the last word
x_train = cat_sentences[:,:-1,:]
y_train = cat_sentences[:,1:,:]
让我们创建一个基于 LSTM 的模型,该模型将从前面的单词预测下一个单词:
model = Sequential()
model.add(LSTM(dontKnow,return_sequences=True,input_shape=(None,dictionary_size)))
model.add(.....)
model.add(LSTM(dictionary_size,return_sequences=True,activation='sigmoid'))
#or a Dense(dictionary_size,activation='sigmoid')
使用 x_train
和 y_train
编译并拟合此模型:
model.compile(....)
model.fit(x_train,y_train,....)
在所有 LSTM
层中使用 stateful=True
创建相同的模型:
newModel = ......
转移训练模型的权重:
newModel.set_weights(model.get_weights())
以明确的方式创建您的包包,形状 (10, dictionary_size)
。
使用模型从 _start_
个词中预测一个词。
#reset the states of the stateful model before you start a 10 word prediction:
newModel.reset_states()
firstWord = newModel.predict(startWord) #startword is shaped as (1,1,dictionary_size)
firstWord
将是一个大小为 dictionary_size
的向量,告诉(某种程度上)每个现有单词的概率。对比一下包里的话。您可以选择最高概率,或者如果包中其他单词的概率也不错,则使用一些随机选择。
#example taking the most probable word:
firstWord = np.array(firstWord == firstWord.max(), dtype=np.float32)
再做同样的事情,但现在在模型中输入firstWord
:
secondWord = newModel.predict(firstWord) #respect the shapes
重复这个过程,直到你得到一个句子。注意你可能会发现 _end_
在满足包中的 10 个单词之前。你可能会决定用一个更短的句子来完成这个过程,尤其是当其他词的概率很低的时候。
Image of Bags and how to choose from them
假设我有 10 个包,在 other.ie Bag 1,Bag 2 之后订购了一个......... Bag n.
每个袋子都有不同的单词集。
为了了解包是什么, 假设我们有 10,000 个单词的词汇量。 第一个包包含单词 Hello , India , Manager.
即 Bag 1 的单词索引处为 1。 ex:Bag 1 的大小为 10000*1 如果 Hello 的指数为 1 India 的指数为 2 而 Manager 的指数为 4 这将是 [0 , 1, 1, 0 , 1 ,0,0,0,0 ......]
*我还没有模型。 *我想用故事书,但对我来说还是有点抽象。
必须从每个包中选择一个单词并分配一个数字 word 1(word from bag 1) 单词 2(袋子 2 中的单词),它们必须按照数字顺序组成一个有意义的句子。!
首先,我们需要一种计算机可以识别单词的方法,否则它无法选择正确的单词。这意味着在这个阶段,我们需要决定我们要教计算机从什么开始(即什么是动词、名词、语法),但我假设我们会将字典倒入其中,除了单词本身之外不提供任何信息。
为了让计算机可以计算出句子是什么,我们需要将它们转换为数字(一种方法是从 1 开始按字母顺序工作,将它们用作字典的键(这次是数字(!))和词作为值)。现在我们可以将相同的线性代数技术应用于这个问题,就像任何其他问题一样。
所以我们需要将生成的权值矩阵乘到字典的键中,然后去掉所有超出字典键范围的权值,剩下的可以用来取字典中的值,使一句话。或者,您还可以使用阈值来减去矩阵乘法的所有输出
现在是困难的部分:学习。一旦你有了一些(比如 100 个)矩阵,我们需要 "breed" 最好的(这是需要人工干预的地方),你需要选择 50 个最有意义的句子(一开始可能很难)并使用它们以你的下一个 100 为基础(最简单的方法是随机加权 50 个矩阵以获得加权平均值 100 次)。
还有无聊的一点,一遍又一遍地保持 运行 几代人,直到你的句子大部分时间都有意义(当然不能保证它总是有意义但是这就是 ANN 的本质)
如果您发现它不起作用,您可以使用更多层(更多矩阵)and/or 我最近听说了一种动态改变网络的不同技术,但我对此无能为力。
有 database
个 thousands/millions 个有效句子。
创建一个字典,其中每个单词代表一个数字(为 "nothing" 保留 0,为 "start of sentence" 保留 1,为 "end of sentence" 保留 2)。
word_dic = { "_nothing_": 0, "_start_": 1, "_end_": 2, "word1": 3, "word2": 4, ...}
reverse_dic = {v:k for k,v in word_dic.items()}
记得在数据库中所有句子的开头和结尾加上"_start_"
和"_end_"
,在结尾后面加上"_nothing_"
来完成想要的能够包含所有句子的长度. (理想情况下,使用 10 个或更少单词的句子,这样您的模型就不会尝试创建更大的句子)。
将你所有的句子转换成索引序列:
#supposing you have an array of shape (sentences, length) as string:
indices = []
for word in database.reshape((-1,)):
indices.append(word_dic[word])
indices = np.array(indices).reshape((sentences,length))
使用 keras 函数将其转换为分类词 to_categorical()
cat_sentences = to_categorical(indices) #shape (sentences,length,dictionary_size)
Hint: keras has lots of useful text preprocessing functions here.
分离训练输入和输出数据:
#input is the sentences except for the last word
x_train = cat_sentences[:,:-1,:]
y_train = cat_sentences[:,1:,:]
让我们创建一个基于 LSTM 的模型,该模型将从前面的单词预测下一个单词:
model = Sequential()
model.add(LSTM(dontKnow,return_sequences=True,input_shape=(None,dictionary_size)))
model.add(.....)
model.add(LSTM(dictionary_size,return_sequences=True,activation='sigmoid'))
#or a Dense(dictionary_size,activation='sigmoid')
使用 x_train
和 y_train
编译并拟合此模型:
model.compile(....)
model.fit(x_train,y_train,....)
在所有 LSTM
层中使用 stateful=True
创建相同的模型:
newModel = ......
转移训练模型的权重:
newModel.set_weights(model.get_weights())
以明确的方式创建您的包包,形状 (10, dictionary_size)
。
使用模型从 _start_
个词中预测一个词。
#reset the states of the stateful model before you start a 10 word prediction:
newModel.reset_states()
firstWord = newModel.predict(startWord) #startword is shaped as (1,1,dictionary_size)
firstWord
将是一个大小为 dictionary_size
的向量,告诉(某种程度上)每个现有单词的概率。对比一下包里的话。您可以选择最高概率,或者如果包中其他单词的概率也不错,则使用一些随机选择。
#example taking the most probable word:
firstWord = np.array(firstWord == firstWord.max(), dtype=np.float32)
再做同样的事情,但现在在模型中输入firstWord
:
secondWord = newModel.predict(firstWord) #respect the shapes
重复这个过程,直到你得到一个句子。注意你可能会发现 _end_
在满足包中的 10 个单词之前。你可能会决定用一个更短的句子来完成这个过程,尤其是当其他词的概率很低的时候。