python - visualization of convolutional layer in keras model -


i created model in keras (i newbie) , somehow managed train nicely. takes 300x300 images , try classify them in 2 groups.

# size of image in pixel img_rows, img_cols = 300, 300 # number of classes (here digits 1 10) nb_classes = 2 # number of convolutional filters use nb_filters = 16 # size of pooling area max pooling nb_pool = 20 # convolution kernel size nb_conv = 20  x = np.vstack([x_train, x_test]).reshape(-1, 1, img_rows, img_cols) y = np_utils.to_categorical(np.concatenate([y_train, y_test]), nb_classes)  # build model model = sequential() model.add(convolution2d(nb_filters, nb_conv, nb_conv, border_mode='valid', input_shape=(1, img_rows, img_cols))) model.add(activation('relu')) model.add(convolution2d(nb_filters, nb_conv, nb_conv)) model.add(activation('relu')) model.add(maxpooling2d(pool_size=(nb_pool, nb_pool))) model.add(dropout(0.25)) model.add(flatten()) model.add(dense(64)) model.add(activation('relu')) model.add(dropout(0.5)) model.add(dense(nb_classes)) model.add(activation('softmax'))  # run model model.compile(loss='categorical_crossentropy', optimizer='adadelta', metrics=['accuracy']) 

now visualize second convolutional layer , if possible first dense layer. "inspiration" taken keras blog. using model.summary() found out name of layers. created following frankenstein code:

from __future__ import print_function scipy.misc import imsave import numpy np import time #from keras.applications import vgg16 import keras keras import backend k  # dimensions of generated pictures each filter. img_width = 300 img_height = 300  # name of layer want visualize # (see model definition @ keras/applications/vgg16.py) layer_name = 'convolution2d_2' #layer_name = 'dense_1'  # util function convert tensor valid image def deprocess_image(x):     # normalize tensor: center on 0., ensure std 0.1     x -= x.mean()     x /= (x.std() + 1e-5)     x *= 0.1      # clip [0, 1]     x += 0.5     x = np.clip(x, 0, 1)      # convert rgb array     x *= 255     if k.image_dim_ordering() == 'th':         x = x.transpose((1, 2, 0))     x = np.clip(x, 0, 255).astype('uint8')     return x  # load model loc_json = 'my_model_short_architecture.json' loc_h5 = 'my_model_short_weights.h5'  open(loc_json, 'r') json_file:     loaded_model_json = json_file.read()  model = keras.models.model_from_json(loaded_model_json)  # load weights new model model.load_weights(loc_h5) print('model loaded.')  model.summary()  # placeholder input images input_img = model.input  # symbolic outputs of each "key" layer (we gave them unique names). layer_dict = dict([(layer.name, layer) layer in model.layers[1:]])   def normalize(x):     # utility function normalize tensor l2 norm     return x / (k.sqrt(k.mean(k.square(x))) + 1e-5)   kept_filters = [] filter_index in range(0, 200):     # scan through first 200 filters,     # there 512 of them     print('processing filter %d' % filter_index)     start_time = time.time()      # build loss function maximizes activation     # of nth filter of layer considered     layer_output = layer_dict[layer_name].output     if k.image_dim_ordering() == 'th':         loss = k.mean(layer_output[:, filter_index, :, :])     else:         loss = k.mean(layer_output[:, :, :, filter_index])       # compute gradient of input picture wrt loss     grads = k.gradients(loss, input_img)[0]      # normalization trick: normalize gradient     grads = normalize(grads)      # function returns loss , grads given input picture     iterate = k.function([input_img], [loss, grads])      # step size gradient ascent     step = 1.      # start gray image random noise     if k.image_dim_ordering() == 'th':         input_img_data = np.random.random((1, 3, img_width, img_height))     else:         input_img_data = np.random.random((1, img_width, img_height, 3))     input_img_data = (input_img_data - 0.5) * 20 + 128      # run gradient ascent 20 steps     in range(20):         loss_value, grads_value = iterate([input_img_data])         input_img_data += grads_value * step          print('current loss value:', loss_value)         if loss_value <= 0.:             # filters stuck 0, can skip them             break      # decode resulting input image     if loss_value > 0:         img = deprocess_image(input_img_data[0])         kept_filters.append((img, loss_value))     end_time = time.time()     print('filter %d processed in %ds' % (filter_index, end_time - start_time))  # stich best 64 filters on 8 x 8 grid. n = 8  # filters have highest loss assumed better-looking. # keep top 64 filters. kept_filters.sort(key=lambda x: x[1], reverse=true) kept_filters = kept_filters[:n * n]  # build black picture enough space # our 8 x 8 filters of size 128 x 128, 5px margin in between margin = 5 width = n * img_width + (n - 1) * margin height = n * img_height + (n - 1) * margin stitched_filters = np.zeros((width, height, 3))  # fill picture our saved filters in range(n):     j in range(n):         img, loss = kept_filters[i * n + j]         stitched_filters[(img_width + margin) * i: (img_width + margin) * + img_width,                          (img_height + margin) * j: (img_height + margin) * j + img_height, :] = img  # save result disk imsave('stitched_filters_%dx%d.png' % (n, n), stitched_filters) 

after executing get:

valueerror                                traceback (most recent call last) /home/user/conv_filter_visualization.py in <module>()      97     # run gradient ascent 20 steps /home/user/.local/lib/python3.4/site-packages/theano/compile/function_module.py in __call__(self, *args, **kwargs)     857         t0_fn = time.time()     858         try: --> 859             outputs = self.fn()     860         except exception:     861             if hasattr(self.fn, 'position_of_error'):  valueerror: corrmm images , kernel must have same stack size  apply node caused error: corrmm{valid, (1, 1)}(convolution2d_input_1, subtensor{::, ::, ::int64, ::int64}.0) toposort index: 8 inputs types: [tensortype(float32, 4d), tensortype(float32, 4d)] inputs shapes: [(1, 3, 300, 300), (16, 1, 20, 20)] inputs strides: [(1080000, 360000, 1200, 4), (1600, 1600, -80, -4)] inputs values: ['not shown', 'not shown'] outputs clients: [[elemwise{add,no_inplace}(corrmm{valid, (1, 1)}.0, reshape{4}.0), elemwise{composite{(i0 * (abs(i1) + i2 + i3))}}[(0, 1)](tensorconstant{(1, 1, 1, 1) of 0.5}, elemwise{add,no_inplace}.0, corrmm{valid, (1, 1)}.0, reshape{4}.0)]]  backtrace when node created(use theano flag traceback.limit=n make longer):   file "/home/user/.local/lib/python3.4/site-packages/keras/models.py", line 787, in from_config     model.add(layer)   file "/home/user/.local/lib/python3.4/site-packages/keras/models.py", line 114, in add     layer.create_input_layer(batch_input_shape, input_dtype)   file "/home/user/.local/lib/python3.4/site-packages/keras/engine/topology.py", line 341, in create_input_layer     self(x)   file "/home/user/.local/lib/python3.4/site-packages/keras/engine/topology.py", line 485, in __call__     self.add_inbound_node(inbound_layers, node_indices, tensor_indices)   file "/home/user/.local/lib/python3.4/site-packages/keras/engine/topology.py", line 543, in add_inbound_node     node.create_node(self, inbound_layers, node_indices, tensor_indices)   file "/home/user/.local/lib/python3.4/site-packages/keras/engine/topology.py", line 148, in create_node     output_tensors = to_list(outbound_layer.call(input_tensors[0], mask=input_masks[0]))   file "/home/user/.local/lib/python3.4/site-packages/keras/layers/convolutional.py", line 356, in call     filter_shape=self.w_shape)   file "/home/user/.local/lib/python3.4/site-packages/keras/backend/theano_backend.py", line 862, in conv2d     filter_shape=filter_shape) 

i guess having bad dimensions, don't know start. appreciated. thanks.

keras makes quite easy layers' weights , outputs. have @ https://keras.io/layers/about-keras-layers/ or https://keras.io/getting-started/functional-api-guide/#the-concept-of-layer-node.

you can properties weights , output of each layer.


Comments