from keras.models import Sequential
from keras.layers import Dense, Activation, Dropout, LSTM, Flatten, Embedding, Merge
from keras.layers.convolutional import Convolution2D, MaxPooling2D, ZeroPadding2D
import h5py

def Word2VecModel(embedding_matrix, num_words, embedding_dim, seq_length, dropout_rate):
    print "Creating text model..."
    model = Sequential()
    model.add(Embedding(num_words, embedding_dim, 
        weights=[embedding_matrix], input_length=seq_length, trainable=False))
    model.add(LSTM(output_dim=512, return_sequences=True, input_shape=(seq_length, embedding_dim)))
    model.add(Dropout(dropout_rate))
    model.add(LSTM(output_dim=512, return_sequences=False))
    model.add(Dropout(dropout_rate))
    model.add(Dense(1024, activation='tanh'))
    return model

def img_model(dropout_rate):
    print "Creating image model..."
    model = Sequential()
    model.add(Dense(1024, input_dim=4096, activation='tanh'))
    return model

def vqa_model(embedding_matrix, num_words, embedding_dim, seq_length, dropout_rate, num_classes):
    vgg_model = img_model(dropout_rate)
    lstm_model = Word2VecModel(embedding_matrix, num_words, embedding_dim, seq_length, dropout_rate)
    print "Merging final model..."
    fc_model = Sequential()
    fc_model.add(Merge([vgg_model, lstm_model], mode='mul'))
    fc_model.add(Dropout(dropout_rate))
    fc_model.add(Dense(1000, activation='tanh'))
    fc_model.add(Dropout(dropout_rate))
    fc_model.add(Dense(num_classes, activation='softmax'))
    fc_model.compile(optimizer='rmsprop', loss='categorical_crossentropy',
        metrics=['accuracy'])
    return fc_model

def VGG(weights_path=None):
    print "Creating VGG Model..."
    model = Sequential()
    model.add(ZeroPadding2D((1,1),input_shape=(3,224,224)))
    model.add(Convolution2D(64, 3, 3, activation='relu'))
    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(64, 3, 3, activation='relu'))
    model.add(MaxPooling2D((2,2), strides=(2,2)))

    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(128, 3, 3, activation='relu'))
    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(128, 3, 3, activation='relu'))
    model.add(MaxPooling2D((2,2), strides=(2,2)))

    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(256, 3, 3, activation='relu'))
    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(256, 3, 3, activation='relu'))
    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(256, 3, 3, activation='relu'))
    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(256, 3, 3, activation='relu'))
    model.add(MaxPooling2D((2,2), strides=(2,2)))

    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(512, 3, 3, activation='relu'))
    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(512, 3, 3, activation='relu'))
    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(512, 3, 3, activation='relu'))
    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(512, 3, 3, activation='relu'))
    model.add(MaxPooling2D((2,2), strides=(2,2)))

    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(512, 3, 3, activation='relu'))
    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(512, 3, 3, activation='relu'))
    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(512, 3, 3, activation='relu'))
    model.add(ZeroPadding2D((1,1)))
    model.add(Convolution2D(512, 3, 3, activation='relu'))
    model.add(MaxPooling2D((2,2), strides=(2,2)))

    model.add(Flatten())
    model.add(Dense(4096, activation='relu', name='fc1_1'))
    model.add(Dropout(0.5))
    model.add(Dense(4096, activation='relu', name='fc1_2'))
    model.add(Dropout(0.5))

    if weights_path:
        f = h5py.File(weights_path)
        for k in range(f.attrs['nb_layers']):
            if  k >= len(model.layers):
                break
            g = f['layer_{}'.format(k)]
            weights = [g['param_{}'.format(p)] for p in range(g.attrs['nb_params'])]
            model.layers[k].set_weights(weights)
            model.layers[k].trainable = False
        f.close()
        
    return model

@@ -1637,2519 +1637,4 @@
 el%0A%0A
-def VGG(weights_path=None):%0A    print %22Creating VGG Model...%22%0A    model = Sequential()%0A    model.add(ZeroPadding2D((1,1),input_shape=(3,224,224)))%0A    model.add(Convolution2D(64, 3, 3, activation='relu'))%0A    model.add(ZeroPadding2D((1,1)))%0A    model.add(Convolution2D(64, 3, 3, activation='relu'))%0A    model.add(MaxPooling2D((2,2), strides=(2,2)))%0A%0A    model.add(ZeroPadding2D((1,1)))%0A    model.add(Convolution2D(128, 3, 3, activation='relu'))%0A    model.add(ZeroPadding2D((1,1)))%0A    model.add(Convolution2D(128, 3, 3, activation='relu'))%0A    model.add(MaxPooling2D((2,2), strides=(2,2)))%0A%0A    model.add(ZeroPadding2D((1,1)))%0A    model.add(Convolution2D(256, 3, 3, activation='relu'))%0A    model.add(ZeroPadding2D((1,1)))%0A    model.add(Convolution2D(256, 3, 3, activation='relu'))%0A    model.add(ZeroPadding2D((1,1)))%0A    model.add(Convolution2D(256, 3, 3, activation='relu'))%0A    model.add(ZeroPadding2D((1,1)))%0A    model.add(Convolution2D(256, 3, 3, activation='relu'))%0A    model.add(MaxPooling2D((2,2), strides=(2,2)))%0A%0A    model.add(ZeroPadding2D((1,1)))%0A    model.add(Convolution2D(512, 3, 3, activation='relu'))%0A    model.add(ZeroPadding2D((1,1)))%0A    model.add(Convolution2D(512, 3, 3, activation='relu'))%0A    model.add(ZeroPadding2D((1,1)))%0A    model.add(Convolution2D(512, 3, 3, activation='relu'))%0A    model.add(ZeroPadding2D((1,1)))%0A    model.add(Convolution2D(512, 3, 3, activation='relu'))%0A    model.add(MaxPooling2D((2,2), strides=(2,2)))%0A%0A    model.add(ZeroPadding2D((1,1)))%0A    model.add(Convolution2D(512, 3, 3, activation='relu'))%0A    model.add(ZeroPadding2D((1,1)))%0A    model.add(Convolution2D(512, 3, 3, activation='relu'))%0A    model.add(ZeroPadding2D((1,1)))%0A    model.add(Convolution2D(512, 3, 3, activation='relu'))%0A    model.add(ZeroPadding2D((1,1)))%0A    model.add(Convolution2D(512, 3, 3, activation='relu'))%0A    model.add(MaxPooling2D((2,2), strides=(2,2)))%0A%0A    model.add(Flatten())%0A    model.add(Dense(4096, activation='relu', name='fc1_1'))%0A    model.add(Dropout(0.5))%0A    model.add(Dense(4096, activation='relu', name='fc1_2'))%0A    model.add(Dropout(0.5))%0A%0A    if weights_path:%0A        f = h5py.File(weights_path)%0A        for k in range(f.attrs%5B'nb_layers'%5D):%0A            if  k %3E= len(model.layers):%0A                break%0A            g = f%5B'layer_%7B%7D'.format(k)%5D%0A            weights = %5Bg%5B'param_%7B%7D'.format(p)%5D for p in range(g.attrs%5B'nb_params'%5D)%5D%0A            model.layers%5Bk%5D.set_weights(weights)%0A            model.layers%5Bk%5D.trainable = False%0A        f.close()%0A        %0A    return model%0A

remove vgg model; since not used;