How to use GPU on Python script

510 Views Asked by At

When I run this code, it runs on CPU. It runs very slowly when it runs on the CPU. That's why I need to use GPU. I tried many ways but I can't do it, it uses CPU every time.


import tkinter as tk
from tkinter import messagebox

from PIL import Image, ImageTk
import cv2
import numpy as np
import face_recognition
import os
import imutils
import time
from imutils.video import VideoStream
from keras.models import load_model
from keras.preprocessing import image
import tensorflow as tf


# Tkinter penceresini oluştur
root = tk.Tk()
root.title("Yüz Tanıma ve Duygu Analizi")

# Frame'leri oluştur
main_frame = tk.Frame(root)
main_frame.pack()

left_frame = tk.Frame(main_frame)
left_frame.pack(side=tk.LEFT)

right_frame = tk.Frame(main_frame)
right_frame.pack(side=tk.RIGHT)

# Kamera görüntüsü için etiket
video_label = tk.Label(left_frame)
video_label.pack()

# Yüz Tanıma ve Duygu Analizi etiketi
label = tk.Label(right_frame, text="Yüz Tanıma ve Duygu Analizi", font=("Helvetica", 16))
label.pack()

# Uygulamayı kapatacak buton
close_button = tk.Button(right_frame, text="Uygulamayı Kapat", command=root.quit)
close_button.pack()

# Eğitilmiş duygu analizi modelini yükle
model = load_model('model_1.h5')
label_dict = {0: 'Kizgin', 1: 'İgrenme', 2: 'Korku', 3: 'Mutlu', 4: 'Notr', 5: 'Uzgun', 6: 'Saskin'}

# Yüz tanıma için kullanılacak parametreler
DEFAULT_PROTOTXT = "deploy.prototxt.txt"
DEFAULT_MODEL = "res10_300x300_ssd_iter_140000.caffemodel"
DEFAULT_CONFIDENCE = 0.5

# Caffe modelini diskten yükle
net = cv2.dnn.readNetFromCaffe(DEFAULT_PROTOTXT, DEFAULT_MODEL)

# Video akışını başlat
vs = VideoStream(src=0).start()
time.sleep(2.0)

# Kamera görüntüsünü güncelle
def update_video():
    frame = vs.read()
    frame = imutils.resize(frame, width=900)
    (h, w) = frame.shape[:2]

    blob = cv2.dnn.blobFromImage(cv2.resize(frame, (300, 300)), 1.0, (300, 300), (104.0, 177.0, 123.0))
    net.setInput(blob)
    detections = net.forward()

    for i in range(0, detections.shape[2]):
        confidence = detections[0, 0, i, 2]

        if confidence < DEFAULT_CONFIDENCE:
            continue

        box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
        (startX, startY, endX, endY) = box.astype("int")

        face_roi = frame[startY:endY, startX:endX]
        face_gray = cv2.cvtColor(face_roi, cv2.COLOR_BGR2GRAY)
        face_img = cv2.resize(face_gray, (48, 48))

        face_img_array = image.img_to_array(face_img)
        face_img_array = np.expand_dims(face_img_array, axis=0)
        face_img_array = np.expand_dims(face_img_array, axis=-1)

        predictions = model.predict(face_img_array)
        emotion_label_index = np.argmax(predictions)
        predicted_emotion = label_dict[emotion_label_index]

        cv2.rectangle(frame, (startX, startY), (endX, endY), (0, 0, 255), 2)
        cv2.putText(frame, f'Duygu: {predicted_emotion}', (startX, startY - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (255, 255, 255), 2, cv2.LINE_AA)

    # Yüz eşleştirme için resimleri yükle
    image_folder = "image"  # Resimlerin bulunduğu klasör

    known_faces = []
    known_face_names = []

    for file in os.listdir(image_folder):
        if file.endswith(".jpg"):
            file_path = os.path.join(image_folder, file)
            img = face_recognition.load_image_file(file_path)
            encoding = face_recognition.face_encodings(img)[0]  # Her bir resmin yüz kodlamasını al
            known_faces.append(encoding)
            known_face_names.append(os.path.splitext(file)[0])  # Dosya adını yüz ismi olarak ekle

    # Yüz eşleştirme
    face_locations = face_recognition.face_locations(frame)
    unknown_face_encodings = face_recognition.face_encodings(frame, face_locations)

    for face_encoding in unknown_face_encodings:
        matches = face_recognition.compare_faces(known_faces, face_encoding)
        name = "Bilinmiyor"  # Eğer eşleşme yoksa

        if True in matches:
            first_match_index = matches.index(True)
            name = known_face_names[first_match_index]

        # Yüzün etrafına isim yazdır
        cv2.putText(frame, name, (startX, startY - 30), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (255, 255, 255), 2, cv2.LINE_AA)

    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    photo = ImageTk.PhotoImage(image=Image.fromarray(frame))
    video_label.config(image=photo)
    video_label.image = photo
    video_label.after(10, update_video)

# Kamera görüntüsünü göster
update_video()

# Yeni label oluştur ve konumlandır
label_text = tk.Label(right_frame, text="İsim Giriniz")
label_text.pack()

# Yeni metin kutusu oluştur ve konumlandır
textbox = tk.Entry(right_frame)
textbox.pack()
def save_photo():
    # Metin kutusundaki değeri al
    photo_name = textbox.get()

    # Eğer metin kutusu boşsa rastgele bir isimle kaydet
    if not photo_name.strip():
        # Uyarı mesajı
        messagebox.showwarning("Uyarı", "Fotoğraf adı boş olamaz. Lütfen bir ad girin.")
        return

    # Kamera görüntüsünü al
    frame = vs.read()

    # Fotoğrafı kaydet
    image_folder = "C:/Users/Paban/Desktop/FaceDetection_Realtime/image"
    file_path = os.path.join(image_folder, f"{photo_name}.jpg")
    cv2.imwrite(file_path, frame)
def show_photo():
    # Metin kutusundaki değeri al
    photo_name = textbox.get()

    # Eğer metin kutusu boşsa uyarı mesajı göster
    if not photo_name.strip():
        messagebox.showwarning("Uyarı", "Fotoğraf adı boş olamaz. Lütfen bir ad girin.")
        return

    # Dosya yolu oluştur
    image_folder = "C:/Users/Paban/Desktop/FaceDetection_Realtime/image"
    file_path = os.path.join(image_folder, f"{photo_name}.jpg")

    # Fotoğrafın varlığını kontrol et
    if not os.path.isfile(file_path):
        messagebox.showwarning("Uyarı", "Belirtilen isimde bir fotoğraf bulunamadı.")
        return

    # Fotoğrafı göster
    img = Image.open(file_path)
    img.show()

# Yeni butonu oluştur ve fonksiyonu bağla
save_button = tk.Button(right_frame, text="Fotoğrafı Kaydet", command=save_photo)
save_button.pack()

# Yeni butonu oluştur ve fonksiyonu bağla
show_button = tk.Button(right_frame, text="Fotoğrafı Göster", command=show_photo)
show_button.pack()

# Tkinter penceresini çalıştır
root.mainloop()

# Temizlik işlemleri
cv2.destroyAllWindows()
vs.stop()

I installed Cuda, CuDNN. When I type tf.test.is_gpu_available it says true on the command line. But when I run it, I get these outputs: OUTPUT

2

There are 2 best solutions below

0
Sayed Mahdi On

First, check that your installed version of tensorflow is compatible with CUDA and CuDNN, second try to config tensorflow with this code snippets:

physical_devices = tf.config.list_physical_devices('GPU')
if len(physical_devices) > 0:
    tf.config.experimental.set_memory_growth(physical_devices[0], True)
    print(f"TensorFlow is using GPU: {physical_devices[0]}")
else:
    print("No GPU devices found. TensorFlow will run on CPU.")

Note that you may want to set GPU memory growth to avoid allocating all GPU memory at once. Add the following code after importing tensorflow :

gpus = tf.config.experimental.list_physical_devices('GPU')
if gpus:
    try:
        for gpu in gpus:
            tf.config.experimental.set_memory_growth(gpu, True)
    except RuntimeError as e:
        print(e)
0
forest-spells On

It is possible that the TensorFlow in your code uses the GPU correctly. Your code is not optimized for GPU use, and that could be the reason for it being slow.

First, check if GPU is visible to TF and if it is being used correctly:

print(f"TensorFlow version: {tf.__version__}")

gpus = tf.config.list_physical_devices('GPU')
if gpus:
    try:
        logical_gpus = 
tf.config.experimental.list_logical_devices('GPU')
        print(len(gpus), "Physical GPUs,", len(logical_gpus), "Logical GPUs")
    except RuntimeError as e:
        print(e)
else:
    print("No GPUs detected.")

matrix_a = tf.random.normal(shape=(1000, 1000))
matrix_b = tf.random.normal(shape=(1000, 1000))
start_time_cpu = time.time()
result_cpu = tf.matmul(matrix_a, matrix_b)
end_time_cpu = time.time()
print("Time on CPU:", end_time_cpu - start_time_cpu)

if gpus:
    matrix_a_gpu = tf.constant(matrix_a)
    matrix_b_gpu = tf.constant(matrix_b)
    start_time_gpu = time.time()
    result_gpu = tf.matmul(matrix_a_gpu, matrix_b_gpu)
    end_time_gpu = time.time()

    print("Time on GPU:", end_time_gpu - start_time_gpu)
else:
    print("GPU not available.")

As a result, you should notice that this code snippet executed on the GPU performed significantly faster (in my case, the above operation gives the result:

Time on CPU: 0.0872....

Time on GPU: 0.0002...)

If you find that there is a problem, it would be useful to know about your version of TensorFlow and the full list of TF warnings from the console (what is shown in your screen is probably not everything?).

Going forward, I recommend you check the execution times of each block of code to see what is causing the delays. The problem may be your object detector. The DNN method with OpenCV is quite resource intensive. If you want to detect faces up close in conditions without occlusion or other obstructions, you might want to consider another method, such as HOG

Keep in mind that just importing TensorFlow does not cause all the code to execute on the GPU. By default, the code still uses the CPU. Most libraries like e.g. Numpy also use the CPU. You use for loops, such as here:

   for file in os.listdir(image_folder):
        if file.endswith(".jpg"):
            file_path = os.path.join(image_folder, file)
            img = face_recognition.load_image_file(file_path)
        encoding = 
face_recognition.face_encodings(img)[0]  
            known_faces.append(encoding)
        

I don't know exactly how many images you have in this folder, but if you have a lot of them, it might be worth executing in parallel.

def process_image(file):
    if file.endswith(".jpg"):
            file_path = os.path.join(image_folder, file)
            img = face_recognition.load_image_file(file_path)
        encoding = 
face_recognition.face_encodings(img)[0]  
            known_faces.append(encoding)

with concurrent.futures.ThreadPoolExecutor() as executor:
    encodings = list(executor.map(process_image, os.listdir(image_folder)))

Sometimes executing code in parallel on the CPU is enough to get satisfactory performance. If not, you can use GPU-enabled frameworks and execute code using methods from there. E.g. Numpy has its counterparts on the GPU (CuPy, JAX). Then you rather use for loop a little less often, and instead perform operations in parallel, as GPUs are not specialized to process data sequentially.

Also, check this: OpenCV DNN Module with NVIDIA GPUs