CoreML মডেল ও এর ব্যবহার – ইমেজ ক্লাসিফিকেশন

এপল কিছু প্রিবিল্ড মেশিন লার্নিং মডেল শেয়ার করেছে। আমরা সেখান থেকে MobileNetV2 ব্যবহার করে দেখব কিভাবে ইমেজ ক্লাসিফিকেশন করা যায়।

এর জন্য প্রথমে Core ML Models পেইজ থেকে MobileNetV2 ডাউনলোড করে নিব।

এরপর একটা iOS – SwiftUI প্রজেক্ট তৈরি করব। ডাউনলোডকৃত MobileNetV2.mlmodel মডেল প্রজেক্টে কপি করব।

এই অ্যাপে আমরা ফটো গ্যালারি থেকে ফটো নিয়ে এরপর ক্লাসিফাই করব। তাই আমাদের ফটো লাইব্রেরি ইউজেজ ডেসক্রিপশন যোগ করতে হবে। না হলে অ্যাপ ক্র্যাশ করবে।

Info.plist এ Privacy – Photo Library Usage Description কী এর জন্য “We need access to your photo library to classify images.” ভ্যালু সেট করব।

মডেল লোড করে ইমেজ ক্লাসিফিকেশন করতে পারি এভাবেঃ

// Function to classify the image using Core ML
    func classifyImage(_ image: UIImage) {
        guard let ciImage = CIImage(image: image) else {
            classificationLabel = "Could not convert UIImage to CIImage."
            return
        }
        
        do {
            // Initialize the model with a configuration
            let modelConfiguration = MLModelConfiguration()
            let model = try VNCoreMLModel(for: MobileNetV2(configuration: modelConfiguration).model)
            
            // Create a request for image classification
            let request = VNCoreMLRequest(model: model) { (request, error) in
                if let results = request.results as? [VNClassificationObservation], let topResult = results.first {
                    DispatchQueue.main.async {
                        self.classificationLabel = "Classification: \(topResult.identifier) (\(Int(topResult.confidence * 100))%)"
                    }
                } else {
                    DispatchQueue.main.async {
                        self.classificationLabel = "Could not classify image."
                    }
                }
            }
            
            // Perform the request on a background thread
            let handler = VNImageRequestHandler(ciImage: ciImage)
            DispatchQueue.global().async {
                try? handler.perform([request])
            }
        } catch {
            classificationLabel = "Could not load model: \(error.localizedDescription)"
        }
    }
}

এখানেঃ

 guard let ciImage = CIImage(image: image) else {
        classificationLabel = "Could not convert UIImage to CIImage."
        return
    }

ভিশন ফ্রেমওয়ার্ক সরাসরি UIImage এর উপর কাজ করতে পারে না। তাই শুরুতে UIImage কে CIImage এ কনভার্ট করে নিতে হয়েছে।

এরপর মডেল লোড করে নিয়েছিঃ

let modelConfiguration = MLModelConfiguration()
let model = try VNCoreMLModel(for: MobileNetV2(configuration: modelConfiguration).model)
       

এরপর ইমেজ ক্লাসিফিকেশন করার জন্য VNCoreMLRequest রিকোয়েস্ট তৈরি করা হয়েছে।

          let request = VNCoreMLRequest(model: model) { (request, error) in
                if let results = request.results as? [VNClassificationObservation], let topResult = results.first {
                    DispatchQueue.main.async {
                        self.classificationLabel = "Classification: \(topResult.identifier) (\(Int(topResult.confidence * 100))%)"
                    }
                } else {
                    DispatchQueue.main.async {
                        self.classificationLabel = "Could not classify image."
                    }
                }
            }

মডেল যদি ইমেজ ক্লাসিফিকেশন করতে পারে, তাহলে VNClassificationObservation দিয়ে তা চেক করা করবে। ক্লাসিফিকেশনের উপর ভিত্তি করে classificationLabel ভ্যারিয়েবল আপডেট করা হবে। ক্লাসিফিকেশন না করতে পারলে Could not classify image মেসেজ সেট করবে।

VNImageRequestHandler ইমেজের উপর ক্লাসিফিকেশন রান করবে।

       let handler = VNImageRequestHandler(ciImage: ciImage)
            DispatchQueue.global().async {
                try? handler.perform([request])
            }

সম্পূর্ণ কোডঃ

import SwiftUI
import CoreML
import Vision
import UIKit

struct ContentView: View {
    @State private var image: UIImage? = nil
    @State private var classificationLabel: String = "Pick an image to classify"
    @State private var isImagePickerPresented: Bool = false

    var body: some View {
        VStack {
            Text(classificationLabel)
                .font(.title)
                .padding()
            
            if let image = image {
                Image(uiImage: image)
                    .resizable()
                    .scaledToFit()
                    .frame(height: 300)
                    .padding()
            }

            Button("Pick an Image") {
                isImagePickerPresented = true
            }
            .padding()
        }
        .sheet(isPresented: $isImagePickerPresented, content: {
            ImagePicker(image: $image, onImagePicked: classifyImage)
        })
    }
    
    // Function to classify the image using Core ML
    func classifyImage(_ image: UIImage) {
        guard let ciImage = CIImage(image: image) else {
            classificationLabel = "Could not convert UIImage to CIImage."
            return
        }
        
        do {
            // Initialize the model with a configuration
            let modelConfiguration = MLModelConfiguration()
            let model = try VNCoreMLModel(for: MobileNetV2(configuration: modelConfiguration).model)
            
            // Create a request for image classification
            let request = VNCoreMLRequest(model: model) { (request, error) in
                if let results = request.results as? [VNClassificationObservation], let topResult = results.first {
                    DispatchQueue.main.async {
                        self.classificationLabel = "Classification: \(topResult.identifier) (\(Int(topResult.confidence * 100))%)"
                    }
                } else {
                    DispatchQueue.main.async {
                        self.classificationLabel = "Could not classify image."
                    }
                }
            }
            
            // Perform the request on a background thread
            let handler = VNImageRequestHandler(ciImage: ciImage)
            DispatchQueue.global().async {
                try? handler.perform([request])
            }
        } catch {
            classificationLabel = "Could not load model: \(error.localizedDescription)"
        }
    }
}

// ImagePicker helper to allow the user to pick an image
struct ImagePicker: UIViewControllerRepresentable {
    @Binding var image: UIImage?
    var onImagePicked: (UIImage) -> Void

    func makeCoordinator() -> Coordinator {
        return Coordinator(self)
    }

    func makeUIViewController(context: Context) -> UIImagePickerController {
        let picker = UIImagePickerController()
        picker.delegate = context.coordinator
        return picker
    }

    func updateUIViewController(_ uiViewController: UIImagePickerController, context: Context) {}

    class Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
        var parent: ImagePicker

        init(_ parent: ImagePicker) {
            self.parent = parent
        }

        func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
            if let uiImage = info[.originalImage] as? UIImage {
                parent.image = uiImage
                parent.onImagePicked(uiImage)
            }

            picker.dismiss(animated: true)
        }
    }
}

#Preview {
    ContentView()
}

গ্যালারি থেকে একটা ইমেজ সিলেক্ট করেন। মডেল ইমেজটি ক্লাসিফাই করার চেষ্টা করবে।

বলে রাখা ভালো এটা খুবি লাইটওয়েট একটা মডেল। তাই অনেক ভুল ক্লাসিফাইও করবে। নির্দিষ্ট কোন প্রজেক্টে ব্যবহার করতে চাইলে নিজের মত করে ট্রেইন করে নিতে হবে। এছাড়া নিজের কোন মডেল ব্যবহার করতে চাইলে আগে CoreML এ কনভার্ট করে নিতে হবে। তা নিয়ে বিস্তারিত আরেকটা লেখা লিখেছিঃ টেনসরফ্লো মডেলকে CoreML এ কনভার্ট করে iOS অ্যাপে ব্যবহার

Leave a Reply