打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Convolutional Neural Network For Sentence Classification<Yoon Kim>解析(三)

Yoon Kim的代码包含三个文件,一个process_data.py,一个conv_net_classes.py,另一个是conv_net_sentence.py。下面首先讲解conv_net_classes.py文件,后面讲解从conv_net_sentence.py。另外,Yoon Kim 采用的CNN的实现借助的架构是基于Theano的。

conv_net_classes.py:
1、类LeNetConvPoolLayer目录1中已经提到过,主要包括卷积与降采样。
[python] view plain copy
  1. class LeNetConvPoolLayer(object):  
  2.     """Pool Layer of a convolutional network """  
  3.   
  4.     def __init__(self, rng, input, filter_shape, image_shape, poolsize=(2, 2), non_linear="tanh"):  
  5.         """ 
  6.         Allocate a LeNetConvPoolLayer with shared variable internal parameters. 
  7.  
  8.         :type rng: numpy.random.RandomState 
  9.         :param rng: a random number generator used to initialize weights 
  10.  
  11.         :type input: theano.tensor.dtensor4 
  12.         :param input: symbolic image tensor, of shape image_shape 
  13.  
  14.         :type filter_shape: tuple or list of length 4 
  15.         :param filter_shape: (number of filters, num input feature maps, 
  16.                               filter height,filter width) 
  17.  
  18.         :type image_shape: tuple or list of length 4 
  19.         :param image_shape: (batch size, num input feature maps, 
  20.                              image height, image width) 
  21.  
  22.         :type poolsize: tuple or list of length 2 
  23.         :param poolsize: the downsampling (pooling) factor (#rows,#cols) 
  24.         """  
  25.   
  26.         assert image_shape[1] == filter_shape[1]  
  27.         self.input = input  
  28.         self.filter_shape = filter_shape  
  29.         self.image_shape = image_shape  
  30.         self.poolsize = poolsize  
  31.         self.non_linear = non_linear  
  32.         # there are "num input feature maps * filter height * filter width"  
  33.         # inputs to each hidden unit  
  34.         fan_in = numpy.prod(filter_shape[1:])  
  35.         # each unit in the lower layer receives a gradient from:  
  36.         # "num output feature maps * filter height * filter width" /  
  37.         #   pooling size  
  38.         fan_out = (filter_shape[0] * numpy.prod(filter_shape[2:]) /numpy.prod(poolsize))  
  39.         # initialize weights with random weights  
  40.         if self.non_linear=="none" or self.non_linear=="relu":  
  41.             self.W = theano.shared(numpy.asarray(rng.uniform(low=-0.01,high=0.01,size=filter_shape),   
  42.                                                 dtype=theano.config.floatX),borrow=True,name="W_conv")  
  43.         else:  
  44.             W_bound = numpy.sqrt(6. / (fan_in + fan_out))  
  45.             self.W = theano.shared(numpy.asarray(rng.uniform(low=-W_bound, high=W_bound, size=filter_shape),  
  46.                 dtype=theano.config.floatX),borrow=True,name="W_conv")     
  47.         b_values = numpy.zeros((filter_shape[0],), dtype=theano.config.floatX)  
  48.         self.b = theano.shared(value=b_values, borrow=True, name="b_conv")  
  49.           
  50.         # convolve input feature maps with filters  
  51.         conv_out = conv.conv2d(input=input, filters=self.W,filter_shape=self.filter_shape, image_shape=self.image_shape)  
  52.         if self.non_linear=="tanh":  
  53.             conv_out_tanh = T.tanh(conv_out + self.b.dimshuffle('x', 0, 'x', 'x'))  
  54.             self.output = downsample.max_pool_2d(input=conv_out_tanh, ds=self.poolsize, ignore_border=True)  
  55.         elif self.non_linear=="relu":  
  56.             conv_out_tanh = ReLU(conv_out + self.b.dimshuffle('x', 0, 'x', 'x'))  
  57.             self.output = downsample.max_pool_2d(input=conv_out_tanh, ds=self.poolsize, ignore_border=True)  
  58.         else:  
  59.             pooled_out = downsample.max_pool_2d(input=conv_out, ds=self.poolsize, ignore_border=True)  
  60.             self.output = pooled_out + self.b.dimshuffle('x', 0, 'x', 'x')  
  61.         self.params = [self.W, self.b]  
  62.           
  63.     def predict(self, new_data, batch_size):  
  64.         """ 
  65.         predict for new data 
  66.         """  
  67.         img_shape = (batch_size, 1, self.image_shape[2], self.image_shape[3])  
  68.         conv_out = conv.conv2d(input=new_data, filters=self.W, filter_shape=self.filter_shape, image_shape=img_shape)  
  69.         if self.non_linear=="tanh":  
  70.             conv_out_tanh = T.tanh(conv_out + self.b.dimshuffle('x', 0, 'x', 'x'))  
  71.             output = downsample.max_pool_2d(input=conv_out_tanh, ds=self.poolsize, ignore_border=True)  
  72.         if self.non_linear=="relu":  
  73.             conv_out_tanh = ReLU(conv_out + self.b.dimshuffle('x', 0, 'x', 'x'))  
  74.             output = downsample.max_pool_2d(input=conv_out_tanh, ds=self.poolsize, ignore_border=True)  
  75.         else:  
  76.             pooled_out = downsample.max_pool_2d(input=conv_out, ds=self.poolsize, ignore_border=True)  
  77.             output = pooled_out + self.b.dimshuffle('x', 0, 'x', 'x')  
  78.         return output  

2、由目录1的原理讲解可知,MLP(多层感知器)包括Hidden Layer 与 LogisticRegression Layer,但是Yoon Kim采用的正则化没有加惩罚项,而是采用dropout的策略与限制二范式的范围。
Hidden Layer:
[python] view plain copy
  1. class HiddenLayer(object):  
  2.     """ 
  3.     Class for HiddenLayer 
  4.     """  
  5.     def __init__(self, rng, input, n_in, n_out, activation, W=None, b=None,  
  6.                  use_bias=False):  
  7.   
  8.         self.input = input  
  9.         self.activation = activation  
  10.   
  11.         if W is None:              
  12.             if activation.func_name == "ReLU":  
  13.                 W_values = numpy.asarray(0.01 * rng.standard_normal(size=(n_in, n_out)), dtype=theano.config.floatX)  
  14.             else:                  
  15.                 W_values = numpy.asarray(rng.uniform(low=-numpy.sqrt(6. / (n_in + n_out)), high=numpy.sqrt(6. / (n_in + n_out)),  
  16.                                                      size=(n_in, n_out)), dtype=theano.config.floatX)  
  17.             W = theano.shared(value=W_values, name='W')          
  18.         if b is None:  
  19.             b_values = numpy.zeros((n_out,), dtype=theano.config.floatX)  
  20.             b = theano.shared(value=b_values, name='b')  
  21.   
  22.         self.W = W  
  23.         self.b = b  
  24.   
  25.         if use_bias:  
  26.             lin_output = T.dot(input, self.W) + self.b  
  27.         else:  
  28.             lin_output = T.dot(input, self.W)  
  29.   
  30.         self.output = (lin_output if activation is None else activation(lin_output))  
  31.       
  32.         # parameters of the model  
  33.         if use_bias:  
  34.             self.params = [self.W, self.b]  
  35.         else:  
  36.             self.params = [self.W]  
dropout Hidden Layer(带有dropout的Hidden Layer):
[python] view plain copy
  1. class DropoutHiddenLayer(HiddenLayer):  
  2.     def __init__(self, rng, input, n_in, n_out,  
  3.                  activation, dropout_rate, use_bias, W=None, b=None):  
  4.         super(DropoutHiddenLayer, self).__init__(  
  5.                 rng=rng, input=input, n_in=n_in, n_out=n_out, W=W, b=b,  
  6.                 activation=activation, use_bias=use_bias)  
  7.   
  8.         self.output = _dropout_from_layer(rng, self.output, p=dropout_rate)  

LogisticRegression Layer:
[python] view plain copy
  1. class LogisticRegression(object):  
  2.     """Multi-class Logistic Regression Class 
  3.  
  4.     The logistic regression is fully described by a weight matrix :math:`W` 
  5.     and bias vector :math:`b`. Classification is done by projecting data 
  6.     points onto a set of hyperplanes, the distance to which is used to 
  7.     determine a class membership probability. 
  8.     """  
  9.   
  10.     def __init__(self, input, n_in, n_out, W=None, b=None):  
  11.         """ Initialize the parameters of the logistic regression 
  12.  
  13.     :type input: theano.tensor.TensorType 
  14.     :param input: symbolic variable that describes the input of the 
  15.     architecture (one minibatch) 
  16.      
  17.     :type n_in: int 
  18.     :param n_in: number of input units, the dimension of the space in 
  19.     which the datapoints lie 
  20.      
  21.     :type n_out: int 
  22.     :param n_out: number of output units, the dimension of the space in 
  23.     which the labels lie 
  24.      
  25.     """  
  26.   
  27.         # initialize with 0 the weights W as a matrix of shape (n_in, n_out)  
  28.         if W is None:  
  29.             self.W = theano.shared(  
  30.                     value=numpy.zeros((n_in, n_out), dtype=theano.config.floatX),  
  31.                     name='W')  
  32.         else:  
  33.             self.W = W  
  34.   
  35.         # initialize the baises b as a vector of n_out 0s  
  36.         if b is None:  
  37.             self.b = theano.shared(  
  38.                     value=numpy.zeros((n_out,), dtype=theano.config.floatX),  
  39.                     name='b')  
  40.         else:  
  41.             self.b = b  
  42.   
  43.         # compute vector of class-membership probabilities in symbolic form  
  44.         self.p_y_given_x = T.nnet.softmax(T.dot(input, self.W) + self.b)  
  45.   
  46.         # compute prediction as class whose probability is maximal in  
  47.         # symbolic form  
  48.         self.y_pred = T.argmax(self.p_y_given_x, axis=1)  
  49.   
  50.         # parameters of the model  
  51.         self.params = [self.W, self.b]  
  52.   
  53.     def negative_log_likelihood(self, y):  
  54.         """Return the mean of the negative log-likelihood of the prediction 
  55.         of this model under a given target distribution. 
  56.  
  57.     .. math:: 
  58.      
  59.     \frac{1}{|\mathcal{D}|} \mathcal{L} (\theta=\{W,b\}, \mathcal{D}) = 
  60.     \frac{1}{|\mathcal{D}|} \sum_{i=0}^{|\mathcal{D}|} \log(P(Y=y^{(i)}|x^{(i)}, W,b)) \\ 
  61.     \ell (\theta=\{W,b\}, \mathcal{D}) 
  62.      
  63.     :type y: theano.tensor.TensorType 
  64.     :param y: corresponds to a vector that gives for each example the 
  65.     correct label 
  66.      
  67.     Note: we use the mean instead of the sum so that 
  68.     the learning rate is less dependent on the batch size 
  69.     """  
  70.         # y.shape[0] is (symbolically) the number of rows in y, i.e.,  
  71.         # number of examples (call it n) in the minibatch  
  72.         # T.arange(y.shape[0]) is a symbolic vector which will contain  
  73.         # [0,1,2,... n-1] T.log(self.p_y_given_x) is a matrix of  
  74.         # Log-Probabilities (call it LP) with one row per example and  
  75.         # one column per class LP[T.arange(y.shape[0]),y] is a vector  
  76.         # v containing [LP[0,y[0]], LP[1,y[1]], LP[2,y[2]], ...,  
  77.         # LP[n-1,y[n-1]]] and T.mean(LP[T.arange(y.shape[0]),y]) is  
  78.         # the mean (across minibatch examples) of the elements in v,  
  79.         # i.e., the mean log-likelihood across the minibatch.  
  80.         return -T.mean(T.log(self.p_y_given_x)[T.arange(y.shape[0]), y])  
  81.   
  82.     def errors(self, y):  
  83.         """Return a float representing the number of errors in the minibatch ; 
  84.     zero one loss over the size of the minibatch 
  85.      
  86.     :type y: theano.tensor.TensorType 
  87.     :param y: corresponds to a vector that gives for each example the 
  88.     correct label 
  89.     """  
  90.   
  91.         # check if y has same dimension of y_pred  
  92.         if y.ndim != self.y_pred.ndim:  
  93.             raise TypeError('y should have the same shape as self.y_pred',  
  94.                 ('y', target.type, 'y_pred', self.y_pred.type))  
  95.         # check if y is of the correct datatype  
  96.         if y.dtype.startswith('int'):  
  97.             # the T.neq operator returns a vector of 0s and 1s, where 1  
  98.             # represents a mistake in prediction  
  99.             return T.mean(T.neq(self.y_pred, y))  
  100.         else:  
  101.             raise NotImplementedError()  

MLPDropout(综合上面的,带有dropout的MLP):
[python] view plain copy
  1. class MLPDropout(object):  
  2.     """A multilayer perceptron with dropout"""  
  3.     def __init__(self,rng,input,layer_sizes,dropout_rates,activations,use_bias=True):  
  4.   
  5.         #rectified_linear_activation = lambda x: T.maximum(0.0, x)  
  6.   
  7.         # Set up all the hidden layers  
  8.         self.weight_matrix_sizes = zip(layer_sizes, layer_sizes[1:])  
  9.         self.layers = []  
  10.         self.dropout_layers = []  
  11.         self.activations = activations  
  12.         next_layer_input = input  
  13.         #first_layer = True  
  14.         # dropout the input  
  15.         next_dropout_layer_input = _dropout_from_layer(rng, input, p=dropout_rates[0])  
  16.         layer_counter = 0  
  17.         for n_in, n_out in self.weight_matrix_sizes[:-1]:  
  18.             next_dropout_layer = DropoutHiddenLayer(rng=rng,  
  19.                     input=next_dropout_layer_input,  
  20.                     activation=activations[layer_counter],  
  21.                     n_in=n_in, n_out=n_out, use_bias=use_bias,  
  22.                     dropout_rate=dropout_rates[layer_counter])  
  23.             self.dropout_layers.append(next_dropout_layer)  
  24.             next_dropout_layer_input = next_dropout_layer.output  
  25.   
  26.             # Reuse the parameters from the dropout layer here, in a different  
  27.             # path through the graph.  
  28.             next_layer = HiddenLayer(rng=rng,  
  29.                     input=next_layer_input,  
  30.                     activation=activations[layer_counter],  
  31.                     # scale the weight matrix W with (1-p)  
  32.                     W=next_dropout_layer.W * (1 - dropout_rates[layer_counter]),  
  33.                     b=next_dropout_layer.b,  
  34.                     n_in=n_in, n_out=n_out,  
  35.                     use_bias=use_bias)  
  36.             self.layers.append(next_layer)  
  37.             next_layer_input = next_layer.output  
  38.             #first_layer = False  
  39.             layer_counter += 1  
  40.           
  41.         # Set up the output layer  
  42.         n_in, n_out = self.weight_matrix_sizes[-1]  
  43.         dropout_output_layer = LogisticRegression(  
  44.                 input=next_dropout_layer_input,  
  45.                 n_in=n_in, n_out=n_out)  
  46.         self.dropout_layers.append(dropout_output_layer)  
  47.   
  48.         # Again, reuse paramters in the dropout output.  
  49.         output_layer = LogisticRegression(  
  50.             input=next_layer_input,  
  51.             # scale the weight matrix W with (1-p)  
  52.             W=dropout_output_layer.W * (1 - dropout_rates[-1]),  
  53.             b=dropout_output_layer.b,  
  54.             n_in=n_in, n_out=n_out)  
  55.         self.layers.append(output_layer)  
  56.   
  57.         # Use the negative log likelihood of the logistic regression layer as  
  58.         # the objective.  
  59.         self.dropout_negative_log_likelihood = self.dropout_layers[-1].negative_log_likelihood  
  60.         self.dropout_errors = self.dropout_layers[-1].errors  
  61.   
  62.         self.negative_log_likelihood = self.layers[-1].negative_log_likelihood  
  63.         self.errors = self.layers[-1].errors  
  64.   
  65.         # Grab all the parameters together.  
  66.         self.params = [ param for layer in self.dropout_layers for param in layer.params ]  
  67.   
  68.     def predict(self, new_data):  
  69.         next_layer_input = new_data  
  70.         for i,layer in enumerate(self.layers):  
  71.             if i<len(self.layers)-1:  
  72.                 next_layer_input = self.activations[i](T.dot(next_layer_input,layer.W) + layer.b)  
  73.             else:  
  74.                 p_y_given_x = T.nnet.softmax(T.dot(next_layer_input, layer.W) + layer.b)  
  75.         y_pred = T.argmax(p_y_given_x, axis=1)  
  76.         return y_pred  
  77.   
  78.     def predict_p(self, new_data):  
  79.         next_layer_input = new_data  
  80.         for i,layer in enumerate(self.layers):  
  81.             if i<len(self.layers)-1:  
  82.                 next_layer_input = self.activations[i](T.dot(next_layer_input,layer.W) + layer.b)  
  83.             else:  
  84.                 p_y_given_x = T.nnet.softmax(T.dot(next_layer_input, layer.W) + layer.b)  
  85.         return p_y_given_x  

conv_net_Sentence.py主要是调用conv_net_classes.py中的类,所以具体的讲解将在源代码中提及。





本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
DeepLearning tutorial(4)CNN卷积神经网络原理简介+代码详解
卷积层Convolutional
Deep Language Modeling for Question Answering using Keras
深度学习(十二)从自编码到栈式自编码
tensorflow学习笔记(十三):conv3d
手把手带你走进卷积神经网络!
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服