I have to save and load a keras model in java and then I thought I could use DL4J. The problem is that when I save my model it does not have the Embedding layer with his own weight. I have the same problem re-loading the model in keras but in this case I can create the same architecture and load only the weight of my model.
In particolar I start from an architecture like this:
Layer (type) Output Shape Param #
=================================================================
embedding_1 (Embedding) (None, 300, 300) 219184200
_________________________________________________________________
lstm_1 (LSTM) (None, 300, 256) 570368
_________________________________________________________________
dropout_1 (Dropout) (None, 300, 256) 0
_________________________________________________________________
lstm_2 (LSTM) (None, 128) 197120
_________________________________________________________________
dropout_2 (Dropout) (None, 128) 0
_________________________________________________________________
dense_1 (Dense) (None, 2) 258
=================================================================
And after save and load I get this (both in keras and in DL4J):
Layer (type) Output Shape Param #
=================================================================
embedding_1 (Embedding) (None, None, 300) 219184200
_________________________________________________________________
lstm_1 (LSTM) (None, None, 256) 570368
_________________________________________________________________
dropout_1 (Dropout) (None, None, 256) 0
_________________________________________________________________
lstm_2 (LSTM) (None, 128) 197120
_________________________________________________________________
dropout_2 (Dropout) (None, 128) 0
_________________________________________________________________
dense_1 (Dense) (None, 2) 258
=================================================================
There is a solution or a work around to have this in java? 1) Is it possible to save and load correctly the structure and the weight in keras?
2) is it possible to create a model of this type in java with DL4J or another library?
3) is it possible to implement the conversion word to Embedding in a function and then give to the neural network the input previously converted in Embedding?
4) Can i load the weights in the embedding layer in java with DL4J?
This is the code for my network:
sentence_indices = Input(shape=input_shape, dtype=np.int32)
emb_dim = 300 # embedding di 300 parole in italiano
embedding_layer = pretrained_embedding_layer(word_to_vec_map, word_to_index, emb_dim)
embeddings = embedding_layer(sentence_indices)
X = LSTM(256, return_sequences=True)(embeddings)
X = Dropout(0.15)(X)
X = LSTM(128)(X)
X = Dropout(0.15)(X)
X = Dense(num_activation, activation='softmax')(X)
model = Model(sentence_indices, X)
sequentialModel = Sequential(model.layers)
Thanks in advance.
I found out that the diffence between the Keras neural network and the DL4J neural network was due to diffenent parsing of the word2Vec (or GloVe) file. In particular loading word2Vec and then parsing to create 3 dictionary: - word2Index - index2Word - word2EmbeddingVec
from gensim.models import Word2Vec
modelW2V = Word2Vec.load('C:/Users/Alessio/Desktop/emoji_ita/embedding/glove_WIKI') # glove model
I discover two different parsing (using the same code) produce different matching for couple "index - word" and "word - index". Saving the dictionary in a json file and then load data from it was a solution for me.
Hope this can help others too.