| 81 | return logits |
| 82 | |
| 83 | def cnn_single_layer(self): |
| 84 | pooled_outputs = [] |
| 85 | for i, filter_size in enumerate(self.filter_sizes): |
| 86 | # with tf.name_scope("convolution-pooling-%s" %filter_size): |
| 87 | with tf.variable_scope("convolution-pooling-%s" % filter_size): |
| 88 | # ====>a.create filter |
| 89 | filter = tf.get_variable("filter-%s" % filter_size, [filter_size, self.embed_size, 1, self.num_filters],initializer=self.initializer) |
| 90 | # ====>b.conv operation: conv2d===>computes a 2-D convolution given 4-D `input` and `filter` tensors. |
| 91 | # Conv.Input: given an input tensor of shape `[batch, in_height, in_width, in_channels]` and a filter / kernel tensor of shape `[filter_height, filter_width, in_channels, out_channels]` |
| 92 | # Conv.Returns: A `Tensor`. Has the same type as `input`. |
| 93 | # A 4-D tensor. The dimension order is determined by the value of `data_format`, see below for details. |
| 94 | # 1)each filter with conv2d's output a shape:[1,sequence_length-filter_size+1,1,1];2)*num_filters--->[1,sequence_length-filter_size+1,1,num_filters];3)*batch_size--->[batch_size,sequence_length-filter_size+1,1,num_filters] |
| 95 | # input data format:NHWC:[batch, height, width, channels];output:4-D |
| 96 | conv = tf.nn.conv2d(self.sentence_embeddings_expanded, filter, strides=[1, 1, 1, 1], padding="VALID",name="conv") # shape:[batch_size,sequence_length - filter_size + 1,1,num_filters] |
| 97 | conv = tf.contrib.layers.batch_norm(conv, is_training=self.is_training_flag, scope='cnn_bn_') |
| 98 | |
| 99 | # ====>c. apply nolinearity |
| 100 | b = tf.get_variable("b-%s" % filter_size, [self.num_filters]) # ADD 2017-06-09 |
| 101 | h = tf.nn.relu(tf.nn.bias_add(conv, b),"relu") # shape:[batch_size,sequence_length - filter_size + 1,1,num_filters]. tf.nn.bias_add:adds `bias` to `value` |
| 102 | # ====>. max-pooling. value: A 4-D `Tensor` with shape `[batch, height, width, channels] |
| 103 | # ksize: A list of ints that has length >= 4. The size of the window for each dimension of the input tensor. |
| 104 | # strides: A list of ints that has length >= 4. The stride of the sliding window for each dimension of the input tensor. |
| 105 | pooled = tf.nn.max_pool(h, ksize=[1, self.sequence_length - filter_size + 1, 1, 1],strides=[1, 1, 1, 1], padding='VALID',name="pool") # shape:[batch_size, 1, 1, num_filters].max_pool:performs the max pooling on the input. |
| 106 | pooled_outputs.append(pooled) |
| 107 | # 3.=====>combine all pooled features, and flatten the feature.output' shape is a [1,None] |
| 108 | # e.g. >>> x1=tf.ones([3,3]);x2=tf.ones([3,3]);x=[x1,x2] |
| 109 | # x12_0=tf.concat(x,0)---->x12_0' shape:[6,3] |
| 110 | # x12_1=tf.concat(x,1)---->x12_1' shape;[3,6] |
| 111 | self.h_pool = tf.concat(pooled_outputs,3) # shape:[batch_size, 1, 1, num_filters_total]. tf.concat=>concatenates tensors along one dimension.where num_filters_total=num_filters_1+num_filters_2+num_filters_3 |
| 112 | self.h_pool_flat = tf.reshape(self.h_pool, [-1,self.num_filters_total]) # shape should be:[None,num_filters_total]. here this operation has some result as tf.sequeeze().e.g. x's shape:[3,3];tf.reshape(-1,x) & (3, 3)---->(1,9) |
| 113 | |
| 114 | # 4.=====>add dropout: use tf.nn.dropout |
| 115 | with tf.name_scope("dropout"): |
| 116 | self.h_drop = tf.nn.dropout(self.h_pool_flat, keep_prob=self.dropout_keep_prob) # [None,num_filters_total] |
| 117 | h = tf.layers.dense(self.h_drop, self.num_filters_total, activation=tf.nn.tanh, use_bias=True) |
| 118 | return h |
| 119 | |
| 120 | def cnn_multiple_layers(self): |
| 121 | # 2.=====>loop each filter size. for each filter, do:convolution-pooling layer(a.create filters,b.conv,c.apply nolinearity,d.max-pooling)---> |