#python #machine-learning #pytorch #conv-neural-network
#python #машинное обучение #pytorch #conv-neural-network
Вопрос:
Я пытаюсь создать нейронную сеть, которая имеет изображение формата L (из Lab) и выводит размеры ab. Я могу передать измерение L без проблем, но у меня возникли проблемы с пониманием того, как выводить размеры ab. Выходные данные должны иметь форму 1x2xHxW, где H и W — высота и ширина входного изображения. Вот моя сеть до сих пор:
class Model(nn.Module):
def __init__(self):
super(Model, self).__init__()
# Get the resnet18 model from torchvision.model library
self.model = models.resnet18(pretrained=True)
self.model.conv1 = nn.Conv2d(1, 64, kernel_size=7, stride=2, padding=3, bias=False)
# Replace fully connected layer of our model to a 2048 feature vector output
self.model.classifier = nn.Sequential()
# Add custom classifier layers
self.fc1 = nn.Linear(1000, 1024)
self.Dropout1 = nn.Dropout()
self.PRelU1 = nn.PReLU()
self.fc2 = nn.Linear(1024, 512)
self.Dropout2 = nn.Dropout()
self.PRelU2 = nn.PReLU()
self.fc3 = nn.Linear(512, 256)
self.Dropout3 = nn.Dropout()
self.PRelU3 = nn.PReLU()
self.fc4 = nn.Linear(256, 313)
# self.PRelU3 = nn.PReLU()
self.softmax = nn.Softmax(dim=1)
self.model_out = nn.Conv2d(313, 2, kernel_size=1, padding=0, dilation=1, stride=1, bias=False)
self.upsample4 = nn.Upsample(scale_factor=4, mode='bilinear')
def forward(self, x):
# x is our input data
x = self.model(x)
x = self.Dropout1(self.PRelU1(self.fc1(x)))
x = self.Dropout2(self.PRelU2(self.fc2(x)))
x = self.Dropout3(self.PRelU3(self.fc3(x)))
x = self.softmax(self.fc4(x))
return x
Комментарии:
1. Получение изображения, выполнение ваших функций и генерация того же изображения с вашими функциями, выполняемыми на нем, звучит как идеальная задача для
autoencoder
. Обратитесь к этому: jeremyjordan.me/autoencoders2. Архитектуры в стиле U-net , вероятно, являются наиболее популярными типами архитектуры для этого. В основном, как сеть автоэнкодера или кодировщика / декодера, но с пропуском соединений между кодировщиком и декодером.
Ответ №1:
Я действительно не знаю, что вы подразумеваете под «размерами ab», и я не уверен, что такое «формат L», но я могу рассказать вам, как использовать cnns для генерации изображений.
Обычно вы используете автоэнкодер, но это зависит от задачи. Автоэнкодер принимает изображение в качестве входных данных и, аналогично обычной классификации, уменьшает размеры. Но, в отличие от классификации, вы не сглаживаете карты объектов и не добавляете слои классификации, а снимаете с них выборки и деконвертируете их. Итак, сначала вы «кодируете» «изображение», а затем «декодируете» его. Средний слой перед началом повышения дискретизации называется узким местом. Нет плотных слоев и не требуется активаций softmax.
Вот пример того, как это будет выглядеть как модель pytorch (автоэнкодер для набора данных cifar10):
class Model(nn.Module):
def __init__(self):
super(Model, self).__init__()
""" encoder """
self.conv1 = nn.Conv2d(3, 32, kernel_size=(5, 5))
self.batchnorm1 = nn.BatchNorm2d(32)
self.conv2 = nn.Conv2d(32, 64, kernel_size=(4, 4), stride=3)
self.batchnorm2 = nn.BatchNorm2d(64)
self.conv3 = nn.Conv2d(64, 128, kernel_size=(3, 3), stride=3)
self.batchnorm3 = nn.BatchNorm2d(128)
self.maxpool2x2 = nn.MaxPool2d(2) # not in usage
""" decoder """
self.upsample2x2 = nn.Upsample(scale_factor=2) # not in usage
self.deconv1 = nn.ConvTranspose2d(128, 64, kernel_size=(3, 3), stride=3)
self.batchnorm1 = nn.BatchNorm2d(64)
self.deconv2 = nn.ConvTranspose2d(64, 32, kernel_size=(4, 4), stride=3)
self.batchnorm2 = nn.BatchNorm2d(32)
self.deconv3 = nn.ConvTranspose2d(32, 3, kernel_size=(5, 5))
self.batchnorm3 = nn.BatchNorm2d(3)
def forward(self, x, train_: bool=True, print_: bool=False, return_bottlenecks: bool=False):
""" encoder """
x = self.conv1(x)
x = self.batchnorm1(x)
x = F.relu(x)
x = self.conv2(x)
x = self.batchnorm2(x)
x = F.relu(x)
x = self.conv3(x)
x = self.batchnorm3(x)
bottlenecks = F.relu(x)
""" decoder """
x = self.deconv1(bottlenecks)
x = self.batchnorm1(x)
x = F.relu(x)
x = self.deconv2(x)
x = self.batchnorm2(x)
x = F.relu(x)
x = self.deconv3(x)
x = torch.sigmoid(x)
return x
В этом примере я не использую «maxpool» и «upsample», но это зависит от вашей модели.
Upsample
по сути, это противоположно maxpool, и вы ConvTranspose2d
также можете видеть, что это противоположно свертке (хотя на самом деле это не было бы правильным объяснением).
Итак, вы в основном хотите, чтобы часть «декодера» была противоположной (или зеркальной версией) части «кодировщика». Определение размеров, размеров ядра и т. Д. Для каждого слоя может быть довольно сложным, но вам в основном нужно настроить их так, чтобы архитектура была почти симметричной, а выходные размеры модели соответствовали размеру изображения, которое вы хотите создать.
Вот что может понравиться архитектуре «создания изображений», например:
Комментарии:
1. Спасибо за отличный ответ! Просто для пояснения, цветовое пространство Lab для изображения разбивает изображение на 3 измерения, где L — интенсивность света (оттенки серого), a для зелено-пурпурного цветового баланса и b для сине-желтого цветового баланса. Итак, в моем случае я ввожу оттенки серого и хочу вывести размеры ab. Следуя вашему примеру, у меня был бы только последний слой с 2 измерениями вместо 3 (как показано на прилагаемом изображении).