Spaces:
Sleeping
Sleeping
import streamlit as st | |
import pandas as pd | |
import openai | |
import joblib | |
from PIL import Image | |
import requests | |
from io import BytesIO | |
import matplotlib.pyplot as plt | |
import numpy as np | |
from sklearn.preprocessing import LabelEncoder | |
from huggingface_hub import hf_hub_download | |
from transformers import AutoFeatureExtractor, AutoModelForImageClassification | |
import torch | |
from datetime import datetime | |
# Dataset loading function with caching | |
def load_datasets(): | |
try: | |
with st.spinner('Loading dataset...'): | |
original_data = pd.read_csv('CTP_Model1.csv', low_memory=False) | |
return original_data | |
except Exception as e: | |
st.error(f"Error loading dataset: {str(e)}") | |
raise e | |
def load_image(image_file): | |
return Image.open(image_file) | |
def classify_image(image): | |
try: | |
# Load the model and feature extractor | |
model_name = "dima806/car_models_image_detection" | |
feature_extractor = AutoFeatureExtractor.from_pretrained(model_name) | |
model = AutoModelForImageClassification.from_pretrained(model_name) | |
# Preprocess the image | |
inputs = feature_extractor(images=image, return_tensors="pt") | |
# Perform inference | |
with torch.no_grad(): | |
outputs = model(**inputs) | |
# Get the predicted class | |
logits = outputs.logits | |
predicted_class_idx = logits.argmax(-1).item() | |
# Get the class label and score | |
predicted_class_label = model.config.id2label[predicted_class_idx] | |
score = torch.nn.functional.softmax(logits, dim=-1)[0, predicted_class_idx].item() | |
# Return the top prediction | |
return [{'label': predicted_class_label, 'score': score}] | |
except Exception as e: | |
st.error(f"Classification error: {e}") | |
return None | |
def get_car_overview(brand, model, year): | |
prompt = f"Provide an overview of the following car:\nYear: {year}\nMake: {brand}\nModel: {model}\n" | |
response = openai.ChatCompletion.create( | |
model="gpt-3.5-turbo", | |
messages=[{"role": "user", "content": prompt}] | |
) | |
return response.choices[0].message['content'] | |
def load_model_and_encodings(): | |
try: | |
with st.spinner('Loading model...'): | |
model_content = hf_hub_download(repo_id="EdBoy2202/car_prediction_model", filename="car_price_modelv3.pkl") | |
model = joblib.load(model_content) | |
return model | |
except Exception as e: | |
st.error(f"Error loading model: {str(e)}") | |
raise e | |
def predict_price(model, brand, model_name, year): | |
# Create a dictionary with default values | |
input_data = { | |
'year': year, | |
'make': brand, | |
'model': model_name, | |
'trim': 'Base', # Default trim | |
'condition': 'Used', # Default condition | |
'fuel': 'Gasoline', # Default fuel type | |
'odometer': year * 12000, # Estimate based on year and average annual mileage | |
'title_status': 'Clean', # Default title status | |
'transmission': 'Automatic', # Default transmission | |
'drive': 'Fwd', # Default drive | |
'size': 'Mid-Size', # Default size | |
'type': 'Sedan', # Default type | |
'paint_color': 'White' # Default color | |
} | |
# Calculate age | |
current_year = datetime.now().year | |
input_data['age'] = current_year - year | |
input_data['age_squared'] = input_data['age'] ** 2 | |
# Prepare the input for the model | |
input_df = pd.DataFrame([input_data]) | |
# Make sure to only include columns that the model expects | |
model_columns = model.feature_names_in_ | |
input_df = input_df[model_columns] | |
# Predict the price | |
predicted_price = model.predict(input_df) | |
return predicted_price[0] | |
# Streamlit App | |
st.title("Auto Appraise") | |
st.write("Upload a car image or take a picture to get its brand, model, overview, and expected price!") | |
# Load model and encodings | |
model = load_model_and_encodings() | |
# Initialize OpenAI API key | |
openai.api_key = st.secrets["GPT_TOKEN"] | |
# File uploader for image | |
uploaded_file = st.file_uploader("Choose a car image", type=["jpg", "jpeg", "png"]) | |
# Camera input as an alternative (optional) | |
camera_image = st.camera_input("Or take a picture of the car") | |
# Process the image (either uploaded or from camera) | |
image = None | |
if uploaded_file is not None: | |
image = Image.open(uploaded_file) | |
st.write("Image uploaded successfully.") | |
elif camera_image is not None: | |
image = Image.open(camera_image) | |
st.write("Image captured successfully.") | |
if image is not None: | |
st.image(image, caption='Processed Image', use_container_width=True) | |
# Classify the car image | |
with st.spinner('Analyzing image...'): | |
car_classifications = classify_image(image) | |
if car_classifications: | |
st.write("Image classification successful.") | |
st.subheader("Car Classification Results:") | |
for classification in car_classifications: | |
st.write(f"Model: {classification['label']}") | |
st.write(f"Confidence: {classification['score']*100:.2f}%") | |
# Use the top prediction for further processing | |
top_prediction = car_classifications[0]['label'] | |
brand, model_name = top_prediction.split(' ', 1) | |
st.write(f"Identified Car: {brand} {model_name}") | |
# Get additional information using GPT-3.5-turbo | |
current_year = datetime.now().year | |
overview = get_car_overview(brand, model_name, current_year) | |
st.write("Car Overview:") | |
st.write(overview) | |
# Interactive Price Prediction | |
st.subheader("Price Prediction Over Time") | |
selected_years = st.slider("Select range of years for price prediction", | |
min_value=2000, max_value=2023, value=(2010, 2023)) | |
years = np.arange(selected_years[0], selected_years[1] + 1) | |
predicted_prices = [] | |
for year in years: | |
price = predict_price(model, brand, model_name, year) | |
predicted_prices.append(price) | |
# Plotting the results | |
plt.figure(figsize=(10, 5)) | |
plt.plot(years, predicted_prices, marker='o') | |
plt.title(f"Predicted Price of {brand} {model_name} Over Time") | |
plt.xlabel("Year") | |
plt.ylabel("Predicted Price ($)") | |
plt.grid() | |
st.pyplot(plt) | |
else: | |
st.error("Could not classify the image. Please try again with a different image.") | |
else: | |
st.write("Please upload an image or take a picture to proceed.") |