Calc dims through a conv layer¶

$O = (\frac{W - K + 2P}{S}) + 1$¶

Calc dims after a max pool layer¶

$O = (\frac{W}{K})$¶

O - The output height/width
W - The input height/width
K - The kernel size
P - Padding
S - Stride

In [12]:
#model v6

class CropDetectCNN3(nn.Module):
    # initialize the class and the parameters
    def __init__(self, inp_size: int, num_classes: int):
        super(CropDetectCNN3, self).__init__()
        # convolutional layer 1 & max pool layer 1
        self.layer1 = nn.Sequential(
            nn.Conv2d(3, 64, kernel_size=11, padding=1, stride=4),
            #nn.BatchNorm2d(64, momentum=0.05, affine=True),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3)
        )

        O = int(int((inp_size - 11 + 2*1)/4) + 1)
        O = int(O/3)

        self.layer2_0 = nn.Sequential(
            #nn.BatchNorm2d(64, momentum=0.05, affine=True),
            nn.Conv2d(64, 175, kernel_size=7, padding=2, stride=1),
            nn.ReLU(inplace=True),
            #nn.BatchNorm2d(64, momentum=0.05, affine=True),
            nn.Conv2d(175, 343, kernel_size=3, padding=1, stride=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(343, 128, kernel_size=3, padding=1, stride=1),
        )
        
        self.layer2_1 = nn.Sequential(
            #nn.BatchNorm2d(64, momentum=0.05, affine=True),
            nn.Conv2d(64, 180, kernel_size=5, padding=2, stride=1),
            nn.ReLU(inplace=True),
            #nn.BatchNorm2d(64, momentum=0.05, affine=True),
            nn.Conv2d(180, 256, kernel_size=3, padding=1, stride=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(256, 128, kernel_size=7, padding=2, stride=1),
        )

        O = int((O - 7 + 2*2)/1 + 1)

        # convolutional layer 2 & max pool layer 2
        self.layer3 = nn.Sequential(
            nn.MaxPool2d(kernel_size=2),
            nn.ReLU(inplace=True),
            nn.Conv2d(256, 128, kernel_size=5, padding=2, stride=1),
        )

        O = int(O/2)
        print(O)

        #Fully connected layer
        self.fc = nn.Sequential(
            nn.ReLU(inplace=True),
            nn.Dropout(0.5),
            nn.Linear(128*O*O, 2048),
            nn.ReLU(inplace=True),
            nn.Dropout(0.5),
            nn.Linear(2048, num_classes)
        )
        self.inp_size = inp_size
        self.out_size = O

         

    # Feed forward the network
    def forward(self, x):
        #xin = x
        out = self.layer1(x)
        
        out1 = self.layer2_0(out)
        out = self.layer2_1(out)
        #print(out.shape)
        out = torch.cat([out1, out], 1)
        out = self.layer3(out)
        #print(out.shape)
        out = out.reshape(out.size(0), -1)
        #print(out.shape)
        #raise
        
        out = self.fc(out)
        return out

model = CropDetectCNN3(IMAGE_SIZE, len(train_data.class_to_idx))
print(model)
8
CropDetectCNN3(
  (layer1): Sequential(
    (0): Conv2d(3, 64, kernel_size=(11, 11), stride=(4, 4), padding=(1, 1))
    (1): ReLU(inplace=True)
    (2): MaxPool2d(kernel_size=3, stride=3, padding=0, dilation=1, ceil_mode=False)
  )
  (layer2_0): Sequential(
    (0): Conv2d(64, 175, kernel_size=(7, 7), stride=(1, 1), padding=(2, 2))
    (1): ReLU(inplace=True)
    (2): Conv2d(175, 343, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (3): ReLU(inplace=True)
    (4): Conv2d(343, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
  )
  (layer2_1): Sequential(
    (0): Conv2d(64, 180, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
    (1): ReLU(inplace=True)
    (2): Conv2d(180, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (3): ReLU(inplace=True)
    (4): Conv2d(256, 128, kernel_size=(7, 7), stride=(1, 1), padding=(2, 2))
  )
  (layer3): Sequential(
    (0): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    (1): ReLU(inplace=True)
    (2): Conv2d(256, 128, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
  )
  (fc): Sequential(
    (0): ReLU(inplace=True)
    (1): Dropout(p=0.5, inplace=False)
    (2): Linear(in_features=8192, out_features=2048, bias=True)
    (3): ReLU(inplace=True)
    (4): Dropout(p=0.5, inplace=False)
    (5): Linear(in_features=2048, out_features=10, bias=True)
  )
)
In [13]:
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)
In [20]:
folder = 'Tomato___Spider_mites Two-spotted_spider_mite'
file = '3cf4bee8-cd23-461c-b1c4-1d857b37ad76___Com.G_SpM_FL 1223_180deg.JPG'
image = f"{data_dir}/val/{folder}/{file}"
predict_file(image, model)
[0.9260930418968201, 0.0408933199942112, 0.024879394099116325, 0.0025633361656218767, 0.002464676508679986]
['Tomato___Spider_mites Two-spotted_spider_mite', 'Tomato___Late_blight', 'Tomato___healthy', 'Tomato___Leaf_Mold', 'Tomato___Septoria_leaf_spot']
No description has been provided for this image
No description has been provided for this image
In [21]:
folder = 'Tomato___Tomato_Yellow_Leaf_Curl_Virus'
file = '599329fe-867f-402a-8d37-a0c351fc2d03___YLCV_GCREC 2822.JPG'
image = f"{data_dir}/val/{folder}/{file}"
predict_file(image, model)
[0.9999997615814209, 2.1923918325228442e-07, 1.1521608556108731e-08, 9.053764959965349e-10, 8.813723084699632e-10]
['Tomato___Tomato_Yellow_Leaf_Curl_Virus', 'Tomato___Early_blight', 'Tomato___Bacterial_spot', 'Tomato___Septoria_leaf_spot', 'Tomato___Target_Spot']
No description has been provided for this image
No description has been provided for this image
In [22]:
# test

file = 'image_bacterial_spot.jpg'
image = f"dataset/test/{file}"
predict_file(image, model)
[0.9977491497993469, 0.0021879547275602818, 4.72764513688162e-05, 8.649002666061278e-06, 6.896947525092401e-06]
['Tomato___Early_blight', 'Tomato___Bacterial_spot', 'Tomato___Late_blight', 'Tomato___Tomato_Yellow_Leaf_Curl_Virus', 'Tomato___Septoria_leaf_spot']
No description has been provided for this image
No description has been provided for this image
In [23]:
# test

file = 'image_healthy.jpg'
image = f"{data_dir}/test/{file}"
predict_file(image, model)
[0.9999951124191284, 3.545002527971519e-06, 8.86273426203843e-07, 2.775699385892949e-07, 1.2637909208024212e-07]
['Tomato___healthy', 'Tomato___Leaf_Mold', 'Tomato___Late_blight', 'Tomato___Bacterial_spot', 'Tomato___Target_Spot']
No description has been provided for this image
No description has been provided for this image
In [24]:
# test

file = 'image_late_blight.jpg'
image = f"dataset/test/{file}"
predict_file(image, model)
[0.9966163039207458, 0.003338481765240431, 3.364967051311396e-05, 8.531874300388154e-06, 1.3274338925839402e-06]
['Tomato___Late_blight', 'Tomato___Early_blight', 'Tomato___Septoria_leaf_spot', 'Tomato___Target_Spot', 'Tomato___Tomato_Yellow_Leaf_Curl_Virus']
No description has been provided for this image
No description has been provided for this image
In [27]:
import os

accuracy = total = 0

true_list = []
pred = []

for (root, dirs, files) in os.walk(data_dir + "\\val"):
    if len(files) == 0:
        continue

    folder = root.split("\\")[-1]

    fol_acc = fol_tot = 0
    
    for file in files:
        image = f"{data_dir}/val/{folder}/{file}"
        ps, classes = predict(image, model, False)
        if classes[0] == folder:
            accuracy += 1
            fol_acc += 1

        true_list.append(folder)
        pred.append(classes[0])
        total += 1
        fol_tot += 1

    print(f"{folder}: {fol_acc}/{fol_tot} OR {fol_acc/fol_tot :.2f}")

print("\n")
print(f"FINAL: {accuracy}/{total} OR {accuracy/total :.2f}")
Tomato___Bacterial_spot: 418/425 OR 0.98
Tomato___Early_blight: 457/480 OR 0.95
Tomato___healthy: 480/481 OR 1.00
Tomato___Late_blight: 436/463 OR 0.94
Tomato___Leaf_Mold: 457/470 OR 0.97
Tomato___Septoria_leaf_spot: 397/436 OR 0.91
Tomato___Spider_mites Two-spotted_spider_mite: 408/435 OR 0.94
Tomato___Target_Spot: 370/457 OR 0.81
Tomato___Tomato_mosaic_virus: 442/448 OR 0.99
Tomato___Tomato_Yellow_Leaf_Curl_Virus: 480/490 OR 0.98


FINAL: 4345/4585 OR 0.95
In [21]:
from torchvision import utils
import numpy as np
import matplotlib.pyplot as plt


def vistensor(tensor, ch=0, allkernels=False, nrow=8, padding=1): 
    n,c,w,h = tensor.shape
    if allkernels: tensor = tensor.view(n*c,-1,w,h )
    elif c != 3: tensor = tensor[:,ch,:,:].unsqueeze(dim=1)

    nrow = int(tensor.shape[0] ** (1/2))
        
    rows = np.min( (tensor.shape[0]//nrow + 1, 64 )  )    
    grid = utils.make_grid(tensor, nrow=nrow, normalize=True, padding=padding)
    plt.figure( figsize=(nrow,rows) )
    plt.imshow(grid.numpy().transpose((1, 2, 0)))

def savetensor(tensor, filename, ch=0, allkernels=False, nrow=8, padding=2):
    n,c,w,h = tensor.shape
    if allkernels: tensor = tensor.view(n*c,-1,w,h )
    elif c != 3: tensor = tensor[:,ch,:,:].unsqueeze(dim=1)    
    utils.save_image(tensor, filename, nrow=nrow )


model.to(torch.device('cpu'))
kernel = model.layer1[0].weight.data.clone()
model.to(torch.device(device))
print(kernel.shape)

vistensor(kernel, ch=0, allkernels=False)

plt.axis('off')
plt.ioff()
plt.show()
torch.Size([64, 3, 11, 11])
No description has been provided for this image
In [62]:
from torch.autograd import Variable

plt.figure(figsize =(4,4))

id_ = 0

model.to(device)
print(classes[id_])
ps, classes = predict(images[id_], model)
ps = ps.cpu().detach().numpy().tolist()[0]
print(ps)
print(classes)
plot_solution(1, ps, classes)

model.to(torch.device('cpu'))
img = Variable(images[id_].unsqueeze(0), requires_grad=True)

# Squeeze tensor to numpy image
y = model.layer1[0](img)

img_conv1 = y.detach().numpy()
img_conv1 = np.squeeze(img_conv1)

fig = plt.figure(figsize=(4, 4))
plt.imshow(img_conv1.mean(axis=0))
plt.show()

nrow = int(img_conv1.shape[0] ** (1/2)) if img_conv1.shape[0] < 121 else int(121 ** 0.5)
fig = plt.figure(figsize=(8, 8))

for i in range(img_conv1.shape[0] if img_conv1.shape[0] < 121 else 121):
    #img = np.random.randint(10, size=(h,w))
    fig.add_subplot(nrow, nrow, i+1)
    plt.tick_params(left = False, right = False , labelleft = False, labelbottom = False, bottom = False)
    plt.imshow(img_conv1[i])

plt.show()

model.to(device)
""
Tomato___Septoria_leaf_spot
[0.9943591952323914, 0.005531017668545246, 9.137901361100376e-05, 1.832947600632906e-05, 1.2844788344068547e-08]
['Tomato___Septoria_leaf_spot', 'Tomato___Early_blight', 'Tomato___Target_Spot', 'Tomato___Bacterial_spot', 'Tomato___Leaf_Mold']
<Figure size 400x400 with 0 Axes>
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
Out[62]:
''
In [ ]: