Я пытаюсь создать код, который позволит мне обобщать слои предварительно обученной модели для создания метамодели, эквивалентной удвоенной исходной модели.
Для этого Я использую сверточные слои, которые, используя концепцию размера группы, генерируют два результата, и на данный момент я хочу, чтобы остальные слои просто дублировались. Таким образом, первая половина вывода свертки будет идти на слой, например, relu 1_1, а вторая — на relu1_2.
Основная проблема, которую я обнаружил, заключается в том, что многие предварительные -Обученные сети не определяются с использованием только простых слоев, а вместо этого используют группы слоев в своей топологии.
В следующем коде:
for name, layer in model.named_children():
if (isinstance(layer, nn.Sequential) or list(layer.children())):
for subname, sublayer in layer.named_children():
Я использовал его как условие, чтобы попытаться отличить простые слои от групп слоев, но даже в этом случае в большинстве моделей существуют группы слоев, которые условие воспринимает так, как будто они были простыми слоями.
здесь я оставляю полный код:
import torch
import torch.nn as nn
import copy
from torchvision import models
from collections import OrderedDict
# Custom class for performing double convolutions with group_size
class ConvolutionalBlock(nn.Module):
def __init__(self, in_channels, out_channels, kernel_size, stride=1, padding=0, groups=2, filter_values=None, bias=True):
super(ConvolutionalBlock, self).__init__()
self.conv = nn.Conv2d(in_channels, out_channels, kernel_size, stride, padding, groups=groups, bias=bias)
if filter_values is not None:
self.initialize_manual_weights(filter_values)
else:
self.initialize_integer_weights()
# Set the weight and bias to float16 after initialization
self.conv.weight.data = self.conv.weight.data.to(torch.float16)
if self.conv.bias is not None:
self.conv.bias.data = self.conv.bias.data.to(torch.float16)
def initialize_integer_weights(self):
int_weights = torch.randint(-5, 5, self.conv.weight.shape, dtype=torch.int16, device=self.conv.weight.device)
self.conv.weight.data = int_weights.to(dtype=torch.float16) # Ensure weights are float16
if self.conv.bias is not None:
int_bias = torch.zeros(self.conv.bias.shape, dtype=torch.int16, device=self.conv.bias.device)
self.conv.bias.data = int_bias.to(dtype=torch.float16) # Ensure bias is also float16
def initialize_manual_weights(self, filter_values):
filter_tensor = torch.tensor(filter_values, dtype=torch.float16, device=self.conv.weight.device).view(self.conv.weight.shape)
self.conv.weight.data = filter_tensor # Weights are already float16
if self.conv.bias is not None:
self.conv.bias.data.fill_(0.0)
self.conv.bias.data = self.conv.bias.data.to(dtype=torch.float16) # Ensure bias is float16
def forward(self, x):
return self.conv(x)
# Function to copy and modify the model
def copy_and_modify_cnn_model(model):
modified_layers = OrderedDict()
for name, layer in model.named_children():
if (isinstance(layer, nn.Sequential) or list(layer.children())):
for subname, sublayer in layer.named_children():
if isinstance(sublayer, nn.Conv2d):
in_channels = sublayer.in_channels
out_channels = sublayer.out_channels
kernel_size = sublayer.kernel_size
stride = sublayer.stride
padding = sublayer.padding
modified_layers[subname] = ConvolutionalBlock(
in_channels=in_channels * 2,
out_channels=out_channels,
kernel_size=kernel_size,
stride=stride,
padding=padding,
groups=2
)
else:
modified_layers[subname + "_1"] = copy.deepcopy(sublayer)
modified_layers[subname + "_2"] = copy.deepcopy(sublayer)
else:
if isinstance(layer, nn.Conv2d):
in_channels = layer.in_channels
out_channels = layer.out_channels
kernel_size = layer.kernel_size
stride = layer.stride
padding = layer.padding
modified_layers[name] = ConvolutionalBlock(
in_channels=in_channels * 2,
out_channels=out_channels,
kernel_size=kernel_size,
stride=stride,
padding=padding,
groups=2
)
else:
modified_layers[name + "_1"] = copy.deepcopy(layer)
modified_layers[name + "_2"] = copy.deepcopy(layer)
new_model = nn.Sequential(modified_layers)
return new_model
# Load a pre-trained model
original_model = models.vgg16(weights=models.VGG16_Weights.IMAGENET1K_V1)
# Set the random seed for reproducibility
torch.manual_seed(0)
torch.backends.cudnn.deterministic = True
torch.backends.cudnn.benchmark = False
# Move the model to the GPU if available
device = 'cuda' if torch.cuda.is_available() else 'cpu'
original_model.to(device)
# Create the modified model
new_model = copy_and_modify_cnn_model(original_model).to(device).half() # Convert the model to float16
# Check the new model
print("modelo original")
print(original_model)
print("nuevo modelo ")
print(new_model)
# Create a synthetic input tensor
input_tensor_1 = torch.randn(1, 3, 224, 224, device=device) # Original input tensor with 3 channels
synthetic_input_tensor = torch.cat((input_tensor_1, input_tensor_1), dim=1).to(torch.float16)
# Test the output of the modified model
output_modified = new_model(synthetic_input_tensor)
print("\nOutput of the modified model:")
print(output_modified)
Напоследок я оставляю примеры при попытке выполнить код для такой модели, как resnet18 или vgg16, и где вы можете видеть, что при попытке дублировать модель есть слои, которые она не обнаруживает или группы слоев, которые он не может обнаружить как свободные слои.
Исходные слои VGG16:
В этом случае, что более сложно, слои также теряются, а другие копируются вместе как блоки, а не как отдельные слои.
Мой Главный вопрос: как я могу скопировать топологию любой предварительно обученной модели слой за слоем, независимо от того, как она определена?
Я пытаюсь создать код, который позволит мне обобщать слои предварительно обученной модели для создания метамодели, эквивалентной удвоенной исходной модели. Для этого Я использую сверточные слои, которые, используя концепцию размера группы, генерируют два результата, и на данный момент я хочу, чтобы остальные слои просто дублировались. Таким образом, первая половина вывода свертки будет идти на слой, например, relu 1_1, а вторая — на relu1_2. Основная проблема, которую я обнаружил, заключается в том, что многие предварительные -Обученные сети не определяются с использованием только простых слоев, а вместо этого используют группы слоев в своей топологии. В следующем коде: [code] for name, layer in model.named_children(): if (isinstance(layer, nn.Sequential) or list(layer.children())): for subname, sublayer in layer.named_children(): [/code] Я использовал его как условие, чтобы попытаться отличить простые слои от групп слоев, но даже в этом случае в большинстве моделей существуют группы слоев, которые условие воспринимает так, как будто они были простыми слоями. здесь я оставляю полный код: [code]import torch import torch.nn as nn import copy from torchvision import models from collections import OrderedDict
# Custom class for performing double convolutions with group_size class ConvolutionalBlock(nn.Module): def __init__(self, in_channels, out_channels, kernel_size, stride=1, padding=0, groups=2, filter_values=None, bias=True): super(ConvolutionalBlock, self).__init__() self.conv = nn.Conv2d(in_channels, out_channels, kernel_size, stride, padding, groups=groups, bias=bias)
if filter_values is not None: self.initialize_manual_weights(filter_values) else: self.initialize_integer_weights()
# Set the weight and bias to float16 after initialization self.conv.weight.data = self.conv.weight.data.to(torch.float16) if self.conv.bias is not None: self.conv.bias.data = self.conv.bias.data.to(torch.float16)
def initialize_integer_weights(self): int_weights = torch.randint(-5, 5, self.conv.weight.shape, dtype=torch.int16, device=self.conv.weight.device) self.conv.weight.data = int_weights.to(dtype=torch.float16) # Ensure weights are float16 if self.conv.bias is not None: int_bias = torch.zeros(self.conv.bias.shape, dtype=torch.int16, device=self.conv.bias.device) self.conv.bias.data = int_bias.to(dtype=torch.float16) # Ensure bias is also float16
def initialize_manual_weights(self, filter_values): filter_tensor = torch.tensor(filter_values, dtype=torch.float16, device=self.conv.weight.device).view(self.conv.weight.shape) self.conv.weight.data = filter_tensor # Weights are already float16 if self.conv.bias is not None: self.conv.bias.data.fill_(0.0) self.conv.bias.data = self.conv.bias.data.to(dtype=torch.float16) # Ensure bias is float16
def forward(self, x): return self.conv(x)
# Function to copy and modify the model def copy_and_modify_cnn_model(model): modified_layers = OrderedDict()
for name, layer in model.named_children(): if (isinstance(layer, nn.Sequential) or list(layer.children())): for subname, sublayer in layer.named_children():
Я пытаюсь создать код, который позволит мне обобщать слои предварительно обученной модели для создания метамодели, эквивалентной удвоенной исходной модели.
Для этого Я использую сверточные слои, которые, используя концепцию размера группы,...
Мой графический процессор — Rtx 3050 4 ГБ. Из-за меньшего количества видеопамяти я уменьшил размер пакета, но это все равно занимало слишком много времени, почти 1 час для каждой эпохи. Могу ли я сохранить обученную модель (.h5) и переобучить ее без...
Я впервые создаю модель CNN для классификации изображений, и я немного запутался в том, что будет формой ввода для каждого типа (1D CNN, 2D CNN, 3D CNN) и как исправить количество фильтров в слое свертки. Мои данные - 100x100x30, где 30 являются...
Нашел эти строки кода, но они, похоже, больше не работают. Кто-нибудь знает, каков обновленный синтаксис для загрузки модели iresnet100?
контекст: я редактирую существующий код Python, который использует предварительно обученная модель resnet50...
Нашел эти строки кода, но они, похоже, больше не работают. Кто-нибудь знает, каков обновленный синтаксис для загрузки модели iresnet100?
контекст: я редактирую существующий код Python, который использует предварительно обученная модель resnet50...