1、书籍
《python神经网络编程》这本书只认真读完了第一章,大概80页内容,就是简单介绍了下三层前馈神经网络,以及推导了利用梯度下降法来反向传播误差,更新权重,即误逆差传播法(error backpropagation, BP)。有点基础的,这本书还是不推荐买了,完全可以直接阅读《深度学习》(周志华)第5章神经网络的内容。
2、上手练习
2.1 利用tensorflow进行文本分类
参考这篇翻译的博客https://blog.csdn.net/u012052268/article/details/77862202
知识点:
(1) nlp里的卷积和池化
图像里的卷积核多是正方形的,假如图像提取的像素是n*m, 卷积核(filter)是k*k,在宽度和高度上同时移动,通常会得到(n-k+1)*(m-k+1)的矩阵,目标是降维。但是文本里,如果单词embedding的长度是m,假设文本有n个单词,则初始特征矩阵是n*m,卷积核的宽度和embedding的长度一致是m,高度设置为window_size,则卷积核只在高度上移动,这样每次窗口滑动过的位置都是完整的单词,不会将几个单词的一部分“vector”进行卷积,这也保证了word作为语言中最小粒度的合理性。这样卷积后得到的结果是一个一维向量,大小为[n-window_size+1, 1]。在经过池化(max-pooling)之后可能是一个标量。
为了将标量变成向量,同一个window_size的卷积核(filter)设置了多个(128个之类的),可以组合(拼接)成一个向量作为feature_vector。window_size通常也会设置多个[3,4,5],最后再将所有window_size下的feature_vector也组合成一个single vector,作为全连接层的输入。
相关的代码实现主要是以下这部分:
# Create a convolution + maxpool layer for each filter size
pooled_outputs = []
for i, filter_size in enumerate(filter_sizes):
with tf.name_scope("conv-maxpool-%s" % filter_size):
# Convolution Layer
filter_shape = [filter_size, embedding_size, 1, num_filters]
W = tf.Variable(tf.truncated_normal(filter_shape, stddev=0.1), name="W")
b = tf.Variable(tf.constant(0.1, shape=[num_filters]), name="b")
conv = tf.nn.conv2d(
self.embedded_chars_expanded,
W,
strides=[1, 1, 1, 1],
padding="VALID"
name="conv")
# Apply nonlinearity
h = tf.nn.relu(tf.nn.bias_add(conv, b), name="relu")
# Maxpooling over the outputs
pooled = tf.nn.max_pool(
h,
ksize=[1, sequence_length - filter_size + 1, 1, 1],
strides=[1, 1, 1, 1]
padding='VALID',
name="pool")
pooled_outputs.append(pooled)
# Combine all the pooled features
num_filters_total = num_filters * len(filter_sizes)
self.h_pool = tf.concat(pooled_outputs, 3)
self.h_pool_flat = tf.reshape(self.h_pool, [-1, num_filters_total])
(2) embedding的实现方式
每个id(词)对应的向量是均匀分布的,值在[-1, 1]。样例中的词表vacabulary size是18758个,所以W的shape = (18758, 128)。
self.W = tf.Variable(tf.random_uniform([vocab_size, embedding_size], -1.0, 1.0), name="W")
每条训练数据默认是56个id(词),tf.nn.embedding_lookup()就是根据input_ids中的id,寻找embeddings,即self.w中的第id行。比如input_ids=[1,3,5],则找出embeddings中第1,3,5行,组成一个tensor返回,tensor的shape = (56, 128),即每条训练数据的经过embedding之后的矩阵是56 * 128
self.embedded_chars = tf.nn.embedding_lookup(self.W, self.input_x)