J'ai remarqué à plusieurs endroits que les gens utilisent quelque chose comme ça, généralement dans des réseaux entièrement convolutionnels, des encodeurs automatiques et similaires:
model.add(UpSampling2D(size=(2,2)))
model.add(Conv2DTranspose(kernel_size=k, padding='same', strides=(1,1))
Je me demande quelle est la différence entre cela et simplement:
model.add(Conv2DTranspose(kernel_size=k, padding='same', strides=(2,2))
Les liens vers des articles expliquant cette différence sont les bienvenus.
Ici et ici vous pouvez trouver une très belle explication du fonctionnement des convolutions transposées . Pour résumer ces deux approches:
Dans votre première approche, vous suréchantillonnez d'abord votre carte des fonctionnalités:
[[1, 2], [3, 4]] -> [[1, 1, 2, 2], [1, 1, 2, 2], [3, 3, 4, 4], [3, 3, 4, 4]]
puis vous appliquez une convolution classique (comme Conv2DTranspose
avec stride=1
et padding='same'
est équivalent à Conv2D
).
Dans votre deuxième approche, vous êtes d'abord un (max) regroupant votre carte des fonctionnalités:
[[1, 2], [3, 4]] -> [[1, 0, 2, 0], [0, 0, 0, 0], [3, 0, 4, 0], [0, 0, 0, 0]]
puis appliquer une convolution classique avec filter_size
, filtres`, etc.
Le fait amusant est que - bien que ces approches soient différentes, elles partagent quelque chose en commun. Transposer la convolution est censé être l'approximation du gradient de convolution, donc la première approche est approximative sum pooling
tandis que le second max pooling
pente. Cela rend les premiers résultats pour produire des résultats légèrement plus lisses.
D'autres raisons pour lesquelles vous pourriez voir la première approche sont:
Conv2DTranspose
(et ses équivalents) sont relativement nouveaux dans keras
donc la seule façon d'effectuer un suréchantillonnage apprenant était d'utiliser Upsample2D
,keras
- François Chollet a utilisé cette approche dans n de ses tutoriels,keras
en raison de certaines API
incohérences.