SW-ramon-dyzman/cnn/visualize.ipynb
2021-12-19 22:37:44 +01:00

55 KiB

import os
import cv2
from torch.utils.data import DataLoader, Dataset
from torch.utils.data import random_split
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import torchvision
from torch.utils.tensorboard import SummaryWriter

writer = SummaryWriter()
class TreesDataset(Dataset):
    def __init__(self, data_links) -> None:
        self.X, self.Y = readData(data_links)

    def __len__(self):
        return len(self.X)

    def __getitem__(self, index):
        return (self.X[index], self.Y[index])


class Net(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = nn.Conv2d(3, 6, 5)
        self.pool = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(6, 16, 5)
        self.fc1 = nn.Linear(3264, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 2)

    def forward(self, x):
        x = self.pool(F.relu(self.conv1(x)))
        x = self.pool(F.relu(self.conv2(x)))
        x = torch.flatten(x, 1)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x
def create_datalinks(root_dir):
    data_links = os.listdir(root_dir)
    data_links = [root_dir + "/" + x for x in data_links]
    return data_links

def preprocess(img):
    scale_percent = 10
    width = int(img.shape[1] * scale_percent / 100)
    height = int(img.shape[0] * scale_percent / 100)
    dim = (width, height)
    resized = cv2.resize(img, dim, interpolation = cv2.INTER_AREA)
    resized = torchvision.transforms.functional.to_tensor(resized)
    return resized

def readData(data_links):
    x, y = [], []
    for link in data_links:
        img = cv2.imread(link, cv2.IMREAD_COLOR)
        img = preprocess(img)
        if("ground" in link):
            label = 1
        elif("AS12" in link):
            label = 0
        else:
            label = 0
        x.append(img)
        y.append(label)

    return x, y
links_3_plus_ground = create_datalinks("new_data/AS12_3") + create_datalinks("new_data/ground")

dataset = TreesDataset(links_3_plus_ground)

train_set, test_set = random_split(dataset, [300, 50], generator=torch.Generator().manual_seed(42))

trainloader = DataLoader(train_set, batch_size=10, shuffle=True, num_workers=2)
testloader = DataLoader(test_set, batch_size=10, shuffle=True, num_workers=2)

classes = ('tree', 'ground')
epochs_num = 15

net = Net()
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)


for epoch in range(epochs_num):
    correct = 0
    total = 0
    running_loss = 0.0
    for i, data in enumerate(trainloader, 0):
        inputs, labels = data
        optimizer.zero_grad()
        outputs = net(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
        running_loss += loss.item()

        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()

        if i % 10 == 0:  
            print('[%d, %5d] loss: %.3f' %
                  (epoch + 1, i + 1, running_loss / 10))
            running_loss = 0.0

        writer.add_scalar("Loss/train", loss.item(), i + epoch)
        writer.add_scalar("Accuracy/train", correct/total, i + epoch)

print('Finished Training')
[1,     1] loss: 0.074
[1,    11] loss: 0.725
[1,    21] loss: 0.695
[2,     1] loss: 0.063
[2,    11] loss: 0.606
[2,    21] loss: 0.594
[3,     1] loss: 0.071
[3,    11] loss: 0.405
[3,    21] loss: 0.477
[4,     1] loss: 0.015
[4,    11] loss: 0.327
[4,    21] loss: 0.484
[5,     1] loss: 0.052
[5,    11] loss: 0.486
[5,    21] loss: 0.370
[6,     1] loss: 0.014
[6,    11] loss: 0.454
[6,    21] loss: 0.317
[7,     1] loss: 0.052
[7,    11] loss: 0.434
[7,    21] loss: 0.467
[8,     1] loss: 0.051
[8,    11] loss: 0.438
[8,    21] loss: 0.457
[9,     1] loss: 0.071
[9,    11] loss: 0.422
[9,    21] loss: 0.358
[10,     1] loss: 0.013
[10,    11] loss: 0.447
[10,    21] loss: 0.373
[11,     1] loss: 0.052
[11,    11] loss: 0.314
[11,    21] loss: 0.387
[12,     1] loss: 0.037
[12,    11] loss: 0.437
[12,    21] loss: 0.395
[13,     1] loss: 0.013
[13,    11] loss: 0.431
[13,    21] loss: 0.423
[14,     1] loss: 0.017
[14,    11] loss: 0.466
[14,    21] loss: 0.371
[15,     1] loss: 0.032
[15,    11] loss: 0.441
[15,    21] loss: 0.324
Finished Training
correct = 0
total = 0
i=0
with torch.no_grad():
    for data in testloader:
        images, labels = data
        outputs = net(images)
        loss = criterion(outputs, labels)
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()
        writer.add_scalar("Accuracy/test", correct/total, i + epoch)
        writer.add_scalar("Loss/test", loss.item(), i + epoch)
        i += 1

print('Accuracy : %d %%' % (100 * correct / total))
Accuracy : 84 %

images, labels = next(iter(trainloader))
grid = torchvision.utils.make_grid(images)
writer.add_image('images', grid, 0)
writer.add_graph(net, images)
writer.close()
multi = create_datalinks("new_data/multi")
multiset = TreesDataset(multi)
multiloader = DataLoader(multiset, batch_size=10, shuffle=True, num_workers=2)
criterion2 = nn.Softmax(dim=1)
correct = 0
total = 0
i=0
with torch.no_grad():
    for data in multiloader:
        images, labels = data
        outputs = net(images)
        loss = criterion2(outputs)
        loss2 = criterion(outputs, labels)
        print(loss)
        _, predicted = torch.max(outputs, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()
        writer.add_scalar("Multi/Accuracy", correct/total, i)
        writer.add_scalar("Multi/Loss", loss2.item(), i + epoch)

        i += 1

print(correct/total)
tensor([[0.8594, 0.1406],
        [0.8276, 0.1724],
        [0.8850, 0.1150],
        [0.8887, 0.1113],
        [0.8737, 0.1263],
        [0.8814, 0.1186],
        [0.8911, 0.1089],
        [0.8364, 0.1636],
        [0.8846, 0.1154],
        [0.8726, 0.1274]])
tensor([[0.8452, 0.1548],
        [0.8533, 0.1467],
        [0.8536, 0.1464],
        [0.8593, 0.1407],
        [0.8557, 0.1443],
        [0.8811, 0.1189],
        [0.8727, 0.1273],
        [0.8529, 0.1471],
        [0.9053, 0.0947],
        [0.8824, 0.1176]])
tensor([[0.8593, 0.1407],
        [0.8952, 0.1048],
        [0.8780, 0.1220],
        [0.8724, 0.1276],
        [0.8451, 0.1549],
        [0.8424, 0.1576],
        [0.8332, 0.1668],
        [0.8567, 0.1433],
        [0.8487, 0.1513],
        [0.8839, 0.1161]])
tensor([[0.8759, 0.1241],
        [0.8340, 0.1660],
        [0.9141, 0.0859],
        [0.9075, 0.0925],
        [0.8674, 0.1326],
        [0.8431, 0.1569],
        [0.8933, 0.1067],
        [0.8475, 0.1525],
        [0.8363, 0.1637],
        [0.8789, 0.1211]])
tensor([[0.8495, 0.1505],
        [0.8402, 0.1598],
        [0.8482, 0.1518],
        [0.8470, 0.1530],
        [0.8733, 0.1267],
        [0.8362, 0.1638],
        [0.8909, 0.1091],
        [0.8568, 0.1432],
        [0.8577, 0.1423],
        [0.8678, 0.1322]])
1.0
from IPython.display import Image
from torchvision import models
from torchsummary import summary
from matplotlib import pyplot
summary(net, (3, 80, 60))
link = "new_data/AS12_3/AS12_3_1.png"
----------------------------------------------------------------
        Layer (type)               Output Shape         Param #
================================================================
            Conv2d-1            [-1, 6, 76, 56]             456
         MaxPool2d-2            [-1, 6, 38, 28]               0
            Conv2d-3           [-1, 16, 34, 24]           2,416
         MaxPool2d-4           [-1, 16, 17, 12]               0
            Linear-5                  [-1, 120]         391,800
            Linear-6                   [-1, 84]          10,164
            Linear-7                    [-1, 2]             170
================================================================
Total params: 405,006
Trainable params: 405,006
Non-trainable params: 0
----------------------------------------------------------------
Input size (MB): 0.05
Forward/backward pass size (MB): 0.37
Params size (MB): 1.54
Estimated Total Size (MB): 1.97
----------------------------------------------------------------
img = cv2.imread(link, cv2.IMREAD_COLOR)
img = preprocess(img)
img = img.view(1, 3, 60, 80)

output = net.pool(F.relu(net.conv1(img)))
print(output.size())

square = 2
ix = 1
pyplot.figure(figsize=(16, 16))
with torch.no_grad():
    for _ in range(square):
        for _ in range(square):
            ax = pyplot.subplot(square, square, ix)
            ax.set_xticks([])
            ax.set_yticks([])
            pyplot.imshow(output[0, ix-1, :, :])
            ix += 1

pyplot.show()
torch.Size([1, 6, 28, 38])
img = cv2.imread(link, cv2.IMREAD_COLOR)
img = preprocess(img)
img = img.view(1, 3, 60, 80)

output = net.pool(F.relu(net.conv1(img)))
output = net.pool(F.relu(net.conv2(output)))
output.size()

square = 4
ix = 1
pyplot.figure(figsize=(16, 16))
with torch.no_grad():
    for _ in range(square):
        for _ in range(square):
            ax = pyplot.subplot(square, square, ix)
            ax.set_xticks([])
            ax.set_yticks([])
            pyplot.imshow(output[0, ix-1, :, :])
            ix += 1

pyplot.show()