0

I am pre processing a number of images(cropped,run through the network etc) which are then stored in units. From the units i am then plotting a figure with multiple subplots displaying the activations of the image at a specific convolution layer.

What i am struggling to achieve is that, given a set of more than one images which ever the number, the figures of each image, will be displayed or saved to a directory (if that makes it easier to handle in jupyter) along with each figures subplots.

Unit of a single image that turns into a unit:

[[0.0000000e+00 0.0000000e+00 0.0000000e+00 ... 3.3075356e-01
    0.0000000e+00 0.0000000e+00]
   [0.0000000e+00 1.4396116e-01 0.0000000e+00 ... 0.0000000e+00
    0.0000000e+00 0.0000000e+00]
   [0.0000000e+00 5.4249477e-01 1.9857159e-01 ... 0.0000000e+00
    1.5366032e+00 1.0890217e+00]
   ...
   [7.5161266e-01 9.6204914e-02 6.8889879e-02 ... 1.3110014e+00
    5.4128194e-01 4.9922270e-01]
   [7.5161266e-01 9.6204914e-02 6.8889879e-02 ... 1.3110014e+00
    5.4128194e-01 4.9922270e-01]
   [7.5161266e-01 9.6204914e-02 6.8889879e-02 ... 1.3110014e+00
    5.4128194e-01 4.9922270e-01]]

The functions:

def getActivations(layer,stimuli):
    with tf.Session(graph=graph) as sess:
        #print (stimuli)
        #im=stimuli
        im=np.reshape(stimuli,[-1,224,224],order='F')#stimuli
        im=np.expand_dims(im,axis=0)

        #im=np.reshape(im,[-1,224,224],order='F')#stimuli
        #plt.imshow(im,interpolation="nearest", cmap="gray")
        #print (im)
        #for im in stimuli:
        #batch = np.array([im for i in range(1)])
        x = graph.get_tensor_by_name('prefix/data:0')
        #x2 = tf.reshape(x,[-1,224,224])
        y=graph.get_tensor_by_name(layer)
        units = sess.run(y,feed_dict={x: np.swapaxes(im,1,3)})#np.reshape(stimuli,[-1,224,224],order='F'),keep_prob:1.0})
        #print (units)
        plotNNFilter(units)



def plotNNFilter(units):
    #for a in units:

    #print ("###############################################################")
    #print (units)
    filters = units.shape[3]
    #print ("###############################################################")
    #print (filters)
    plt.figure(1,figsize=(20,20))
    n_columns = 6
    n_rows = math.ceil(filters / n_columns) + 1
    for i in range (filters):
        #plt.subplot(n_rows,n_columns, i+1)
        plt.subplot(n_rows,n_columns, i+1)
        plt.title('Filter' + str(i))
        plt.imshow(units[0,:,:,i],interpolation="nearest",cmap="gray")

I am getting this Depreciation error:

MatplotlibDeprecationWarning: Adding an axes using the same arguments as a previous axes currently reuses the earlier instance. In a future version, a new instance will always be created and returned. Meanwhile, this warning can be suppressed, and the future behavior ensured, by passing a unique label to each axes instance. warnings.warn(message, mplDeprecation, stacklevel=1)

I have seen another question with the same error warning:

Matplotlib: Adding an axes using the same arguments as a previous axes

Plotting on multiple figures with subplots in a single loop

But i think the answers do not apply to what i want to achieve? Due to having less than 10 reputation i can not attach an image. The image has 64 subplots, as many as the filters

Printing the len(units) so i can use the number and use it as an iteration over to do plt.figure(i,...) prints 1 for each individual unit.

1 Answers1

0

You could create the subplots first using fig, axes = plt.subplots(numrows, numcols). axes will then be an array of subplots which you can iterate over and plot whatever you like.

Note: The number of rows and columns must be integers

filters = units.shape[3]
n_columns = 6
n_rows = int(math.ceil(filters / n_columns) + 1)
fig, axes = plt.subplots(n_rows, n_columns, figsize=(20, 20))

for i, ax in enumerate(axes.flatten()):
    if i>=filters:
        ax.remove()
    else:
        ax.set_title('Filter' + str(i))
        ax.imshow(units[0, :, :, i], interpolation="nearest", cmap="gray")

axes is an array of subplots, so to loop through them we need to flatten this array. We then loop through them, assigning ax to each subplot and i is essentially a counter. Because not all of the subplots are being used (the last two will be empty) I check if i is greater than or equal to the number of images if i>=filters: and if that is true I remove those subplots. If it isn't true we go ahead and plot the image.

DavidG
  • 24,279
  • 14
  • 89
  • 82
  • HI @DavidG , this throws on the "fig,axes.." line a TypeError: 'float' object cannot be interpreted as an index – ProddoBaggins Apr 18 '18 at 15:11
  • @ProddoBaggins `n_rows` is a float. However, the number of rows and columns passed to `plt.subplots()` must be integers. I've updated my answer – DavidG Apr 18 '18 at 15:15
  • this produces the first(?) figure and then throws: IndexError: index 64 is out of bounds for axis 3 with size 64 – ProddoBaggins Apr 18 '18 at 15:20
  • i have counted the subplots, so it prints correctly one figure with 64 subplots then "attempts" to print another 2 before it halts wiht different dimensions than the previous subplots @DavidG – ProddoBaggins Apr 18 '18 at 15:23
  • @ProddoBaggins Can you tell me what the value of `n_rows` is (without the int() conversion)? – DavidG Apr 18 '18 at 15:24
  • -> that's the value 11.0 – ProddoBaggins Apr 18 '18 at 15:35
  • @ProddoBaggins I've updated the answer. See if that solves the problem – DavidG Apr 18 '18 at 15:46
  • yes it does! @DavidG can't thank you enough. if i want to store the plots instead(save them to directory),what change needs to happen? Also, if possible in the answer i have accepted if you can explain the for loop please – ProddoBaggins Apr 18 '18 at 15:51