本篇知识点:Tensorflow编程
CNN相关知识
PySpark相关知识
因为例子较为复杂,我们会假设你不但学习了【Tensorflow基础】,而且还自己主动扩展了TF相关的知识,并且根据里面的推荐,了解了CNN的相关的术语,比如窗口,滑动等。
本小节会附有完整代码,建议大家手动输入进自己的编辑器,而不是简单复制黏贴,加深理解。
依托于前面几个章节内容的铺垫,本节会通过SDL ,利用CNN来实现一个文本意图识别的例子。
假设数据是CSV格式,只有两列,一列是文本字段,一列是分类字段。他们都是字符串格式。大致格式如下:
最近的医院在哪里, 医院
附近哪个餐厅最好吃,餐馆
......
还记得我们之前【Tensorflow基础】提到的套路么?定义你要喂进去数据格式,也就是placeholder
建立网络结构
定义你要优化的目标值
选择优化器
定义一些指标衡量结果,比如准确率
打开session会话
执行训练过程以及验证结果
关闭会话
这次我们也会按照上面的套路进行。
先定义输入格式:
input_x = tf.placeholder(tf.int32, [None, 64], name="input_x")input_y = tf.placeholder(tf.float32, [None, 200], name="input_y")
输入是一个二维数组,第二个维度是64个int类型的数字。第一个维度指的是每次喂给算法的样本的个数,在运行时确定。
接着我们开始定义网络结构,工欲善其事必先利其器,我们先开发一个方法,可以很方便的建立卷积层:
def conv_poo_layer(input, size_in, size_out, filter_width, filter_height, include_pool=False, name="conv"):
with tf.name_scope(name):
w = tf.Variable(tf.truncated_normal([filter_height, filter_width, size_in, size_out], stddev=0.1), name="W")
b = tf.Variable(tf.constant(0.1, shape=[size_out], name="B"))
conv = tf.nn.conv2d(input, w, strides=[1, 1, 1, 1], padding="VALID")
act = tf.nn.relu(conv + b)
tf.summary.histogram("weights", w)
tf.summary.histogram("biases", b)
tf.summary.histogram("activations", act) if include_pool: return tf.nn.max_pool(act, ksize=[1, filter_height, 1, 1], strides=[1, 1, 1, 1], padding="VALID") else: return act
有了上面的方法,我们就可以简单调用conpoolayer就能创建一层卷积网络了。里面具体的参数大家还是需要自己了解,如果不清楚,可以简单的把这个当做一个工具类。
通常卷积层之后,要接一个全连接层,方便后续做分类。同样的,我们开发一个工具方法,方便全连接网络结构的建立:
def fc_layer(input, size_in, size_out, active="relu", name="fc"):
with tf.name_scope(name):
w = tf.Variable(tf.truncated_normal([size_in, size_out], stddev=0.1), name="W_" + name)
b = tf.Variable(tf.constant(0.1, shape=[size_out], name="B_" + name)) if active == "sigmoid":
act = tf.nn.sigmoid(tf.matmul(input, w) + b) elif active is None:
act = tf.matmul(input, w) + b else:
act = tf.nn.relu(tf.matmul(input, w) + b)
tf.summary.histogram("W_" + name + "_weights", w)
tf.summary.histogram("B_" + name + "_biases", b)
tf.summary.histogram(name + "_activations", act) return act
现在我们可以通过fc_layer方法随意构建一个全连接层。
为了模拟实际场景,我们打算构建三个两层的卷积网络,每个卷积网络的滑动窗口分别是5,10,20。
embedded_input_x = tf.expand_dims(lookup_embedding(input_x), -1)
buffer = [] for vw in [5, 10, 20]:
conv_layout_num = 0
pool_layout_num = 0
conv1 = conv_poo_layer(embedded_input_x, 1, 16, filter_width=EMBEDDING_DIM, filter_height=vw,
name="conv1_" + str(vw))
conv_layout_num += 1
pool_layout_num += 0
conv_out = conv_poo_layer(conv1, 16, 32, filter_width=1, filter_height=vw,
name="conv2_" + str(vw))
conv_layout_num += 1
pool_layout_num += 0
flattened = tf.reshape(conv_out, [-1, (
SEQUENCE_LENGTH + conv_layout_num + pool_layout_num - conv_layout_num * vw - pool_layout_num * vw) * 32])
buffer.append(flattened)
在上面的代码中,因为Tensorflow的API比较底层,很多东西都要自己算,所以多加了一些额外的代码方便计算。事实上,Tensorflow提供了