Skip to content

Instantly share code, notes, and snippets.

@rmdort
Forked from slashvar/siamese_lstm.py
Created May 1, 2017 16:49
Show Gist options
  • Save rmdort/a512629fc35b14120b881e4729e9b37d to your computer and use it in GitHub Desktop.
Save rmdort/a512629fc35b14120b881e4729e9b37d to your computer and use it in GitHub Desktop.
LSTM siamese network (masking issues)
from keras import backend as K
from keras.layers import Input, Dense, merge, Dropout, Lambda, LSTM, Masking
from keras.models import Model, Sequential
from keras.optimizers import SGD, RMSprop, Adam, Nadam
from sys import argv
import argparse
import csv
import json
import numpy as np
import pickle
import random
DROPFACTOR=0.3
def core_layers(bucket_size, out_dims):
seq = Sequential()
seq.add(Masking(input_shape = (None, bucket_size), mask_value=0.0))
seq.add(LSTM(out_dims * 8, return_sequences=False,
# input_shape = (None, bucket_size),
kernel_initializer='he_normal',
dropout=DROPFACTOR, recurrent_dropout=DROPFACTOR, implementation=1))
seq.add(Dropout(DROPFACTOR))
seq.add(Dense(out_dims * 8, activation='relu', kernel_initializer='he_normal'))
seq.add(Dropout(DROPFACTOR))
seq.add(Dense(out_dims * 4, activation='relu', kernel_initializer='he_normal'))
seq.add(Dropout(DROPFACTOR))
seq.add(Dense(out_dims * 2, activation='relu', kernel_initializer='he_normal'))
seq.add(Dropout(DROPFACTOR))
seq.add(Dense(out_dims, activation='linear', kernel_initializer='he_normal'))
return seq
def euclidean_dist(vects):
x, y = vects
return K.sqrt(K.sum(K.square(x - y), axis=1, keepdims=True))
def eucl_dist_output_shape(shapes):
shape1, shape2 = shapes
return (shape1[0], 1)
def contrastive_loss(y_true, y_pred):
'''Contrastive loss from Hadsell-et-al.'06
http://yann.lecun.com/exdb/publis/pdf/hadsell-chopra-lecun-06.pdf
'''
margin = 1
return K.mean(y_true * K.square(y_pred)
+ (1 - y_true) * K.square(K.maximum(margin - y_pred, 0)))
def build_model(bucket_size, out_dims):
input1 = Input(shape=(None, bucket_size))
input2 = Input(shape=(None, bucket_size))
core = core_layers(bucket_size, out_dims)
redux1 = core(input1)
redux2 = core(input2)
distance = Lambda(euclidean_dist,
output_shape=eucl_dist_output_shape)([redux1, redux2])
model = Model(inputs=[input1, input2], outputs=distance)
rms = RMSprop()
model.compile(loss=contrastive_loss, optimizer=rms, metrics=['accuracy'])
return model, core
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment