def create_model(self, ret_model = False):
image_model = Sequential()
image_model.add(Dense(EMBEDDING_DIM, input_dim = 4096, activation='relu'))
image_model.add(RepeatVector(self.max_length))
lang_model = Sequential()
lang_model.add(Embedding(self.vocab_size, 256, input_length=self.max_length))
lang_model.add(LSTM(256,return_sequences=True))
lang_model.add(TimeDistributed(Dense(EMBEDDING_DIM)))
model = Sequential()
model.add(Merge([image_model, lang_model], mode='concat'))
model.add(LSTM(1000,return_sequences=False))
model.add(Dense(self.vocab_size))
model.add(Activation('softmax'))
print ("Model created!")
if(ret_model==True):
return model
model.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
return model
python类Embedding()的实例源码
def _get_embedding_layer(self, embedding_file=None):
if self.embedding_layer is None:
if embedding_file is None:
if not self.tune_embedding:
print >>sys.stderr, "Pretrained embedding is not given. Setting tune_embedding to True."
self.tune_embedding = True
embedding = None
else:
# Put the embedding in a list for Keras to treat it as initiali weights of the embedding
# layer.
embedding = [self.data_processor.get_embedding_matrix(embedding_file, onto_aware=False)]
vocab_size = self.data_processor.get_vocab_size(onto_aware=False)
self.embedding_layer = Embedding(input_dim=vocab_size, output_dim=self.embed_dim,
weights=embedding, trainable=self.tune_embedding,
mask_zero=True, name="embedding")
return self.embedding_layer
def build(self, input_shape):
# input shape is (batch_size, num_words, num_senses, num_hyps)
self.num_senses = input_shape[-2]
self.num_hyps = input_shape[-1] - 1 # -1 because the last value is a word index
# embedding of size 1.
if self.set_sense_priors:
self.sense_priors = self._get_initial_sense_priors((self.word_index_size, 1), name='{}_sense_priors'.format(self.name))
else:
# OntoLSTM makes sense proabilities uniform if the passed sense parameters are zero.
self.sense_priors = K.zeros((self.word_index_size, 1)) # uniform sense probs
# Keeping aside the initial weights to not let Embedding set them. It wouldn't know what sense priors are.
if self.initial_weights is not None:
self.onto_aware_embedding_weights = self.initial_weights
self.initial_weights = None
# The following method will set self.trainable_weights
super(OntoAwareEmbedding, self).build(input_shape) # input_shape will not be used by Embedding's build.
if not self.tune_embedding:
# Move embedding to non_trainable_weights
self._non_trainable_weights.append(self._trainable_weights.pop())
if self.set_sense_priors:
self._trainable_weights.append(self.sense_priors)
if self.onto_aware_embedding_weights is not None:
self.set_weights(self.onto_aware_embedding_weights)
def HAN1(MAX_NB_WORDS, MAX_WORDS, MAX_SENTS, EMBEDDING_DIM, WORDGRU, embedding_matrix, DROPOUTPER):
#model = Sequential()
wordInputs = Input(shape=(MAX_WORDS,), name='word1', dtype='float32')
wordEmbedding = Embedding(MAX_NB_WORDS, EMBEDDING_DIM, weights=[embedding_matrix], mask_zero=True, trainable=True, name='emb1')(wordInputs) #Assuming all the sentences have same number of words. Check for input_length again.
hij = Bidirectional(GRU(WORDGRU, name='gru1', return_sequences=True))(wordEmbedding)
wordDrop = Dropout(DROPOUTPER, name='drop1')(hij)
alpha_its, Si = AttentionLayer(name='att1')(wordDrop)
v6 = Dense(1, activation="sigmoid", name="dense")(Si)
#model.add(Dense(1, activation="sigmoid", name="documentOut3"))
model = Model(inputs=[wordInputs] , outputs=[v6])
model.compile(loss='binary_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
return model
def fGRU_avg(MAX_NB_WORDS, MAX_WORDS, MAX_SENTS, EMBEDDING_DIM, WORDGRU, embedding_matrix, DROPOUTPER):
wordInputs = Input(shape=(MAX_SENTS+1, MAX_WORDS), name="wordInputs", dtype='float32')
wordInp = Flatten()(wordInputs)
wordEmbedding = Embedding(MAX_NB_WORDS, EMBEDDING_DIM, weights=[embedding_matrix], mask_zero=False, trainable=True, name='wordEmbedding')(wordInp)
hij = Bidirectional(GRU(WORDGRU, return_sequences=True), name='gru1')(wordEmbedding)
head = GlobalAveragePooling1D()(hij)
v6 = Dense(1, activation="sigmoid", name="dense")(head)
model = Model(inputs=[wordInputs] , outputs=[v6])
model.compile(loss='binary_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
return model
def fGlove_avg(MAX_NB_WORDS, MAX_WORDS, MAX_SENTS, EMBEDDING_DIM, WORDGRU, embedding_matrix, DROPOUTPER):
wordInputs = Input(shape=(MAX_SENTS+1, MAX_WORDS), name="wordInputs", dtype='float32')
wordInp = Flatten()(wordInputs)
wordEmbedding = Embedding(MAX_NB_WORDS, EMBEDDING_DIM, weights=[embedding_matrix], mask_zero=False, trainable=True, name='wordEmbedding')(wordInp)
head = GlobalAveragePooling1D()(wordEmbedding)
v6 = Dense(1, activation="sigmoid", name="dense")(head)
model = Model(inputs=[wordInputs] , outputs=[v6])
model.compile(loss='binary_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
return model
def __init__(self, n_classes, vocab_size, max_len, num_units=128,
useBiDirection=False, useAttention=False, learning_rate=0.001, dropout=0, embedding_size=300):
self.model = Sequential()
self.model.add(Embedding(input_dim=vocab_size,
output_dim=embedding_size, input_length=max_len))
lstm_model = LSTM(num_units, dropout=dropout)
if useBiDirection:
lstm_model = Bidirectional(lstm_model)
if useAttention:
lstm_model = lstm_model
print("Attention not implement yet ... ")
self.model.add(lstm_model)
self.model.add(Dense(n_classes, activation='softmax'))
self.model.summary()
self.model.compile(loss='categorical_crossentropy',
optimizer=Adam(lr=learning_rate),
metrics=['accuracy'])
def create_BiLSTM(wordvecs, lstm_dim=300, output_dim=2, dropout=.5,
weights=None, train=True):
model = Sequential()
if weights != None:
model.add(Embedding(len(wordvecs)+1,
len(wordvecs['the']),
weights=[weights],
trainable=train))
else:
model.add(Embedding(len(wordvecs)+1,
len(wordvecs['the']),
trainable=train))
model.add(Dropout(dropout))
model.add(Bidirectional(LSTM(lstm_dim)))
model.add(Dropout(dropout))
model.add(Dense(output_dim, activation='softmax'))
if output_dim == 2:
model.compile('adam', 'binary_crossentropy',
metrics=['accuracy'])
else:
model.compile('adam', 'categorical_crossentropy',
metrics=['accuracy'])
return model
def reactionrnn_model(weights_path, num_classes, maxlen=140):
'''
Builds the model architecture for textgenrnn and
loads the pretrained weights for the model.
'''
input = Input(shape=(maxlen,), name='input')
embedded = Embedding(num_classes, 100, input_length=maxlen,
name='embedding')(input)
rnn = GRU(256, return_sequences=False, name='rnn')(embedded)
output = Dense(5, name='output',
activation=lambda x: K.relu(x) / K.sum(K.relu(x),
axis=-1))(rnn)
model = Model(inputs=[input], outputs=[output])
model.load_weights(weights_path, by_name=True)
model.compile(loss='mse', optimizer='nadam')
return model
def textgenrnn_model(weights_path, num_classes, maxlen=40):
'''
Builds the model architecture for textgenrnn and
loads the pretrained weights for the model.
'''
input = Input(shape=(maxlen,), name='input')
embedded = Embedding(num_classes, 100, input_length=maxlen,
trainable=True, name='embedding')(input)
rnn = LSTM(128, return_sequences=False, name='rnn')(embedded)
output = Dense(num_classes, name='output', activation='softmax')(rnn)
model = Model(inputs=[input], outputs=[output])
model.load_weights(weights_path, by_name=True)
model.compile(loss='categorical_crossentropy', optimizer='nadam')
return model
def build(self) -> None:
"""
?????????? ??????.
"""
inp = Input(shape=(None,))
emb = Embedding(len(self.grapheme_alphabet), self.emb_dimension)(inp)
encoded = Bidirectional(self.rnn(self.units1, return_sequences=True, recurrent_dropout=self.dropout))(emb)
encoded = Dropout(self.dropout)(encoded)
decoded = TimeDistributed(Dense(self.units2, activation="relu"))(encoded)
predictions = TimeDistributed(Dense(len(self.phonetic_alphabet), activation="softmax"))(decoded)
model = Model(inputs=inp, outputs=predictions)
model.compile(loss='sparse_categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
print(model.summary())
self.model = model
def build(self) -> None:
"""
?????????? ??????.
"""
inp = Input(shape=(None,))
emb = Embedding(len(self.grapheme_set), self.emb_dimension)(inp)
encoded = Bidirectional(self.rnn(self.units, return_sequences=True, recurrent_dropout=self.dropout))(emb)
encoded = Dropout(self.dropout)(encoded)
decoded = TimeDistributed(Dense(self.units, activation="relu"))(encoded)
predictions = TimeDistributed(Dense(3, activation="softmax"))(decoded)
model = Model(inputs=inp, outputs=predictions)
model.compile(loss='sparse_categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
print(model.summary())
self.model = model
def build(self) -> None:
"""
?????????? ??????.
"""
inp = Input(shape=(None,))
emb = Embedding(len(self.phonetic_alphabet), self.emb_dimension)(inp)
encoded = Bidirectional(self.rnn(self.units, return_sequences=True, recurrent_dropout=self.dropout))(emb)
encoded = Dropout(self.dropout)(encoded)
decoded = Bidirectional(self.rnn(self.units, return_sequences=True, recurrent_dropout=self.dropout))(encoded)
decoded = Dropout(self.dropout)(decoded)
predictions = TimeDistributed(Dense(3, activation="softmax"))(decoded)
model = Model(inputs=inp, outputs=predictions)
model.compile(loss='sparse_categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
print(model.summary())
self.model = model
def test_keras_export(self):
tests = open(os.path.join(settings.BASE_DIR, 'tests', 'unit', 'keras_app',
'keras_export_test.json'), 'r')
response = json.load(tests)
tests.close()
net = yaml.safe_load(json.dumps(response['net']))
net = {'l0': net['Input3'], 'l1': net['Embed']}
net['l0']['connection']['output'].append('l1')
# Test 1
inp = data(net['l0'], '', 'l0')['l0']
temp = embed(net['l1'], [inp], 'l1')
model = Model(inp, temp['l1'])
self.assertEqual(model.layers[1].__class__.__name__, 'Embedding')
# Test 2
net['l1']['params']['input_length'] = None
net['l1']['params']['weight_filler'] = 'VarianceScaling'
inp = data(net['l0'], '', 'l0')['l0']
temp = embed(net['l1'], [inp], 'l1')
model = Model(inp, temp['l1'])
self.assertEqual(model.layers[1].__class__.__name__, 'Embedding')
# ********** Merge Layers Test **********
def embed(layer, layer_in, layerId):
out = {}
if (layer['params']['weight_filler'] in fillerMap):
embeddings_initializer = fillerMap[layer['params']['weight_filler']]
else:
embeddings_initializer = layer['params']['weight_filler']
embeddings_regularizer = regularizerMap[layer['params']['embeddings_regularizer']]
embeddings_constraint = constraintMap[layer['params']['embeddings_constraint']]
mask_zero = layer['params']['mask_zero']
if (layer['params']['input_length']):
input_length = layer['params']['input_length']
else:
input_length = None
out[layerId] = Embedding(layer['params']['input_dim'], layer['params']['num_output'],
embeddings_initializer=embeddings_initializer,
embeddings_regularizer=embeddings_regularizer,
embeddings_constraint=embeddings_constraint,
mask_zero=mask_zero, input_length=input_length)(*layer_in)
return out
# ********** Merge Layers **********
def test_highway_layers():
n_highway_layers = 5
x = Input(shape=(8,), dtype="int32")
v = Embedding(input_dim=2, output_dim=10)(x)
v = Flatten()(v)
assert hasattr(v, "_keras_shape")
v = highway_layers(v, n_layers=n_highway_layers)
output = Dense(1)(v)
model = Model(inputs=[x], outputs=[output])
assert len(model.layers) > n_highway_layers * 3
x = np.array([
[1] + [0] * 7,
[0] * 8,
[0] * 7 + [1]])
y = np.array([0, 1, 0])
model.compile("rmsprop", "mse")
model.fit(x, y, epochs=10)
pred = model.predict(x)
mean_diff = np.abs(pred - y).mean()
assert mean_diff < 0.5, pred
def create_model(numNodes, factors):
left_input = Input(shape=(1,))
right_input = Input(shape=(1,))
left_model = Sequential()
left_model.add(Embedding(input_dim=numNodes + 1, output_dim=factors, input_length=1, mask_zero=False))
left_model.add(Reshape((factors,)))
right_model = Sequential()
right_model.add(Embedding(input_dim=numNodes + 1, output_dim=factors, input_length=1, mask_zero=False))
right_model.add(Reshape((factors,)))
left_embed = left_model(left_input)
right_embed = left_model(right_input)
left_right_dot = merge([left_embed, right_embed], mode="dot", dot_axes=1, name="left_right_dot")
model = Model(input=[left_input, right_input], output=[left_right_dot])
embed_generator = Model(input=[left_input, right_input], output=[left_embed, right_embed])
return model, embed_generator
def test_tiny_concat_seq_random(self):
np.random.seed(1988)
max_features = 10
embedding_dims = 4
seq_len = 5
num_channels = 6
# Define a model
input_tensor = Input(shape = (seq_len, ))
x1 = Embedding(max_features, embedding_dims)(input_tensor)
x2 = Embedding(max_features, embedding_dims)(input_tensor)
x3 = concatenate([x1, x2], axis=1)
model = Model(inputs=[input_tensor], outputs=[x3])
# Set some random weights
model.set_weights([np.random.rand(*w.shape) for w in model.get_weights()])
# Get the coreml model
self._test_keras_model(model, one_dim_seq_flags=[True])
def test_tiny_image_captioning_feature_merge(self):
img_input_1 = Input(shape=(16,16,3))
x = Conv2D(2,(3,3))(img_input_1)
x = Flatten()(x)
img_model = Model([img_input_1], [x])
img_input = Input(shape=(16,16,3))
x = img_model(img_input)
x = Dense(8, name = 'cap_dense')(x)
x = Reshape((1,8), name = 'cap_reshape')(x)
sentence_input = Input(shape=(5,)) # max_length = 5
y = Embedding(8, 8, name = 'cap_embedding')(sentence_input)
z = concatenate([x,y], axis = 1, name = 'cap_merge')
combined_model = Model(inputs=[img_input, sentence_input], outputs=[z])
self._test_keras_model(combined_model, one_dim_seq_flags=[False, True])
def test_tiny_babi_rnn(self):
vocab_size = 10
embed_hidden_size = 8
story_maxlen = 5
query_maxlen = 5
input_tensor_1 = Input(shape=(story_maxlen,))
x1 = Embedding(vocab_size, embed_hidden_size)(input_tensor_1)
x1 = Dropout(0.3)(x1)
input_tensor_2 = Input(shape=(query_maxlen,))
x2 = Embedding(vocab_size, embed_hidden_size)(input_tensor_2)
x2 = Dropout(0.3)(x2)
x2 = LSTM(embed_hidden_size, return_sequences=False)(x2)
x2 = RepeatVector(story_maxlen)(x2)
x3 = add([x1, x2])
x3 = LSTM(embed_hidden_size, return_sequences=False)(x3)
x3 = Dropout(0.3)(x3)
x3 = Dense(vocab_size, activation='softmax')(x3)
model = Model(inputs=[input_tensor_1,input_tensor_2], outputs=[x3])
self._test_keras_model(model, one_dim_seq_flags=[True, True])
def test_merge_mask_3d():
from keras.layers import Input, merge, Embedding, SimpleRNN
from keras.models import Model
rand = lambda *shape: np.asarray(np.random.random(shape) > 0.5, dtype='int32')
# embeddings
input_a = Input(shape=(3,), dtype='int32')
input_b = Input(shape=(3,), dtype='int32')
embedding = Embedding(3, 4, mask_zero=True)
embedding_a = embedding(input_a)
embedding_b = embedding(input_b)
# rnn
rnn = SimpleRNN(3, return_sequences=True)
rnn_a = rnn(embedding_a)
rnn_b = rnn(embedding_b)
# concatenation
merged_concat = merge([rnn_a, rnn_b], mode='concat', concat_axis=-1)
model = Model([input_a, input_b], [merged_concat])
model.compile(loss='mse', optimizer='sgd')
model.fit([rand(2, 3), rand(2, 3)], [rand(2, 3, 6)])
def get_model_41(params):
embedding_weights = pickle.load(open("../data/datasets/train_data/embedding_weights_w2v-google_MSD-AG.pk","rb"))
# main sequential model
model = Sequential()
model.add(Embedding(len(embedding_weights[0]), params['embedding_dim'], input_length=params['sequence_length'],
weights=embedding_weights))
#model.add(Dropout(params['dropout_prob'][0], input_shape=(params['sequence_length'], params['embedding_dim'])))
model.add(LSTM(2048))
#model.add(Dropout(params['dropout_prob'][1]))
model.add(Dense(output_dim=params["n_out"], init="uniform"))
model.add(Activation(params['final_activation']))
logging.debug("Output CNN: %s" % str(model.output_shape))
if params['final_activation'] == 'linear':
model.add(Lambda(lambda x :K.l2_normalize(x, axis=1)))
return model
# CRNN Arch for audio
def __init__(self, widths, vocab_size=5000):
from keras.models import Sequential
from keras.layers import Embedding, Dense, TimeDistributedMerge
from keras.layers.advanced_activations import ELU
from keras.preprocessing.sequence import pad_sequences
from keras.optimizers import SGD
self.n_classes = widths[-1]
self.vocab_size = vocab_size
self.word_to_int = {}
self.int_to_word = np.ndarray(shape=(vocab_size+1,), dtype='int64')
self.model = Sequential()
self.model.add(Embedding(vocab_size, widths[0]))
self.model.add(TimeDistributedMerge(mode='ave'))
for width in widths[1:-1]:
layer = Dense(output_dim=hidden_width, init='he_normal', activation=ELU(1.0))
self.model.add(layer)
self.model.add(
Dense(
n_classes,
init='zero',
activation='softmax'))
sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
self.model.compile(loss='categorical_crossentropy', optimizer=sgd)
def bag_of_convs_model(optimizer="adam",compile=True):
main_input = Input(shape=(100,), dtype='int32', name='main_input')
embedding = Embedding(output_dim=32, input_dim=100, input_length=100,
dropout=0)(main_input)
conv1 = getconvmodel(2,256)(embedding)
conv2 = getconvmodel(3,256)(embedding)
conv3 = getconvmodel(4,256)(embedding)
conv4 = getconvmodel(5,256)(embedding)
merged = merge([conv1,conv2,conv3,conv4],mode="concat")
middle = Dense(1024,activation='relu')(merged)
middle = Dropout(0.5)(middle)
middle = Dense(1024,activation='relu')(middle)
middle = Dropout(0.5)(middle)
output = Dense(1,activation='sigmoid')(middle)
model = Model(input=main_input,output=output)
if compile:
model.compile(loss='binary_crossentropy', optimizer=optimizer)
return model
def subj_run(index_embedding, dataset, num_words=5000, embedding_len=100, max_len=50):
(x_train, y_train), (x_test, y_test) = ds.load_data(dataset, num_words)
x_train = sequence.pad_sequences(x_train, maxlen=max_len)
x_test = sequence.pad_sequences(x_test, maxlen=max_len)
model = Sequential()
model.add(Embedding(num_words, embedding_len, input_length=max_len, weights=[index_embedding]))
model.add(LSTM(max_len, dropout=0.5, recurrent_dropout=0.5))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy',
optimizer='adam',
metrics=['accuracy'])
print(model.summary())
model.fit(x_train, y_train, epochs=4, batch_size=50, verbose=2)
score, acc = model.evaluate(x_test, y_test, verbose=0)
print('Test score:', score)
print('Test accuracy:', acc)
def imdb_run(index_embedding, dataset, num_words=5000, embedding_len=100, max_len=500):
(x_train, y_train), (x_test, y_test) = ds.load_data(dataset, num_words)
x_train = sequence.pad_sequences(x_train, maxlen=max_len)
x_test = sequence.pad_sequences(x_test, maxlen=max_len)
model = Sequential()
model.add(Embedding(num_words, embedding_len, input_length=max_len, weights=[index_embedding]))
model.add(LSTM(100, dropout=0.2, recurrent_dropout=0.2))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy',
optimizer='adam',
metrics=['accuracy'])
print(model.summary())
model.fit(x_train, y_train, epochs=3, batch_size=64, verbose=2)
score, acc = model.evaluate(x_test, y_test, verbose=0)
print('Test score:', score)
print('Test accuracy:', acc)
def __init__(self, maxlen, d_L, d_C, d_D, V_C):
"""
maxlen = maximum input/output word size
d_L = language model hidden state (= context vector) size
d_C = character features (input embedding vector size)
d_D = decoder hidden state h size
V_C = character vocabulary
"""
# extend embeddings to treat zero values as zeros vectors (for y_0 = 0)
# but don't do any masking
class CharEmb(Embedding):
def call(self, x, mask=None):
y = super(CharEmb, self).call(x)
return y * K.cast(K.expand_dims(x, -1), K.floatx())
c = Input(shape=(d_L,), name='c')
y_tm1 = Input(shape=(maxlen,), name='y_tm1', dtype='int32')
ye_tm1 = CharEmb(V_C.size + 1, d_C)(y_tm1)
h = DecoderGRU(d_D, return_sequences=True)([ye_tm1, c])
s = Maxout(d_C)([h, ye_tm1, RepeatVector(maxlen)(c)])
s = Dropout(.2)(s)
c_I = ProjectionOverTime(V_C.size)(s)
super(W2C, self).__init__(input=[c, y_tm1], output=c_I, name='W2C')
def test_chain_crf(self):
vocab_size = 20
n_classes = 11
model = Sequential()
model.add(Embedding(vocab_size, n_classes))
layer = ChainCRF()
model.add(layer)
model.compile(loss=layer.loss, optimizer='sgd')
# Train first mini batch
batch_size, maxlen = 2, 2
x = np.random.randint(1, vocab_size, size=(batch_size, maxlen))
y = np.random.randint(n_classes, size=(batch_size, maxlen))
y = np.eye(n_classes)[y]
model.train_on_batch(x, y)
print(x)
print(y)
def test_merge_mask_3d():
from keras.layers import Input, merge, Embedding, SimpleRNN
from keras.models import Model
rand = lambda *shape: np.asarray(np.random.random(shape) > 0.5, dtype='int32')
# embeddings
input_a = Input(shape=(3,), dtype='int32')
input_b = Input(shape=(3,), dtype='int32')
embedding = Embedding(3, 4, mask_zero=True)
embedding_a = embedding(input_a)
embedding_b = embedding(input_b)
# rnn
rnn = SimpleRNN(3, return_sequences=True)
rnn_a = rnn(embedding_a)
rnn_b = rnn(embedding_b)
# concatenation
merged_concat = merge([rnn_a, rnn_b], mode='concat', concat_axis=-1)
model = Model([input_a, input_b], [merged_concat])
model.compile(loss='mse', optimizer='sgd')
model.fit([rand(2, 3), rand(2, 3)], [rand(2, 3, 6)])
def build_lstm(input_shape):
model = Sequential()
# model.add(Masking(input_shape=input_shape, mask_value=-1.))
model.add(Embedding(input_shape[0], 128, input_length=input_shape[1]))
model.add(Convolution1D(nb_filter=64,
filter_length=5,
border_mode='valid',
activation='relu',
subsample_length=1))
model.add(MaxPooling1D(pool_length=4))
model.add(GRU(128))
# model.add(GRU(128, return_sequences=False))
# Add dropout if overfitting
# model.add(Dropout(0.5))
model.add(Dense(1))
model.add(Activation('sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
return model