1 . 能干什么
在知乎,博客上面會看到有人分享自己的一些有意思的項目恩敌,比如下面這些瞬测,用rnn學(xué)習(xí)一個詩歌,散文,黨章涣楷,小說什么的分唾。然后,在自己生成一些東西狮斗。比如绽乔,下面的這兩個例子。作為一個初學(xué)者碳褒,自己也想搭一個模型折砸,然后試著玩一玩。
關(guān)于RNN的模型結(jié)構(gòu)的基本原理沙峻,公式推導(dǎo)什么的睦授,就先不在這里展開了。下面寫得是摔寨,如何用tensorflow去實現(xiàn)這個模型去枷。
2. 使用tensorflow 搭建這個RNN的模型去實現(xiàn)
- 讀文件,將文件里面的句子分割成詞是复,然后變成一個list删顶。
## 預(yù)處理數(shù)據(jù)
def read_file():
# Text file containing words for training
training_file = 'belling_the_cat.txt'
content=[]
with open(training_file,'r') as f:
for line in f.readlines():
# line 表示讀到數(shù)據(jù)的每一行,linelist是按照空格切分成一個list
linelist=line.strip().split()
for i in linelist:
content.append(i.strip())
content=np.array(content)
content=np.reshape(content,[-1,]) #shape (204,1)
return content
- 建立字典淑廊,建立字典的目的是實現(xiàn)將詞轉(zhuǎn)換成詞向量
字典的目的是實現(xiàn)word-->向量逗余,這個沒有使用word2vec的算法。使用本書文本數(shù)據(jù)的詞建立的向量季惩。簡化的過程录粱,如下:
#文本數(shù)據(jù)
hello ml hello dl
#去重以后的詞匯
hello ml dl
#建立字典
{'hello':0 , 'ml':1 , 'dl':2 }
#反向字典
{0:'hello' , 1:'ml' , 2: 'dl'}
代碼如下:
def mybuild_dataset(words):
# words -- > ['hello','hello','world','python','tensorflow','rnn']
count = collections.Counter(words)
# Counter({'hello': 2, 'python': 1, 'rnn': 1, 'tensorflow': 1, 'world': 1})
dictionary=dict()
for key in count:
dictionary[key]=len(dictionary)
#dictionary -- > {'hello': 0, 'python': 3, 'rnn': 1, 'tensorflow': 2, 'world': 4}
reverse_dictionary = dict(zip(dictionary.values(), dictionary.keys()))
#reverse_dictionary -- > {0: 'hello', 1: 'rnn', 2: 'tensorflow', 3: 'python', 4: 'world'}
return dictionary, reverse_dictionary #len(dictionary) --> 112
- 建立RNN模型訓(xùn)練
理解一個模型,我覺得一個比較好的方式是先搞明白它訓(xùn)練的輸入和輸出画拾。在這個模型里面啥繁,處理訓(xùn)練數(shù)據(jù)的輸入和輸出,如下所示:
#訓(xùn)練數(shù)據(jù)
the mice had a xxxxx
# 訓(xùn)練的思路是青抛,將前三個數(shù)據(jù)作為訓(xùn)練的輸入
[[the],[mice],[had]] --> 轉(zhuǎn)化為詞向量
#將第四個詞匯作為輸出
['a']
#然后將輸出的詞匯轉(zhuǎn)換成onehot的形式
[ 0,0,0,0 ...0,1,0,0 ... 0,0,0 ] #長度是詞向量字典的長度 , 置1的地方是詞向量字典里面‘a(chǎn)’對應(yīng)的輸出設(shè)置為1
具體實現(xiàn)的代碼输虱,如下:
3.1 RNN模型的訓(xùn)練數(shù)據(jù)的輸入
n_input = 3
offset = 是一個隨機的偏移,這個是程序設(shè)計上面的一個trick脂凶,不影響理解這一段代碼
# 輸入x 宪睹,將前三個詞匯轉(zhuǎn)換成詞向量
# symbols_in_keys 是一個二維的list --> [[34], [92], [85]]
symbols_in_keys = [[dictionary[ str(training_data[i])]] for i in range(offset, offset+n_input) ]
# reshape 把他們轉(zhuǎn)換成 (1, 3, 1)
symbols_in_keys = np.reshape(np.array(symbols_in_keys), [-1, n_input, 1])
3.2 RNN模型的訓(xùn)練數(shù)據(jù)的輸出
# 這一段代碼搞定是 y_true ,把第四個詞轉(zhuǎn)換成詞向量 onehot的類型
symbols_out_onehot = np.zeros([vocab_size], dtype=float)
# str(training_data[offset+n_input]) -> 'mice'
symbols_out_onehot[dictionary[str(training_data[offset+n_input])]] = 1.0
symbols_out_onehot = np.reshape(symbols_out_onehot,[1,-1])
3.3 RNN模型的訓(xùn)練
def RNN(x, weights, biases):
batch_size=1
x = tf.reshape(x, [batch_size,n_input,1]) # (1,3,1) 相當(dāng)于batch =1
# rnn
cell = tf.contrib.rnn.BasicLSTMCell(n_hidden)
init_state = cell.zero_state(batch_size, dtype=tf.float32)
# final_state 的維度是 batch * n_hidden --> 1 * 512
# outputs 的維度是 batch * n_input(time_step) * n_hidden --> 1 * 3 * 512
outputs, final_state = tf.nn.dynamic_rnn(cell, x, initial_state=init_state, time_major=False)
#print ("before unstack , output shape : ",outputs.shape) # output shape : (1,3,512) (batch,time_step,cell_n_hidden)
#unstack 更改維度
outputs = tf.unstack(tf.transpose(outputs, [1,0,2]))
#這個時候 outputs 變成了list
#print ("output shape[-1] 2: ",outputs[-1].shape) # output shape : (3,1,512), outputs[-1] shape (1,512)
results = tf.matmul(outputs[-1], weights['out']) + biases['out']
#(1,112) 這個的表示意義是一個(1,112)的onehot蚕钦,112表示字典里面總共有112個詞匯
return results #(1, 112) 這個表示的是一個onehot
- 完整代碼
https://github.com/zhaozhengcoder/Machine-Learning/tree/master/tensorflow_tutorials/ RNN學(xué)習(xí)的目錄下面
訓(xùn)練的數(shù)據(jù)使用了伊索寓言的數(shù)據(jù)亭病,但是數(shù)據(jù)的量很少,迭代的次數(shù)也很少嘶居∽锾可以更換成其他的數(shù)據(jù)促煮,然后增大迭代的次數(shù)。