├── .gitignore ├── README.md ├── __init__.py ├── images └── ntn.png ├── neural_tensor_layer.py ├── neural_tensor_layer.pyc └── ntn_example.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | *~ 3 | *.DS_Store 4 | 5 | # Package Files # 6 | *.ear 7 | *.pyc 8 | *.o 9 | 10 | .idea 11 | /target 12 | /.settings 13 | .classpath 14 | .project 15 | /bin 16 | /build 17 | src/play/ipython/.ipynb_checkpoints/ 18 | 19 | src/main/python/anahata.egg-info/ 20 | src/main/python/build/ 21 | src/main/python/dist/ 22 | 23 | 24 | src/main/resources/kaggle/* 25 | src/main/resources/kaggle/airbnb/* 26 | src/main/resources/finefoods.txt 27 | src/main/resources/movies.txt 28 | src/main/resources/movies.txt.gz 29 | 30 | *.tar.gz 31 | *.pickle 32 | *.zip 33 | *.gz 34 | 35 | # Saved ml models 36 | *.model 37 | *.do 38 | *.npy 39 | *.h5 40 | 41 | 42 | 43 | #Compiled Lua sources 44 | luac.out 45 | 46 | # luarocks build files 47 | *.src.rock 48 | *.zip 49 | *.tar.gz 50 | *.caffemodel 51 | *.net 52 | 53 | # Object files 54 | *.o 55 | *.os 56 | *.ko 57 | *.obj 58 | *.elf 59 | 60 | anahata.iml 61 | *.iml 62 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # keras-neural-tensor-layer 2 | -------- 3 | 4 | 5 | Neural Tensor Network Implementation as a keras layer. Based on the paper 6 | [Reasoning with Neural Tensor Networks for Knowledge Base Completion](http://nlp.stanford.edu/pubs/SocherChenManningNg_NIPS2013.pdf) 7 | 8 | 9 | #### Requirements 10 | - keras === 2.0.0 11 | - tensorflow === 1.0.1 12 | - numpy, scipy 13 | 14 | 15 | ![alt tag](https://github.com/dapurv5/keras-neural-tensor-layer/blob/master/images/ntn.png) 16 | -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapurv5/keras-neural-tensor-layer/a39e928659bb9ca39524ad744a35822e3104d5ab/__init__.py -------------------------------------------------------------------------------- /images/ntn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapurv5/keras-neural-tensor-layer/a39e928659bb9ca39524ad744a35822e3104d5ab/images/ntn.png -------------------------------------------------------------------------------- /neural_tensor_layer.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import scipy.stats as stats 4 | 5 | from keras import backend as K 6 | from keras.engine.topology import Layer 7 | 8 | class NeuralTensorLayer(Layer): 9 | def __init__(self, output_dim, input_dim=None, **kwargs): 10 | self.output_dim = output_dim #k 11 | self.input_dim = input_dim #d 12 | if self.input_dim: 13 | kwargs['input_shape'] = (self.input_dim,) 14 | super(NeuralTensorLayer, self).__init__(**kwargs) 15 | 16 | 17 | def build(self, input_shape): 18 | mean = 0.0 19 | std = 1.0 20 | # W : k*d*d 21 | k = self.output_dim 22 | d = self.input_dim 23 | initial_W_values = stats.truncnorm.rvs(-2 * std, 2 * std, loc=mean, scale=std, size=(k,d,d)) 24 | initial_V_values = stats.truncnorm.rvs(-2 * std, 2 * std, loc=mean, scale=std, size=(2*d,k)) 25 | self.W = K.variable(initial_W_values) 26 | self.V = K.variable(initial_V_values) 27 | self.b = K.zeros((self.input_dim,)) 28 | self.trainable_weights = [self.W, self.V, self.b] 29 | 30 | 31 | def call(self, inputs, mask=None): 32 | if type(inputs) is not list or len(inputs) <= 1: 33 | raise Exception('BilinearTensorLayer must be called on a list of tensors ' 34 | '(at least 2). Got: ' + str(inputs)) 35 | e1 = inputs[0] 36 | e2 = inputs[1] 37 | batch_size = K.shape(e1)[0] 38 | k = self.output_dim 39 | # print([e1,e2]) 40 | feed_forward_product = K.dot(K.concatenate([e1,e2]), self.V) 41 | # print(feed_forward_product) 42 | bilinear_tensor_products = [ K.sum((e2 * K.dot(e1, self.W[0])) + self.b, axis=1) ] 43 | # print(bilinear_tensor_products) 44 | for i in range(k)[1:]: 45 | btp = K.sum((e2 * K.dot(e1, self.W[i])) + self.b, axis=1) 46 | bilinear_tensor_products.append(btp) 47 | result = K.tanh(K.reshape(K.concatenate(bilinear_tensor_products, axis=0), (batch_size, k)) + feed_forward_product) 48 | # print(result) 49 | return result 50 | 51 | 52 | def compute_output_shape(self, input_shape): 53 | # print (input_shape) 54 | batch_size = input_shape[0][0] 55 | return (batch_size, self.output_dim) 56 | -------------------------------------------------------------------------------- /neural_tensor_layer.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapurv5/keras-neural-tensor-layer/a39e928659bb9ca39524ad744a35822e3104d5ab/neural_tensor_layer.pyc -------------------------------------------------------------------------------- /ntn_example.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import math 4 | import numpy as np 5 | from sklearn.datasets import load_digits 6 | 7 | from keras import backend as K 8 | 9 | from keras.optimizers import SGD 10 | from keras.layers import Dense 11 | 12 | from keras.layers import Input 13 | from keras.models import Model 14 | 15 | from neural_tensor_layer import NeuralTensorLayer 16 | 17 | 18 | def get_data(): 19 | digits = load_digits() 20 | L = int(math.floor(digits.data.shape[0] * 0.15)) 21 | X_train = digits.data[:L] 22 | y_train = digits.target[:L] 23 | X_test = digits.data[L + 1:] 24 | y_test = digits.target[L + 1:] 25 | return X_train, y_train, X_test, y_test 26 | 27 | 28 | def main(): 29 | input1 = Input(shape=(64,), dtype='float32') 30 | input2 = Input(shape=(64,), dtype='float32') 31 | btp = NeuralTensorLayer(output_dim=32, input_dim=64)([input1, input2]) 32 | 33 | p = Dense(output_dim=1)(btp) 34 | model = Model(input=[input1, input2], output=[p]) 35 | 36 | sgd = SGD(lr=0.0000000001, decay=1e-6, momentum=0.9, nesterov=True) 37 | model.compile(loss='mean_squared_error', optimizer=sgd) 38 | X_train, Y_train, X_test, Y_test = get_data() 39 | X_train = X_train.astype(np.float32) 40 | Y_train = Y_train.astype(np.float32) 41 | X_test = X_test.astype(np.float32) 42 | Y_test = Y_test.astype(np.float32) 43 | 44 | model.fit([X_train, X_train], Y_train, nb_epoch=50, batch_size=5) 45 | score = model.evaluate([X_test, X_test], Y_test, batch_size=1) 46 | print score 47 | 48 | print K.get_value(model.layers[2].W) 49 | 50 | main() --------------------------------------------------------------------------------