چکیده :

در زمینه بازیابی اطلاعات با 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 ها دارای جواب کاندید خود هستند

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

۱.۲. روشهای یادگیری:

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

یکی از تفاوتهای این روش با روش نقطه به نقطه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 است که در مکان متناظر با ان قرار دارد

۲.۱.۲. لایه ها برای ارائه میانی :

۲.۱.۳.


با توجه به شکل برای اینکه یک ارائه میانی از جمله ورودی داشته باشیم نیازبه ماتریس جمله s داشتیم ، بعد از آن نیاز به فیلترها داریم که دارای ابعاد d*m است .البته در صورت استفاده از پنجره عریض 17باید چپ و راست ماتریس جمله به تعداد m-1 ستون صفر اضافه کرد عموما چون تاثیر ستون های ابتدایی وانتهایی در حالت wide بیشتر دیده میشود از این حالت استفاده میکنند . در ضمن خروجی فیلتر ها به صورتی برداری ساخته میشود البته دلیلش هم مشخص است چون تعداد سطرهای آن با ماتریس جمله یکی است .

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

2.1.4. Pooling:

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

1-average pooling :

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

2- maxpooling :

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

۲.۲. معماری برای تطابق جفت متن ها 21

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

۲.۲.۱. تطابق پرس و جو و سندها :

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

این معادله برای میزان شباهت استفاده کردیم .

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 وزنهای لایه مخفی است و الفا یک تابع غیر خطی است که کار این لایه برای برقراری ارتباط بین لایه است .

۲.۲.۳. بیشینه ملایم :

در این لایه خروجی لایه‌ها که به بصورت بردار مانند برایش فرستاده شده است برای آنها احتمالشان محاسبه شده است

۲.۲.۴. جریان اطلاعات 26

در این قسمت به بررسی برداری میپردازیم که شامل ارائه میانی ورودی و شباهت بین آنها و ویژگی ‎‌های اضافی است تا آماده دبرای انتقال به لایه بیشینه هموار
باشد .

{ x }_{ joint }=[{ x }_{ q }^{ T };{ x }_{ sim };{ x }_{ d }^{ T };{ x }_{ feat }^{ T }]

۲.۲.۵. تمرین شبکه :

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


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

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

۲.۳. ارزیابی 28

در این مرحله بر اساس دو معیار29MAR و 30MRR به بررسی معماری خود برروی دیتاست مربوطه میپردازیم ابتدا تعریف دو معیار فوق را میگوییم .

MRR :

فرمول این معیار عبارت است از :

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

MAP :

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

۲.۳.۱. ارزیابی:

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


۲.۴. نتیجه گیری و کارهای آتی :

این معماری یک روش جدید برای مبحث بازیابی اطلاعات است به گونه ای که دیگر نیاز به هیچ گونه تکنیک دستی و منابع خارجی دیگر نداریم . این روش بر روی بسیاری از مجموعه های 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]

۲.۵.۴. کلاس 32Ranking :

در ایتدا ما میخواهیم ماتریس 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

کد این مرحله عبارت است از :

...
    # 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 داریم

۲.۵.۶. محاسبه ماتریس شباهت

ماتریس شباهت که یک ماتریس مربعی است و بگونه ای تعریف گردیده در طول مراحل 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 Reciprocal Rank

  30. Mean Average Precision

  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/