No account yet ?
Global Average Pooling where GAP is a pooling operation designed to replace fully connected layers in classic CNNs.
Global Average Mutualization is an operation that calculates the average output of each feature map in the previous CNN layer.
This greatly reduces the data and prepares the model for the final classification layer.
Global Average Mutualization has no trainable parameters.
Tested in Anaconda and Python 3.7
import keras from keras.datasets import cifar10 from keras.models import Model from keras.layers import Input, Conv2D, GlobalAveragePooling2D, Activation, MaxPooling2D, BatchNormalization from tensorflow.keras import backend as K import numpy as np import matplotlib.pyplot as plt from PIL import Image num_classes = 10 cls_names = ['airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck'] # The data (x_train, y_train), (x_test, y_test) = cifar10.load_data() x_train = x_train.astype('float32') x_test = x_test.astype('float32') x_train /= 255 x_test /= 255 print('x_train shape:', x_train.shape) print(x_train.shape[0], 'train samples') print(x_test.shape[0], 'test samples') # Convert class vectors to binary class matrices. y_train = keras.utils.to_categorical(y_train, num_classes) y_test = keras.utils.to_categorical(y_test, num_classes) input_shape = (32, 32, 3) input_img = Input(shape=input_shape) x = Conv2D(16, (3, 3), activation='relu', padding='same')(input_img) x = BatchNormalization()(x) x = MaxPooling2D(pool_size=(2, 2))(x) x = Conv2D(32, (3, 3), activation='relu', padding='same')(x) x = BatchNormalization()(x) x = MaxPooling2D(pool_size=(2, 2))(x) x = Conv2D(32, (3, 3), activation='relu', padding='same')(x) x = BatchNormalization()(x) x = Conv2D(10, (3, 3), activation='relu', padding='same')(x) x = GlobalAveragePooling2D()(x) output_cls = Activation(activation='softmax')(x) model = Model(input_img, output_cls) model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) print(model.summary()) history = model.fit(x_train, y_train, batch_size=128, epochs=40, verbose=1, validation_data=(x_test, y_test)) plt.figure(figsize=(10, 7)) plt.plot(history.history['loss'], label='Train') plt.plot(history.history['val_loss'], label='Test') plt.title('Learning curve') plt.ylabel('Loss') plt.xlabel('Epoch') plt.legend() fmaps_fn = K.function(model.input, model.layers[-3].output) props_fn = K.function(model.input, model.layers[-1].output) def get_props_fmaps(inp): props = props_fn(inp) fmaps = fmaps_fn(inp)[0,:] return props, fmaps fig=plt.figure(figsize=(17, 17)) columns = 10 rows = 10 for i in range(rows * columns): ax = fig.add_subplot(rows, columns, i+1) plt.imshow(x_train[i]) plt.title(str(i)+ ":" + cls_names[np.argmax(y_train[i,:])]) ax.get_xaxis().set_visible(False) ax.get_yaxis().set_visible(False) plt.show() inp = x_train[7] inp = np.expand_dims(inp, axis=0) plt.figure(figsize=(2, 2)) ax = fig.add_subplot() plt.imshow(inp.squeeze()) plt.axis('off') plt.show() props, _ = get_props_fmaps(inp) print(np.argmax(props), cls_names[np.argmax(props)]) plt.plot(props.squeeze()) fig=plt.figure(figsize=(14, 7)) columns = 5 rows = 2 props, fmaps = get_props_fmaps(inp) props = np.round(props.squeeze(),3) for i in range(props.shape[0]): ax = fig.add_subplot(rows, columns, i+1) plt.imshow(inp.squeeze()) overlay = np.array(Image.fromarray((fmaps[:,:,i]).astype("uint8")).resize((32,32))) plt.imshow(overlay, vmin=0.0, vmax=np.max(fmaps), cmap="cool", alpha=0.5) plt.title(cls_names[i] + ":"+ str(props[i])) ax.get_xaxis().set_visible(False) ax.get_yaxis().set_visible(False) # plt.colorbar() plt.show()
see-inside-cnn
Copyright (c) 2020 Ibrahim Sobh
Welcome, my name is Eric Soupet and I am the administrator of the site elodees.com. elodees.com is a state of the art of Artificial Intelligence and aims to be collaborative, you can now offer content such as articles, events, tutorials, ... so don't hesitate !
Platform images credit : Pixabay - Pixabay License | Pexels - Pexels License