<jupyter_start><jupyter_text><jupyter_code>import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import torchvision
import torch.autograd
import torch.autograd.variable<jupyter_output><empty_output><jupyter_text>L'objectif de ce tp est de manipuler les objets "convolutions" et "pooling".Nous ne traiteront pas d'images réelles (car les moyens informatiques à mettre en oeuvre sont complexes). Mais nous observerons l'effet de ces objets sur des tenseurs aléatoires.EN CAS DE DOUTE CONSULTER LA DOCUMENTATION SUR https://pytorch.org/N'hésitez pas à regarder sur internet les illustrations sur la convolution/pooling avec ou sans stride et padding (par example : https://github.com/vdumoulin/conv_arithmetic).Ici, on conservera l'esprit convolution  stride 1 // pooling  stride 2. TP Author: <NAME> <EMAIL>  Les convolutions<jupyter_code>image = torch.rand((1,3,32,32))
print(image.shape)
conv = nn.Conv2d(3,5,kernel_size = (5))
print(conv.weight.shape)<jupyter_output>torch.Size([5, 3, 5, 5])<jupyter_text>**Q1 : À quoi correspondent les arguments de Conv2d ?** (regardez la doc) https://pytorch.org/docs/stable/nn.htmlconv2dtorch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True, padding_mode='zeros')<jupyter_code>imageApresConv = conv(image)
print(imageApresConv.shape)<jupyter_output>torch.Size([1, 5, 28, 28])<jupyter_text>Ici, la convolution n'avait pas de padding, la taille de l'image est modifié... Généralement, on préfère que les convolutions aient du padding pour conserver la taille de l'image<jupyter_code>convpadding = nn.Conv2d(3,5,kernel_size = (5),padding=2)
print(convpadding.weight.shape)
imageApresConvPadding = convpadding(image)
print(imageApresConvPadding.shape)<jupyter_output>torch.Size([5, 3, 5, 5])
torch.Size([1, 5, 32, 32])<jupyter_text>**Q2 : Comment transformeriez vous une image en 1 seul vecteur à l'aide d'une seule convolution ?**<jupyter_code>print("TODO")
print(image.shape)
old_channels = 3  # to have image.shape[1]*image.shape[2]*image.shape[3]
convFor1D = nn.Conv2d(image.shape[1], image.shape[1], kernel_size = (1), padding=0, stride=1 )
oneVecImg = convFor1D(image)
print(oneVecImg.shape)<jupyter_output>TODO
torch.Size([1, 3, 32, 32])
torch.Size([1, 3, 32, 32])<jupyter_text>**Q3 : Combien de poids a cette convolution (vis à vis de l'image) ? Qu'elle différence avec un neurone classique dans ce cas ?**Si l'image faisait 64x64 pixel, quelle serait la taille qu'on obtiendrait ?Pareil si l'image faisait 128x128 pixel ? (vous pouvez coder pour tester si vous n'êtes pas sur) **Q4 :**il n'y a aucun intérêt à avoir de si grosse convolution, généralement les convolutions sont petites - 3x3 avec padding - et combiné avec du pooling**Écrire une convolution 3x3 avec padding qui va donner une valeur très forte au niveau des pixels qui ont des valeurs plus fortes au dessus qu'en dessous (l'entrée est une image 1D la sortie aussi). Tester votre code sur des matrices aléatoires**<jupyter_code>print("TODO")<jupyter_output><empty_output><jupyter_text>Relu<jupyter_code>image = torch.rand((1,1,6,6))-0.5
print(image)
imagerelu = F.relu(image)
print(imagerelu)<jupyter_output><empty_output><jupyter_text>**Q5 : Que fait la fonction relu ? Combinez là avec votre convolution "dégradé de couleur vers le haut".**<jupyter_code>print("TODO")<jupyter_output><empty_output><jupyter_text>Les pooling<jupyter_code>image = torch.rand((1,3,32,32))
print(image.shape)
imagepool = F.max_pool2d(image, kernel_size=2, stride=2)
print(imagepool.shape)<jupyter_output><empty_output><jupyter_text>**Q6 : Que fait le pooling ?Quel serait le résultat sur une image 64x64 ou 128x128 ?** (vous pouvez coder pour tester si vous n'êtes pas sur) **Q7 : Transformer une image 128x128 en une image 1x1 en utilisant uniquement des des convolutions 3x3 avec padding suivi de pooling 2x2 et 1 convolution 4x4 sans padding.****Combien de poids à ce réseau ? Calculer le ratio avec 1 convolution 128x128.**<jupyter_code>print("TODO")<jupyter_output><empty_output><jupyter_text>estimation du champs recepteur d'un réseau **Q8 :** Le code suivant permet de mesurer la taille du champs recepteur des 13 première couche du réseau VGG 16 (un réseau très classique - regarder sur internet). **Qu'est ce que vous pensez que ça signifie ?**<jupyter_code>class EmptyVGG(nn.Module):
    def __init__(self):
        super(EmptyVGG, self).__init__()
        self.conv = nn.Conv2d(1,1,kernel_size = 3,padding=1,bias=False)
        self.conv.weight.data = torch.ones(1,1,3,3)

    def forward(self,x):
        x = self.conv(x)
        x = self.conv(x)
        x = F.max_pool2d(x, kernel_size=2, stride=2)
        x = self.conv(x)
        x = self.conv(x)
        x = F.max_pool2d(x, kernel_size=2, stride=2)
        x = self.conv(x)
        x = self.conv(x)
        x = self.conv(x)
        x = F.max_pool2d(x, kernel_size=2, stride=2)
        x = self.conv(x)
        x = self.conv(x)
        x = self.conv(x)
        x = F.max_pool2d(x, kernel_size=2, stride=2)
        x = self.conv(x)
        x = self.conv(x)
        x = self.conv(x)

        x = F.upsample(x,scale_factor=16)

        return x


def measureReceptivefield(model):
    x = torch.torch.zeros(1,1,601,601)
    x[0][0][0][0]=1
    x = model(x)
    i = 1
    while x[0][0][i][i]>0:
      i+=1
    return i
VGG = EmptyVGG()
print(measureReceptivefield(VGG))<jupyter_output><empty_output><jupyter_text>**Q bonus : adapter le code pour calculer le champs récepteur d'un réseau UNET  (regarder sur internet).**<jupyter_code>print("TODO")<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11706102117061021, 'fraction_numerical': 0.03273438889877246, 'mean_word_length': 4.99360341151386, 'pattern_counts': {'":': 0, '<': 47, '<?xml version=': 0, '>': 48, 'https://': 3, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '12', 'dir': 'jupyter-structured-clean-dedup', 'id': '581352', 'license': 'MIT', 'n_tokens_mistral': 2162, 'n_tokens_neox': 2058, 'n_words': 548, 'path': 'Neural_Networks_MI203_TD3.ipynb', 'repo_name': 'NataliaDiaz/colab', 'size': '5657'}