raghakot / keras-vis

Neural network visualization toolkit for keras
https://raghakot.github.io/keras-vis
MIT License
2.98k stars 660 forks source link

all sorts of weird results and errors #38

Closed kirk86 closed 7 years ago

kirk86 commented 7 years ago

Hi man, I just found that there are a number of weird results and errors occurring when using kerfs-vis. Let's direct them one by one.

  1. Image requires to be in range [0-255] for cam, not sure though about saliency. Maybe you should handle this internally like when we use the deprocess function from vgg16.

  2. weird results occur when using either method, whether its cam, saliency, dense layer visualization or convolutional layer.

Example: screen shot 2017-06-13 at 1 18 46 pm

  1. When talking about convolution layer filter visualization your method gives output from filters in color while the model was trained on gray scale images for instance. why? Is that because it scales the images to [0-255]?

  2. Provide some examples on the documents how to produce saliency maps and dense layer visualization for MLP.

  3. If possible provide all the examples on standard dataset such as mnist & cifar. Easiest to test than huge models trained on imagenet.

  4. The draw util on images is broken doesn't work.

  5. Why there is such a discrepancy between saliency and cam screen shot 2017-06-13 at 1 58 12 pm screen shot 2017-06-13 at 1 58 30 pm

  6. Why does cam return no result in some cases and works in some others. Is that an expected behavior? screen shot 2017-06-13 at 2 00 33 pm

  7. How would you interpret those filters from dense and convolutional layers? I have no idea. To me they seem wrong?

screen shot 2017-06-13 at 2 05 57 pm screen shot 2017-06-13 at 2 15 21 pm

These are what I get with my own method. stitched_filters_4x4 stitched_filters_6x6

  1. Somewhere in the visualization.py file it throws warning because there is division by zero. /Users/user/anaconda2/lib/python2.7/site-packages/keras_vis-0.3-py2.7.egg/vis/visualization.py:247: RuntimeWarning: invalid value encountered in divide grads /= np.max(grads) /Users/user/anaconda2/lib/python2.7/site-packages/matplotlib/colors.py:496: RuntimeWarning: invalid value encountered in less cbook._putmask(xa, xa < 0.0, -1)

  2. In the gist below I provide all the issues especially in the end in the comments. It would be nice if those things in the comments could be replicated as examples to show us how they work. None of those examples in the end worked for me.

import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
from keras import backend as K
from keras.datasets import mnist
from keras.utils import np_utils
from keras.models import Model, load_model, Sequential
from keras.layers import Conv2D, Dropout, Flatten, Dense, Input
from keras.layers import BatchNormalization, Activation
from vis.visualization import visualize_cam, visualize_saliency
from vis.visualization import visualize_activation, get_num_filters
from vis.utils import utils

def vis_cam(model, img, layer_name=None, penultimate_layer_idx=None,
            mode='saliency', nb_out_imgs=5):

    if layer_name is None:
        raise Warning("You need to provide a layer name indicating the layer"
                      " index of the cam you want to compute.")
        return -1

    layer_idx = [idx for idx, layer in enumerate(model.layers)
                 if layer.name == layer_name][0]

    if np.max(img) != 255:
        img *= 255

    pred_class = np.argmax(model.predict(img))

    if mode == 'saliency':
        heatmap = visualize_saliency(model, layer_idx, [pred_class], img)
        if heatmap.shape[2] == 1:
            heatmap = heatmap.reshape(heatmap.shape[0], heatmap.shape[1])
        plt.imshow(heatmap)
        plt.show()
    if mode == 'cam':
        heatmap = visualize_cam(model, layer_idx, [pred_class], img,
                                penultimate_layer_idx)
        if heatmap.shape[3] == 1:
            heatmap = heatmap.reshape(heatmap.shape[1], heatmap.shape[2])
        elif heatmap.shape[3] == 3:
            heatmap = heatmap.reshape(heatmap.shape[1:])
        plt.imshow(heatmap)
        plt.show()
    if mode == 'conv':
        filters = np.arange(get_num_filters(model.layers[layer_idx]))
        vis_images = []
        for idx in filters:
            img = visualize_activation(model, layer_idx, filter_indices=idx)
            vis_images.append(img)

        stitched = utils.stitch_images(vis_images, cols=8)
        if stitched.shape[2] == 1:
            stitched = stitched.reshape(-1, stitched.shape[1])
        plt.figure(figsize=(60, 30))
        plt.axis('off')
        plt.imshow(stitched)
        plt.title(layer_name)
        plt.show()
    if mode == 'dense':
        del img
        vis_images = []
        for idx in xrange(nb_out_imgs):
            img = visualize_activation(model, layer_idx,
                                       filter_indices=pred_class,
                                       max_iter=500)
            vis_images.append(img)

        stitched = utils.stitch_images(vis_images)
        if stitched.shape[2] == 1:
            stitched = stitched.reshape(-1, stitched.shape[1])
        plt.figure(figsize=(60, 30))
        plt.axis('off')
        plt.imshow(stitched)
        plt.title(layer_name)
        plt.show()

def cnn(data_shape):
    inpt = Input(shape=data_shape)
    x = Dropout(0.2, input_shape=data_shape)(inpt)
    x = Conv2D(64, (8, 8), strides=(2, 2),
               padding='same', activation='relu')(inpt)
    x = Conv2D((128), (6, 6), strides=(2, 2),
               padding='valid', activation='relu')(x)
    x = Conv2D((128), (5, 5), strides=(1, 1),
               padding='valid', activation='relu')(x)
    x = Dropout(0.5)(x)
    x = Flatten()(x)
    x = Dense(10, activation='softmax')(x)
    model = Model(inpt, x)
    model.compile(optimizer='adam', loss='categorical_crossentropy',
                  metrics=['accuracy'])

    return model

def mlp(data_shape):
    model = Sequential()
    model.add(Dropout(0.5, input_shape=data_shape))
    model.add(BatchNormalization(axis=1))
    model.add(Dense(784))
    model.add(Activation('relu'))
    model.add(BatchNormalization(axis=1))
    model.add(Dense(512))
    model.add(Activation('relu'))
    model.add(Dropout(0.2))
    model.add(BatchNormalization(axis=1))
    model.add(Dense(256))
    model.add(Activation('relu'))
    model.add(Dense(10))
    model.add(Activation('softmax'))

    model.compile(loss='categorical_crossentropy',
                  optimizer='adam',
                  metrics=['accuracy'])

    return model

if __name__ == "__main__":
    sess = tf.Session()
    K.set_session(sess)
    (trX, trY), (teX, teY) = mnist.load_data()
    trX = np.expand_dims(trX, axis=3)
    teX = np.expand_dims(teX, axis=3)
    trX = trX / 255.
    teX = teX / 255.
    trY = np_utils.to_categorical(trY, 10)
    teY = np_utils.to_categorical(teY, 10)
    model = cnn(trX.shape[1:])
    model.summary()
    model.fit(trX, trY, validation_split=0.21, batch_size=128, epochs=10,
              verbose=1)
    model.save('cnn_model.hdf5')
    trX = trX.reshape(-1, 784)
    teX = teX.reshape(-1, 784)
    model = mlp(trX.shape[1:])
    model.summary()
    model.fit(trX, trY, validation_split=0.21, batch_size=128, epochs=10,
              verbose=1)
    model.save('mlp_model.hdf5')
    # plot original image
    img_idx = np.random.randint(0, 47400)
    img = trX[img_idx]
    plt.imshow(img.reshape(28, 28), cmap='gray_r')
    plt.show()
    img = np.expand_dims(img, axis=0)
    print("image shape = {}".format(img.shape))

    # Here I get all sorts of weird results with end filters or
    # activations being green in color. Saliency and cam are not
    # working as they are supposed to

    # 1. plot saliency for mlp model ==> not working
    vis_cam(model, img, 'dense_1', mode='saliency')
    # 2. plot dense layer for mlp ==> not working
    vis_cam(model, img, 'dense_1', mode='dense')
    # 3. plot dense for cnn model
    model = load_model('cnn_model.hdf5')
    vis_cam(model, img, 'dense_1', mode='dense')
    # 4. plot conv filter for cnn model
    vis_cam(model, img, 'conv2d_2', mode='conv')
    # 5. plot cam for cnn model
    vis_cam(model, img, 'dense_1', mode='cam', penultimate_layer_idx=2)
    # 6. plot saliency for cnn model
    vis_cam(model, img, 'dense_1', mode='saliency')

    sess.close()
raghakot commented 7 years ago

Thanks for the detailed description. I will get to the bottom of each one by the end of this weekend

raghakot commented 7 years ago

I added notebook examples for MNIST in examples/ folder. Hopefully, that clarifies a lot of things. Also the API changed. visualize_xxx now has a regression and class variant separated out.

Take a look at that and let me know if that works for you.

kirk86 commented 7 years ago

@raghakot Hi, sorry for posting this here. Not related to keras-vis but was hopping to get some quick feedback. You have also a repo about keras-resnet have you noticed any problems in terms of convergence. I've tried pretty much anything I can think of from reducing the learning rate to changing optimizers but nothing has worked so far. I can't make it reach above 46% accuracy. Did you had any of those issues?

raghakot commented 7 years ago

Hmm. There is a Cigar training example in there that should converge pretty well. I wonder if something broke with latest keras. In either case, feel free to open an issue there and I will take a look at it

raghakot commented 7 years ago

I haven't seen any correspondence related to this current issue. I am closing this assuming it's fixed. Feel free to reopen or create new issues if you see anything off.