三十五、一個lstm單元讓聊天機器人學會甄嬛體
當今比較流行的seq2seq基本都是用lstm組成的編碼器解碼器模型實現,開源的實現大都基於one-hot的embedding(沒有詞向量表達的資訊量大),因此打算自己實現一個基於word2vec詞向量的強大的seq2seq模型,首先實現了只有一個lstm單元的機器人
下載《甄嬛傳》小說原文
上網隨便百度一個“甄嬛傳 txt”,下載下來,首先要把檔案轉碼成utf-8編碼,然後要把windows的回車符都替換成\n,以便後續處理,最終效果如下:
[root@centos $] head zhenhuanzhuan.txt
序文--不過是「情」
在鍵盤上敲落一個個文字的時候,窗外有大雨過後的清新。站在十二樓的落地玻璃窗前往外看,有大片大片開闊的深綠蔓延。
我喜歡這個有山有水的小城,所以在這樣一個煩熱的下午,揹負著窒悶的心情不顧一切逃出暫居的城市,來到這裡,在寫完了一個整整寫了三年多的故事之後。
終於,寫完了《後宮:甄嬛傳》的最後一本,第七本。七,是我喜歡的一個數字。甄嬛的故事,最後一個字,是我在初夏的某日坐在師大某個小賓館的房間裡寫下的。這個故事,自我在母校時始,又於母校終,像一個有始有終的圓圈,終於完結了。
這是我的第一部長篇,自己也輕籲一口氣,居然寫了那麼長,那麼久。
可是完結的那一刻,我心裡一點也不快活。因?是我自己,把我喜愛的清,把我理想中溫潤如玉的男子,寫到玉碎斑駁。
對甄嬛傳切詞
執行
python ./word_segment.py zhenhuanzhuan.txt zhenhuanzhuan.segment
生成的檔案如下:
[root@centos $] head zhenhuanzhuan.segment
序文 - - 不過 是 「 情 」
在 鍵盤 上 敲落 一個個 文字 的 時候 , 窗外 有 大雨 過後 的 清新 。 站 在 十二樓 的 落地 玻璃窗 前往 外看 , 有 大片大片 開闊 的 深綠 蔓延 。
我 喜歡 這個 有山有水 的 小城 , 所以 在 這樣 一個 煩熱 的 下午 , 揹負著 窒悶 的 心情 不顧一切 逃出 暫居 的 城市 , 來到 這裡 , 在 寫 完 了 一個 整整 寫 了 三年 多 的 故事 之後 。
終於 , 寫 完 了 《 後宮 : 甄 嬛 傳 》 的 最後 一本 , 第七 本 。 七 , 是 我 喜歡 的 一個 數字 。 甄 嬛 的 故事 , 最後 一個 字 , 是 我 在 初夏 的 某日 坐在 師大 某個 小 賓館 的 房間 裡 寫下 的 。 這個 故事 , 自我 在 母校 時始 , 又 於 母校 終 , 像 一個 有始有終 的 圓圈 , 終於 完結 了 。
這 是 我 的 第一部 長篇 , 自己 也 輕籲 一口氣 , 居然 寫 了 那麼 長 , 那麼 久 。
可是 完結 的 那一刻 , 我 心裡 一點 也 不 快活 。 因 ? 是 我 自己 , 把 我 喜愛 的 清 , 把 我 理想 中 溫潤 如玉 的 男子 , 寫 到 玉碎 斑駁 。
生成詞向量
執行
./word2vec -train ./zhenhuanzhuan.segment -output vectors.bin -cbow 1 -size 200 -window 8 -negative 25 -hs 0 -sample 1e-4 -threads 20 -binary 1 -iter 15
這樣會生成一個vectors.bin檔案,這就是我們想要的基於甄嬛傳原文生成的詞向量檔案
如果想知道vectors.bin檔案裡如何儲存以及如何載入,可以參考我的另一篇文章《三十二-用三千萬影視劇字幕語料庫生成詞向量》
訓練程式碼
下面是我的程式碼原文,僅供參考
# -*- coding: utf-8 -*-
import sys
import math
import tflearn
import chardet
import numpy as np
import struct
seq = []
max_w = 50
float_size = 4
word_vector_dict = {}
def load_vectors(input):
"""從vectors.bin載入詞向量,返回一個word_vector_dict的詞典,key是詞,value是200維的向量
"""
print "begin load vectors"
input_file = open(input, "rb")
# 獲取詞表數目及向量維度
words_and_size = input_file.readline()
words_and_size = words_and_size.strip()
words = long(words_and_size.split(' ')[0])
size = long(words_and_size.split(' ')[1])
print "words =", words
print "size =", size
for b in range(0, words):
a = 0
word = ''
# 讀取一個詞
while True:
c = input_file.read(1)
word = word + c
if False == c or c == ' ':
break
if a < max_w and c != '\n':
a = a + 1
word = word.strip()
vector = []
for index in range(0, size):
m = input_file.read(float_size)
(weight,) = struct.unpack('f', m)
vector.append(weight)
# 將詞及其對應的向量存到dict中
word_vector_dict[word.decode('utf-8')] = vector
input_file.close()
print "load vectors finish"
def init_seq():
"""讀取切好詞的文字檔案,載入全部詞序列
"""
file_object = open('zhenhuanzhuan.segment', 'r')
vocab_dict = {}
while True:
line = file_object.readline()
if line:
for word in line.decode('utf-8').split(' '):
if word_vector_dict.has_key(word):
seq.append(word_vector_dict[word])
else:
break
file_object.close()
def vector_sqrtlen(vector):
len = 0
for item in vector:
len += item * item
len = math.sqrt(len)
return len
def vector_cosine(v1, v2):
if len(v1) != len(v2):
sys.exit(1)
sqrtlen1 = vector_sqrtlen(v1)
sqrtlen2 = vector_sqrtlen(v2)
value = 0
for item1, item2 in zip(v1, v2):
value += item1 * item2
return value / (sqrtlen1*sqrtlen2)
def vector2word(vector):
max_cos = -10000
match_word = ''
for word in word_vector_dict:
v = word_vector_dict[word]
cosine = vector_cosine(vector, v)
if cosine > max_cos:
max_cos = cosine
match_word = word
return (match_word, max_cos)
def main():
load_vectors("./vectors.bin")
init_seq()
xlist = []
ylist = []
test_X = None
#for i in range(len(seq)-100):
for i in range(10):
sequence = seq[i:i+20]
xlist.append(sequence)
ylist.append(seq[i+20])
if test_X is None:
test_X = np.array(sequence)
(match_word, max_cos) = vector2word(seq[i+20])
print "right answer=", match_word, max_cos
X = np.array(xlist)
Y = np.array(ylist)
net = tflearn.input_data([None, 20, 200])
net = tflearn.lstm(net, 200)
net = tflearn.fully_connected(net, 200, activation='linear')
net = tflearn.regression(net, optimizer='sgd', learning_rate=0.1,
loss='mean_square')
model = tflearn.DNN(net)
model.fit(X, Y, n_epoch=500, batch_size=10,snapshot_epoch=False,show_metric=True)
model.save("model")
predict = model.predict([test_X])
#print predict
#for v in test_X:
# print vector2word(v)
(match_word, max_cos) = vector2word(predict[0])
print "predict=", match_word, max_cos
main()
解釋一下上面的程式碼,load_vectors是從vectors.bin中載入詞向量,init_seq是載入甄嬛傳切詞後的文字並存到一個序列裡,vector2word是求距離某向量最近的詞,模型中只有一個lstm單元
執行效果如下:
[[email protected] $] python one_lstm_sequence_generate.py
begin load vectors
words = 16995
size = 200
load vectors finish
right answer= 站 1.0
---------------------------------
Run id: DQK34Q
Log directory: /tmp/tflearn_logs/
---------------------------------
Training samples: 10
Validation samples:
--
Training Step: 500 | total loss: 0.33673
| SGD | epoch: 500 | loss: 0.33673 - acc: 0.1748 -- iter: 10/10
--
predict= 站 0.941794432002
可以看出:經過500個epoch的訓練,均方損失降到0.33673,並能以0.941794432002的餘弦相似度預測出下一個字
如果你有強大的gpu,可以調整上述引數,把整篇文章都訓練進去,稍稍修改程式碼中predict的部分,讓他不斷的輸出下一個字,就可以自動吐出甄嬛體
這段程式碼是基於tflearn實現的,在tflearn官方文件的examples中實現的seq2seq是直接呼叫了tensorflow中的tensorflow/python/ops/seq2seq.py,而這部分是基於one-hot的embedding方法,這是一定沒有詞向量效果好的,因此下一步打算基於上面的程式碼繼續改造,實現基於詞向量的seq2seq,相信能夠讓我的聊天機器人問答效果更好,敬請期待
相關推薦
三十五、一個lstm單元讓聊天機器人學會甄嬛體
當今比較流行的seq2seq基本都是用lstm組成的編碼器解碼器模型實現,開源的實現大都基於one-hot的embedding(沒有詞向量表達的資訊量大),因此打算自己實現一個基於word2vec詞向量的強大的seq2seq模型,首先實現了只有一個lstm單元的機器人 下載《甄嬛傳》小說原文 上網隨
三十五、 rsync工具介紹、rsync常用選項、rsync通過ssh同步
rsync工具 rsync常用選項 rsync通過ssh同步 三十五、 rsync工具介紹、rsync常用選項、rsync通過ssh同步一、rsync工具數據備份,很重要。rsync工具:數據備份的工具。remote sync(遠程同步)rsync可以遠程同步數據(類似scp),也可以本地同步數據
三十五、robotframework中怎麽將100轉化成100.00
bubuko frame 分享圖片 技術 分享 圖片 怎麽 技術分享 http 1.將100轉化成100.00 三十五、robotframework中怎麽將100轉化成100.00
三十五、python學習之Flask框架(七)資料庫:Flask對資料庫的基本操作、常見關係模板、資料庫遷移、綜合案例:圖書管理
補充: 使用SQL_Alchemy定義一個模型類,不可以不指定primary_key=True建立表. 一、資料庫基本操作 1. 資料庫的基本操作(CRUD): 在Flask-SQLAlchemy中,插入、修改、刪除操作,均由資料庫會話管理。
三十五、懶載入(原生封裝)
var Lazy = { $:function(arg,context){ var tagAll,n,eles=[],i,sub = arg.substring(1); context = context|| document;
三十五、JAVA泛型實現原理
1. 概述 泛型在java中有很重要的地位,在面向物件程式設計及各種設計模式中有非常廣泛的應用。 什麼是泛型?為什麼要使用泛型? 泛型,即“引數化型別”。一提到引數,最熟悉的就是定義方法時有形參,然後呼叫此方法時傳遞實參。那麼引數化型別怎麼理解呢?顧名思義,就是將型別由原來的具體
三十五、HDFS的FileSystem常用操作
package com.yang.hdfs; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import org.apache.had
三十五、jquery動畫 無縫滾動兩種方式
無縫輪播有兩種方式,一種可以讓ul中的每個li進行移動,另外一種時令整個ul進行移動。無縫輪播效果之前用js寫過一次,以下是用jQuery分別實現這兩種方式; 一、第一種 控制每個li標籤移動實現無縫輪播 1.基本佈局樣式 2.實現自動向左輪播 採用列舉物件封裝函式的方法,封
三十五、minishell(3)
35.1 內容 在當前的 minishell 中,如果執行 date clear 命令等,minishell 會停止: 這是因為引入程序組的時候,mshell 放置在前臺程序組,同時之後在子程序中又建立了一個程序組,在程式碼中,第二個程序組在沒有將其設定為前臺程序組之前,一直是後臺程序組。
三十五、java學習--多執行緒程式設計
Java 多執行緒程式設計 Java 給多執行緒程式設計提供了內建的支援。 一條執行緒指的是程序中一個單一順序的控制流,一個程序中可以併發多個執行緒,每條執行緒並行執行不同的任務。 多執行緒是多工的一種特別的形式,但多執行緒使用了更小的資源開銷。 這裡定義和執行緒相關的
三十六、python學習之Flask框架: 藍圖和單元測試
一、藍圖和單元測試: 1.藍圖: 隨著flask程式越來越複雜,我們需要對程式進行模組化的處理,之前學習過python的模組化管理,於是針對一個簡單的flask程式進行模組化處理 名詞解釋: 高內聚,低耦合: 所謂高內聚是指一個軟體模組是由相關性很強的程式碼組成,
演算法題(三十五):二叉樹的下一個結點
題目描述 給定一個二叉樹和其中的一個結點,請找出中序遍歷順序的下一個結點並且返回。注意,樹中的結點不僅包含左右子結點,同時包含指向父結點的指標。 分析 分情況討論: 1.如果結點有右孩子,則返回右子樹中最後一個左孩子; 2.如果結點沒有右孩子,且該結點是父結點的左孩子,則返回
javaSE (三十五)多執行緒 ( 多執行緒實現方法和區別、同步程式碼塊和方法(執行緒安全))
主要還是熟悉api,熟悉方法,簡單,需要多實踐 1、 多執行緒實現方法和區別: 多執行緒實現的兩種方法: 1)類繼承Thread類或實現Runnable介面,重寫run()方法 2)建立Thread的子類物件(需要開幾個執行緒就建立幾個物件,可建立匿名內部類) 3)子類
十五、做一個完美的管理後臺側邊欄
在sonata管理後臺除了我們常用的部分之外,還有側欄的內容我們沒有涉及過,這一節講幾個簡單的配置來讓我們管理後臺內容更豐富更易用 把管理後臺據為己有 我們的管理後臺左上角logo部分顯示的內容是這樣的: 是不是有點low了?我想改個名字叫做“後臺管理系統”怎麼辦呢?非常簡單,開啟app/co
IT 移動端:足跡第三十五步:靜態、自適應、流式、響應式四種HTML網頁佈局的區別(哪種佈局在移動端最好用)
1)靜態佈局:在PC端與移動端用2個佈局;一個元素的位置和大小都不變化;2)自適應佈局:在PC端與移動端用2個佈局;一個元素的位置會變化。3)流式佈局:在PC端與移動端1個佈局;元素的位置會變化,元素的
# Unity 遊戲框架搭建 2019 (三十四、三十五) 9 ~ 10 示例整理
## 第九個示例 目前程式碼如下: ```cs using UnityEngine; #if UNITY_EDITOR using UnityEditor; #endif namespace QFramework { public class ResolutionCheck { #if UNITY_E
AGG第三十五課 gsv_text 渲染ASCII字符
agg gsv_text代碼 agg::rendering_buffer &rbuf = rbuf_window(); agg::pixfmt_bgr24 pixf(rbuf); typedef agg::renderer_base<agg::pixfmt_bgr24>
十五、Spring Boot 環境變量讀取 和 屬性對象的綁定
bean database 環境 autoconf lac autowire 屬性 boot title 凡是被spring管理的類,實現接口 EnvironmentAware 重寫方法 setEnvironment 可以在工程啟動時,獲取到系統環境變量和applicati
Linux 入門記錄:十五、Linux 網絡基本配置
包含 mac地址 圖像 鏈接 ifcfg 修改主機名 www. 永久生效 expr 一、以太網(Ethernet) 以太網(Ethernet)是一種計算機局域網技術。IEEE 組織的 IEEE 802.3 標準制定了以太網的技術標準,它規定了包括物理層的連線、電子信號和介
愛創課堂每日一題第三十五天- 說說你對閉包的理解?
前端 前端學習 前端入門使用閉包主要是為了設計私有的方法和變量。閉包的優點是可以避免全局變量的汙染,缺點是閉包會常駐內存,會增大內存使用量,使用不當很容易造成內存泄露。在js中,函數即閉包,只有函數才會產生作用域的概念閉包有三個特性:1.函數嵌套函數2.函數內部可以引用外部的參數和變量3.參數和變量不會