Skip to content

Instantly share code, notes, and snippets.

@shashankg7
Forked from joshloyal/ngram_cnn.py
Created September 20, 2016 15:34
Show Gist options
  • Save shashankg7/7731841e81f1b7ab8cec0f97bdf9e177 to your computer and use it in GitHub Desktop.
Save shashankg7/7731841e81f1b7ab8cec0f97bdf9e177 to your computer and use it in GitHub Desktop.
Convolutional Network for Sentence Classification (Keras)
from keras.models import Graph
from keras.layers import containers
from keras.layers.core import Dense, Dropout, Activation, Reshape, Flatten
from keras.layers.embeddings import Embedding
from keras.layers.convolutional import Convolution2D, MaxPooling2D
def ngram_cnn(n_vocab, max_length, embedding_size, ngram_filters=[2, 3, 4, 5], n_feature_maps=100, dropout=0.5, n_hidden=15):
"""A single-layer convolutional network using different n-gram filters.
Parameters
----------
n_vocab: int
Number of words in the corpus vocabulary.
max_length: int
Maximum sentence length in the corpus.
embedding_size: int
Size of the dense embedding layer.
ngram_filters: iterable
N-gram filter sizes for the convolutional layers.
n_feature_maps: int
The number of feature maps used for each filter.
dropout: float
Dropout probability for the dropout layer after the conv layers.
n_hidden: int
Number of hidden units used in the fully-connected layer
References
----------
A Sensitivity Analysis of Convolutional Neural Networks for Sentence Classification.
Ye Zhang, Byron C. Wallace. <http://arxiv.org/pdf/1510.03820v3.pdf>
Convolutional Neural Networks for Sentence Classification.
Yoon Kim. <http://arxiv.org/pdf/1408.5882v2.pdf>
"""
model = Graph()
model.add_input(name='data', input_shape=(max_length,), dtype='int32')
model.add_node(Embedding(n_vocab, embedding_size, input_length=max_length),
name='embedding', input='data')
model.add_node(Reshape((1, max_length, embedding_size)),
name='reshape_embedding', input='embedding')
# convolutional n-grams
for n_gram in ngram_filters:
sequential = containers.Sequential()
sequential.add(Convolution2D(n_feature_maps, n_gram, embedding_size, input_shape=(1, max_length, embedding_size)))
sequential.add(Activation('relu'))
sequential.add(MaxPooling2D(pool_size=(max_length - n_gram + 1, 1)))
sequential.add(Flatten()) # this generates a single number from the n-gram level convolution
model.add_node(sequential, name=('unit_' + str(n_gram)), input='reshape_embedding')
model.add_node(Dropout(dropout), name='dropout', inputs=['unit_' + str(n) for n in ngram_filters])
# fully-connected module
fc = containers.Sequential()
fc.add(Dense(n_hidden, input_shape=(n_feature_maps * len(ngram_filters),)))
fc.add(Activation('relu'))
fc.add(Dense(1))
fc.add(Activation('sigmoid'))
model.add_node(fc, name='fully_connected', input='dropout')
model.add_output(name='output', input='fully_connected')
model.compile(loss={'output': 'binary_crossentropy'},
optimizer='adam')
return model
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment