Hello,
I have a problem with my neural network for some time.
It is made to differentiate between 4 different distances of a person to the camera by using two pictures aligned into one as an input.
The neural network does train without any problems. But if I want to test it, it just outputs one neuron all the time.
The code is the following:
import torch
import torchvision
from torchvision import transforms
from PIL import Image
from os import listdir
import random
import torch.optim as optim
from torch.autograd import Variable
import torch.nn.functional as F
import torch.nn as nn
import os
import sys
normalize = transforms.Normalize(
mean=[0.485 , 0.456 , 0.406],
std=[0.229, 0.224, 0.225]
)
transform = transforms.Compose([
transforms.Resize(512),
transforms.CenterCrop(512),
transforms.ToTensor(),
normalize])
trainingdatadirectory = 'Testdata'
testdatadirectory = 'Trainingdata'
train_data_list = []
train_data= []
target_list = []
files = listdir(trainingdatadirectory)
learning = True
loadNN = False
learningrate = 0.00001
epochs = 50
if (learning == True):
for i in range(len(listdir(trainingdatadirectory))): #insert trainingfile-directory
f = random.choice(files)
#print("\r"+f, end="")
files.remove(f)
img = Image.open(trainingdatadirectory + "/" + f) #instert trainingfile-directory
img_tensor = transform(img)
train_data_list.append(img_tensor)
isnear = 1 if 'near' in f else 0
ismiddle = 1 if 'middle' in f else 0
iswide = 1 if 'long' in f else 0
isnothing = 1 if 'none' in f else 0
target = (isnear,ismiddle,iswide, isnothing) #redo the target definition
#print("\r File: " + f + " target: " + str(target), end="")
target_list.append(target)
if len(train_data_list) >= 64:
#print(torch.stack(train_data_list).size())
train_data.append((torch.stack(train_data_list), target_list))
train_data_list = []
target_list = []
print("Loaded: " , len(train_data), ' of ', int(len(listdir(trainingdatadirectory))) / 64)
class Netz(nn.Module):
def __init__(self):
super(Netz, self).__init__()
self.conv1 = nn.Conv2d(3, 6, kernel_size=5)
self.conv2 = nn.Conv2d(6, 10, kernel_size=5)
self.conv3 = nn.Conv2d(10, 16, kernel_size=5)
self.fc1 = nn.Linear(57600, 12500)
self.fc2 = nn.Linear(12500, 1000)
self.fc3 = nn.Linear(1000, 4)
self.conv1_bn = nn.BatchNorm2d(6)
self.conv2_bn = nn.BatchNorm2d(10)
self.conv3_bn = nn.BatchNorm2d(16)
def forward(self, x):
x = self.conv1(x)
x = F.max_pool2d(x, 2)
x = self.conv1_bn(x)
x = F.relu(x)
x = self.conv2(x)
x = F.max_pool2d(x, 2)
x = self.conv2_bn(x)
x = F.relu(x)
x = self.conv3(x)
x = F.max_pool2d(x, 2)
x = self.conv3_bn(x)
x = F.relu(x)
x = x.view(-1, 57600)
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)
return torch.sigmoid(x)
model = Netz()
model.cuda()
#optimizer = optim.SGD(model.parameters(), lr=learningrate)
optimizer = optim.Adam(model.parameters(), lr=learningrate)
def train(epoch):
model.train()
batch_id = 0
for data, target in train_data:
target = torch.FloatTensor(target)
data = Variable(data)
data = data.cuda()
target = Variable(target)
target = target.cuda()
optimizer.zero_grad()
out = model(data)
criterion = F.binary_cross_entropy
loss = criterion(out, target)
loss.backward()
optimizer.step()
batch_id = batch_id + 1
print('Train Epoch : {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(epoch, batch_id * len(data) / 64, len(train_data), 100. * batch_id / len(train_data), loss.item()))
def test():
model.eval()
files = listdir(testdatadirectory)
f = random.choice(files)
print(f)
img = Image.open(testdatadirectory + '/' + f)
img_eval_Tensor = transform(img)
img_eval_Tensor.unsqueeze_(0)
print(img_eval_Tensor.size())
data = Variable(img_eval_Tensor.cuda())
out = model(data)
print(out.data.max(1, keepdim=True)[1])
#img.show()
#print(str(out))
x = input('')
if(learning == True):
if loadNN == True:
model = torch.load('net.pt')
for epoch in range(1,epochs):
train(epoch)
torch.save(model, 'net.pt')
if(learning == False):
model = torch.load('net.pt')
while 1:
test()
and here a screenshot of the output, to show you what I mean:
I hope someone can help me.