Learning to Rank Short Text Pairs with Convolutional Deep Neural Networks

تغییرات پروژه از تاریخ 1396/10/09 تا تاریخ 1396/11/21
![](https://boute.s3.amazonaws.com/295-Capture2.PNG)
----------


## _چکیده :_

در زمینه بازیابی اطلاعات با query_document_pair و در زمینه question_answering  با question_answer_pair مواجه هسیم . قبل از یادگیری جفت‌های مذکور باید از فضای اصلی (فضای نمادین کلمات) به فضای ویژگی‌ها(شامل ویژگی نوشتاری[^1] و معنایی[^2] و لغوی[^3] ....)
نگاشت شوند . 

در این مقاله سعی شده تا با استفاده از معماری CNN ، برای رتبه بندی جفت‌ها، به منظور به دست اوردن یک نمایش بهینه از آنها و همچنین یک تابع
شباهت [^4]برای بدست آوردن یک ارتباط باناظر[^5] بین آنها استفاده شود . 

متد مورد نظر روی دوعملیات[^6] زیر در زمینه بازیابی اطلاعات[^7] از trec  تست شده 

1-Question  answering 

2-microblog Retrieval
#  یادگیری برای رتبه‌بندی[^8]

##  فرموله کردن مسئله:_

ما در اینجا یک مجموعه از پرس و جو[^9] داریم (q عضو Q )که هر کدام از این query ها دارای جواب کاندید خود هستند 

که این کاندید ها با توجه به ارتباط با سوال قضاوت میشوند  که این مجموعه در صورت ارتباط مقدار یک یا بالاتر و در غیر این صورت مقدار صفر دارا است 

## روشهای یادگیری:_
سه روش متداول برای ساخت تابع رتبه بندی براساس اسم این است :


![](https://boute.s3.amazonaws.com/295-1.JPG)

یکی از تفاوتهای این روش با روش نقطه به نقطه[^10] در داشتن یک حداستانه[^11]  است و همچنین این پارامتر اضافه باعث جداسازی بهتر میشود 

3- Listwise 

در اینجا ما از روش point wise استفاده میکنیم اگرچه دوروش دیگر  از روش اول که فقط یک تابع جداسازی به روش خطی است کارایی بالاتری دارند ولی در  هنگام اموزش شبکه تاثیر کمتری دارند و همچنین به علت پیچیدگی بیشتر و محاسبات سنگین انها استفاده نشدند . 

# ساختار مدل عمیق [^12]

##  ساختار جمله:

در این مرحله هدف ما این است داده های ورودی را به شکل مورد نظر برای  شبکه تبدیل کرد ، بعبارتی بتوان : یک ارائه میانی[^13]  از پرس وجو و سندها[^14]  ارائه کرد که بتوان از ان برای بررسی تطابق معنایی انها استفاده کرد 

###  ساختار ماتریس جمله [^15]:

هر جمله s  شامل مجموعه از کلمات است $$ \left[ { w }_{ 1 },{ w }_{ 2 },...{ w }_{ |s| } \right] $$
که هر کلمه از مجموعه کلمات V  انتخاب شده است که هر کلمه $$ w\epsilon { R }^{ d }$$
باید از ماتریس تعبیه شده$$W\epsilon { R }^{ d*|V| }$$ 
که شامل تمام لغات در V است ، جستجو شود . برای راحتی جستجو لغات بصورت عددی[^16]  اندیس گذاری شده اند . 1,2,3…|v|

برای هر جمله ورودی  باید ماتریس ان جمله ساخته شود. به شکلی هر ستون i متناظر باکلمه شماره i است که در مکان متناظر با ان قرار دارد 

![](https://boute.s3.amazonaws.com/295-2.JPG)


### لایه ها برای ارائه میانی :

### 
![](https://boute.s3.amazonaws.com/295-3.JPG)
با توجه به شکل برای اینکه یک ارائه میانی از جمله ورودی داشته باشیم نیازبه ماتریس جمله s داشتیم ، بعد از آن نیاز به فیلترها داریم که دارای ابعاد d*m  است .البته در صورت استفاده از پنجره عریض [^17]باید چپ و راست ماتریس جمله به تعداد m-1 ستون صفر اضافه کرد عموما چون تاثیر ستون های ابتدایی وانتهایی در حالت wide بیشتر دیده میشود از این حالت استفاده میکنند . در ضمن خروجی فیلتر ها به صورتی برداری ساخته میشود البته دلیلش هم مشخص است چون تعداد سطرهای آن با ماتریس جمله یکی است . 

نیاز به تابع فعالساز است که میتوان از [^18]tanh , sigmoid , relu  استفاده کرد باتوجه به ازمایشات انجام شده relu   بهتر جواب میدهد [1] 

### Pooling:

یکی دیگر از ملزمات ما استفاده از لایه پولینگ (poling) است . برای این لایه دو روش مرسوم است که کار کاهش نمونه[^19] یا همان پولینگ را انجام میدهند (maxpooling,average pooling  ) که این روشها با معایبی همراه هستند . 

1-average pooling  :

مشکل این روش این است که کل درایه هی ورودی درگیر این میانگین گیری میشوند که برای توابع فعالسازی 
همچون  tanh  ممکن است منفی ها و مثبت ها یکدیگر را خنثی کنند[2] 

2- maxpooling :

برای این روش هر چند مشکل بازگشت به عقب روش بالا وجود ندارد اما این مشکل [^20] بیش برازش دارد .
  برای حل مشکلات فوق میتوان  k-maxpooling   استفاده کرد[3]

## معماری برای تطابق جفت متن ها [^21]

در این مرحله ما میخواهیم نشان دهیم که چگونه میتوانیم با استفاده از یک ارائه میانی از ورودید . بتوانیم میزان شباهت سندها و سوالات رو بررسی کرده و رتبه‌بندی
کنیم . یک سری توضیحات راجع به لایه‌های باقی مانده هم ارائه میدهیم 

![](https://boute.s3.amazonaws.com/295-4.JPG)
### تطابق پرس و جو و سندها :

در این مرحله میخواهیم با توجه به ارائه میانی از سندها و پرس وجوها بتوانیم یک معیار شباهت بین این دو ورودی پیدا کنیم . 

این معادله برای میزان شباهت استفاده کردیم . 
$$sim\left( { x }_{ q },{ x }_{ d } \right) ={ x }_{ q }^{ T }M{ x }_{ d }$$
در این معادله $$M\epsilon { \Re  }^{ d*d }$$
یک ماتریس تشابه است . که این ماتریس در طول آموزش میتواند بهبود یابد و تمرین داده شود . معادله بالا یک مدل کانال نویزی [^22]است که در ترجمه ماشین [^23]استفاده شود 

### لایه مخفی [^24]

در این بخش با یک لایه مخفی قبل از لایه بیشنه هموار [^25] مواجه هسیم که معادله آن به شکل زیر است $$\alpha \left( { w }_{ h }.x+b \right) $$. در این معادله wh  وزنهای لایه مخفی است و الفا یک تابع غیر خطی است که کار این لایه برای برقراری ارتباط بین لایه است . 

### بیشینه ملایم : 

در این لایه خروجی لایه‌ها که به بصورت بردار مانند برایش فرستاده شده است برای آنها احتمالشان محاسبه شده است  
![](https://boute.s3.amazonaws.com/295-5.JPG)

### جریان اطلاعات [^26]

در این قسمت به بررسی برداری میپردازیم که شامل ارائه میانی ورودی و شباهت بین آنها و ویژگی ‎‌های اضافی است تا آماده دبرای انتقال به لایه بیشینه هموار
باشد . 
$${ x }_{ joint }=[{ x }_{ q }^{ T };{ x }_{ sim };{ x }_{ d }^{ T };{ x }_{ feat }^{ T }]$$

### تمرین شبکه : 

در این مرحله شبکه باید با توجه به پارامترها خود را آموزش بدهد. 
![](https://boute.s3.amazonaws.com/295-6.JPG)
در این مرحله بر اساس cross-entropy برای تابع هزینه عمل میکند . A خروجی لایه بیشینه هموار است و تتا شامل تمامی پارامترها است 

![](https://boute.s3.amazonaws.com/295-7.JPG)

شامل ماتریس کلمات ،وزن و بایاس فیلترها و ماتریس شباهت و وزن و بایاس لایه مخفی و بیشینه هموار . البته ناگفته نماند که میتوان با استفاده از لایه  کناره‌گیری[^27] با نسبت 0.5 استفاده کرد که باعث تنظیم لایه ها میشود و جلوگیری از اینکه بیش از حد تطابق پیدا کند . 

## ارزیابی [^28]

در این مرحله بر اساس دو معیار MAP[^6] و MRR[^7]  به بررسی معماری خود برروی دیتاست مربوطه میپردازیم ابتدا تعریف دو معیار فوق را میگوییم . 

MRR :

فرمول این معیار عبارت است از : ![](https://boute.s3.amazonaws.com/295-8.JPG)

که (Rank(q  یعنی اینکه جایگاه اولین جواب درست از لیست کاندید

MAP :

این معیار به بررسی تمامی جوابهای درست برای سوال مورد نظر پرداخته 

![](https://boute.s3.amazonaws.com/295-9.JPG)

حال به مقایسه روش مربوطه میپردازیم 

![](https://boute.s3.amazonaws.com/295-table.JPG)
![](https://boute.s3.amazonaws.com/295-table4.JPG)

##مراجع
1.V. Nair and G. E. Hinton. Rectified linear units improve restricted  boltzmann machines. In Proceedings of the 27th International Conference on Machine Learning (ICML-10), pages 807–814, 2010.

2.M. D. Zeiler and R. Fergus. Stochastic pooling for regularization of deep convolutional neural networks. CoRR, abs/1301.3557, 2013.

3.N. Kalchbrenner, E. Grefenstette, and P. Blunsom. Aconvolutional neural network for modelling sentences.
Proceedings of the 52nd Annual Meeting of the Association for Computational Linguistics, June 2014.

[^24]:Hidden layer

[^25]:Softamx

[^26]:Information flow

[^27]:Dropout 

[^28]:evaluation

[^29]:Mean Average Precision

[^30]: Mean Reciprocal Rank

[^22]:noisy channel
[^23]:machine translation
[^21]:Text pair  

[^17]:wide

[^18]:Rectified linear unit

[^20]:overfitting
[^19]:Down sampling
[^12]:Deep model

[^13]:intermediate representations

[^14]:document

[^15]:Matrix sentence

[^16]:integer

[^8]:Learning to rank

[^9]:query

[^10]:pointwise

[^11]:threshold

[^1]:syntactic

[^2]:semantic

[^3]:lexical

[^4]:Similarity function

[^5]:supervised

[^6]:task

[^7]:Information retrieval[^30]MAR و [^29]MRR  به بررسی معماری خود برروی دیتاست مربوطه میپردازیم ابتدا تعریف دو معیار فوق را میگوییم . 

MRR :

فرمول این معیار عبارت است از : ![](https://boute.s3.amazonaws.com/295-8.JPG)

که (Rank(q  یعنی اینکه جایگاه اولین جواب درست از لیست کاندید. برای مواردی خوب است که برای هر یک فقط یک جواب درست وجود داشته باشد 

MAP :

این معیار به بررسی تمامی جوابهای درست برای سوال مورد نظر پرداخته و از انها میانگین میگیرد 

![](https://boute.s3.amazonaws.com/295-9.JPG)
###ارزیابی:

حال به مقایسه روش مربوطه میپردازیم . 

![](https://boute.s3.amazonaws.com/295-table.JPG)
![](https://boute.s3.amazonaws.com/295-table4.JPG)
##نتیجه گیری و کارهای آتی :
این معماری یک روش جدید برای مبحث بازیابی اطلاعات است به گونه ای که دیگر نیاز به هیچ گونه تکنیک دستی و منابع خارجی دیگر نداریم . این روش بر روی بسیاری از مجموعه های trec qa ازمایش شده و نشان داده که در انتخاب جمله برای سوالات نزدیک به 3% بهبود در میزان پارامتر MAP,MRR داشته است . 
این روش حتی قادر است که  بهترین سیستم  از TRECMicroblog2012 را بهبود ببخشد .
حتی این امکان وجود دارد که با بهترینsyntatctic reranker ها مقایسه شود در صورتی که نیاز به هیج گونه پارسر و یا منابع خارجی ندارد که این نیز خودش یک کار جدید است که برروی مباحث گرامری نیز استفاده کنیم . 
در ابن مدل یادگیری ژرف با توجه به اینکه بعضی از توابع فعالساز که دارای حالتهایی با جواب منفی هستند ، این امکان وجود دارد که در صورت استفاده از average pooling   عناصر یکدیگر را خنثی کنند چون تمام عناصر دخیل هستند و بعضی از عناصر بشدت مثبت و بعضی به شدت منفی باعث میشوند اثرات هم را خنثی کرده و نتیجه مطلوب حاصل نشود . از طرفی maxpooling باعث overfitting داده ها میشود و از این حیث میزان generalize شدن شبکه بشدت کاهش میابد بنابراین میتوان بجای این موارد از k-maxpooling استفاده کرد که بنظر میرسد از مشکلات بالا جلوگیری کند و خروجی مطلوب تری حاصل کند . 
در این مقاله از xfeat یا همان ویژگی های اضافی استفاده نشده است که خلا این موضوع احساس میشود ما میتوانیم از میزان هم پوشانی لغات و بسیاری از ویژگی های دیگر که رابطه بین سوال و جواب را به خوبی نشان دهند استفاده کنیم . البته این موضوع ممکن است که جواب ضعیف تر بدهد چون ما نمیتوانیم رابطه بین ویزگی هایی که خود شبکه یادگرفته است با ویژگی هایی که ما به ان اضافه کرده ایم را در یابیم و این موضوع ممکن است تاثیر عکس بگذارد اما باز این موضوع قابل بحث است . 

----------


## پیوست : کدهای مربوط به مقاله :
###تابع load_data : 
در ابتدا داده ها از دو فایل که به نام test وtrain هستند باز میشوند که شکل این داده به این صورت است هر سطر ان از سه قسمت تشکیل شده که با ',' از هم جدا شده اند که به ترتیب این سه قسمت عبارتند از 1: سوال  2:جواب پیشنهادی برای سوال مورد نظر 3: برچسب انتخابی برای این سوال و جواب  در صورت درست بودن جواب برابر یک و در غیر این صورت برابر صفر است. 
دیتا ست مورد انتخابی از مجموعه trec qa که توسط wang et al انتخاب و یکی از دیتا ستهایی است که بسیار مورد استفاده قرار گرفته [^31]

	...
	# data_left: همان سوال است 
	#data_right : همان جواب پیشنهادی برای سوال است 
	#data_label:همان برچسب پیشنهادی ارزشیابی برای سوال و جواب است 
	def load_data(filepath, vocab_tuple=None):
    data = list(set(open(filepath).readlines()))
    data = [d.split(',') for d in data]
    data = filter(lambda x: len(x)==3, data)
    data_left = [x[0].strip().split(' ') for x in data]
    data_right = [x[1].strip().split(' ') for x in data]
    data_label = [int(x[2]) for x in data]
    num_pos = sum(data_label)
    data_left = pad_sentences(data_left, FLAGS.max_len_left)
    data_right = pad_sentences(data_right, FLAGS.max_len_right)
    if vocab_tuple is None:
        vocab, vocab_inv = build_vocab(data_left+data_right)
    else:
        vocab, vocab_inv = vocab_tuple
    data_left, data_right, data_label = build_input_data(data_left, data_right,
    data_label, vocab)

###تابعpad_sentence:
این تابع برای یکسان سازی طول جملات به کار میرود زیرا زمانی که ما جملات را به صورت batch  میفرسم نیاز است که طول ماتریس های ما یکسان باشد حداقل در همان دسته `

	def pad_sentences(sentences, sequence_length, padding_word="<PAD/>"):
    padded_sentences = []
    for i in range(len(sentences)):
        sentence = sentences[i]
        if len(sentence) < sequence_length:
            num_padding = sequence_length - len(sentence)
            new_sentence = sentence + [padding_word] * num_padding
        else:
            new_sentence = sentence[:sequence_length]
        padded_sentences.append(new_sentence)
    return padded_sentences

###تابعbuild_vocab:
این تابع تمام لغات موجود در داده ها را شمارش کرده و برا ی هر کدام از لغات یک اندیس انتخاب کرده است یعنی داده هارا از فضای string  به فضای integer  برده و ملاک جدا سازی کلمات بر اساس فاصله یا همان "  " است 

	...
	def build_vocab(sentences):
    # Build vocabulary
    word_counts = Counter(itertools.chain(*sentences))
    # Mapping from index to word
    vocabulary_inv = [x[0] for x in word_counts.most_common(FLAGS.most_words-1)]
    vocabulary_inv = list(sorted(vocabulary_inv))
    vocabulary_inv.append('<UNK/>')
    # Mapping from word to index
    vocabulary = {x: i for i, x in enumerate(vocabulary_inv)}
    return [vocabulary, vocabulary_inv]

###کلاس [^32]Ranking :
در ایتدا ما میخواهیم ماتریس w را بسازیم البته برا ی اینکار میتوانیم از word2vec استفاده کنیم اما ما از tensorflow.random_uniform استفاده میکنیم که به هر کلمه یک سطرو با تعداد embeding_size ستون میسازد که این سطر از تمام سطر های دیگه متمایز است و مقادیر تمام درایه ها از 1- تا 1 است . البته برایاینکه  ورودی برای شبکه CNN اماده باشد نیاز است ماتریس چهاربعدی باشد فلذا یک ستون به اخر ورودی اضافه میکنیم . زیرا خروجی w یک ماتریس به شکل [None, vocab_size, embedding_size] است اما CNN دارای ماتریس ورودی به شکل [batch,width,height,channel] 

	...
	        # Embedding layer for both CNN
        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_left = tf.expand_dims(tf.nn.embedding_lookup(W,  
            self.input_left), -1)
            tf.expand_dims(tf.nn.embedding_lookup(W, self.input_right), -1)           
            print (self.embedded_chars_left)
            print (self.embedded_chars_right)

###ساخت لایه CNN ,MAXPOOL:
در اینجا ما سه عدد فیلتر داریم که این فیلتر داریم که از نوع narrow هستند و دارای ارتفاع های [3,4,5] هستند و هیچگونه padding  هم نداریم . ماتریس وزن براساس توزیعی به شکل truncade با انحراف از معیار 0.1 میسازیم و بردار بایاس به صورت یک ثابت تعریف میکنیم . تابع فعالسازی غیر خطی relu نیز استفاده میکنیم خروجی لایه کانولوشن که همان ورودی maxpooling است برابر ksize=[1, max_len_left - filter_size + 1, 1, 1] است 

	...
        # Create a convolution + maxpool layer for each filter size
        pooled_outputs_left = []
        pooled_outputs_right = []
        for i, filter_size in enumerate(filter_sizes):
            filter_shape = [filter_size, embedding_size, 1, num_filters]
            with tf.name_scope("conv-maxpool-left-%s" % filter_size):
                # Convolution Layer
                W = tf.Variable(tf.truncated_normal(filter_shape, stddev=0.1), 
                name="W")
                conv = tf.nn.conv2d(                     
                self.embedded_chars_left,
                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, max_len_left - filter_size + 1, 1, 1],
               strides=[1, 1, 1, 1],
               padding='VALID',
               name="pool")
            pooled_outputs_left.append(pooled)
	

در انتهای این مرحله ما نیاز داریم که خروجی این لایه های maxpooling  را با همدیگر ترکیب کرده و یک بردار شامل تمامی این خروجی ها با فیلتر های مختلف بدست بیاوریم . که شکل ان به صورت زیر است . 
![ترکیب خروجی ها با فیلترهایی به طول 2و3و4](https://boute.s3.amazonaws.com/295-Capture.PNG)
کد این مرحله عبارت است از :

	...
        # Combine all the pooled features
        num_filters_total = num_filters * len(filter_sizes)
        self.h_pool_left = tf.reshape(tf.concat(3, pooled_outputs_left), [-1,  
        num_filters_total], name='h_pool_left')
![تفسیر کد برای حالتی که فیلترهایی به سایز 3و4و5 داریم ](https://boute.s3.amazonaws.com/295-Screen-Shot-2015-12-10-at-10.22.29-AM.png)
###محاسبه ماتریس شباهت 
ماتریس شباهت که یک ماتریس  مربعی است و بگونه ای تعریف گردیده در طول مراحل train  ، اموزش یابد . و در نهایت این ماتریس در خروجی لایه pooling برای سوال و جواب نظیرش ضرب شده و در نهایت یک عدد به عنوان خروجی میدهد . 

	...
	        # Compute similarity
	        with tf.name_scope("similarity"):
           W = tf.get_variable(
                "W",
                shape=[num_filters_total, num_filters_total],
                initializer=tf.contrib.layers.xavier_initializer())
            self.transform_left = tf.matmul(self.h_pool_left, W)
            self.sims = tf.reduce_sum(tf.mul(self.transform_left,  
            self.h_pool_right), 1, keep_dims=True)
            print (self.sims)

### لایه مخفی :
در ایتدا برای اینکه ورودی لایه مخفی را اماده کنیم باید خروجی maxpooling چپ و راست و خروجی similarity را تبدیل به یک بردار کرده 

	...  
	self.new_input = tf.concat(1, [self.h_pool_left, self.sims,    
	self.h_pool_right], name='new_input')
و حالا لایه مخفی را و بردار وزنهایش و بایاس ان و میزان loss انها را بدست میاوریم 

	...
	     # hidden layer
        with tf.name_scope("hidden"):
            W = tf.get_variable(
                "W_hidden",
                shape=[2*num_filters_total+1, num_hidden],
                initializer=tf.contrib.layers.xavier_initializer())
            b = tf.Variable(tf.constant(0.1, shape=[num_hidden]), name="b")
            l2_loss += tf.nn.l2_loss(W)
            l2_loss += tf.nn.l2_loss(b)
            self.hidden_output = tf.nn.relu(tf.nn.xw_plus_b(self.new_input, W,  
            b, name="hidden_output"))

###خروجی نهایی شبکه :
در انتها خروجی لا یه مخفی را به لایه dropout میدهیم و به محاسبه میزان cross_entropy پرداخته و همراه با l2 regularization میزان loss شبکه را بدست اورده  . همچنین به راحتی میتوان میزان دقت یا همان accuracy زا نیز محاسبه کرد 

        # Add dropout
        with tf.name_scope("dropout"):
            self.h_drop = tf.nn.dropout(self.hidden_output, 
            self.dropout_keep_prob, name="hidden_output_drop")
            print (self.h_drop)

        # Final (unnormalized) scores and predictions
        with tf.name_scope("output"):
            W = tf.get_variable(
                "W_output",
                shape=[num_hidden, 2],
                initializer=tf.contrib.layers.xavier_initializer())
            b = tf.Variable(tf.constant(0.1, shape=[2]), 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")

        # 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

        # 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")
	        


----------


###عملیات training :
در این مرحله ما میتوانیم با استفاده از گرادیان به اپدیت پارامترها پرداخته . هر بار اجرا شدن train_op برابر یکبار مرحله train است . در این جا  tensorflow میفهمد که کدام گارامتر قابل train  است و گرادیان مربوطه را محاسبه میکند . با استفاده از متغیر global_step تعداد مراحل train  را شمارش کرده . بعد از محاسبه گرادیان با استفاده از adamoptimizer  به اصلاح پارامترها میپردازد . 

	...
	         # Define Training procedure
            global_step = tf.Variable(0, name="global_step", trainable=False)
            optimizer = tf.train.AdamOptimizer(1e-3)
            grads_and_vars = optimizer.compute_gradients(cnn.loss)
            train_op = optimizer.apply_gradients(grads_and_vars,  
            global_step=global_step)

حال با استفاده از تابع train_step  به اموزش شبکه و انجام train میپردازیم که خروجی ccuraacy,loss شبکه را میگیریم و بروزرسانی وزنها را انجام میدهیم و خروجی انها را چاپ میکنیم ناگفته نماند که میزان دقت در صورتی که batch_size کم باشد میتواند به میزان قابل توجهی متفاوت باشئد  . 
تابع dev_step شبیه تابع بالایی است با  این تفاوت که برروی داده های ارزیابی بجای کل داده ها ازمایش میشود و عملیات به روزرسانی وزنها نیز انجام نمیشود و dropout هم غیر فعال است در این مرحله 

	...
	            def train_step(x_left_batch, x_right_batch, y_batch):
                feed_dict = {
                cnn.input_left: x_left_batch,
                cnn.input_right: x_right_batch,
                cnn.input_y: y_batch,
                cnn.dropout_keep_prob: FLAGS.dropout_keep_prob
                }
                _, step, loss, accuracy = sess.run(
                    [train_op, global_step, cnn.loss, cnn.accuracy],
                    feed_dict)
                time_str = datetime.datetime.now().isoformat()
                if step % 10 == 0:
                    print("{}: step {}, loss {:g}, acc {:g}".format(time_str,  
                    step, loss, accuracy))

            def dev_step(x_left_batch_dev, x_right_batch_dev, y_batch_dev):
                feed_dict = {
                cnn.input_left: x_left_batch_dev,
                cnn.input_right: x_right_batch_dev,
                cnn.input_y: y_batch_dev,
                cnn.dropout_keep_prob: 1.0
                }
                step, loss, accuracy, sims, pres = sess.run(
                        [global_step, cnn.loss, cnn.accuracy, cnn.sims,  
                        cnn.scores],
                        feed_dict)

###تابعbatch_itr:
استفاده اصلی این تابع برای این است در هر epoch  داده هارا به صورت تصادفی قرار داده و با توجه به batch_size داده مورد نظر برای هر دسته را انتخاب کرده و خروجی مورد نظر را به عنوان ورودی به شبکه فرستاده تا شبکه  امورش ببیند 

	...
	            def batch_iter(all_data, batch_size, num_epochs, shuffle=True):
                data = np.array(all_data)
                data_size = len(data)
                num_batches_per_epoch = int(data_size/batch_size)
                for epoch in range(num_epochs):
                    # Shuffle the data at each epoch
                    if shuffle:
                        shuffle_indices =  
                        np.random.permutation(np.arange(data_size))
                        shuffled_data = data[shuffle_indices]
                    else:
                        shuffled_data = data
                    for batch_num in range(num_batches_per_epoch):
                        start_index = batch_num * batch_size
                        end_index = min((batch_num + 1) * batch_size,  
                        data_size)
                        yield shuffled_data[start_index:end_index]
در انتها توابعی برای جلوگیری از ovefiitting  نیز داریم که با توجه میزان دقت 5 تا دسته اخری که در صورت کاهش اعلام overfitting  میکند 

 


----------


##مراجع
1.V. Nair and G. E. Hinton. Rectified linear units improve restricted  boltzmann machines. In Proceedings of the 27th International Conference on Machine Learning (ICML-10), pages 807–814, 2010.

2.M. D. Zeiler and R. Fergus. Stochastic pooling for regularization of deep convolutional neural networks. CoRR, abs/1301.3557, 2013.

3.N. Kalchbrenner, E. Grefenstette, and P. Blunsom. Aconvolutional neural network for modelling sentences.
Proceedings of the 52nd Annual Meeting of the Association for Computational Linguistics, June 2014.
4.http://www.wildml.com/2015/12/implementing-a-cnn-for-text-classification-in-tensorflow/


----------
[^1]:syntactic

[^2]:semantic

[^3]:lexical

[^4]:Similarity function

[^5]:supervised

[^6]:task

[^7]:Information retrieval
[^8]:Learning to rank

[^9]:query

[^10]:pointwise

[^11]:threshold
[^12]:Deep model

[^13]:intermediate representations

[^14]:document

[^15]:Matrix sentence

[^16]:integer

[^17]:wide

[^18]:Rectified linear unit

[^19]:Down sampling

[^20]:overfitting

[^21]:Text pair  

[^22]:noisy channel

[^23]:machine translation

[^24]:Hidden layer

[^25]:Softamx

[^26]:Information flow

[^27]:Dropout 

[^28]:evaluation

[^29]:Mean Average Precision

[^30]: Mean Reciprocal Rank

[^31]:http://cs.stanford.edu/people/mengqiu/data/ qg-emnlp07-data.tgz

[^32]:http://www.wildml.com/2015/12/implementing-a-cnn-for-text-classification-in-tensorflow/