前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >学习笔记CB013: TensorFlow、TensorBoard、seq2seq

学习笔记CB013: TensorFlow、TensorBoard、seq2seq

原创
作者头像
利炳根
发布2018-05-05 12:59:30
1.1K4
发布2018-05-05 12:59:30
举报
文章被收录于专栏:利炳根的专栏

tensorflow基于图结构深度学习框架,内部通过session实现图和计算内核交互。

tensorflow基本数学运算用法。

代码语言:txt
复制
import tensorflow as tf
代码语言:txt
复制
sess = tf.Session()
代码语言:txt
复制
a = tf.placeholder("float")
代码语言:txt
复制
b = tf.placeholder("float")
代码语言:txt
复制
c = tf.constant(6.0)
代码语言:txt
复制
d = tf.mul(a, b)
代码语言:txt
复制
y = tf.mul(d, c)
代码语言:txt
复制
print sess.run(y, feed_dict={a: 3, b: 3})
代码语言:txt
复制
A = [[1.1,2.3],[3.4,4.1]]
代码语言:txt
复制
Y = tf.matrix_inverse(A)
代码语言:txt
复制
print sess.run(Y)
代码语言:txt
复制
sess.close()

主要数字运算。

代码语言:txt
复制
tf.add
代码语言:txt
复制
tf.sub
代码语言:txt
复制
tf.mul
代码语言:txt
复制
tf.div
代码语言:txt
复制
tf.mod
代码语言:txt
复制
tf.abs
代码语言:txt
复制
tf.neg
代码语言:txt
复制
tf.sign
代码语言:txt
复制
tf.inv
代码语言:txt
复制
tf.square
代码语言:txt
复制
tf.round
代码语言:txt
复制
tf.sqrt
代码语言:txt
复制
tf.pow
代码语言:txt
复制
tf.exp
代码语言:txt
复制
tf.log
代码语言:txt
复制
tf.maximum
代码语言:txt
复制
tf.minimum
代码语言:txt
复制
tf.cos
代码语言:txt
复制
tf.sin

主要矩阵运算。

代码语言:txt
复制
tf.diag #生成对角阵
代码语言:txt
复制
tf.transpose
代码语言:txt
复制
tf.matmul
代码语言:txt
复制
tf.matrix_determinant #计算行列式的值
代码语言:txt
复制
tf.matrix_inverse #计算矩阵的逆

tensorboard使用。tensorflow代码,先构建图,然后执行,对中间过程调试不方便,提供一个tensorboard工具调试。训练时提示写入事件文件到目录(/tmp/tflearn_logs/11U8M4/)。执行命令打开 http://192.168.1.101:6006 看到tensorboard的界面。

代码语言:txt
复制
tensorboard --logdir=/tmp/tflearn_logs/11U8M4/

Graph和Session。

代码语言:txt
复制
import tensorflow as tf
代码语言:txt
复制
with tf.Graph().as_default() as g:
代码语言:txt
复制
    with g.name_scope("myscope") as scope: # 有了这个scope,下面的op的name都是类似myscope/Placeholder这样的前缀
代码语言:txt
复制
        sess = tf.Session(target='', graph = g, config=None) # target表示要连接的tf执行引擎
代码语言:txt
复制
        print "graph version:", g.version # 0
代码语言:txt
复制
        a = tf.placeholder("float")
代码语言:txt
复制
        print a.op # 输出整个operation信息,跟下面g.get_operations返回结果一样
代码语言:txt
复制
        print "graph version:", g.version # 1
代码语言:txt
复制
        b = tf.placeholder("float")
代码语言:txt
复制
        print "graph version:", g.version # 2
代码语言:txt
复制
        c = tf.placeholder("float")
代码语言:txt
复制
        print "graph version:", g.version # 3
代码语言:txt
复制
        y1 = tf.mul(a, b) # 也可以写成a * b
代码语言:txt
复制
        print "graph version:", g.version # 4
代码语言:txt
复制
        y2 = tf.mul(y1, c) # 也可以写成y1 * c
代码语言:txt
复制
        print "graph version:", g.version # 5
代码语言:txt
复制
        operations = g.get_operations()
代码语言:txt
复制
       for (i, op) in enumerate(operations):
代码语言:txt
复制
            print "============ operation", i+1, "==========="
代码语言:txt
复制
            print op # 一个结构,包括:name、op、attr、input等,不同op不一样
代码语言:txt
复制
        assert y1.graph is g
代码语言:txt
复制
        assert sess.graph is g
代码语言:txt
复制
        print "================ graph object address ================"
代码语言:txt
复制
        print sess.graph
代码语言:txt
复制
        print "================ graph define ================"
代码语言:txt
复制
        print sess.graph_def
代码语言:txt
复制
        print "================ sess str ================"
代码语言:txt
复制
        print sess.sess_str
代码语言:txt
复制
        print sess.run(y1, feed_dict={a: 3, b: 3}) # 9.0 feed_dictgraph中的元素和值的映射
代码语言:txt
复制
        print sess.run(fetches=[b,y1], feed_dict={a: 3, b: 3}, options=None, run_metadata=None) # 传入的feches和返回值的shape相同
代码语言:txt
复制
        print sess.run({'ret_name':y1}, feed_dict={a: 3, b: 3}) # {'ret_name': 9.0} 传入的feches和返回值的shape相同
代码语言:txt
复制
        assert tf.get_default_session() is not sess
代码语言:txt
复制
        with sess.as_default(): # 把sess作为默认的session,那么tf.get_default_session就是sess, 否则不是
代码语言:txt
复制
            assert tf.get_default_session() is sess
代码语言:txt
复制
        h = sess.partial_run_setup([y1, y2], [a, b, c]) # 分阶段运行,参数指明了feches和feed_dict列表
代码语言:txt
复制
        res = sess.partial_run(h, y1, feed_dict={a: 3, b: 4}) # 12 运行第一阶段
代码语言:txt
复制
        res = sess.partial_run(h, y2, feed_dict={c: res}) # 144.0 运行第二阶段,其中使用了第一阶段的执行结果
代码语言:txt
复制
        print "partial_run res:", res
代码语言:txt
复制
        sess.close()

tensorflow Session是Graph和执行者媒介,Session.run()将graph、fetches、feed_dict序列化到字节数组,调用tf_session.TF_Run(参见/usr/local/lib/python2.7/site-packages/tensorflow/python/client/session.py)。tf_session.TF_Run调用动态链接库_pywrap_tensorflow.so实现_pywrap_tensorflow.TF_Run接口(参见/usr/local/lib/python2.7/site-packages/tensorflow/python/pywrap_tensorflow.py)。动态链接库是tensorflow多语言python接口。_pywrap_tensorflow.so和pywrap_tensorflow.py通过SWIG工具自动生成,tensorflow核心语言c语言,通过SWIG生成各种脚本语言接口。

10行关键代码实现线性回归。用梯度下降求解线性回归问题是tensorflow最简单入门例子(10行关键代码)。

代码语言:txt
复制
# -*- coding: utf-8 -*-
代码语言:txt
复制
import numpy as np
代码语言:txt
复制
import tensorflow as tf
代码语言:txt
复制
# 随机生成1000个点,围绕在y=0.1x+0.3的直线周围
代码语言:txt
复制
num_points = 1000
代码语言:txt
复制
vectors_set = []
代码语言:txt
复制
for i in xrange(num_points):
代码语言:txt
复制
    x1 = np.random.normal(0.0, 0.55)
代码语言:txt
复制
    y1 = x1 * 0.1 + 0.3 + np.random.normal(0.0, 0.03)
代码语言:txt
复制
    vectors_set.append([x1, y1])
代码语言:txt
复制
# 生成一些样本
代码语言:txt
复制
x_data = [v[0] for v in vectors_set]
代码语言:txt
复制
y_data = [v[1] for v in vectors_set]
代码语言:txt
复制
# 生成1维的W矩阵,取值是[-1,1]之间的随机数
代码语言:txt
复制
W = tf.Variable(tf.random_uniform([1], -1.0, 1.0), name='W')
代码语言:txt
复制
# 生成1维的b矩阵,初始值是0
代码语言:txt
复制
b = tf.Variable(tf.zeros([1]), name='b')
代码语言:txt
复制
# 经过计算得出预估值y
代码语言:txt
复制
y = W * x_data + b
代码语言:txt
复制
# 以预估值y和实际值y_data之间的均方误差作为损失
代码语言:txt
复制
loss = tf.reduce_mean(tf.square(y - y_data), name='loss')
代码语言:txt
复制
# 采用梯度下降法来优化参数
代码语言:txt
复制
optimizer = tf.train.GradientDescentOptimizer(0.5)
代码语言:txt
复制
# 训练的过程就是最小化这个误差值
代码语言:txt
复制
train = optimizer.minimize(loss, name='train')
代码语言:txt
复制
sess = tf.Session()
代码语言:txt
复制
# 输出图结构
代码语言:txt
复制
#print sess.graph_def
代码语言:txt
复制
init = tf.initialize_all_variables()
代码语言:txt
复制
sess.run(init)
代码语言:txt
复制
# 初始化的W和b是多少
代码语言:txt
复制
print "W =", sess.run(W), "b =", sess.run(b), "loss =", sess.run(loss)
代码语言:txt
复制
# 执行20次训练
代码语言:txt
复制
for step in xrange(20):
代码语言:txt
复制
    sess.run(train)
代码语言:txt
复制
    # 输出训练好的W和b
代码语言:txt
复制
    print "W =", sess.run(W), "b =", sess.run(b), "loss =", sess.run(loss)
代码语言:txt
复制
# 生成summary文件,用于tensorboard使用
代码语言:txt
复制
writer = tf.train.SummaryWriter("./tmp", sess.graph)

一张图展示线性回归工作原理。执行代码在本地生成一个tmp目录,产生tensorboard读取数据,执行:

代码语言:txt
复制
tensorboard --logdir=./tmp/

打开 http://localhost:6006/ GRAPHS,展开一系列关键节点。图是代码生成graph结构,graph描述整个梯度下降解决线性回归问题整个过程,每一个节点代表代码的一步操作。

详细分析线性回归graph。W和b。代码对W有三种操作 Assign、read、train。assign基于random_uniform赋值。

代码语言:txt
复制
W = tf.Variable(tf.random_uniform([1], -1.0, 1.0), name='W')

tf.random_uniform graph。read对应:

代码语言:txt
复制
y = W * x_data + b

train对应梯度下降训练过程操作。

对b有三种操作:Assign、read、train。用zeros赋初始化值。

W和b通过梯度下降计算update_W和update_b,更新W和b的值。update_W和update_b基于三个输入计算得出,学习率learning_rate、W/b当前值、梯度gradients。

最关键的梯度下降过程。

代码语言:txt
复制
loss = tf.reduce_mean(tf.square(y - y_data), name='loss')

以y-y_data为输入,x不是x_data,是一个临时常量 2。2(y-y_data),明显是(y-y_data)^2导数。以2(y-y_data)为输入经过各种处理最终生成参数b的增量update_b。生成update_W更新W,反向追溯依赖于add_grad(基于y-y_data)和W以及y生成,详细计算过程:http://stackoverflow.com/questions/39580427/how-does-tensorflow-calculate-the-gradients-for-the-tf-train-gradientdescentopti ,一步简单操作被tensorflow转成很多个节点图,细节节点不深入分析,只是操作图表达,没有太重要意义。

tensorflow自带seq2seq模型基于one-hot词嵌入,每个词用一个数字代替不足表示词与词之间关系,word2vec多维向量做词嵌入,能够表示出词之间关系。基于seq2seq思想,利用多维词向量实现模型,预期会有更高准确性。

seq2seq模型原理。参考《Sequence to Sequence Learning with Neural Networks》论文。核心思想,ABC是输入语句,WXYZ是输出语句,EOS是标识一句话结束,训练单元是lstm,lstm的特点是有长短时记忆,能够根据输入多个字确定后面多个字,lstm知识参考 http://deeplearning.net/tutorial/lstm.html 模型编码器和解码器共用同一个lstm层,共享参数,分开 https://github.com/farizrahman4u/seq2seq 绿色是编码器,黄色是解码器,橙色箭头传递lstm层状态信息(记忆信息),编码器唯一传给解码器的状态信息。

解码器每一时序输入是前一个时序输出,通过不同时序输入“How are you <EOL>”,模型能自动一个字一个字输出“W I am fine <EOL>”,W是特殊标识,是编码器最后输出,是解码器触发信号。

直接把解码器每一时序输入强制改为"W I am fine",把这部分从训练样本输入X中传过来,Y依然是预测输出"W I am fine <EOL>",这样训练出来的模型就是编码器解码器模型。

使用训练模型预测,在解码时以前一时序输出为输入做预测,就能输出"W I am fine <EOL>”。

语料准备。至少300w聊天语料用于词向量训练和seq2seq模型训练,语料越丰富训练词向量质量越好。

切词:

代码语言:txt
复制
python word_segment.py ./corpus.raw ./corpus.segment

切词文件转成“|”分隔问答对:

代码语言:txt
复制
cat ./corpus.segment | awk '{if(last!="")print last"|"$0;last=$0}' | sed 's/| /|/g' > ./corpus.segment.pair

训练词向量。用google word2vec训练词向量:

代码语言:txt
复制
word2vec -train ./corpus.segment -output vectors.bin -cbow 1 -size 200 -window 8 -negative 25 -hs 0 -sample 1e-5 -threads 20 -binary 1 -iter 15

corpus.raw 原始语料数据,vectors.bin 生成的词向量二进制文件。

生成词向量二进制加载方法 https://github.com/warmheartli/ChatBotCourse/blob/master/word_vectors_loader.py

创建模型。用tensorflow+tflearn库来实现。

代码语言:txt
复制
# 首先我们为输入的样本数据申请变量空间,如下。其中self.max_seq_len是指一个切好词的句子最多包含多少个词,self.word_vec_dim是词向量的维度,这里面shape指定了输入数据是不确定数量的样本,每个样本最多包含max_seq_len*2个词,每个词用word_vec_dim维浮点数表示。这里面用2倍的max_seq_len是因为我们训练是输入的X既要包含question句子又要包含answer句子
代码语言:txt
复制
input_data = tflearn.input_data(shape=[None, self.max_seq_len*2, self.word_vec_dim], dtype=tf.float32, name = "XY")
代码语言:txt
复制
# 然后我们将输入的所有样本数据的词序列切出前max_seq_len个,也就是question句子部分,作为编码器的输入
代码语言:txt
复制
encoder_inputs = tf.slice(input_data, [0, 0, 0], [-1, self.max_seq_len, self.word_vec_dim], name="enc_in")
代码语言:txt
复制
# 再取出后max_seq_len-1个,也就是answer句子部分,作为解码器的输入。注意,这里只取了max_seq_len-1个,是因为还要在前面拼上一组GO标识来告诉解码器我们要开始解码了,也就是下面加上go_inputs拼成最终的go_inputs
代码语言:txt
复制
decoder_inputs_tmp = tf.slice(input_data, [0, self.max_seq_len, 0], [-1, self.max_seq_len-1, self.word_vec_dim], name="dec_in_tmp")
代码语言:txt
复制
go_inputs = tf.ones_like(decoder_inputs_tmp)
代码语言:txt
复制
go_inputs = tf.slice(go_inputs, [0, 0, 0], [-1, 1, self.word_vec_dim])
代码语言:txt
复制
decoder_inputs = tf.concat(1, [go_inputs, decoder_inputs_tmp], name="dec_in")
代码语言:txt
复制
# 之后开始编码过程,返回的encoder_output_tensor展开成tflearn.regression回归可以识别的形如(?, 1, 200)的向量;返回的states后面传入给解码器
代码语言:txt
复制
(encoder_output_tensor, states) = tflearn.lstm(encoder_inputs, self.word_vec_dim, return_state=True, scope='encoder_lstm')
代码语言:txt
复制
encoder_output_sequence = tf.pack([encoder_output_tensor], axis=1)
代码语言:txt
复制
# 取出decoder_inputs的第一个词,也就是GO
代码语言:txt
复制
first_dec_input = tf.slice(decoder_inputs, [0, 0, 0], [-1, 1, self.word_vec_dim])
代码语言:txt
复制
# 将其输入到解码器中,如下,解码器的初始化状态为编码器生成的states,注意:这里的scope='decoder_lstm'是为了下面重用同一个解码器
代码语言:txt
复制
decoder_output_tensor = tflearn.lstm(first_dec_input, self.word_vec_dim, initial_state=states, return_seq=False, reuse=False, scope='decoder_lstm')
代码语言:txt
复制
# 暂时先将解码器的第一个输出存到decoder_output_sequence_list中供最后一起输出
代码语言:txt
复制
decoder_output_sequence_single = tf.pack([decoder_output_tensor], axis=1)
代码语言:txt
复制
decoder_output_sequence_list = [decoder_output_tensor]
代码语言:txt
复制
# 接下来我们循环max_seq_len-1次,不断取decoder_inputs的一个个词向量作为下一轮解码器输入,并将结果添加到decoder_output_sequence_list中,这里面的reuse=True, scope='decoder_lstm'说明和上面第一次解码用的是同一个lstm层
代码语言:txt
复制
for i in range(self.max_seq_len-1):
代码语言:txt
复制
   next_dec_input = tf.slice(decoder_inputs, [0, i+1, 0], [-1, 1, self.word_vec_dim])
代码语言:txt
复制
   decoder_output_tensor = tflearn.lstm(next_dec_input, self.word_vec_dim, return_seq=False, reuse=True, scope='decoder_lstm')
代码语言:txt
复制
   decoder_output_sequence_single = tf.pack([decoder_output_tensor], axis=1)
代码语言:txt
复制
   decoder_output_sequence_list.append(decoder_output_tensor)
代码语言:txt
复制
# 下面我们把编码器第一个输出和解码器所有输出拼接起来,作为tflearn.regression回归的输入
代码语言:txt
复制
decoder_output_sequence = tf.pack(decoder_output_sequence_list, axis=1)
代码语言:txt
复制
real_output_sequence = tf.concat(1, [encoder_output_sequence, decoder_output_sequence])
代码语言:txt
复制
net = tflearn.regression(real_output_sequence, optimizer='sgd', learning_rate=0.1, loss='mean_square')
代码语言:txt
复制
model = tflearn.DNN(net)

模型创建完成,汇总思想:

代码语言:txt
复制
1)训练输入X、Y分别是编码器解码器输入和预测输出;
代码语言:txt
复制
2)X切分两半,前一半是编码器输入,后一半是解码器输入;
代码语言:txt
复制
3)编码解码器输出预测值用Y做回归训练
代码语言:txt
复制
4)训练通过样本真实值作解码器输入,实际预测不会有WXYZ部分,上一时序输出将作下一时序输入

训练模型。实例化模型并喂数据做训练:

代码语言:txt
复制
model = self.model()
代码语言:txt
复制
model.fit(trainXY, trainY, n_epoch=1000, snapshot_epoch=False, batch_size=1)
代码语言:txt
复制
model.load('./model/model')

trainXY和trainY通过加载语料赋值。

加载词向量存到word_vector_dict,读取语料文件挨个词查word_vector_dict,赋值向量给question_seq和answer_seq:

代码语言:txt
复制
def init_seq(input_file):
代码语言:txt
复制
    """读取切好词的文本文件,加载全部词序列
代码语言:txt
复制
    """
代码语言:txt
复制
    file_object = open(input_file, 'r')
代码语言:txt
复制
    vocab_dict = {}
代码语言:txt
复制
    while True:
代码语言:txt
复制
        question_seq = []
代码语言:txt
复制
        answer_seq = []
代码语言:txt
复制
        line = file_object.readline()
代码语言:txt
复制
        if line:
代码语言:txt
复制
            line_pair = line.split('|')
代码语言:txt
复制
            line_question = line_pair[0]
代码语言:txt
复制
            line_answer = line_pair[1]
代码语言:txt
复制
            for word in line_question.decode('utf-8').split(' '):
代码语言:txt
复制
                if word_vector_dict.has_key(word):
代码语言:txt
复制
                    question_seq.append(word_vector_dict[word])
代码语言:txt
复制
            for word in line_answer.decode('utf-8').split(' '):
代码语言:txt
复制
                if word_vector_dict.has_key(word):
代码语言:txt
复制
                    answer_seq.append(word_vector_dict[word])
代码语言:txt
复制
        else:
代码语言:txt
复制
            break
代码语言:txt
复制
        question_seqs.append(question_seq)
代码语言:txt
复制
        answer_seqs.append(answer_seq)
代码语言:txt
复制
    file_object.close()

有question_seq和answer_seq,构造trainXY和trainY:

代码语言:txt
复制
    def generate_trainig_data(self):
代码语言:txt
复制
        xy_data = []
代码语言:txt
复制
        y_data = []
代码语言:txt
复制
        for i in range(len(question_seqs)):
代码语言:txt
复制
            question_seq = question_seqs[i]
代码语言:txt
复制
            answer_seq = answer_seqs[i]
代码语言:txt
复制
            if len(question_seq) < self.max_seq_len and len(answer_seq) < self.max_seq_len:
代码语言:txt
复制
                sequence_xy = [np.zeros(self.word_vec_dim)] * (self.max_seq_len-len(question_seq)) + list(reversed(question_seq))
代码语言:txt
复制
                sequence_y = answer_seq + [np.zeros(self.word_vec_dim)] * (self.max_seq_len-len(answer_seq))
代码语言:txt
复制
                sequence_xy = sequence_xy + sequence_y
代码语言:txt
复制
                sequence_y = [np.ones(self.word_vec_dim)] + sequence_y
代码语言:txt
复制
                xy_data.append(sequence_xy)
代码语言:txt
复制
                y_data.append(sequence_y)
代码语言:txt
复制
        return np.array(xy_data), np.array(y_data)

构造训练数据创建模型,训练:

代码语言:txt
复制
python my_seq2seq_v2.py train

最终生成./model/model模型文件。

效果预测。训练模型,输入一句话预测一下回答:

代码语言:txt
复制
predict = model.predict(testXY)

只有question没有answer,testXY没有Y部分,用上一句输出作为下一句输入:

代码语言:txt
复制
for i in range(self.max_seq_len-1):
代码语言:txt
复制
   # next_dec_input = tf.slice(decoder_inputs, [0, i+1, 0], [-1, 1, self.word_vec_dim])这里改成下面这句
代码语言:txt
复制
   next_dec_input = decoder_output_sequence_single
代码语言:txt
复制
   decoder_output_tensor = tflearn.lstm(next_dec_input, self.word_vec_dim, return_seq=False, reuse=True, scope='decoder_lstm')
代码语言:txt
复制
   decoder_output_sequence_single = tf.pack([decoder_output_tensor], axis=1)
代码语言:txt
复制
   decoder_output_sequence_list.append(decoder_output_tensor)

词向量是多维浮点数,预测词向量要通过余弦相似度匹配,余弦相似度匹配方法:

代码语言:txt
复制
def vector2word(vector):
代码语言:txt
复制
    max_cos = -10000
代码语言:txt
复制
    match_word = ''
代码语言:txt
复制
    for word in word_vector_dict:
代码语言:txt
复制
        v = word_vector_dict[word]
代码语言:txt
复制
        cosine = vector_cosine(vector, v)
代码语言:txt
复制
        if cosine > max_cos:
代码语言:txt
复制
            max_cos = cosine
代码语言:txt
复制
            match_word = word
代码语言:txt
复制
    return (match_word, max_cos)

其中的vector_cosine实现如下:

代码语言:txt
复制
def vector_cosine(v1, v2):
代码语言:txt
复制
    if len(v1) != len(v2):
代码语言:txt
复制
        sys.exit(1)
代码语言:txt
复制
    sqrtlen1 = vector_sqrtlen(v1)
代码语言:txt
复制
    sqrtlen2 = vector_sqrtlen(v2)
代码语言:txt
复制
    value = 0
代码语言:txt
复制
    for item1, item2 in zip(v1, v2):
代码语言:txt
复制
        value += item1 * item2
代码语言:txt
复制
    return value / (sqrtlen1*sqrtlen2)
代码语言:txt
复制
def vector_sqrtlen(vector):
代码语言:txt
复制
    len = 0
代码语言:txt
复制
    for item in vector:
代码语言:txt
复制
        len += item * item
代码语言:txt
复制
    len = math.sqrt(len)
代码语言:txt
复制
    return len

预测:

代码语言:txt
复制
python my_seq2seq_v2.py test test.data

输出第一列是预测每个时序产生词,第二列是预测输出向量和最近词向量余弦相似度,第三列是预测向量欧氏距离。

max_seq_len定长8,输出序列最后会多余一些字,根据余弦相似度或者其他指标设定一个阈值截断。

全部代码 https://github.com/warmheartli/ChatBotCourse/blob/master/chatbotv2/my_seq2seq_v2.py

参考资料:

《Python 自然语言处理》

《NLTK基础教程 用NLTK和Python库构建机器学习应用》

http://www.shareditor.com/blogshow?blogId=119

http://www.shareditor.com/blogshow?blogId=120

http://www.shareditor.com/blogshow?blogId=121

欢迎推荐上海机器学习工作机会,我的微信:qingxingfengzi

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
腾讯云 TI 平台
腾讯云 TI 平台(TencentCloud TI Platform)是基于腾讯先进 AI 能力和多年技术经验,面向开发者、政企提供的全栈式人工智能开发服务平台,致力于打通包含从数据获取、数据处理、算法构建、模型训练、模型评估、模型部署、到 AI 应用开发的产业 + AI 落地全流程链路,帮助用户快速创建和部署 AI 应用,管理全周期 AI 解决方案,从而助力政企单位加速数字化转型并促进 AI 行业生态共建。腾讯云 TI 平台系列产品支持公有云访问、私有化部署以及专属云部署。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档