neural network - train - Cómo convertir capas FC pretrabadas a capas CONV en Pytorch
pytorch mnist tutorial (2)
Quiero convertir un CNN preentrenado (como VGG-16) en una red completamente convolucional en Pytorch. ¿Como lo puedo hacer?
Cualquier sugerencia sería útil.
con suerte no es demasiado tarde. No estoy del todo seguro de qué partes desea conservar, pero si desea manipular un modelo preformado o volver a utilizar partes de él, mi enfoque sería el siguiente:
Descargue el modelo preentrenado, por ejemplo
import torch import torch.nn as nn from torchvision import models model = models.resnet101(pretrained=True)
Extraiga las partes que le interesen y cree un nuevo modelo a partir de estas partes, por ejemplo
list(model.modules()) # to inspect the modules of your model my_model = nn.Sequential(*list(model.modules())[:-1]) # strips off last linear layer
Por supuesto, puede extraer y reutilizar cualquier parte del modelo que desee, así como agregar nuevos módulos, simplemente modifique la lista en consecuencia.
Puede hacerlo de la siguiente manera (ver comentarios para la descripción):
import torch
import torch.nn as nn
from torchvision import models
# 1. LOAD PRE-TRAINED VGG16
model = models.vgg16(pretrained=True)
# 2. GET CONV LAYERS
features = model.features
# 3. GET FULLY CONNECTED LAYERS
fcLayers = nn.Sequential(
# stop at last layer
*list(model.classifier.children())[:-1]
)
# 4. CONVERT FULLY CONNECTED LAYERS TO CONVOLUTIONAL LAYERS
### convert first fc layer to conv layer with 512x7x7 kernel
fc = fcLayers[0].state_dict()
in_ch = 512
out_ch = fc["weight"].size(0)
firstConv = nn.Conv2d(in_ch, out_ch, 7, 7)
### get the weights from the fc layer
firstConv.load_state_dict({"weight":fc["weight"].view(out_ch, in_ch, 7, 7),
"bias":fc["bias"]})
# CREATE A LIST OF CONVS
convList = [firstConv]
# Similarly convert the remaining linear layers to conv layers
for layer in enumerate(fcLayers[1:]):
if isinstance(module, nn.Linear):
# Convert the nn.Linear to nn.Conv
fc = module.state_dict()
in_ch = fc["weight"].size(1)
out_ch = fc["weight"].size(0)
conv = nn.Conv2d(in_ch, out_ch, 1, 1)
conv.load_state_dict({"weight":fc["weight"].view(out_ch, in_ch, 1, 1),
"bias":fc["bias"]})
convList += [conv]
else:
# Append other layers such as ReLU and Dropout
convList += [layer]
# Set the conv layers as a nn.Sequential module
convLayers = nn.Sequential(*convList)