Logo elodees  elodees

Une IA bien-veillante pour un monde meilleur













Seuls les caractères alphabétiques accentués ou non ainsi que l'espace sont acceptés

Logo IA




Mutualisation pyramidale





Pas encore de compte ?

Inscrivez-vous pour accéder à tous les contenus




Les réseaux de neurones à convolution profonde (CNN) existants nécessitent une image d'entrée de taille fixe (par exemple, 224x224).

Cette exigence réduit la précision de la reconnaissance des images.

La mise en commun pyramidale spatiale à été créée pour éliminer cette exigence.

La nouvelle structure de réseau, appelée SPP-net, peut générer une représentation de longueur fixe quelle que soit les dimensions de l'image.

La mutualisation pyramidale est également robuste aux déformations d'objets.

SPP-net améliore toutes les méthodes de classification d'images basées sur CNN.

La puissance de SPP-net est significative dans la détection d'objets.

À l'aide de SPP-net, nous calculons les cartes de caractéristiques à partir de l'image entière une seule fois, puis nous regroupons les caractéristiques dans des régions arbitraires ou sous-images pour générer des représentations de longueur fixe pour la formation des détecteurs.

Cette méthode évite de calculer à plusieurs reprises les caractéristiques convolutives.

Dans le traitement des images, la structure de réseau SPP-net est 24 à 102 fois plus rapide que la méthode R-CNN, tout en obtenant une précision meilleure.



Image gratuite et libre de droits fournie par pexel.com



Image gratuite et libre de droits fournie par pexel.com


Pyramid Pooling implemented in PyTorch

License: MITLicenseMIT  Copyright (c) 2019 revidee


GitHub





Image gratuite et libre de droits fournie par pexel.com


keras-spp

License: MITLicenseMIT  Copyright (c) 2016 Yann Henon


GitHub



Testé sous Anaconda et Python 3.7

# This Spatial Pyramid Pooling Layer is for keras 2.2.4+ running over TensorFlow 2.0
import os
import numpy as np
import tensorflow
from tensorflow.keras import optimizers
from tensorflow.keras.datasets import mnist
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Convolution2D, Activation, MaxPooling2D, Dense, Dropout
 
from SpatialPyramidPooling import SpatialPyramidPooling
 
# Minimizes Tensorflow Logging
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
 
BATCH_SIZE = 64
NUM_CHANNELS = 1
NUM_CLASSES = 10
 
def makeModel():
	model = Sequential()
 
	# MODEL 1
	# uses tensorflow ordering. Note that we leave the image size as None to allow multiple image sizes
	model.add(Convolution2D(32, 3, NUM_CHANNELS, padding='same', input_shape=(None, None, NUM_CHANNELS)))
	model.add(Activation('relu'))
	model.add(Convolution2D(32, 3, NUM_CHANNELS, padding='same'))
	model.add(Activation('relu'))
	model.add(MaxPooling2D(pool_size=(2, 2), padding='same'))
	model.add(Convolution2D(64, 3, NUM_CHANNELS, padding='same'))
	model.add(Activation('relu'))
	model.add(Convolution2D(64, 3, NUM_CHANNELS, padding='same'))
	model.add(Activation('relu'))
	model.add(SpatialPyramidPooling([1, 2, 4]))
	model.add(Dense(NUM_CLASSES))
	model.add(Activation('softmax'))
 
	return model
 
def main():
	model=makeModel()
	model.summary()
 
	(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
	train_images = train_images.reshape(train_images.shape[0], 28, 28, 1).astype('float32')
	train_images = (train_images - 127.5) / 127.5		# Normalize the images to [-1, 1]
 
	test_images = test_images.reshape(test_images.shape[0], 28, 28, 1).astype('float32')
	test_images = (test_images - 127.5) / 127.5			# Normalize the images to [-1, 1]
 
	adam=optimizers.Adam(learning_rate=0.001, beta_1=0.9, beta_2=0.999, amsgrad=False)
	model.compile(loss='sparse_categorical_crossentropy', optimizer=adam, metrics = ["accuracy"])
	model.fit(train_images, train_labels)
 
	# results = model.evaluate(test_images, test_labels, batch_size=128)
	# print('test loss, test acc:', results)
 
	model.compile(loss='categorical_crossentropy', optimizer=adam, metrics = ["accuracy"])
	# train on 64x64x3 random images
	model.fit(np.random.rand(BATCH_SIZE, 64, 64, NUM_CHANNELS), np.zeros((BATCH_SIZE, NUM_CLASSES)))
	# train on 32x32x3 random images
	model.fit(np.random.rand(BATCH_SIZE, 32, 32, NUM_CHANNELS), np.zeros((BATCH_SIZE, NUM_CLASSES)))
 
if __name__ == '__main__':
	main()


Spatial Pyramid Pooling

Testé sous Anaconda et Python 3.7

# This Spatial Pyramid Pooling Layer is for keras 2.2.4+ running over TensorFlow 2.0
from tensorflow.python.keras.layers import Layer
import tensorflow.keras.backend as K
 
class SpatialPyramidPooling(Layer):
	"""Spatial pyramid pooling layer for 2D inputs.
	See Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition,
	K. He, X. Zhang, S. Ren, J. Sun
	# Arguments
		pool_list: list of int
			List of pooling regions to use. The length of the list is the number of pooling regions,
			each int in the list is the number of regions in that pool. For example [1,2,4] would be 3
			regions with 1, 2x2 and 4x4 max pools, so 21 outputs per feature map
	# Input shape
		4D tensor with shape:
		`(samples, channels, rows, cols)` if dim_ordering='channels_first'
		or 4D tensor with shape:
		`(samples, rows, cols, channels)` if dim_ordering='channels_last'.
	# Output shape
		2D tensor with shape:
		`(samples, channels * sum([i * i for i in pool_list])`
	"""
 
	def __init__(self, pool_list, **kwargs):
 
		self.dim_ordering = K.image_data_format()
		assert self.dim_ordering in {'channels_last', 'channels_first'}, 'dim_ordering must be in {channels_last, channels_first}'
 
		self.pool_list = pool_list
 
		self.num_outputs_per_channel = sum([i * i for i in pool_list])
 
		super(SpatialPyramidPooling, self).__init__(**kwargs)
 
	def build(self, input_shape):
		if self.dim_ordering == 'channels_first':
			self.nb_channels = input_shape[1]
		elif self.dim_ordering == 'channels_last':
			self.nb_channels = input_shape[3]
 
	def compute_output_shape(self, input_shape):
		return (input_shape[0], self.nb_channels * self.num_outputs_per_channel)
 
	def get_config(self):
		config = {'pool_list': self.pool_list}
		base_config = super(SpatialPyramidPooling, self).get_config()
		return dict(list(base_config.items()) + list(config.items()))
 
	def call(self, x, mask=None):
 
		input_shape = K.shape(x)
 
		if self.dim_ordering == 'channels_first':
			num_rows = input_shape[2]
			num_cols = input_shape[3]
		elif self.dim_ordering == 'channels_last':
			num_rows = input_shape[1]
			num_cols = input_shape[2]
 
		row_length = [K.cast(num_rows, dtype='float32') / i for i in self.pool_list]
		col_length = [K.cast(num_cols, dtype='float32') / i for i in self.pool_list]
 
		outputs = []
 
		if self.dim_ordering == 'channels_first':
			for pool_num, num_pool_regions in enumerate(self.pool_list):
				for jy in range(num_pool_regions):
					for ix in range(num_pool_regions):
						x1 = ix * col_length[pool_num]
						x2 = ix * col_length[pool_num] + col_length[pool_num]
						y1 = jy * row_length[pool_num]
						y2 = jy * row_length[pool_num] + row_length[pool_num]
 
						x1 = K.cast(K.round(x1), 'int32')
						x2 = K.cast(K.round(x2), 'int32')
						y1 = K.cast(K.round(y1), 'int32')
						y2 = K.cast(K.round(y2), 'int32')
						new_shape = [input_shape[0], input_shape[1],
									 y2 - y1, x2 - x1]
						x_crop = x[:, :, y1:y2, x1:x2]
						xm = K.reshape(x_crop, new_shape)
						pooled_val = K.max(xm, axis=(2, 3))
						outputs.append(pooled_val)
 
		elif self.dim_ordering == 'channels_last':
			for pool_num, num_pool_regions in enumerate(self.pool_list):
				for jy in range(num_pool_regions):
					for ix in range(num_pool_regions):
						x1 = ix * col_length[pool_num]
						x2 = ix * col_length[pool_num] + col_length[pool_num]
						y1 = jy * row_length[pool_num]
						y2 = jy * row_length[pool_num] + row_length[pool_num]
 
						x1 = K.cast(K.round(x1), 'int32')
						x2 = K.cast(K.round(x2), 'int32')
						y1 = K.cast(K.round(y1), 'int32')
						y2 = K.cast(K.round(y2), 'int32')
 
						new_shape = [input_shape[0], y2 - y1,
									 x2 - x1, input_shape[3]]
 
						x_crop = x[:, y1:y2, x1:x2, :]
						xm = K.reshape(x_crop, new_shape)
						pooled_val = K.max(xm, axis=(1, 2))
						outputs.append(pooled_val)
 
		if self.dim_ordering == 'channels_first':
			outputs = K.concatenate(outputs)
		elif self.dim_ordering == 'channels_last':
			# outputs = K.concatenate(outputs, axis = 1)
			outputs = K.concatenate(outputs)
			# outputs = K.reshape(outputs, (len(self.pool_list), self.num_outputs_per_channel, input_shape[0], input_shape[1]))
			# outputs = K.permute_dimensions(outputs, (3, 1, 0, 2))
			outputs = K.reshape(outputs, (input_shape[0], self.num_outputs_per_channel * self.nb_channels))
 
		return outputs


Spatial Pyramid Pooling - GitHub



Model: "sequential_1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_4 (Conv2D) (None, None, None, 32) 320
_________________________________________________________________
activation_5 (Activation) (None, None, None, 32) 0
_________________________________________________________________
conv2d_5 (Conv2D) (None, None, None, 32) 9248
_________________________________________________________________
activation_6 (Activation) (None, None, None, 32) 0
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, None, None, 32) 0
_________________________________________________________________
conv2d_6 (Conv2D) (None, None, None, 64) 18496
_________________________________________________________________
activation_7 (Activation) (None, None, None, 64) 0
_________________________________________________________________
conv2d_7 (Conv2D) (None, None, None, 64) 36928
_________________________________________________________________
activation_8 (Activation) (None, None, None, 64) 0
_________________________________________________________________
spatial_pyramid_pooling_1 (S (None, 1344) 0
_________________________________________________________________
dense_1 (Dense) (None, 10) 13450
_________________________________________________________________
activation_9 (Activation) (None, 10) 0
=================================================================
Total params: 78,442
Trainable params: 78,442
Non-trainable params: 0
_________________________________________________________________
60000/60000 [==============================] - 32s 530us/sample - loss: 0.1128 - acc: 0.9655
64/64 [==============================] - 1s 11ms/sample - loss: 0.0000e+00 - acc: 0.0000e+00
64/64 [==============================] - 0s 601us/sample - loss: 0.0000e+00 - acc: 0.0000e+00





Apprentissage profond

Apprentissage automatique












Bienvenu, je m’appelle Eric Soupet et je suis l'administrateur du site elodees.com. elodees.com est un état de l'art de l'Intelligence Artificielle et se veut collaboratif, vous pouvez dès à présent proposer du contenu tels que des articles, des événements, des tutoriels, ... alors n'hésitez pas !

Crédit des images de la plate-forme : Pixabay - Pixabay License | Pexels - Pexels License