У меня есть каталог с именем "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 о его реализации.
Любая идея будет полезна.