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']
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']
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']
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']
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']
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])
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>
Out[62]:
''
In [ ]: