Emmanuel Frimpong Asante
commited on
Commit
·
f6bbd69
1
Parent(s):
712de7e
update space
Browse files- .idea/workspace.xml +15 -14
- models/auth.h5 +3 -0
- models/{Final_Chicken_disease_model.h5 → diseases.h5} +0 -0
- services/convert_model.py +1 -1
- services/disease_detection_service.py +77 -51
.idea/workspace.xml
CHANGED
@@ -5,10 +5,11 @@
|
|
5 |
</component>
|
6 |
<component name="ChangeListManager">
|
7 |
<list default="true" id="27c9ae1a-a6fa-4472-8bcd-a7087620894b" name="Changes" comment="update space">
|
8 |
-
<change afterPath="$PROJECT_DIR$/
|
9 |
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
10 |
-
<change beforePath="$PROJECT_DIR$/
|
11 |
-
<change beforePath="$PROJECT_DIR$/
|
|
|
12 |
</list>
|
13 |
<option name="SHOW_DIALOG" value="false" />
|
14 |
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
@@ -51,7 +52,7 @@
|
|
51 |
"RunOnceActivity.ShowReadmeOnStart": "true",
|
52 |
"git-widget-placeholder": "main",
|
53 |
"ignore.virus.scanning.warn.message": "true",
|
54 |
-
"last_opened_file_path": "C:/git/Generative_AI_with_poultry_disease_detection_system_v2",
|
55 |
"list.type.of.created.stylesheet": "CSS",
|
56 |
"node.js.detected.package.eslint": "true",
|
57 |
"node.js.detected.package.tslint": "true",
|
@@ -64,11 +65,11 @@
|
|
64 |
}]]></component>
|
65 |
<component name="RecentsManager">
|
66 |
<key name="CopyFile.RECENT_KEYS">
|
|
|
67 |
<recent name="C:\git\Generative_AI_with_poultry_disease_detection_system_v2" />
|
68 |
<recent name="C:\git\Generative_AI_with_poultry_disease_detection_system_v2\static" />
|
69 |
<recent name="C:\git\Generative_AI_with_poultry_disease_detection_system_v2\templates\tasks" />
|
70 |
<recent name="C:\git\Generative_AI_with_poultry_disease_detection_system_v2\templates\todo" />
|
71 |
-
<recent name="C:\git\Generative_AI_with_poultry_disease_detection_system_v2\templates" />
|
72 |
</key>
|
73 |
<key name="MoveFile.RECENT_KEYS">
|
74 |
<recent name="C:\git\Generative_AI_with_poultry_disease_detection_system_v2\static\images" />
|
@@ -130,14 +131,6 @@
|
|
130 |
<workItem from="1730397485849" duration="22781000" />
|
131 |
<workItem from="1730454506390" duration="12672000" />
|
132 |
</task>
|
133 |
-
<task id="LOCAL-00075" summary="update space">
|
134 |
-
<option name="closed" value="true" />
|
135 |
-
<created>1730400686897</created>
|
136 |
-
<option name="number" value="00075" />
|
137 |
-
<option name="presentableId" value="LOCAL-00075" />
|
138 |
-
<option name="project" value="LOCAL" />
|
139 |
-
<updated>1730400686897</updated>
|
140 |
-
</task>
|
141 |
<task id="LOCAL-00076" summary="update space">
|
142 |
<option name="closed" value="true" />
|
143 |
<created>1730402280098</created>
|
@@ -522,7 +515,15 @@
|
|
522 |
<option name="project" value="LOCAL" />
|
523 |
<updated>1730488911425</updated>
|
524 |
</task>
|
525 |
-
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
526 |
<servers />
|
527 |
</component>
|
528 |
<component name="TypeScriptGeneratedFilesManager">
|
|
|
5 |
</component>
|
6 |
<component name="ChangeListManager">
|
7 |
<list default="true" id="27c9ae1a-a6fa-4472-8bcd-a7087620894b" name="Changes" comment="update space">
|
8 |
+
<change afterPath="$PROJECT_DIR$/models/auth.h5" afterDir="false" />
|
9 |
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
10 |
+
<change beforePath="$PROJECT_DIR$/models/Final_Chicken_disease_model.h5" beforeDir="false" afterPath="$PROJECT_DIR$/models/diseases.h5" afterDir="false" />
|
11 |
+
<change beforePath="$PROJECT_DIR$/services/convert_model.py" beforeDir="false" afterPath="$PROJECT_DIR$/services/convert_model.py" afterDir="false" />
|
12 |
+
<change beforePath="$PROJECT_DIR$/services/disease_detection_service.py" beforeDir="false" afterPath="$PROJECT_DIR$/services/disease_detection_service.py" afterDir="false" />
|
13 |
</list>
|
14 |
<option name="SHOW_DIALOG" value="false" />
|
15 |
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
|
|
52 |
"RunOnceActivity.ShowReadmeOnStart": "true",
|
53 |
"git-widget-placeholder": "main",
|
54 |
"ignore.virus.scanning.warn.message": "true",
|
55 |
+
"last_opened_file_path": "C:/git/Generative_AI_with_poultry_disease_detection_system_v2/models",
|
56 |
"list.type.of.created.stylesheet": "CSS",
|
57 |
"node.js.detected.package.eslint": "true",
|
58 |
"node.js.detected.package.tslint": "true",
|
|
|
65 |
}]]></component>
|
66 |
<component name="RecentsManager">
|
67 |
<key name="CopyFile.RECENT_KEYS">
|
68 |
+
<recent name="C:\git\Generative_AI_with_poultry_disease_detection_system_v2\models" />
|
69 |
<recent name="C:\git\Generative_AI_with_poultry_disease_detection_system_v2" />
|
70 |
<recent name="C:\git\Generative_AI_with_poultry_disease_detection_system_v2\static" />
|
71 |
<recent name="C:\git\Generative_AI_with_poultry_disease_detection_system_v2\templates\tasks" />
|
72 |
<recent name="C:\git\Generative_AI_with_poultry_disease_detection_system_v2\templates\todo" />
|
|
|
73 |
</key>
|
74 |
<key name="MoveFile.RECENT_KEYS">
|
75 |
<recent name="C:\git\Generative_AI_with_poultry_disease_detection_system_v2\static\images" />
|
|
|
131 |
<workItem from="1730397485849" duration="22781000" />
|
132 |
<workItem from="1730454506390" duration="12672000" />
|
133 |
</task>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
134 |
<task id="LOCAL-00076" summary="update space">
|
135 |
<option name="closed" value="true" />
|
136 |
<created>1730402280098</created>
|
|
|
515 |
<option name="project" value="LOCAL" />
|
516 |
<updated>1730488911425</updated>
|
517 |
</task>
|
518 |
+
<task id="LOCAL-00124" summary="update space">
|
519 |
+
<option name="closed" value="true" />
|
520 |
+
<created>1730490013545</created>
|
521 |
+
<option name="number" value="00124" />
|
522 |
+
<option name="presentableId" value="LOCAL-00124" />
|
523 |
+
<option name="project" value="LOCAL" />
|
524 |
+
<updated>1730490013545</updated>
|
525 |
+
</task>
|
526 |
+
<option name="localTasksCounter" value="125" />
|
527 |
<servers />
|
528 |
</component>
|
529 |
<component name="TypeScriptGeneratedFilesManager">
|
models/auth.h5
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:55ca5e07d8f4d45eab021364be749ced18402f85f5edb7425486ed76ea5c3093
|
3 |
+
size 234256896
|
models/{Final_Chicken_disease_model.h5 → diseases.h5}
RENAMED
File without changes
|
services/convert_model.py
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
|
3 |
import tensorflow as tf
|
4 |
|
5 |
-
MODEL_PATH = "models/
|
6 |
NEW_MODEL_PATH = "models/Final_Chicken_disease_model"
|
7 |
|
8 |
# Load the .h5 model
|
|
|
2 |
|
3 |
import tensorflow as tf
|
4 |
|
5 |
+
MODEL_PATH = "models/diseases.h5"
|
6 |
NEW_MODEL_PATH = "models/Final_Chicken_disease_model"
|
7 |
|
8 |
# Load the .h5 model
|
services/disease_detection_service.py
CHANGED
@@ -3,19 +3,20 @@
|
|
3 |
import os
|
4 |
import logging
|
5 |
import threading
|
6 |
-
import
|
7 |
import cv2
|
8 |
import numpy as np
|
|
|
9 |
from huggingface_hub import login
|
10 |
from transformers import AutoTokenizer, AutoModelForCausalLM
|
11 |
from services.utils import db # MongoDB instance from utils
|
12 |
import configparser
|
13 |
|
14 |
-
# Configure logging
|
15 |
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
16 |
logger = logging.getLogger(__name__)
|
17 |
|
18 |
-
# Load
|
19 |
HF_TOKEN = os.environ.get('HF_Token')
|
20 |
if HF_TOKEN:
|
21 |
login(token=HF_TOKEN, add_to_git_credential=True)
|
@@ -23,44 +24,65 @@ if HF_TOKEN:
|
|
23 |
else:
|
24 |
logger.warning("Hugging Face token missing. Please set HF_Token in environment variables.")
|
25 |
|
26 |
-
# Load configuration for model paths
|
27 |
config = configparser.ConfigParser()
|
28 |
config.read('config.ini')
|
29 |
logger.info("Configuration loaded from config.ini.")
|
30 |
|
31 |
-
#
|
32 |
-
|
33 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
|
35 |
# Global model variables and threading event for synchronization
|
36 |
-
disease_model = None
|
37 |
llama_model, llama_tokenizer = None, None
|
38 |
model_loading_event = threading.Event()
|
39 |
|
40 |
# Function to load the disease detection model
|
41 |
def load_disease_model():
|
42 |
-
"""Load the
|
43 |
try:
|
44 |
-
model_path = config.get('MODELS', 'DISEASE_MODEL_PATH', fallback="models/
|
45 |
-
|
46 |
-
|
47 |
-
|
|
|
48 |
return model
|
49 |
except Exception as e:
|
50 |
logger.error("Error loading disease detection model", exc_info=True)
|
51 |
raise RuntimeError("Failed to load disease detection model") from e
|
52 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
53 |
# Function to load the Llama 3.2 model for language generation
|
54 |
def load_llama_model():
|
55 |
"""Load the Llama model and tokenizer for language generation."""
|
56 |
global llama_model, llama_tokenizer
|
57 |
try:
|
58 |
logger.info("Loading Llama 3.2 model and tokenizer using PyTorch-compatible model.")
|
59 |
-
model_name = "meta-llama/Llama-3.2-1B"
|
60 |
|
61 |
-
# Load the tokenizer and model from the Hugging Face hub
|
62 |
llama_tokenizer = AutoTokenizer.from_pretrained(model_name)
|
63 |
-
llama_model = AutoModelForCausalLM.from_pretrained(model_name)
|
64 |
|
65 |
# Add a padding token if it's missing
|
66 |
if llama_tokenizer.pad_token is None:
|
@@ -69,11 +91,11 @@ def load_llama_model():
|
|
69 |
llama_model.resize_token_embeddings(len(llama_tokenizer))
|
70 |
|
71 |
logger.info("Llama model and tokenizer loaded successfully.")
|
72 |
-
model_loading_event.set()
|
73 |
return llama_model, llama_tokenizer
|
74 |
except Exception as e:
|
75 |
logger.error("Failed to load Llama model", exc_info=True)
|
76 |
-
model_loading_event.set()
|
77 |
raise RuntimeError("Failed to load the Llama 3.2 model. Verify compatibility.")
|
78 |
|
79 |
# Disease mappings and recommended treatments
|
@@ -86,63 +108,65 @@ recommendations = {
|
|
86 |
3: 'Administer antibiotics as prescribed by a veterinarian and ensure biosecurity.'
|
87 |
}
|
88 |
|
89 |
-
class PoultryFarmBot:
|
90 |
-
"""Poultry Farm Bot for disease prediction and response generation."""
|
91 |
|
92 |
-
|
93 |
-
|
94 |
-
self.
|
95 |
-
|
|
|
|
|
96 |
|
97 |
-
def preprocess_image(self, image: np.ndarray) ->
|
98 |
"""Preprocess the input image for model prediction."""
|
99 |
try:
|
100 |
-
if image is None or image.size == 0:
|
101 |
-
raise ValueError("Invalid or empty image.")
|
102 |
image = cv2.resize(image, (224, 224))
|
103 |
-
image
|
104 |
-
image = torch.tensor(image, dtype=torch.float32).unsqueeze(0) / 255.0
|
105 |
-
logger.info("Image preprocessed successfully.")
|
106 |
-
return image.to(device)
|
107 |
except Exception as e:
|
108 |
-
logger.error("Error in image preprocessing", exc_info=True)
|
109 |
-
raise
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
110 |
|
111 |
def predict_disease(self, image: np.ndarray):
|
112 |
"""Predict disease from preprocessed image and provide detailed results."""
|
113 |
try:
|
114 |
preprocessed_image = self.preprocess_image(image)
|
115 |
-
|
116 |
-
|
117 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
118 |
disease_name = name_disease.get(predicted_class, "Unknown disease")
|
119 |
disease_status = status_map.get(predicted_class, "Unknown status")
|
120 |
recommendation = recommendations.get(predicted_class, "No recommendation available")
|
121 |
-
confidence =
|
122 |
-
logger.info(f"Disease Prediction: {disease_name} with {confidence:.2f}% confidence.")
|
123 |
|
124 |
# Generate a detailed response using Llama model
|
125 |
detailed_response = self.generate_detailed_response(disease_name, disease_status, recommendation)
|
126 |
return detailed_response, disease_name, disease_status, recommendation, confidence
|
127 |
except Exception as e:
|
128 |
-
logger.error("Error in disease prediction", exc_info=True)
|
129 |
return "Prediction failed.", None, None, None, None
|
130 |
|
131 |
-
def generate_detailed_response(self, disease_name: str, status: str, recommendation: str) -> str:
|
132 |
-
"""Generate detailed response using Llama model based on prediction."""
|
133 |
-
prompt = (
|
134 |
-
f"The detected disease is {disease_name}, classified as {status}. "
|
135 |
-
f"Suggested action: {recommendation}. "
|
136 |
-
f"Here is additional information on {disease_name}: causes, symptoms, and effective management."
|
137 |
-
)
|
138 |
-
response = self.llama_response(prompt)
|
139 |
-
return response.replace(prompt, "").strip()
|
140 |
-
|
141 |
def llama_response(self, prompt: str) -> str:
|
142 |
"""Generate a response from the Llama model based on a prompt."""
|
143 |
try:
|
144 |
max_length = min(len(prompt) + 50, 512)
|
145 |
-
inputs = llama_tokenizer(prompt, return_tensors="
|
146 |
outputs = llama_model.generate(inputs["input_ids"], max_length=max_length, do_sample=True, temperature=0.7, top_p=0.9)
|
147 |
return llama_tokenizer.decode(outputs[0], skip_special_tokens=True)
|
148 |
except Exception as e:
|
@@ -155,10 +179,12 @@ class PoultryFarmBot:
|
|
155 |
return "Provide a valid poultry fecal image.", None, None, None, None
|
156 |
return self.predict_disease(image)
|
157 |
|
|
|
158 |
# Load models upon service startup
|
159 |
disease_model = load_disease_model()
|
|
|
160 |
llama_model, llama_tokenizer = load_llama_model()
|
161 |
|
162 |
# Initialize the bot instance with MongoDB
|
163 |
-
bot = PoultryFarmBot(
|
164 |
logger.info("Bot instance initialized with models loaded.")
|
|
|
3 |
import os
|
4 |
import logging
|
5 |
import threading
|
6 |
+
import tensorflow as tf
|
7 |
import cv2
|
8 |
import numpy as np
|
9 |
+
from keras.models import load_model
|
10 |
from huggingface_hub import login
|
11 |
from transformers import AutoTokenizer, AutoModelForCausalLM
|
12 |
from services.utils import db # MongoDB instance from utils
|
13 |
import configparser
|
14 |
|
15 |
+
# Configure logging
|
16 |
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
17 |
logger = logging.getLogger(__name__)
|
18 |
|
19 |
+
# Load Hugging Face API token for secure model access
|
20 |
HF_TOKEN = os.environ.get('HF_Token')
|
21 |
if HF_TOKEN:
|
22 |
login(token=HF_TOKEN, add_to_git_credential=True)
|
|
|
24 |
else:
|
25 |
logger.warning("Hugging Face token missing. Please set HF_Token in environment variables.")
|
26 |
|
27 |
+
# Load configuration for model paths
|
28 |
config = configparser.ConfigParser()
|
29 |
config.read('config.ini')
|
30 |
logger.info("Configuration loaded from config.ini.")
|
31 |
|
32 |
+
# Configure TensorFlow for GPU and mixed precision if supported
|
33 |
+
gpu_devices = tf.config.list_physical_devices('GPU')
|
34 |
+
if gpu_devices:
|
35 |
+
for gpu in gpu_devices:
|
36 |
+
tf.config.experimental.set_memory_growth(gpu, True)
|
37 |
+
if tf.config.experimental.get_device_details(gpu_devices[0]).get('compute_capability', (0, 0))[0] >= 7:
|
38 |
+
from tensorflow.keras import mixed_precision
|
39 |
+
policy = mixed_precision.Policy('mixed_float16')
|
40 |
+
mixed_precision.set_global_policy(policy)
|
41 |
+
logger.info("Mixed precision enabled on supported GPU.")
|
42 |
+
else:
|
43 |
+
logger.info("No GPU detected, using CPU without mixed precision.")
|
44 |
|
45 |
# Global model variables and threading event for synchronization
|
46 |
+
disease_model, auth_model = None, None
|
47 |
llama_model, llama_tokenizer = None, None
|
48 |
model_loading_event = threading.Event()
|
49 |
|
50 |
# Function to load the disease detection model
|
51 |
def load_disease_model():
|
52 |
+
"""Load the disease detection model."""
|
53 |
try:
|
54 |
+
model_path = config.get('MODELS', 'DISEASE_MODEL_PATH', fallback="models/diseases.h5")
|
55 |
+
device = tf.config.list_logical_devices('GPU')[0] if gpu_devices else tf.config.list_logical_devices('CPU')[0]
|
56 |
+
with tf.device(device.name):
|
57 |
+
model = load_model(model_path, compile=True)
|
58 |
+
logger.info(f"Disease detection model loaded successfully on {device.name}.")
|
59 |
return model
|
60 |
except Exception as e:
|
61 |
logger.error("Error loading disease detection model", exc_info=True)
|
62 |
raise RuntimeError("Failed to load disease detection model") from e
|
63 |
|
64 |
+
# Function to load the authentication model
|
65 |
+
def load_auth_model():
|
66 |
+
"""Load the authentication model to verify poultry images."""
|
67 |
+
try:
|
68 |
+
auth_model_path = config.get('MODELS', 'AUTH_MODEL_PATH', fallback="models/auth.h5")
|
69 |
+
auth_model = load_model(auth_model_path, compile=True)
|
70 |
+
logger.info("Authentication model loaded successfully.")
|
71 |
+
return auth_model
|
72 |
+
except Exception as e:
|
73 |
+
logger.error("Error loading authentication model", exc_info=True)
|
74 |
+
raise RuntimeError("Failed to load authentication model") from e
|
75 |
+
|
76 |
# Function to load the Llama 3.2 model for language generation
|
77 |
def load_llama_model():
|
78 |
"""Load the Llama model and tokenizer for language generation."""
|
79 |
global llama_model, llama_tokenizer
|
80 |
try:
|
81 |
logger.info("Loading Llama 3.2 model and tokenizer using PyTorch-compatible model.")
|
82 |
+
model_name = "meta-llama/Llama-3.2-1B"
|
83 |
|
|
|
84 |
llama_tokenizer = AutoTokenizer.from_pretrained(model_name)
|
85 |
+
llama_model = AutoModelForCausalLM.from_pretrained(model_name)
|
86 |
|
87 |
# Add a padding token if it's missing
|
88 |
if llama_tokenizer.pad_token is None:
|
|
|
91 |
llama_model.resize_token_embeddings(len(llama_tokenizer))
|
92 |
|
93 |
logger.info("Llama model and tokenizer loaded successfully.")
|
94 |
+
model_loading_event.set()
|
95 |
return llama_model, llama_tokenizer
|
96 |
except Exception as e:
|
97 |
logger.error("Failed to load Llama model", exc_info=True)
|
98 |
+
model_loading_event.set()
|
99 |
raise RuntimeError("Failed to load the Llama 3.2 model. Verify compatibility.")
|
100 |
|
101 |
# Disease mappings and recommended treatments
|
|
|
108 |
3: 'Administer antibiotics as prescribed by a veterinarian and ensure biosecurity.'
|
109 |
}
|
110 |
|
|
|
|
|
111 |
|
112 |
+
class PoultryFarmBot:
|
113 |
+
def __init__(self, disease_model, auth_model):
|
114 |
+
self.disease_model = disease_model
|
115 |
+
self.auth_model = auth_model
|
116 |
+
logging.basicConfig(level=logging.INFO)
|
117 |
+
self.logger = logging.getLogger(__name__)
|
118 |
|
119 |
+
def preprocess_image(self, image: np.ndarray) -> np.ndarray:
|
120 |
"""Preprocess the input image for model prediction."""
|
121 |
try:
|
|
|
|
|
122 |
image = cv2.resize(image, (224, 224))
|
123 |
+
return image / 255.0 # Normalize
|
|
|
|
|
|
|
124 |
except Exception as e:
|
125 |
+
self.logger.error("Error in image preprocessing", exc_info=True)
|
126 |
+
raise ValueError("Invalid image format or empty image provided.")
|
127 |
+
|
128 |
+
def generate_detailed_response(self, disease_name: str, status: str, recommendation: str) -> str:
|
129 |
+
"""Generate detailed response using Llama model based on prediction."""
|
130 |
+
prompt = (
|
131 |
+
f"The detected disease is {disease_name}, classified as {status}. "
|
132 |
+
f"Suggested action: {recommendation}. "
|
133 |
+
f"Here is additional information on {disease_name}: causes, symptoms, and effective management."
|
134 |
+
)
|
135 |
+
response = self.llama_response(prompt)
|
136 |
+
return response.replace(prompt, "").strip()
|
137 |
|
138 |
def predict_disease(self, image: np.ndarray):
|
139 |
"""Predict disease from preprocessed image and provide detailed results."""
|
140 |
try:
|
141 |
preprocessed_image = self.preprocess_image(image)
|
142 |
+
|
143 |
+
# Use auth_model to verify the image is poultry-related
|
144 |
+
is_poultry = self.auth_model.predict(preprocessed_image.reshape(1, 224, 224, 3)).argmax()
|
145 |
+
if is_poultry != 0:
|
146 |
+
self.logger.info("Image not recognized as poultry.")
|
147 |
+
return "Unknown Image", "N/A", "N/A", "Image not recognized as poultry.", None
|
148 |
+
|
149 |
+
# Predict disease if image is verified
|
150 |
+
prediction = self.disease_model.predict(preprocessed_image.reshape(1, 224, 224, 3))
|
151 |
+
predicted_class = prediction.argmax()
|
152 |
disease_name = name_disease.get(predicted_class, "Unknown disease")
|
153 |
disease_status = status_map.get(predicted_class, "Unknown status")
|
154 |
recommendation = recommendations.get(predicted_class, "No recommendation available")
|
155 |
+
confidence = prediction[0][predicted_class] * 100
|
156 |
+
self.logger.info(f"Disease Prediction: {disease_name} with {confidence:.2f}% confidence.")
|
157 |
|
158 |
# Generate a detailed response using Llama model
|
159 |
detailed_response = self.generate_detailed_response(disease_name, disease_status, recommendation)
|
160 |
return detailed_response, disease_name, disease_status, recommendation, confidence
|
161 |
except Exception as e:
|
162 |
+
self.logger.error("Error in disease prediction", exc_info=True)
|
163 |
return "Prediction failed.", None, None, None, None
|
164 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
165 |
def llama_response(self, prompt: str) -> str:
|
166 |
"""Generate a response from the Llama model based on a prompt."""
|
167 |
try:
|
168 |
max_length = min(len(prompt) + 50, 512)
|
169 |
+
inputs = llama_tokenizer(prompt, return_tensors="tf", max_length=max_length, truncation=True, padding=True)
|
170 |
outputs = llama_model.generate(inputs["input_ids"], max_length=max_length, do_sample=True, temperature=0.7, top_p=0.9)
|
171 |
return llama_tokenizer.decode(outputs[0], skip_special_tokens=True)
|
172 |
except Exception as e:
|
|
|
179 |
return "Provide a valid poultry fecal image.", None, None, None, None
|
180 |
return self.predict_disease(image)
|
181 |
|
182 |
+
|
183 |
# Load models upon service startup
|
184 |
disease_model = load_disease_model()
|
185 |
+
auth_model = load_auth_model()
|
186 |
llama_model, llama_tokenizer = load_llama_model()
|
187 |
|
188 |
# Initialize the bot instance with MongoDB
|
189 |
+
bot = PoultryFarmBot(disease_model, auth_model)
|
190 |
logger.info("Bot instance initialized with models loaded.")
|