Commit fdbd75a0 authored by Jon Krohn's avatar Jon Krohn
Browse files

add conv sentiment classifier soln

parent f76b0f91
Loading
Loading
Loading
Loading
+220 −0
Changes for solutions/convolutional_sentiment_classifier.ipynb: 220 added lines, 0 removed lines.
Original line number Diff line number Diff line
%% Cell type:markdown id: tags:

# Convolutional Sentiment Classifier

%% Cell type:markdown id: tags:

In this notebook, we build a *convolutional* neural net to classify IMDB movie reviews by their sentiment.

%% Cell type:markdown id: tags:

#### Load dependencies

%% Cell type:code id: tags:

``` python
import keras
from keras.datasets import imdb
from keras.preprocessing.sequence import pad_sequences
from keras.models import Sequential
from keras.layers import Dense, Dropout, Embedding
from keras.layers import SpatialDropout1D, Conv1D, GlobalMaxPooling1D # new!
from keras.callbacks import ModelCheckpoint
import os
from sklearn.metrics import roc_auc_score
import matplotlib.pyplot as plt
%matplotlib inline
```

%% Output

    Using TensorFlow backend.

%% Cell type:markdown id: tags:

#### Set hyperparameters

%% Cell type:code id: tags:

``` python
# output directory name:
output_dir = 'model_output/conv'

# training:
epochs = 4
batch_size = 128

# vector-space embedding:
n_dim = 64
n_unique_words = 5000
max_review_length = 400
pad_type = trunc_type = 'pre'
drop_embed = 0.2 # new!

# convolutional layer architecture:
n_conv = 256 # filters, a.k.a. kernels
k_conv = 3 # kernel length

# dense layer architecture:
n_dense = 256
dropout = 0.2
```

%% Cell type:markdown id: tags:

#### Load data

%% Cell type:code id: tags:

``` python
(x_train, y_train), (x_valid, y_valid) = imdb.load_data(num_words=n_unique_words) # removed n_words_to_skip
```

%% Cell type:markdown id: tags:

#### Preprocess data

%% Cell type:code id: tags:

``` python
x_train = pad_sequences(x_train, maxlen=max_review_length, padding=pad_type, truncating=trunc_type, value=0)
x_valid = pad_sequences(x_valid, maxlen=max_review_length, padding=pad_type, truncating=trunc_type, value=0)
```

%% Cell type:markdown id: tags:

#### Design neural network architecture

%% Cell type:code id: tags:

``` python
model = Sequential()
model.add(Embedding(n_unique_words, n_dim, input_length=max_review_length))
model.add(SpatialDropout1D(drop_embed))
model.add(Conv1D(n_conv, k_conv, activation='relu'))
# model.add(Conv1D(n_conv, k_conv, activation='relu'))
model.add(GlobalMaxPooling1D())
model.add(Dense(n_dense, activation='relu'))
model.add(Dropout(dropout))
model.add(Dense(1, activation='sigmoid'))
```

%% Cell type:code id: tags:

``` python
model.summary()
```

%% Output

    _________________________________________________________________
    Layer (type)                 Output Shape              Param #
    =================================================================
    embedding_1 (Embedding)      (None, 400, 64)           320000
    _________________________________________________________________
    spatial_dropout1d_1 (Spatial (None, 400, 64)           0
    _________________________________________________________________
    conv1d_1 (Conv1D)            (None, 398, 256)          49408
    _________________________________________________________________
    global_max_pooling1d_1 (Glob (None, 256)               0
    _________________________________________________________________
    dense_1 (Dense)              (None, 256)               65792
    _________________________________________________________________
    dropout_1 (Dropout)          (None, 256)               0
    _________________________________________________________________
    dense_2 (Dense)              (None, 1)                 257
    =================================================================
    Total params: 435,457
    Trainable params: 435,457
    Non-trainable params: 0
    _________________________________________________________________

%% Cell type:markdown id: tags:

#### Configure model

%% Cell type:code id: tags:

``` python
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
```

%% Cell type:code id: tags:

``` python
modelcheckpoint = ModelCheckpoint(filepath=output_dir+"/weights.{epoch:02d}.hdf5")
if not os.path.exists(output_dir):
    os.makedirs(output_dir)
```

%% Cell type:markdown id: tags:

#### Train!

%% Cell type:code id: tags:

``` python
# 89.1% validation accuracy in epoch 2
# ...with second convolutional layer is essentially the same at 89.0%
model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, verbose=1, validation_data=(x_valid, y_valid), callbacks=[modelcheckpoint])
```

%% Output

    Train on 25000 samples, validate on 25000 samples
    Epoch 1/4
    25000/25000 [==============================] - 45s - loss: 0.4800 - acc: 0.7472 - val_loss: 0.2931 - val_acc: 0.8754
    Epoch 2/4
    25000/25000 [==============================] - 3s - loss: 0.2502 - acc: 0.8974 - val_loss: 0.2602 - val_acc: 0.8918
    Epoch 3/4
    25000/25000 [==============================] - 3s - loss: 0.1719 - acc: 0.9357 - val_loss: 0.2811 - val_acc: 0.8848
    Epoch 4/4
    25000/25000 [==============================] - 3s - loss: 0.1147 - acc: 0.9609 - val_loss: 0.3094 - val_acc: 0.8834

    <keras.callbacks.History at 0x7f99e7711f60>

%% Cell type:markdown id: tags:

#### Evaluate

%% Cell type:code id: tags:

``` python
model.load_weights(output_dir+"/weights.01.hdf5") # zero-indexed
```

%% Cell type:code id: tags:

``` python
y_hat = model.predict_proba(x_valid)
```

%% Output

    24544/25000 [============================>.] - ETA: 0s

%% Cell type:code id: tags:

``` python
plt.hist(y_hat)
_ = plt.axvline(x=0.5, color='orange')
```

%% Output


%% Cell type:code id: tags:

``` python
"{:0.2f}".format(roc_auc_score(y_valid, y_hat)*100.0)
```

%% Output

    '95.97'

%% Cell type:code id: tags:

``` python
```