IsmatS commited on
Commit
ddf9b49
·
verified ·
1 Parent(s): 22038ab

Upload folder using huggingface_hub

Browse files
crop_desease_detection.ipynb ADDED
The diff for this file is too large to render. See raw diff
 
crop_desease_detection.py ADDED
@@ -0,0 +1,601 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """crop_desease_detection.ipynb
3
+
4
+ Automatically generated by Colab.
5
+
6
+ Original file is located at
7
+ https://colab.research.google.com/drive/1PCO8YxMl3tqzsbMVP1iiSylwED-u_VfW
8
+ """
9
+
10
+
11
+
12
+
13
+
14
+
15
+
16
+ # Complete Pipeline for Tree Disease Detection with PDT Dataset
17
+
18
+ # Cell 1: Install required packages
19
+ !pip install ultralytics torch torchvision opencv-python matplotlib
20
+ !pip install huggingface_hub
21
+
22
+ import os
23
+ import shutil
24
+ import zipfile
25
+ from ultralytics import YOLO
26
+ import torch
27
+ import cv2
28
+ import matplotlib.pyplot as plt
29
+ import numpy as np
30
+ from huggingface_hub import snapshot_download
31
+ from IPython.display import Image, display
32
+
33
+ # Cell 2: Download the PDT dataset from HuggingFace
34
+ print("Downloading PDT dataset from HuggingFace...")
35
+
36
+ try:
37
+ dataset_path = snapshot_download(
38
+ repo_id='qwer0213/PDT_dataset',
39
+ repo_type='dataset',
40
+ local_dir='/content/PDT_dataset',
41
+ resume_download=True
42
+ )
43
+ print(f"Dataset downloaded to: {dataset_path}")
44
+ except Exception as e:
45
+ print(f"Error downloading dataset: {e}")
46
+
47
+ # Cell 3: Find and extract the zip file
48
+ print("\nLooking for zip file in downloaded dataset...")
49
+
50
+ # Find the zip file
51
+ zip_file_path = None
52
+ for root, dirs, files in os.walk('/content/PDT_dataset'):
53
+ for file in files:
54
+ if file.endswith('.zip'):
55
+ zip_file_path = os.path.join(root, file)
56
+ print(f"Found zip file: {zip_file_path}")
57
+ break
58
+ if zip_file_path:
59
+ break
60
+
61
+ if not zip_file_path:
62
+ print("No zip file found in the downloaded dataset!")
63
+ else:
64
+ # Extract the zip file
65
+ extract_path = '/content/PDT_dataset_extracted'
66
+ os.makedirs(extract_path, exist_ok=True)
67
+
68
+ print(f"Extracting {zip_file_path} to {extract_path}")
69
+ with zipfile.ZipFile(zip_file_path, 'r') as zip_ref:
70
+ zip_ref.extractall(extract_path)
71
+ print("Extraction completed!")
72
+
73
+ # Cell 4: Explore the extracted dataset structure
74
+ print("\nExploring dataset structure...")
75
+
76
+ def explore_dataset_structure(base_path):
77
+ """Explore and find the actual dataset structure"""
78
+ dataset_info = {
79
+ 'yolo_txt_path': None,
80
+ 'voc_xml_path': None,
81
+ 'train_path': None,
82
+ 'val_path': None,
83
+ 'test_path': None
84
+ }
85
+
86
+ for root, dirs, files in os.walk(base_path):
87
+ # Look for YOLO_txt directory
88
+ if 'YOLO_txt' in root:
89
+ dataset_info['yolo_txt_path'] = root
90
+ print(f"Found YOLO_txt at: {root}")
91
+
92
+ # Check for train/val/test
93
+ for split in ['train', 'val', 'test']:
94
+ split_path = os.path.join(root, split)
95
+ if os.path.exists(split_path):
96
+ dataset_info[f'{split}_path'] = split_path
97
+ print(f"Found {split} at: {split_path}")
98
+
99
+ # Look for VOC_xml directory
100
+ if 'VOC_xml' in root:
101
+ dataset_info['voc_xml_path'] = root
102
+ print(f"Found VOC_xml at: {root}")
103
+
104
+ return dataset_info
105
+
106
+ dataset_info = explore_dataset_structure('/content/PDT_dataset_extracted')
107
+
108
+ # Cell 5: Setup YOLO dataset from the PDT dataset
109
+ def setup_yolo_dataset(dataset_info, output_dir='/content/PDT_yolo'):
110
+ """Setup YOLO dataset from the extracted PDT dataset"""
111
+ print(f"\nSetting up YOLO dataset to {output_dir}")
112
+
113
+ # Clean output directory
114
+ if os.path.exists(output_dir):
115
+ shutil.rmtree(output_dir)
116
+ os.makedirs(output_dir, exist_ok=True)
117
+
118
+ # Create directory structure
119
+ for split in ['train', 'val', 'test']:
120
+ os.makedirs(os.path.join(output_dir, 'images', split), exist_ok=True)
121
+ os.makedirs(os.path.join(output_dir, 'labels', split), exist_ok=True)
122
+
123
+ total_copied = 0
124
+
125
+ # Process each split
126
+ for split in ['train', 'val', 'test']:
127
+ split_path = dataset_info[f'{split}_path']
128
+
129
+ if not split_path or not os.path.exists(split_path):
130
+ print(f"Warning: {split} split not found")
131
+ continue
132
+
133
+ print(f"\nProcessing {split} from: {split_path}")
134
+
135
+ # Find images and labels directories
136
+ img_dir = os.path.join(split_path, 'images')
137
+ lbl_dir = os.path.join(split_path, 'labels')
138
+
139
+ if not os.path.exists(img_dir) or not os.path.exists(lbl_dir):
140
+ print(f"Warning: Could not find images or labels for {split}")
141
+ continue
142
+
143
+ # Copy images and labels
144
+ img_files = [f for f in os.listdir(img_dir) if f.endswith(('.jpg', '.jpeg', '.png'))]
145
+ print(f"Found {len(img_files)} images in {split}")
146
+
147
+ for img_file in img_files:
148
+ # Copy image
149
+ src_img = os.path.join(img_dir, img_file)
150
+ dst_img = os.path.join(output_dir, 'images', split, img_file)
151
+ shutil.copy2(src_img, dst_img)
152
+
153
+ # Copy corresponding label
154
+ base_name = os.path.splitext(img_file)[0]
155
+ txt_file = base_name + '.txt'
156
+ src_txt = os.path.join(lbl_dir, txt_file)
157
+ dst_txt = os.path.join(output_dir, 'labels', split, txt_file)
158
+
159
+ if os.path.exists(src_txt):
160
+ shutil.copy2(src_txt, dst_txt)
161
+ total_copied += 1
162
+
163
+ # Create data.yaml
164
+ data_yaml_content = f"""# PDT dataset configuration
165
+ path: {os.path.abspath(output_dir)}
166
+ train: images/train
167
+ val: images/val
168
+ test: images/test
169
+
170
+ # Classes
171
+ names:
172
+ 0: unhealthy
173
+ nc: 1
174
+ """
175
+
176
+ yaml_path = os.path.join(output_dir, 'data.yaml')
177
+ with open(yaml_path, 'w') as f:
178
+ f.write(data_yaml_content)
179
+
180
+ print(f"\nDataset setup completed!")
181
+ print(f"Total images copied: {total_copied}")
182
+
183
+ # Verify the dataset
184
+ for split in ['train', 'val', 'test']:
185
+ img_dir = os.path.join(output_dir, 'images', split)
186
+ lbl_dir = os.path.join(output_dir, 'labels', split)
187
+ if os.path.exists(img_dir):
188
+ img_count = len([f for f in os.listdir(img_dir) if f.endswith(('.jpg', '.jpeg', '.png'))])
189
+ lbl_count = len([f for f in os.listdir(lbl_dir) if f.endswith('.txt')])
190
+ print(f"{split}: {img_count} images, {lbl_count} labels")
191
+
192
+ return yaml_path
193
+
194
+ # Setup the dataset
195
+ data_yaml_path = setup_yolo_dataset(dataset_info)
196
+
197
+ # Cell 6: Train the model
198
+ print("\nStarting model training...")
199
+
200
+ # Use YOLOv8s model
201
+ model = YOLO('yolov8s.yaml')
202
+
203
+ # Train the model
204
+ results = model.train(
205
+ data=data_yaml_path,
206
+ epochs=50, # Adjust based on your needs
207
+ imgsz=640,
208
+ batch=16, # Adjust based on GPU memory
209
+ name='yolov8s_pdt',
210
+ patience=10,
211
+ save=True,
212
+ device='0' if torch.cuda.is_available() else 'cpu',
213
+ workers=4,
214
+ project='runs/train',
215
+ exist_ok=True,
216
+ pretrained=False,
217
+ optimizer='SGD',
218
+ lr0=0.01,
219
+ momentum=0.9,
220
+ weight_decay=0.001,
221
+ verbose=True,
222
+ plots=True,
223
+ )
224
+
225
+ print("Training completed!")
226
+
227
+ # Cell 7: Evaluate the model
228
+ print("\nEvaluating model performance...")
229
+
230
+ # Load the best model
231
+ best_model_path = 'runs/train/yolov8s_pdt/weights/best.pt'
232
+ model = YOLO(best_model_path)
233
+
234
+ # Validate
235
+ metrics = model.val()
236
+
237
+ print(f"\nValidation Metrics:")
238
+ print(f"mAP50: {metrics.box.map50:.3f}")
239
+ print(f"mAP50-95: {metrics.box.map:.3f}")
240
+ print(f"Precision: {metrics.box.p.mean():.3f}")
241
+ print(f"Recall: {metrics.box.r.mean():.3f}")
242
+
243
+ # Cell 8: Test the model
244
+ print("\nTesting on sample images...")
245
+
246
+ # Test on validation images
247
+ val_img_dir = '/content/PDT_yolo/images/val'
248
+ val_images = [f for f in os.listdir(val_img_dir) if f.endswith(('.jpg', '.jpeg', '.png'))][:5]
249
+
250
+ fig, axes = plt.subplots(2, 3, figsize=(18, 12))
251
+ axes = axes.ravel()
252
+
253
+ for i, img_name in enumerate(val_images[:6]):
254
+ img_path = os.path.join(val_img_dir, img_name)
255
+
256
+ # Run inference
257
+ results = model(img_path, conf=0.25)
258
+
259
+ # Plot results
260
+ img_with_boxes = results[0].plot()
261
+ axes[i].imshow(cv2.cvtColor(img_with_boxes, cv2.COLOR_BGR2RGB))
262
+ axes[i].set_title(f'{img_name}')
263
+ axes[i].axis('off')
264
+
265
+ # Hide empty subplot
266
+ if len(val_images) < 6:
267
+ axes[5].axis('off')
268
+
269
+ plt.tight_layout()
270
+ plt.show()
271
+
272
+ # Cell 9: Create inference function
273
+ def detect_tree_disease(image_path, conf_threshold=0.25):
274
+ """Detect unhealthy trees in an image"""
275
+ results = model(image_path, conf=conf_threshold)
276
+
277
+ detections = []
278
+ for result in results:
279
+ boxes = result.boxes
280
+ if boxes is not None:
281
+ for box in boxes:
282
+ detection = {
283
+ 'confidence': float(box.conf[0]),
284
+ 'bbox': box.xyxy[0].tolist(),
285
+ 'class': 'unhealthy'
286
+ }
287
+ detections.append(detection)
288
+
289
+ # Visualize
290
+ img_with_boxes = results[0].plot()
291
+ plt.figure(figsize=(12, 8))
292
+ plt.imshow(cv2.cvtColor(img_with_boxes, cv2.COLOR_BGR2RGB))
293
+ plt.axis('off')
294
+ plt.title(f'Detected {len(detections)} unhealthy tree(s)')
295
+ plt.show()
296
+
297
+ return detections
298
+
299
+ # Cell 10: Save the model
300
+ print("\nSaving model...")
301
+ final_model_path = 'tree_disease_detector.pt'
302
+ model.save(final_model_path)
303
+ print(f"Model saved to: {final_model_path}")
304
+
305
+ # Cell 11: Save to Google Drive (optional)
306
+ from google.colab import drive
307
+
308
+ try:
309
+ drive.mount('/content/drive')
310
+
311
+ save_dir = '/content/drive/MyDrive/tree_disease_detection'
312
+ os.makedirs(save_dir, exist_ok=True)
313
+
314
+ # Copy files
315
+ shutil.copy(best_model_path, os.path.join(save_dir, 'best_model.pt'))
316
+ shutil.copy(final_model_path, os.path.join(save_dir, 'tree_disease_detector.pt'))
317
+
318
+ # Copy training results
319
+ results_png = 'runs/train/yolov8s_pdt/results.png'
320
+ if os.path.exists(results_png):
321
+ shutil.copy(results_png, os.path.join(save_dir, 'training_results.png'))
322
+
323
+ print(f"Results saved to Google Drive: {save_dir}")
324
+ except:
325
+ print("Google Drive not mounted. Results saved locally.")
326
+
327
+ # Cell 12: Summary
328
+ print("\n=== Training Complete ===")
329
+ print("Model: YOLOv8s")
330
+ print("Dataset: PDT (Pests and Diseases Tree)")
331
+ print(f"Best Model: {best_model_path}")
332
+ print("The model is ready for tree disease detection!")
333
+
334
+ # Test with your own image
335
+ print("\nTo test with your own image:")
336
+ print("detections = detect_tree_disease('path/to/your/image.jpg')")
337
+
338
+
339
+
340
+
341
+
342
+
343
+
344
+
345
+
346
+ # Cell 1: Install Hugging Face Hub
347
+ !pip install huggingface_hub
348
+
349
+ # Cell 2: Login to Hugging Face
350
+ from huggingface_hub import login, HfApi, create_repo
351
+ import os
352
+ import shutil
353
+
354
+ # Login to Hugging Face (you'll need your token)
355
+ # Get your token from: https://huggingface.co/settings/tokens
356
+ login()
357
+
358
+ # Cell 3: Prepare model files for upload
359
+ # Create a directory for model files
360
+ model_dir = "pdt_tree_disease_model"
361
+ os.makedirs(model_dir, exist_ok=True)
362
+
363
+ # Copy the trained model
364
+ best_model_path = 'runs/train/yolov8s_pdt/weights/best.pt'
365
+ if os.path.exists(best_model_path):
366
+ shutil.copy(best_model_path, os.path.join(model_dir, "best.pt"))
367
+
368
+ # Copy the final saved model
369
+ if os.path.exists('tree_disease_detector.pt'):
370
+ shutil.copy('tree_disease_detector.pt', os.path.join(model_dir, "tree_disease_detector.pt"))
371
+
372
+ # Copy training results
373
+ results_path = 'runs/train/yolov8s_pdt/results.png'
374
+ if os.path.exists(results_path):
375
+ shutil.copy(results_path, os.path.join(model_dir, "training_results.png"))
376
+
377
+ # Copy confusion matrix if exists
378
+ confusion_matrix_path = 'runs/train/yolov8s_pdt/confusion_matrix.png'
379
+ if os.path.exists(confusion_matrix_path):
380
+ shutil.copy(confusion_matrix_path, os.path.join(model_dir, "confusion_matrix.png"))
381
+
382
+ # Copy other training plots
383
+ for plot_file in ['F1_curve.png', 'P_curve.png', 'R_curve.png', 'PR_curve.png']:
384
+ plot_path = f'runs/train/yolov8s_pdt/{plot_file}'
385
+ if os.path.exists(plot_path):
386
+ shutil.copy(plot_path, os.path.join(model_dir, plot_file))
387
+
388
+ # Cell 4: Create model card (README.md)
389
+ model_card = """---
390
+ tags:
391
+ - object-detection
392
+ - yolov8
393
+ - tree-disease-detection
394
+ - pdt-dataset
395
+ library_name: ultralytics
396
+ datasets:
397
+ - qwer0213/PDT_dataset
398
+ metrics:
399
+ - mAP50
400
+ - mAP50-95
401
+ ---
402
+
403
+ # YOLOv8 Tree Disease Detection Model
404
+
405
+ This model is trained on the PDT (Pests and Diseases Tree) dataset for detecting unhealthy trees using YOLOv8.
406
+
407
+ ## Model Description
408
+
409
+ - **Architecture**: YOLOv8s
410
+ - **Task**: Object Detection (Tree Disease Detection)
411
+ - **Classes**: 1 (unhealthy)
412
+ - **Input Size**: 640x640
413
+ - **Framework**: Ultralytics YOLOv8
414
+
415
+ ## Training Details
416
+
417
+ - **Dataset**: PDT (Pests and Diseases Tree) dataset
418
+ - **Training Images**: 4,536
419
+ - **Validation Images**: 567
420
+ - **Test Images**: 567
421
+ - **Epochs**: 50
422
+ - **Batch Size**: 16
423
+ - **Optimizer**: SGD
424
+ - **Learning Rate**: 0.01
425
+
426
+ ## Performance Metrics
427
+
428
+ | Metric | Value |
429
+ |--------|-------|
430
+ | mAP50 | 0.xxx |
431
+ | mAP50-95 | 0.xxx |
432
+ | Precision | 0.xxx |
433
+ | Recall | 0.xxx |
434
+
435
+ ## Usage
436
+
437
+ ```python
438
+ from ultralytics import YOLO
439
+
440
+ # Load model
441
+ model = YOLO('tree_disease_detector.pt')
442
+
443
+ # Run inference
444
+ results = model('path/to/image.jpg')
445
+
446
+ # Process results
447
+ for result in results:
448
+ boxes = result.boxes
449
+ if boxes is not None:
450
+ for box in boxes:
451
+ confidence = box.conf[0]
452
+ bbox = box.xyxy[0].tolist()
453
+ print(f"Unhealthy tree detected with confidence: {confidence}")
454
+ Dataset
455
+ This model was trained on the PDT dataset, which contains high-resolution UAV images of trees with pest and disease annotations.
456
+ Citation
457
+ bibtex@dataset{pdt_dataset,
458
+ title={PDT: UAV Pests and Diseases Tree Dataset},
459
+ author={Zhou et al.},
460
+ year={2024},
461
+ publisher={HuggingFace}
462
+ }
463
+ License
464
+ MIT License
465
+ """
466
+ Fill in the actual metrics
467
+ if 'metrics' in globals() and metrics is not None:
468
+ model_card = model_card.replace('0.xxx', f'{metrics.box.map50:.3f}')
469
+ model_card = model_card.replace('0.xxx', f'{metrics.box.map:.3f}')
470
+ model_card = model_card.replace('0.xxx', f'{metrics.box.p.mean():.3f}')
471
+ model_card = model_card.replace('0.xxx', f'{metrics.box.r.mean():.3f}')
472
+ Save model card
473
+ with open(os.path.join(model_dir, "README.md"), "w") as f:
474
+ f.write(model_card)
475
+ Cell 5: Create config file
476
+ config_content = """# YOLOv8 Tree Disease Detection Configuration
477
+ model_type: yolov8s
478
+ task: detect
479
+ nc: 1 # number of classes
480
+ names: ['unhealthy'] # class names
481
+ Input
482
+ imgsz: 640
483
+ Inference settings
484
+ conf: 0.25 # confidence threshold
485
+ iou: 0.45 # IoU threshold for NMS
486
+ """
487
+ with open(os.path.join(model_dir, "config.yaml"), "w") as f:
488
+ f.write(config_content)
489
+ Cell 6: Push to Hugging Face Hub
490
+ from huggingface_hub import HfApi
491
+ Initialize API
492
+ api = HfApi()
493
+ Create repository (replace 'your-username' with your HuggingFace username)
494
+ repo_id = "your-username/yolov8-tree-disease-detection" # Change this!
495
+ Create the repository
496
+ try:
497
+ create_repo(
498
+ repo_id=repo_id,
499
+ repo_type="model",
500
+ exist_ok=True
501
+ )
502
+ print(f"Repository created: https://huggingface.co/{repo_id}")
503
+ except Exception as e:
504
+ print(f"Repository might already exist or error: {e}")
505
+ Upload all files in the model directory
506
+ api.upload_folder(
507
+ folder_path=model_dir,
508
+ repo_id=repo_id,
509
+ repo_type="model",
510
+ )
511
+ print(f"Model uploaded successfully to: https://huggingface.co/{repo_id}")
512
+ Cell 7: Create a simple inference script for users
513
+ inference_script = """# Tree Disease Detection Inference
514
+ from ultralytics import YOLO
515
+ import cv2
516
+ import matplotlib.pyplot as plt
517
+ Download and load model from Hugging Face
518
+ model = YOLO('https://huggingface.co/{}/resolve/main/tree_disease_detector.pt')
519
+ def detect_tree_disease(image_path):
520
+ # Run inference
521
+ results = model(image_path, conf=0.25)
522
+ # Process results
523
+ detections = []
524
+ for result in results:
525
+ boxes = result.boxes
526
+ if boxes is not None:
527
+ for box in boxes:
528
+ detection = {
529
+ 'confidence': float(box.conf[0]),
530
+ 'bbox': box.xyxy[0].tolist(),
531
+ 'class': 'unhealthy'
532
+ }
533
+ detections.append(detection)
534
+
535
+ # Visualize
536
+ annotated_img = results[0].plot()
537
+ plt.figure(figsize=(12, 8))
538
+ plt.imshow(cv2.cvtColor(annotated_img, cv2.COLOR_BGR2RGB))
539
+ plt.axis('off')
540
+ plt.title(f'Detected {len(detections)} unhealthy tree(s)')
541
+ plt.show()
542
+
543
+ return detections
544
+ Example usage
545
+ if name == "main":
546
+ detections = detect_tree_disease('path/to/your/image.jpg')
547
+ print(f"Found {len(detections)} unhealthy trees")
548
+ """.format(repo_id)
549
+ with open(os.path.join(model_dir, "inference.py"), "w") as f:
550
+ f.write(inference_script)
551
+ Upload the inference script
552
+ api.upload_file(
553
+ path_or_fileobj=os.path.join(model_dir, "inference.py"),
554
+ path_in_repo="inference.py",
555
+ repo_id=repo_id,
556
+ repo_type="model",
557
+ )
558
+ Cell 8: Create requirements.txt
559
+ requirements = """ultralytics>=8.0.0
560
+ torch>=2.0.0
561
+ opencv-python>=4.8.0
562
+ matplotlib>=3.7.0
563
+ pillow>=10.0.0
564
+ """
565
+ with open(os.path.join(model_dir, "requirements.txt"), "w") as f:
566
+ f.write(requirements)
567
+ Upload requirements
568
+ api.upload_file(
569
+ path_or_fileobj=os.path.join(model_dir, "requirements.txt"),
570
+ path_in_repo="requirements.txt",
571
+ repo_id=repo_id,
572
+ repo_type="model",
573
+ )
574
+ print("\nModel successfully uploaded to Hugging Face!")
575
+ print(f"View your model at: https://huggingface.co/{repo_id}")
576
+ print("\nTo use your model:")
577
+ print(f"model = YOLO('https://huggingface.co/{repo_id}/resolve/main/tree_disease_detector.pt')")
578
+
579
+ ## Steps to upload your model:
580
+
581
+ 1. **Get a Hugging Face token**:
582
+ - Go to https://huggingface.co/settings/tokens
583
+ - Create a new token with write permissions
584
+ - Copy the token
585
+
586
+ 2. **Replace placeholder values**:
587
+ - Change `your-username` to your actual Hugging Face username
588
+ - Update the metrics in the model card with actual values
589
+
590
+ 3. **Run the cells** in order
591
+
592
+ ## After uploading, others can use your model like this:
593
+
594
+ ```python
595
+ from ultralytics import YOLO
596
+
597
+ # Load model directly from Hugging Face
598
+ model = YOLO('https://huggingface.co/your-username/yolov8-tree-disease-detection/resolve/main/tree_disease_detector.pt')
599
+
600
+ # Run inference
601
+ results = model('image.jpg')