jannatulferdaws commited on
Commit
c3c087d
·
verified ·
1 Parent(s): 242a31d

update README.md

Browse files
Files changed (1) hide show
  1. README.md +377 -7
README.md CHANGED
@@ -6,35 +6,405 @@ tags:
6
  - code
7
  ---
8
 
9
- # Title:
10
- Image Classification of Grapevine Leaves.
11
 
12
  ## Introduction:
13
  In this project, we are trying to build a model using **PyTorch**, a powerful deep learning framework, for the image classification of five distinct types of grapevine leaves. Our objective is to harness the flexibility and efficiency of PyTorch to develop a robust neural network model. By training on a dataset of grapevine leaf images, our approach seeks to achieve accurate classification, enabling the differentiation of various grapevine varieties. The dataset contains 5 classes of grapevine leaves. The classes are :- Black Rot, Esca (Black Measles), Healthy, Leaf Blight (Isariopsis Leaf Spot), and Leaf Blight (Black Dead Arm). The dataset contains 1000 images of grapevine leaves. The dataset is divided into 80% training set and 20% test set. The model is trained on the training set and tested on the test set. The model is trained for 10 epochs. We have taken our dataset from the kaggle dataset https://www.kaggle.com/datasets/muratkokludataset/grapevine-leaves-image-dataset?resource=download. It uses the *gradio* SDK to create a simple UI for the Image Classifier of the Grapevine Leaves model. This exploration not only demonstrates the potential of PyTorch in image classification but also contributes to the advancement of viticulture through enhanced leaf identification capabilities.
14
 
15
  ### Model Architecture:
16
  The model is trained on the `MobileNetV2` architecture. MobileNetV2 is a convolutional neural network design aimed at achieving high performance on mobile devices. The MobileNetV2 model architecture for image classification of grapevine leaves in PyTorch consists of a series of convolutional layers, batch normalization, and rectified linear unit (ReLU) activations. The key components include depthwise separable convolutions, which enhance efficiency. The model utilizes Inverted Residual blocks, containing a combination of 3x3 depthwise separable convolutions and 1x1 pointwise convolutions. The final layers involve global average pooling and a fully connected layer for classification. The output size of the last linear layer should be adjusted based on the specific number of classes in the grapevine leaves dataset.
17
- [More Information Needed]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
 
19
  ## How to Guide:
20
 
21
  - **Pre-trained Model:**
22
  We have trained a model using a deep learning framework 'PyTorch'. Alternatively, you can use a pre-trained model and fine-tune it on your grapevine leaves dataset.
 
 
23
 
24
- - **Load the Model:**
25
- We have load the pre-trained model using 'torch.load'.
26
 
27
  - **Preprocess Input Image:**
28
  We have preprocess the input image to match the format expected by the model. It involved resizing, cropping, and normalizing the image.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
 
30
  - **Inference:**
31
  We have passed the preprocessed image through the model to obtain predictions. The output will be a probability distribution over the different classes.
32
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  - **Post-process Results:**
34
  Depending on the model's architecture, the post-process the results obtained the final classification extracting the class with the highest probability or considering top-k predictions.
35
-
 
 
 
 
36
  - **Display or Use Results:**
37
  We have used gradio UI library to display the classification results. We can Select an image from the dropdown menu and click on the `Submit` button or drag and drop an image in the box. The model will classified the image into one of the 5 classes of grapevine leaves.
 
 
38
 
39
  Use the code below to get started with the model.
40
  https://huggingface.co/spaces/jannatulferdaws/amrin_gradio_grapevine.
 
6
  - code
7
  ---
8
 
9
+ # Image Classification of Grapevine Leaves.
 
10
 
11
  ## Introduction:
12
  In this project, we are trying to build a model using **PyTorch**, a powerful deep learning framework, for the image classification of five distinct types of grapevine leaves. Our objective is to harness the flexibility and efficiency of PyTorch to develop a robust neural network model. By training on a dataset of grapevine leaf images, our approach seeks to achieve accurate classification, enabling the differentiation of various grapevine varieties. The dataset contains 5 classes of grapevine leaves. The classes are :- Black Rot, Esca (Black Measles), Healthy, Leaf Blight (Isariopsis Leaf Spot), and Leaf Blight (Black Dead Arm). The dataset contains 1000 images of grapevine leaves. The dataset is divided into 80% training set and 20% test set. The model is trained on the training set and tested on the test set. The model is trained for 10 epochs. We have taken our dataset from the kaggle dataset https://www.kaggle.com/datasets/muratkokludataset/grapevine-leaves-image-dataset?resource=download. It uses the *gradio* SDK to create a simple UI for the Image Classifier of the Grapevine Leaves model. This exploration not only demonstrates the potential of PyTorch in image classification but also contributes to the advancement of viticulture through enhanced leaf identification capabilities.
13
 
14
  ### Model Architecture:
15
  The model is trained on the `MobileNetV2` architecture. MobileNetV2 is a convolutional neural network design aimed at achieving high performance on mobile devices. The MobileNetV2 model architecture for image classification of grapevine leaves in PyTorch consists of a series of convolutional layers, batch normalization, and rectified linear unit (ReLU) activations. The key components include depthwise separable convolutions, which enhance efficiency. The model utilizes Inverted Residual blocks, containing a combination of 3x3 depthwise separable convolutions and 1x1 pointwise convolutions. The final layers involve global average pooling and a fully connected layer for classification. The output size of the last linear layer should be adjusted based on the specific number of classes in the grapevine leaves dataset.
16
+
17
+ ```bash
18
+ MobileNetV2(
19
+ (features): Sequential(
20
+ (0): Conv2dNormActivation(
21
+ (0): Conv2d(3, 32, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
22
+ (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
23
+ (2): ReLU6(inplace=True)
24
+ )
25
+ (1): InvertedResidual(
26
+ (conv): Sequential(
27
+ (0): Conv2dNormActivation(
28
+ (0): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=32, bias=False)
29
+ (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
30
+ (2): ReLU6(inplace=True)
31
+ )
32
+ (1): Conv2d(32, 16, kernel_size=(1, 1), stride=(1, 1), bias=False)
33
+ (2): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
34
+ )
35
+ )
36
+ (2): InvertedResidual(
37
+ (conv): Sequential(
38
+ (0): Conv2dNormActivation(
39
+ (0): Conv2d(16, 96, kernel_size=(1, 1), stride=(1, 1), bias=False)
40
+ (1): BatchNorm2d(96, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
41
+ (2): ReLU6(inplace=True)
42
+ )
43
+ (1): Conv2dNormActivation(
44
+ (0): Conv2d(96, 96, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), groups=96, bias=False)
45
+ (1): BatchNorm2d(96, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
46
+ (2): ReLU6(inplace=True)
47
+ )
48
+ (2): Conv2d(96, 24, kernel_size=(1, 1), stride=(1, 1), bias=False)
49
+ (3): BatchNorm2d(24, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
50
+ )
51
+ )
52
+ (3): InvertedResidual(
53
+ (conv): Sequential(
54
+ (0): Conv2dNormActivation(
55
+ (0): Conv2d(24, 144, kernel_size=(1, 1), stride=(1, 1), bias=False)
56
+ (1): BatchNorm2d(144, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
57
+ (2): ReLU6(inplace=True)
58
+ )
59
+ (1): Conv2dNormActivation(
60
+ (0): Conv2d(144, 144, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=144, bias=False)
61
+ (1): BatchNorm2d(144, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
62
+ (2): ReLU6(inplace=True)
63
+ )
64
+ (2): Conv2d(144, 24, kernel_size=(1, 1), stride=(1, 1), bias=False)
65
+ (3): BatchNorm2d(24, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
66
+ )
67
+ )
68
+ (4): InvertedResidual(
69
+ (conv): Sequential(
70
+ (0): Conv2dNormActivation(
71
+ (0): Conv2d(24, 144, kernel_size=(1, 1), stride=(1, 1), bias=False)
72
+ (1): BatchNorm2d(144, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
73
+ (2): ReLU6(inplace=True)
74
+ )
75
+ (1): Conv2dNormActivation(
76
+ (0): Conv2d(144, 144, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), groups=144, bias=False)
77
+ (1): BatchNorm2d(144, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
78
+ (2): ReLU6(inplace=True)
79
+ )
80
+ (2): Conv2d(144, 32, kernel_size=(1, 1), stride=(1, 1), bias=False)
81
+ (3): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
82
+ )
83
+ )
84
+ (5): InvertedResidual(
85
+ (conv): Sequential(
86
+ (0): Conv2dNormActivation(
87
+ (0): Conv2d(32, 192, kernel_size=(1, 1), stride=(1, 1), bias=False)
88
+ (1): BatchNorm2d(192, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
89
+ (2): ReLU6(inplace=True)
90
+ )
91
+ (1): Conv2dNormActivation(
92
+ (0): Conv2d(192, 192, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=192, bias=False)
93
+ (1): BatchNorm2d(192, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
94
+ (2): ReLU6(inplace=True)
95
+ )
96
+ (2): Conv2d(192, 32, kernel_size=(1, 1), stride=(1, 1), bias=False)
97
+ (3): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
98
+ )
99
+ )
100
+ (6): InvertedResidual(
101
+ (conv): Sequential(
102
+ (0): Conv2dNormActivation(
103
+ (0): Conv2d(32, 192, kernel_size=(1, 1), stride=(1, 1), bias=False)
104
+ (1): BatchNorm2d(192, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
105
+ (2): ReLU6(inplace=True)
106
+ )
107
+ (1): Conv2dNormActivation(
108
+ (0): Conv2d(192, 192, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=192, bias=False)
109
+ (1): BatchNorm2d(192, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
110
+ (2): ReLU6(inplace=True)
111
+ )
112
+ (2): Conv2d(192, 32, kernel_size=(1, 1), stride=(1, 1), bias=False)
113
+ (3): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
114
+ )
115
+ )
116
+ (7): InvertedResidual(
117
+ (conv): Sequential(
118
+ (0): Conv2dNormActivation(
119
+ (0): Conv2d(32, 192, kernel_size=(1, 1), stride=(1, 1), bias=False)
120
+ (1): BatchNorm2d(192, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
121
+ (2): ReLU6(inplace=True)
122
+ )
123
+ (1): Conv2dNormActivation(
124
+ (0): Conv2d(192, 192, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), groups=192, bias=False)
125
+ (1): BatchNorm2d(192, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
126
+ (2): ReLU6(inplace=True)
127
+ )
128
+ (2): Conv2d(192, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
129
+ (3): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
130
+ )
131
+ )
132
+ (8): InvertedResidual(
133
+ (conv): Sequential(
134
+ (0): Conv2dNormActivation(
135
+ (0): Conv2d(64, 384, kernel_size=(1, 1), stride=(1, 1), bias=False)
136
+ (1): BatchNorm2d(384, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
137
+ (2): ReLU6(inplace=True)
138
+ )
139
+ (1): Conv2dNormActivation(
140
+ (0): Conv2d(384, 384, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=384, bias=False)
141
+ (1): BatchNorm2d(384, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
142
+ (2): ReLU6(inplace=True)
143
+ )
144
+ (2): Conv2d(384, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
145
+ (3): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
146
+ )
147
+ )
148
+ (9): InvertedResidual(
149
+ (conv): Sequential(
150
+ (0): Conv2dNormActivation(
151
+ (0): Conv2d(64, 384, kernel_size=(1, 1), stride=(1, 1), bias=False)
152
+ (1): BatchNorm2d(384, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
153
+ (2): ReLU6(inplace=True)
154
+ )
155
+ (1): Conv2dNormActivation(
156
+ (0): Conv2d(384, 384, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=384, bias=False)
157
+ (1): BatchNorm2d(384, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
158
+ (2): ReLU6(inplace=True)
159
+ )
160
+ (2): Conv2d(384, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
161
+ (3): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
162
+ )
163
+ )
164
+ (10): InvertedResidual(
165
+ (conv): Sequential(
166
+ (0): Conv2dNormActivation(
167
+ (0): Conv2d(64, 384, kernel_size=(1, 1), stride=(1, 1), bias=False)
168
+ (1): BatchNorm2d(384, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
169
+ (2): ReLU6(inplace=True)
170
+ )
171
+ (1): Conv2dNormActivation(
172
+ (0): Conv2d(384, 384, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=384, bias=False)
173
+ (1): BatchNorm2d(384, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
174
+ (2): ReLU6(inplace=True)
175
+ )
176
+ (2): Conv2d(384, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
177
+ (3): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
178
+ )
179
+ )
180
+ (11): InvertedResidual(
181
+ (conv): Sequential(
182
+ (0): Conv2dNormActivation(
183
+ (0): Conv2d(64, 384, kernel_size=(1, 1), stride=(1, 1), bias=False)
184
+ (1): BatchNorm2d(384, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
185
+ (2): ReLU6(inplace=True)
186
+ )
187
+ (1): Conv2dNormActivation(
188
+ (0): Conv2d(384, 384, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=384, bias=False)
189
+ (1): BatchNorm2d(384, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
190
+ (2): ReLU6(inplace=True)
191
+ )
192
+ (2): Conv2d(384, 96, kernel_size=(1, 1), stride=(1, 1), bias=False)
193
+ (3): BatchNorm2d(96, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
194
+ )
195
+ )
196
+ (12): InvertedResidual(
197
+ (conv): Sequential(
198
+ (0): Conv2dNormActivation(
199
+ (0): Conv2d(96, 576, kernel_size=(1, 1), stride=(1, 1), bias=False)
200
+ (1): BatchNorm2d(576, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
201
+ (2): ReLU6(inplace=True)
202
+ )
203
+ (1): Conv2dNormActivation(
204
+ (0): Conv2d(576, 576, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=576, bias=False)
205
+ (1): BatchNorm2d(576, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
206
+ (2): ReLU6(inplace=True)
207
+ )
208
+ (2): Conv2d(576, 96, kernel_size=(1, 1), stride=(1, 1), bias=False)
209
+ (3): BatchNorm2d(96, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
210
+ )
211
+ )
212
+ (13): InvertedResidual(
213
+ (conv): Sequential(
214
+ (0): Conv2dNormActivation(
215
+ (0): Conv2d(96, 576, kernel_size=(1, 1), stride=(1, 1), bias=False)
216
+ (1): BatchNorm2d(576, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
217
+ (2): ReLU6(inplace=True)
218
+ )
219
+ (1): Conv2dNormActivation(
220
+ (0): Conv2d(576, 576, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=576, bias=False)
221
+ (1): BatchNorm2d(576, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
222
+ (2): ReLU6(inplace=True)
223
+ )
224
+ (2): Conv2d(576, 96, kernel_size=(1, 1), stride=(1, 1), bias=False)
225
+ (3): BatchNorm2d(96, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
226
+ )
227
+ )
228
+ (14): InvertedResidual(
229
+ (conv): Sequential(
230
+ (0): Conv2dNormActivation(
231
+ (0): Conv2d(96, 576, kernel_size=(1, 1), stride=(1, 1), bias=False)
232
+ (1): BatchNorm2d(576, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
233
+ (2): ReLU6(inplace=True)
234
+ )
235
+ (1): Conv2dNormActivation(
236
+ (0): Conv2d(576, 576, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), groups=576, bias=False)
237
+ (1): BatchNorm2d(576, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
238
+ (2): ReLU6(inplace=True)
239
+ )
240
+ (2): Conv2d(576, 160, kernel_size=(1, 1), stride=(1, 1), bias=False)
241
+ (3): BatchNorm2d(160, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
242
+ )
243
+ )
244
+ (15): InvertedResidual(
245
+ (conv): Sequential(
246
+ (0): Conv2dNormActivation(
247
+ (0): Conv2d(160, 960, kernel_size=(1, 1), stride=(1, 1), bias=False)
248
+ (1): BatchNorm2d(960, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
249
+ (2): ReLU6(inplace=True)
250
+ )
251
+ (1): Conv2dNormActivation(
252
+ (0): Conv2d(960, 960, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=960, bias=False)
253
+ (1): BatchNorm2d(960, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
254
+ (2): ReLU6(inplace=True)
255
+ )
256
+ (2): Conv2d(960, 160, kernel_size=(1, 1), stride=(1, 1), bias=False)
257
+ (3): BatchNorm2d(160, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
258
+ )
259
+ )
260
+ (16): InvertedResidual(
261
+ (conv): Sequential(
262
+ (0): Conv2dNormActivation(
263
+ (0): Conv2d(160, 960, kernel_size=(1, 1), stride=(1, 1), bias=False)
264
+ (1): BatchNorm2d(960, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
265
+ (2): ReLU6(inplace=True)
266
+ )
267
+ (1): Conv2dNormActivation(
268
+ (0): Conv2d(960, 960, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=960, bias=False)
269
+ (1): BatchNorm2d(960, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
270
+ (2): ReLU6(inplace=True)
271
+ )
272
+ (2): Conv2d(960, 160, kernel_size=(1, 1), stride=(1, 1), bias=False)
273
+ (3): BatchNorm2d(160, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
274
+ )
275
+ )
276
+ (17): InvertedResidual(
277
+ (conv): Sequential(
278
+ (0): Conv2dNormActivation(
279
+ (0): Conv2d(160, 960, kernel_size=(1, 1), stride=(1, 1), bias=False)
280
+ (1): BatchNorm2d(960, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
281
+ (2): ReLU6(inplace=True)
282
+ )
283
+ (1): Conv2dNormActivation(
284
+ (0): Conv2d(960, 960, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=960, bias=False)
285
+ (1): BatchNorm2d(960, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
286
+ (2): ReLU6(inplace=True)
287
+ )
288
+ (2): Conv2d(960, 320, kernel_size=(1, 1), stride=(1, 1), bias=False)
289
+ (3): BatchNorm2d(320, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
290
+ )
291
+ )
292
+ (18): Conv2dNormActivation(
293
+ (0): Conv2d(320, 1280, kernel_size=(1, 1), stride=(1, 1), bias=False)
294
+ (1): BatchNorm2d(1280, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
295
+ (2): ReLU6(inplace=True)
296
+ )
297
+ )
298
+ (classifier): Sequential(
299
+ (0): Dropout(p=0.2, inplace=False)
300
+ (1): Linear(in_features=1280, out_features=1000, bias=True)
301
+ )
302
+ )
303
+ ```
304
 
305
  ## How to Guide:
306
 
307
  - **Pre-trained Model:**
308
  We have trained a model using a deep learning framework 'PyTorch'. Alternatively, you can use a pre-trained model and fine-tune it on your grapevine leaves dataset.
309
+ ```python
310
+ model = mobilenet_v2(pretrained=True)
311
 
312
+ ```
 
313
 
314
  - **Preprocess Input Image:**
315
  We have preprocess the input image to match the format expected by the model. It involved resizing, cropping, and normalizing the image.
316
+ ```python
317
+ transform = transforms.Compose([
318
+ transforms.RandomResizedCrop(224),
319
+ transforms.RandomHorizontalFlip(),
320
+ transforms.ToTensor(),
321
+ transforms.Normalize([0.485,0.456,0.406],[0.229,0.224,0.225])
322
+ ])
323
+ ```
324
+ ```python
325
+ training_set = ImageFolder('../data/train', transform=transform)
326
+ test_set = ImageFolder('../data/test', transform=transform)
327
+ val_set = ImageFolder('../data/val', transform=transform)
328
+ ```
329
+
330
+ - **Train the Model:**
331
+ We have load the pre-trained model using 'torch.load'.
332
+ ```python
333
+ # train the model
334
+ for epoch in range(epochs):
335
+ model.train()
336
+ for batch_idx, (data, target) in enumerate(train_loader):
337
+ optimizer.zero_grad()
338
+ output = model(data)
339
+ print("Out: ", [a.argmax().item() for a in output])
340
+ print("Target: ", target)
341
+ loss = loss_fn(output, target)
342
+ loss.backward()
343
+ optimizer.step()
344
+ if batch_idx % 10 == 0:
345
+ print('Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
346
+ epoch, batch_idx * len(data), len(train_loader.dataset),
347
+ 100. * batch_idx / len(train_loader), loss.item()
348
+ ))
349
+
350
+ # test the model
351
+ model.eval()
352
+ test_loss = 0
353
+ correct = 0
354
+ with torch.no_grad():
355
+ for data, target in test_loader:
356
+ output = model(data)
357
+ test_loss += loss_fn(output, target).item()
358
+ pred = output.argmax(dim=1, keepdim=True)
359
+ correct += pred.eq(target.view_as(pred)).sum().item()
360
+
361
+ test_loss /= len(test_loader.dataset)
362
+ print('\nTest set: Avg. loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
363
+ test_loss, correct, len(test_loader.dataset),
364
+ 100. * correct / len(test_loader.dataset)
365
+ ))
366
+ ```
367
+
368
 
369
  - **Inference:**
370
  We have passed the preprocessed image through the model to obtain predictions. The output will be a probability distribution over the different classes.
371
+ ```batch
372
+ Out: [2, 3, 1, 1, 0, 4, 0, 2]
373
+ Target: tensor([2, 3, 1, 1, 0, 2, 1, 2])
374
+ Epoch: 0 [0/400 (0%)] Loss: 0.918071
375
+ Out: [3, 3, 4, 2, 2, 0, 1, 4]
376
+ Target: tensor([3, 3, 4, 0, 0, 0, 1, 4])
377
+ Out: [1, 4, 4, 1, 4, 4, 2, 3]
378
+ Target: tensor([1, 4, 4, 1, 4, 4, 2, 3])
379
+ Out: [4, 2, 4, 0, 1, 3, 3, 1]
380
+ Target: tensor([4, 2, 4, 0, 2, 3, 3, 2])
381
+ Out: [0, 2, 3, 4, 1, 4, 3, 1]
382
+ Target: tensor([1, 1, 3, 1, 1, 4, 3, 1])
383
+ Out: [4, 2, 0, 0, 4, 4, 1, 3]
384
+ Target: tensor([0, 2, 0, 0, 4, 2, 0, 3])
385
+ Out: [3, 1, 1, 4, 4, 3, 0, 1]
386
+ Target: tensor([2, 2, 1, 2, 4, 3, 0, 1])
387
+ Out: [2, 4, 3, 1, 1, 0, 4, 3]
388
+ Target: tensor([2, 1, 3, 1, 1, 0, 4, 3])
389
+ Out: [4, 4, 1, 1, 4, 2, 0, 3]
390
+ Target: tensor([4, 3, 1, 1, 4, 2, 0, 3])
391
+ Out: [1, 0, 0, 4, 3, 2, 3, 2]
392
+ Target: tensor([2, 0, 2, 4, 3, 2, 3, 2])
393
+ Out: [2, 2, 0, 3, 1, 4, 0, 4]
394
+ Target: tensor([2, 2, 0, 0, 1, 4, 0, 3])
395
+ Epoch: 0 [80/400 (20%)] Loss: 0.715335
396
+ ```
397
  - **Post-process Results:**
398
  Depending on the model's architecture, the post-process the results obtained the final classification extracting the class with the highest probability or considering top-k predictions.
399
+ We have saved the model using
400
+ ```python
401
+ model_scripted = torch.jit.script(model)
402
+ model_scripted.save('../models/mobilenet.pt')
403
+ ```
404
  - **Display or Use Results:**
405
  We have used gradio UI library to display the classification results. We can Select an image from the dropdown menu and click on the `Submit` button or drag and drop an image in the box. The model will classified the image into one of the 5 classes of grapevine leaves.
406
+ ![image/png](https://huggingface.co/jannatulferdaws/dl-project1/blob/main/images/UI%20input.png)
407
+ ![image/png](https://huggingface.co/jannatulferdaws/dl-project1/blob/main/images/UI.png)
408
 
409
  Use the code below to get started with the model.
410
  https://huggingface.co/spaces/jannatulferdaws/amrin_gradio_grapevine.