Char RNN原理介紹以及文字生成實踐

2021-08-28 12:55:53 字數 3726 閱讀 6325

char-rnn,字元級迴圈神經網路,出自於andrej karpathy寫的the unreasonable effectiveness of recurrent neural networks。眾所周知,rnn非常擅長處理序列問題。序列資料前後有很強的關聯性,而rnn通過每個單元權重與偏置的共享以及迴圈計算(前面處理過的資訊會被利用處理後續資訊)來體現。char-rnn模型是從字元的維度上,讓機器生成文字,即通過已經觀測到的字元出發,**下乙個字元出現的概率,也就是序列資料的推測。現在網上介紹的用深度學習寫歌、寫詩、寫**的大多都是基於這個方法。

在基本的rnn單元中,只有乙個隱藏狀態,對於長距離的記憶效果很差(序列開始的資訊在後期保留很少),而且存在梯度消失的問題,因此誕生了許多變體,如lstm、gru等。本文介紹的char-rnn就是選用lstm作為基本模型。

char rnn 原理

上圖展示了char-rnn的原理。以要讓模型學習寫出「hello」為例,char-rnn的輸入輸出層都是以字元為單位。輸入「h」,應該輸出「e」;輸入「e」,則應該輸出後續的「l」。輸入層我們可以用只有乙個元素為1的向量來編碼不同的字元,例如,h被編碼為「1000」、「e」被編碼為「0100」,而「l」被編碼為「0010」。使用rnn的學習目標是,可以讓生成的下乙個字元盡量與訓練樣本裡的目標輸出一致。在圖一的例子中,根據前兩個字元產生的狀態和第三個輸入「l」**出的下乙個字元的向量為<0.1, 0.5, 1.9, -1.1>,最大的一維是第三維,對應的字元則為「0010」,正好是「l」。這就是乙個正確的**。但從第乙個「h」得到的輸出向量是第四維最大,對應的並不是「e」,這樣就產生代價。學習的過程就是不斷降低這個代價。學習到的模型,對任何輸入字元可以很好地不斷**下乙個字元,如此一來就能生成句子或段落。

下面是乙個利用char rnn實現寫詩的應用,**來自來自原先比較火的專案:然後自己將其做成web應用,湊著學習了下如何使用tensorflow實現char rnn

def char_rnn(model,input_data,output_data,vocab_size,rnn_size=128,num_layers=2,batch_size=64,

learning_rate=0.01):

""":param model: rnn單元的型別 rnn, lstm gru

:param input_data: 輸入資料

:param output_data: 輸出資料

:param vocab_size: 詞彙大小

:param rnn_size:

:param num_layers:

:param batch_size:

:param learning_rate:學習率

:return:

"""end_points = {}

if model=='rnn':

cell_fun=tf.contrib.rnn.basicrnncell

elif model=='gru':

cell_fun=tf.contrib.rnn.grucell

elif model=='lstm':

cell_fun=tf.contrib.rnn.basiclstmcell

cell = cell_fun(rnn_size, state_is_tuple=true)

cell = tf.contrib.rnn.multirnncell([cell] * num_layers, state_is_tuple=true)

if output_data is not none:

initial_state = cell.zero_state(batch_size, tf.float32)

else:

initial_state = cell.zero_state(1, tf.float32)

with tf.device("/cpu:0"):

embedding=tf.get_variable('embedding',initializer=tf.random_uniform(

[vocab_size+1,rnn_size],-1.0,1.0))

inputs=tf.nn.embedding_lookup(embedding,input_data)

# [batch_size, ?, rnn_size] = [64, ?, 128]

outputs, last_state = tf.nn.dynamic_rnn(cell, inputs, initial_state=initial_state)

output = tf.reshape(outputs, [-1, rnn_size])

# logit計算

weights = tf.variable(tf.truncated_normal([rnn_size, vocab_size + 1]))

bias = tf.variable(tf.zeros(shape=[vocab_size + 1]))

logits = tf.nn.bias_add(tf.matmul(output, weights), bias=bias)

# [?, vocab_size+1]

if output_data is not none:

# 獨熱編碼

labels = tf.one_hot(tf.reshape(output_data, [-1]), depth=vocab_size + 1)

# [?, vocab_size+1]

loss = tf.nn.softmax_cross_entropy_with_logits(labels=labels, logits=logits)

# [?, vocab_size+1]

total_loss = tf.reduce_mean(loss)

train_op = tf.train.adamoptimizer(learning_rate).minimize(total_loss)

end_points['initial_state'] = initial_state

end_points['output'] = output

end_points['train_op'] = train_op

end_points['total_loss'] = total_loss

end_points['loss'] = loss

end_points['last_state'] = last_state

else:

prediction = tf.nn.softmax(logits)

end_points['initial_state'] = initial_state

end_points['last_state'] = last_state

end_points['prediction'] = prediction

return end_points

效果如下:

效果 1

效果 2

文字挖掘之文字聚類的介紹以及應用

文字聚類是乙個將文字集分組的全自動處理過程,是一種典型的無指導的機器學習過程。類是通過相關資料發現的一些組,類內的文字和其它組相比更為相近。換一種說法就是,文字聚類的目標是找到這樣一些類的集合,類之間的相似度盡可能最小,而類內部的相似性盡可能最大。作為一種無監督的機器學習方法,聚類是不需要訓練過程的...

Dubbo的核心原理以及使用介紹

dubbo 是乙個分布式服務框架,是阿里巴巴開源專案 被國內電商及網際網路專案中使用,dubbo 致力於提供高效能和透明化的 rpc 遠端服務呼叫方案,以及 soa 服務治理方案。簡單的說,dubbo 就是個服務框架,如果沒有分布式的需求,其實是不需要用的,只有在分布式的時候,才有 dubbo 這樣...

BFC的作用以及原理介紹

內部的box會在垂直方向,乙個接乙個地放置。box垂直方向的距離由margin決定。屬於同乙個bfc的兩個相鄰box的margin會發生重疊。每個元素的margin box的左邊,與包含塊border box的左邊相接觸 對於從左往右的格式化,否則相反 即使存在浮動也是如此。bfc的區域不會與flo...