In [1]:
import sys
print sys.executable
%load_ext autoreload
%autoreload 2
%reload_ext autoreload


/Users/lisa1010/tf_venv/bin/python

In [6]:
import tensorflow as tf
import tflearn
import numpy as np
import time

In [78]:
import concept_dependency_graph as cdg
import dataset_utils
import dynamics_model_class as dm
import data_generator as dgen
from filepaths import *
from constants import *

Generate data

Only needs to be done once. NOTE: If you already have the pickle files in the "synthetic_data" folder, you do NOT need to run the following cell.


In [ ]:
n_students = 10000
seqlen = 100
concept_tree = cdg.ConceptDependencyGraph()
concept_tree.init_default_tree(n=N_CONCEPTS)
print ("Initializing synthetic data sets...")
for policy in ['random', 'expert', 'modulo']:
    filename = "{}stud_{}seq_{}.pickle".format(n_students, seqlen, policy)
    dgen.generate_data(concept_tree, n_students=n_students, seqlen=seqlen, policy=policy, filename="{}{}".format(SYN_DATA_DIR, filename))
print ("Data generation completed. ")

Load data set

Takes about 3 minutes for 10000 students with sequence length 100.


In [19]:
dataset_name = "10000stud_100seq_modulo"

In [5]:
# load generated data from picke files and convert it to a format so we can feed it into an RNN for training
# NOTE: This step is not necessary if you already have the data saved in the format for RNNs. 
data = dataset_utils.load_data(filename="../synthetic_data/{}.pickle".format(dataset_name))
input_data_, output_mask_, target_data_ = dataset_utils.preprocess_data_for_rnn(data)

In [18]:
# Save numpy matrices to files so data loading is faster, since we don't have to do the conversion again.
dataset_utils.save_rnn_data(input_data_, output_mask_, target_data_, dataset_name)

In [20]:
# load the numpy matrices
input_data_, output_mask_, target_data_ = dataset_utils.load_rnn_data(dataset_name)

In [24]:
print input_data_.shape
print target_data_.shape


(10000, 100, 20)
(10000, 100, 10)

In [42]:
from sklearn.model_selection import train_test_split

In [43]:
x_train, x_test, mask_train, mask_test, y_train, y_test = train_test_split(input_data_, output_mask_, target_data_, test_size=0.1, random_state=42)

In [44]:
train_data = (x_train, mask_train, y_train)

Build, train and save RNN Dynamics Model


In [33]:
import models_dict_utils

In [39]:
# Each RNN model can be identified by its model_id string. 
# We will save checkpoints separately for each model. 
# Models can have different architectures, parameter dimensions etc. and are specified in models_dict.json
model_id = "learned_from_modulo"

In [40]:
# Specify input / output dimensions and hidden size
n_timesteps = 100
n_inputdim = 20
n_outputdim = 10
n_hidden = 32

# If you are creating a new RNN model or just to check if it already exists:
# Only needs to be done once for each model

models_dict_utils.check_model_exists_or_create_new(model_id, n_inputdim, n_hidden, n_outputdim)


A model with the same model_id 'learned_from_modulo' already exists. 
No differences found. Yay! 

In [75]:
# Load model with parameters initialized randomly
dmodel = dm.DynamicsModel(model_id=model_id, timesteps=100, load_checkpoint=False)


Loading RNN dynamics model...
Directory path for tensorboard summaries: ../tensorboard_logs/learned_from_modulo/
Checkpoint directory path: ../checkpoints/learned_from_modulo/
Model loaded.

In [76]:
# train model for two epochs (saves checkpoint after each epoch) 
# (checkpoint saves the weights, so we can load in pretrained models.)
dmodel.train(train_data, n_epoch=2)


Training Step: 253  | total loss: 0.01340 | time: 12.437s
| Adam | epoch: 002 | loss: 0.01340 -- iter: 8064/8100
Training Step: 254  | total loss: 0.01336 | time: 13.544s
| Adam | epoch: 002 | loss: 0.01336 | val_loss: 0.01319 -- iter: 8100/8100
--
WARNING:tensorflow:Error encountered when serializing layer_tensor/lstm_1.
Type is unsupported, or the types of the items don't match field type in CollectionDef.
'list' object has no attribute 'name'
WARNING:tensorflow:Error encountered when serializing layer_tensor/lstm_2.
Type is unsupported, or the types of the items don't match field type in CollectionDef.
'list' object has no attribute 'name'

In [79]:
# Load model from latest checkpoint 
dmodel = dm.DynamicsModel(model_id=model_id, timesteps=100, load_checkpoint=True)


Loading RNN dynamics model...
Directory path for tensorboard summaries: ../tensorboard_logs/learned_from_modulo/
Checkpoint directory path: ../checkpoints/learned_from_modulo/
/Users/lisa1010/dev/smart-tutor/checkpoints/learned_from_modulo/_-254
Checkpoint loaded.
Model loaded.

In [80]:
# train for 2 more epochs
dmodel.train(train_data, n_epoch=2)


Training Step: 253  | total loss: 0.01204 | time: 15.510s
| Adam | epoch: 002 | loss: 0.01204 -- iter: 8064/8100
Training Step: 254  | total loss: 0.01205 | time: 16.652s
| Adam | epoch: 002 | loss: 0.01205 | val_loss: 0.01206 -- iter: 8100/8100
--
WARNING:tensorflow:Error encountered when serializing layer_tensor/lstm_1.
Type is unsupported, or the types of the items don't match field type in CollectionDef.
'list' object has no attribute 'name'
WARNING:tensorflow:Error encountered when serializing layer_tensor/lstm_2.
Type is unsupported, or the types of the items don't match field type in CollectionDef.
'list' object has no attribute 'name'

In [81]:
dmodel.train(train_data, n_epoch=16)


Training Step: 2285  | total loss: 0.01130 | time: 13.150s
| Adam | epoch: 018 | loss: 0.01130 -- iter: 8064/8100
Training Step: 2286  | total loss: 0.01128 | time: 14.259s
| Adam | epoch: 018 | loss: 0.01128 | val_loss: 0.01130 -- iter: 8100/8100
--
WARNING:tensorflow:Error encountered when serializing layer_tensor/lstm_1.
Type is unsupported, or the types of the items don't match field type in CollectionDef.
'list' object has no attribute 'name'
WARNING:tensorflow:Error encountered when serializing layer_tensor/lstm_2.
Type is unsupported, or the types of the items don't match field type in CollectionDef.
'list' object has no attribute 'name'

In [89]:
# important to cast preds as numpy array. 
preds = np.array(dmodel.predict(x_test[:1]))

In [90]:
print preds.shape


(1, 100, 10)

In [91]:
print preds[0,0]


[ 0.3591972   0.43897602  0.34933782  0.27990732  0.27030045  0.2504656
  0.26783279  0.22879325  0.24082358  0.22392181]

In [92]:
# Load model with different number of timesteps from checkpoint
# Since RNN weights don't depend on # timesteps (weights are the same across time), we can load in the weights for 
# any number of timesteps. The timesteps parameter describes the # of timesteps in the input data.
generator_model = dm.DynamicsModel(model_id=model_id, timesteps=1, load_checkpoint=True)


Loading RNN dynamics model...
Directory path for tensorboard summaries: ../tensorboard_logs/learned_from_modulo/
Checkpoint directory path: ../checkpoints/learned_from_modulo/
Checkpoint filename: /Users/lisa1010/dev/smart-tutor/checkpoints/learned_from_modulo/_-2286
Checkpoint loaded.
Model loaded.

In [93]:
# make a prediction
preds = generator_model.predict(x_test[:1,:1, :])

In [94]:
print preds[0][0]


[0.359197199344635, 0.4389760196208954, 0.3493378162384033, 0.27990731596946716, 0.2703004479408264, 0.25046560168266296, 0.26783278584480286, 0.22879324853420258, 0.24082358181476593, 0.22392180562019348]

In [ ]: