Функция потерь Pytorch, основанная на центральных точках и радиусе круга - PullRequest
0 голосов
/ 29 февраля 2020

У меня есть каталог с именем "images" с png-файлами RGB размером 128x128 (поэтому читаемое изображение имеет форму (3 128 128)) и файл "tags.txt", содержащий имя изображения, центральные точки (как x, y) и радиус окружностей для всех изображений в каталоге «images», например:

0000,   0.48 ,   0.75 ,   0.18 
0001,   0.4  ,   0.78 ,   0.19 
0002,   0.78 ,   0.6  ,   0.18 
0003,   0.76 ,   0.3  ,   0.18 
0004,   0.41 ,   0.56 ,   0.22 

Изображение подается в нейронную сеть, выходные данные которой являются центром и радиусом круга в изображении , Этот проект идентифицирует и рисует круги, представленные в изображениях RGB . В частности, каждое входное изображение содержит прямоугольник, треугольник и круг. Рассматриваемая область - это «[0,1] x [0,1]« box ».

Я создал нейронную сеть, но я борюсь с созданием функции потерь, я предполагаю, что у нее есть чем заняться с уравнением окружности, но в данный момент я использую стандартную функцию MSELoss.Я создал функции обучения и проверки, но я считаю, что из-за функции потерь она недостаточно точна и не может нарисовать круги в точные местоположения.

Мой NN выглядит следующим образом:

class CircleNet(nn.Module):    # nn.Module is parent class  
    def __init__(self):
        super(CircleNet, self).__init__()  #calls init of parent class
        #----------------------------------------------
        # implementation needed here 
        #----------------------------------------------
        #keep dimensions of input image: (I-F+2P)/S +1= (128-3+2)/1 + 1 = 128

        #RGB image = input channels = 3. Use 12 filters for first 2 convolution layers, then double
        self.conv1 = nn.Conv2d(in_channels=3, out_channels=12, kernel_size=3, stride=1, padding=1)
        self.conv2 = nn.Conv2d(in_channels=12, out_channels=12, kernel_size=3, stride=1, padding=1)
        self.conv3 = nn.Conv2d(in_channels=12, out_channels=24, kernel_size=3, stride=1, padding=1)
        self.conv4 = nn.Conv2d(in_channels=24, out_channels=32, kernel_size=3, stride=1, padding=1)

        #Pooling to reduce sizes, and dropout to prevent overfitting
        self.pool = nn.MaxPool2d(kernel_size=2)
        self.relu = nn.ReLU()

        self.drop = nn.Dropout2d(p=0.25)
        self.norm1 = nn.BatchNorm2d(12)
        self.norm2 = nn.BatchNorm2d(24)

        # There are 2 pooling layers, each with kernel size of 2. Output size: 128/(2*2) = 32
        # Have 3 output features, corresponding to x-pos, y-pos, radius. 
        self.fc = nn.Linear(in_features=32 * 32 * 32, out_features=3)

    def forward(self, x):
        """
        Feed forward through network
        Args:
            x - input to the network

        Returns "x", which is the network's output
        """

        #----------------------------------------------
        # implementation needed here 
        #----------------------------------------------
        #Conv1
        out = self.conv1(x)
        out = self.pool(out)
        out = self.relu(out)
        out = self.norm1(out)
        #Conv2
        out = self.conv2(out)
        out = self.pool(out)
        out = self.relu(out)
        out = self.norm1(out)
        #Conv3
        out = self.conv3(out)
        out = self.drop(out)
        #Conv4
        out = self.conv4(out)
        out = F.dropout(out, training=self.training)
        out = out.view(-1, 32 * 32 * 32)
        out = self.fc(out)

        return out

И моя функция потери следующая:

criterion = nn.MSELoss()

def my_loss(outputs, labels):

    """
    Args:
        outputs - output of network ([batch size, 3]) 
        labels  - desired labels  ([batch size, 3])
    """

    loss = torch.zeros(1, dtype=torch.float, requires_grad=True)
    loss = loss.to(device)
    #The point which I believe is incorrect based on the requirement
    loss = criterion(outputs, labels)

    #----------------------------------------------
    # implementation needed here 
    #----------------------------------------------

    # Observe: If you need to iterate and add certain values to loss defined above
    # you cannot write: loss +=... because this will raise the error: 
    # "Leaf variable was used in an inplace operation"
    # Instead, to avoid this error write: loss = loss + ...       

    return loss

Вывод, который я получаю, this .

И ожидаемый выход должен быть this .

Как уже упоминалось, я предполагаю, что он имеет какое-то отношение к уравнению круг, но не уверен, как я могу go о его реализации.

Любая идея будет полезна.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...