赞
踩
本文转载自:http://www.dataguru.cn/forum.php?mod=viewthread&tid=637971&extra=page=1&page=1
Ox00: Motivation最近在研究Yoon Kim的一篇经典之作Convolutional Neural Networks for Sentence Classification,这篇文章可以说是cnn模型用于文本分类的开山之作(其实第一个用的不是他,但是Kim提出了几个variants,并有详细的调参)
wildml对这篇paper有一个tensorflow的实现,具体参见here。其实blog已经写的很详细了,但是对于刚入手tensorflow的新人来说代码可能仍存在一些细节不太容易理解,我也是初学,就简单总结下自己的理解,如果对读者有帮助那将是极好的。
Ox01: Start!我主要对TextCNN这个类进行解读,具体代码在这里。
研究别人代码时,时常问自己几个问题,由问题切入,在读的过程中找答案,这种方式我个人认为是最efficient的1 这个class的主要作用是什么? TextCNN类搭建了一个最basic的CNN模型,有input layer,convolutional layer,max-pooling layer和最后输出的softmax layer。
重要的事情说三遍:一个卷积核对于一个句子,convolution后得到的是一个vector;max-pooling后,得到的是一个scalar。如果对上述讲解还有什么不理解的地方,请移步wildml的另一篇 blog ,包教包会。
1 2 3 4 5 6 7 | # Embedding layer with tf.device('/cpu:0'), tf.name_scope("embedding"): W = tf.Variable( tf.random_uniform([vocab_size, embedding_size], -1.0, 1.0), name="W") self.embedded_chars = tf.nn.embedding_lookup(W, self.input_x) self.embedded_chars_expanded = tf.expand_dims(self.embedded_chars, -1) |
1 | self.input_x = tf.placeholder(tf.int32, [None, sequence_length], name="input_x") |
This operation is useful if you want to add a batch dimension to a single element. For example, if you have a single image of shape [height, width, channels], you can make it a batch of 1 image with expand_dims(image, 0), which will make the shape [1, height, width, channels].因此只需要
Example:
# ‘t’ is a tensor of shape [2]
shape(expand_dims(t, -1)) ==> [2, 1]
1 | tf.expand_dims(self.embedded_chars, -1) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | # 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(3, pooled_outputs) self.h_pool_flat = tf.reshape(self.h_pool, [-1, num_filters_total]) |
1 | W = tf.Variable(tf.truncated_normal(filter_shape, stddev=0.1), name="W") |
Outputs random values from a truncated normal distribution.也就是说random出来的值的范围都在[mean - 2 standard_deviations, mean + 2 standard_deviations]内。
The generated values follow a normal distribution with specified mean and standard deviation, except that values whose magnitude is more than 2 standard deviations from the mean are dropped and re-picked.
“VALID” padding means that we slide the filter over our sentence without padding the edges, performing a narrow convolution that gives us an output of shape [1, sequence_length - filter_size + 1, 1, 1].
1 2 3 | # Add dropout with tf.name_scope("dropout"): self.h_drop = tf.nn.dropout(self.h_pool_flat, self.dropout_keep_prob) |
1 2 3 4 5 6 7 8 9 10 11 12 | # Final (unnormalized) scores and predictions with tf.name_scope("output"): W = tf.get_variable( "W", shape=[num_filters_total, num_classes], initializer=tf.contrib.layers.xavier_initializer()) b = tf.Variable(tf.constant(0.1, shape=[num_classes]), name="b") l2_loss += tf.nn.l2_loss(W) l2_loss += tf.nn.l2_loss(b) self.scores = tf.nn.xw_plus_b(self.h_drop, W, b, name="scores") self.predictions = tf.argmax(self.scores, 1, name="predictions") |
1 2 3 4 | # CalculateMean cross-entropy loss with tf.name_scope("loss"): losses = tf.nn.softmax_cross_entropy_with_logits(self.scores, self.input_y) self.loss = tf.reduce_mean(losses) + l2_reg_lambda * l2_loss |
1 2 3 4 | # Accuracy with tf.name_scope("accuracy"): correct_predictions = tf.equal(self.predictions, tf.argmax(self.input_y, 1)) self.accuracy = tf.reduce_mean(tf.cast(correct_predictions, "float"), name="accuracy") |
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。