Các thuật toán học máy có ở khắp mọi nơi xung quanh bạn. Các đề xuất bạn nhận được trên youtube, ước tính thời gian đi làm, nhận diện khuôn mặt trong ảnh google và nhiều tính năng khác, tất cả những tính năng này giúp cuộc sống của chúng ta dễ dàng hơn sẽ không thể thực hiện được nếu không có những tiến bộ trong thuật toán máy học.
Các bài viết liên quan:
Học máy có thể được phân loại thêm thành nhiều lĩnh vực khác nhau; nhiều trong số này có ý nghĩa sâu sắc đối với cuộc sống hàng ngày của chúng ta. Một lĩnh vực đang phát triển trong Học máy là Object detection.
Object detection
Nhiệm vụ được giao cho một thuật toán Object detection khá dễ hiểu đối với con người. Nó có nhiệm vụ phát hiện tất cả các đối tượng từ một hình ảnh cho trước. Về mặt hình thức, Object detection là một kỹ thuật thị giác máy tính cho phép chúng ta xác định và định vị các đối tượng trong một hình ảnh hoặc video. Với loại nhận dạng và bản địa hóa này, tính năng Object detection có thể được sử dụng để đếm các đối tượng trong một cảnh và xác định và theo dõi vị trí chính xác của chúng trong khi ghi nhãn chính xác.
Nguồn: https://github.com/pjreddie/darknet/blob/master/data/dog.jpg
Tình trạng hiện tại là mạng EfficientDet7 đạt độ chính xác trung bình gần 55,1% trên tập dữ liệu COCO của Microsoft. Nó hiệu quả hơn nhiều so với những người tiền nhiệm về thời gian suy luận cũng như độ chính xác.
Các ứng dụng của thuật toán Object detection được phổ biến rộng rãi. Object detection có thể được sử dụng ở những nơi như hệ thống an ninh, phương tiện tự hành và phân tích hình ảnh y tế, chỉ để nêu tên một số. Object detection dường như là một nhiệm vụ tầm thường đối với con người nhưng đối với một cỗ máy thì việc phân loại đối tượng từ khung ảnh lại là một việc khá phức tạp. Đây là lúc API Object detection TensorFlow phát huy tác dụng.
API TF Objective Det là gì?
API TensorFlow là một giao diện dễ sử dụng bao quanh chức năng Object detection cốt lõi của các pre-trained models’ khác nhau. API này giúp chúng tôi dễ dàng tạo, đào tạo và chạy suy luận trên nhiều mô hình. Bạn cũng có thể sử dụng bất kỳ mạng nào được đào tạo trước được liệt kê trong Vườn thú TF2. Tôi đã thảo luận về các mô hình khác nhau trong Vườn thú TF2 trong phần sau. Điều này sẽ cho phép bạn xác định chính xác mô hình bạn nên sử dụng theo nhu cầu của bạn. Cách dễ nhất để bắt đầu là chạy mã của bạn trên đám mây trên sổ ghi chép CoLab. Môi trường Colab đi kèm với hầu hết các phụ thuộc được tải trước, vì vậy sẽ không mất nhiều thời gian để bắt đầu.
Điều đầu tiên bạn cần làm là cài đặt API Object detection trong môi trường colab của bạn. Một điều cần lưu ý về môi trường này là phiên của bạn chỉ được lưu trữ trong một thời gian sau khi bạn đóng tab trình duyệt của mình. Khi bạn bị ngắt kết nối khỏi phiên của mình, sổ ghi chép sẽ được tái chế và mỗi khi bạn cần làm việc trên sổ ghi chép đó, bạn cần thực hiện từng bước liên quan đến việc tải xuống API.
Các mô hình trong TF2 ZOO
Thời gian suy luận của một mô hình là thời gian được thực hiện bởi chương trình để chạy suy luận trên một ví dụ huấn luyện sử dụng mô hình cụ thể đó. Ngoài hiệu suất phần cứng, thời gian suy luận cũng phụ thuộc vào số lượng ma trận, các thao tác và phép nhân liên quan đến việc chạy suy luận bằng cách sử dụng mô hình. Rõ ràng, khi kích thước đầu vào tăng lên, số lượng pixel liên quan đến hình ảnh cũng tăng lên, điều này cuối cùng dẫn đến việc tăng số lượng phép tính. Do đó, chúng ta có thể nói rằng đối với các kiến trúc mô hình tương tự, việc tăng kích thước đầu vào cũng làm tăng thời gian suy luận của nó.
Các thuật toán cũng sử dụng các xương sống khác nhau để Object detection, điều này ảnh hưởng đáng kể đến điểm mAP. Trước khi bắt đầu sử dụng một thuật toán nào đó, bạn phải làm quen với xương sống đang được sử dụng để có thể đánh giá liệu chúng có đáp ứng trường hợp sử dụng của bạn hay không.
Trong trường hợp thời gian suy luận là ưu tiên của bạn, thì bạn nên sử dụng thuật toán R-CNN nhanh hơn hoặc sử dụng kiến trúc mạng di động kết hợp với kích thước đầu vào thấp hơn. Ở kích thước khác, nếu bạn muốn tạo ra các dự đoán chính xác hơn, bạn nên cố gắng sử dụng kích thước đầu vào lớn hơn
- Centernet: Object detection khung hơi khác so với các phương pháp Object detection không có mỏ neo truyền thống. Mô hình này dự đoán một bộ ba điểm trên hình ảnh để tìm một hình ảnh. Theo truyền thống, các mô hình sử dụng một cặp điểm chính để phát hiện một đối tượng trong ảnh.
- EfficientDet: Thuật toán này sử dụng kiến trúc mạng hiệu quả mới làm xương sống của nó, giúp nó hoạt động mạnh mẽ và nhanh chóng. Các đầu ra của mỗi lớp bên trong effnet được đưa vào mạng đặc tính hai chiều, sau đó sẽ xuất ra các lớp và hộp giới hạn.
- SSD: Phát hiện một lần chụp có nghĩa là mỗi đối tượng trong hình ảnh được định vị và đánh dấu chỉ trong một lần chuyển tiếp duy nhất của mạng nơ-ron. Điều này làm giảm đáng kể thời gian suy luận vì chúng ta đang giảm số lượng các phép toán nhân ma trận.
- Faster R-CNN: Thuật toán này nhanh hơn rất nhiều so với các thuật toán tiền nhiệm. Điều này sử dụng mạng đề xuất khu vực để tạo dự đoán trái ngược với tìm kiếm chọn lọc trong R-CNN nhanh. Tuy nhiên, một điều quan trọng cần lưu ý là thuật toán này yêu cầu một số lần chuyển hình ảnh qua CNN để đưa ra dự đoán chính xác.
Bắt đầu với API
Chúng tôi sẽ làm việc trong môi trường Colab, vì vậy chúng tôi không cần phải suy nghĩ nhiều về việc cài đặt các phụ thuộc. Chúng tôi sẽ sử dụng protobufs để biên dịch các tệp nhị phân trong mô-đun API Object detection TensorFlow. Protobufs là một cách trung lập về ngôn ngữ để mô tả thông tin. Nói cách khác, bạn chỉ có thể viết protobuf một lần và sau đó bạn có thể biên dịch nó theo yêu cầu để sử dụng với Python, Java hoặc bất kỳ ngôn ngữ nào khác.
# Gets models from TF2 Zoo $ git clone https://github.com/tensorflow/models.git # Compile protobufs using protoc command $ cd ./models/research/ $ protoc object_detection/protos/*.proto --python_out=. # Install TensorFlow Object Detection API. $ cp object_detection/packages/tf2/setup.py . $ python -m pip install . # Run the model builder test $ python /content/models/research/object_detection/builders/model_builder_tf2_test.py
Lựa chọn dữ liệu
Để cung cấp dữ liệu vào mô hình của chúng tôi, chúng tôi sẽ cung cấp dữ liệu ở định dạng tfrecords. Nói một cách đơn giản, tfrecord là một định dạng lưu trữ nhị phân được tối ưu hóa để sử dụng với TensorFlow. Bạn có thể chọn bất kỳ tập dữ liệu nào mà bạn muốn đào tạo mô hình của mình. Bạn phải đảm bảo rằng dữ liệu có sẵn ở định dạng tfrecords để API có thể sử dụng nó. Tôi sẽ sử dụng một tập dữ liệu tùy chỉnh trên Kaggle, tập dữ liệu này đã được chuyển đổi thành tfrecords.
Tại sao sử dụng bản ghi Tf?
Một tệp bản ghi tf lưu trữ dữ liệu nhị phân trong một cấu trúc có trình tự. Việc chuyển đổi sang tfrecords ban đầu có thể là một nhiệm vụ khó khăn vì nhiệm vụ tìm hiểu một định dạng tệp mới để học sâu có vẻ khó khăn đối với một số người.
Tuy nhiên, chuyển đổi dữ liệu từ hình ảnh sang tfrecords có lợi vì nhiều lý do. Chúng tôi có thể xử lý trước dữ liệu trước khi lưu dưới dạng tfrecords. Điều này cho phép chúng tôi sử dụng dữ liệu sau này bằng cách chỉ cần đọc tệp tfrecords và giúp chúng tôi không phải đau đầu khi chuẩn hóa lại dữ liệu. Vì chúng tôi đang xử lý dữ liệu trước khi lưu dưới dạng tfrecords, điều này cũng cung cấp cho chúng tôi sự linh hoạt để kết hợp nhiều bộ dữ liệu một cách dễ dàng. Ví dụ: 2 bộ dữ liệu có thể sử dụng các ký hiệu hơi khác nhau cho các hộp giới hạn của chúng. Chúng tôi có thể thay đổi điều này bằng cách sử dụng tiền xử lý và lưu dữ liệu một cách thống nhất.
Định dạng tệp TFRecord được tối ưu hóa để sử dụng với tensorflow. Một đường dẫn cung cấp dữ liệu được tối ưu hóa cho phép đào tạo và thử nghiệm các mô hình khác nhau nhanh hơn.
Tôi đang sử dụng tập dữ liệu kangaroo có sẵn trên Kaggle. Trong tập dữ liệu này, chúng tôi sẽ chỉ sử dụng 1 lớp để phát hiện, đó là lớp kangaroo, vì mục đích đơn giản. Chúng tôi sẽ chỉ định điều này trong một labelmap.pbtxt
và tải nó lên phiên colab của chúng tôi để tập lệnh chuyển đổi tập dữ liệu sang định dạng tfrecord có thể xác định số lớp.
Downloading dataset from kaggle pip install -q kaggle pip install -q kaggle-cli # Set your username and API tokens as environment variables KAGGLE_USERNAME='username' KAGGLE_KEY='api-token' # Creating folder for dataset and downloading mkdir ./dataset cd ./dataset kaggle datasets download -d hugozanini1/kangaroodataset --unzip
Bây giờ, chúng tôi chuyển đổi tập dữ liệu thành tfrecords bằng cách sử dụng tập lệnh create_tfrecords do tác giả tập dữ liệu cung cấp. Chúng tôi có thể tải tập lệnh này bằng cách tải xuống từ GitHub.
# Download the script to generate TFRecords from dataset cd /content/ wget https://raw.githubusercontent.com/hugozanini/object-detection/master/generate_tf_record.py # Convert to tfrecords python generate_tf_record.py -l labelmap.txt -o dataset/train.record -i dataset/images -csv dataset/train_labels.csv python generate_tf_record.py -l labelmap.txt -o dataset/test.record -i dataset/images -csv dataset/test_labels.csv
Bây giờ hãy để chúng tôi hiểu những gì tập lệnh create_tf_Record.py này đang thực hiện đằng sau hậu trường. Người ta phải hiểu cách hoạt động của tập lệnh để bạn có thể tạo tập lệnh của mình cho các tập dữ liệu tùy chỉnh trong tương lai. Liên kết này lưu trữ tập lệnh python chuyển đổi thô. Tôi sẽ tập trung vào các thành phần quan trọng của kịch bản trong phần tiếp theo. Một điều quan trọng cần xem xét là ở đây tập dữ liệu cung cấp cho chúng ta một tệp CSV. Tệp CSV chứa tên tệp, xmin, ymin, xmax, ymax và tên lớp cho một hình ảnh nhất định. Chúng tôi có nhiều bản ghi có cùng giá trị trong cột tên tệp khi chúng tôi có nhiều hộp giới hạn.
Lớp TFRecord – Đây chỉ là một lớp đóng gói tất cả các logic cần thiết để chuyển đổi dữ liệu thành tfrecords. Thông thường, thực hành tốt là đóng gói các hàm để mã của bạn trở nên dễ bảo trì và dễ hiểu hơn.
Chức năng tách – Như đã thảo luận trước đó, một có thể có nhiều hộp giới hạn trong một hình ảnh và trong trường hợp đó, chúng tôi có nhiều bản ghi có cùng tên tệp trong tệp CSV. Hàm này nhóm tất cả các bản ghi như vậy lại với nhau và trả về một tuple được đặt tên với tên tệp thuộc tính và nhóm gấu trúc.
Hàm create_tf – Đây là hàm quan trọng nhất chịu trách nhiệm tạo tfrecord riêng lẻ cho một hình ảnh.
Những dòng này đọc hình ảnh từ bộ nhớ
with tf.io.gfile.GFile(os.path.join(path, '{}'format(group.filename)), 'rb') as fid: encoded_jpg = fid.read() encoded_jpg_io = io.BytesIO(encoded_jpg) image = Image.open(encoded_jpg_io) width, height = image.size
Các dòng này chèn các giá trị của tọa độ và nhãn lớp vào danh sách trống. Một điều quan trọng cần lưu ý ở đây là tọa độ nằm trong khoảng từ 0-1 vì chúng ta đang chia các tọa độ theo chiều rộng và chiều cao cho phù hợp.
tf_sample = tf.train.Example(features=tf.train.Features(feature={ 'image/height': dataset_util.int64_feature(height), 'image/width': dataset_util.int64_feature(width), 'image/filename': dataset_util.bytes_feature(filename), 'image/source_id': dataset_util.bytes_feature(filename), 'image/encoded': dataset_util.bytes_feature(encoded_jpg), 'image/format': dataset_util.bytes_feature(image_format), 'image/object/bbox/xmin': dataset_util.float_list_feature(xmins), 'image/object/bbox/xmax': dataset_util.float_list_feature(xmaxs), 'image/object/bbox/ymin': dataset_util.float_list_feature(ymins), 'image/object/bbox/ymax': dataset_util.float_list_feature(ymaxs), 'image/object/class/text': dataset_util.bytes_list_feature(classes_text), 'image/object/class/label': dataset_util.int64_list_feature(classes), })) return tf_sample
Đây là một lệnh gọi phương thức khởi tạo đơn giản tới lớp tf.train.Example. Chúng ta tạo một feature dict được đưa vào hàm tạo để tất cả các bản ghi của chúng ta có cùng một cấu trúc. Cuối cùng, hàm serializeToString được cung cấp trong lớp tf.train.Example có thể được sử dụng để tuần tự hóa dữ liệu tfrecord.
tf_sample = tf.train.Example(features=tf.train.Features(feature={ 'image/height': dataset_util.int64_feature(height), 'image/width': dataset_util.int64_feature(width), 'image/filename': dataset_util.bytes_feature(filename), 'image/source_id': dataset_util.bytes_feature(filename), 'image/encoded': dataset_util.bytes_feature(encoded_jpg), 'image/format': dataset_util.bytes_feature(image_format), 'image/object/bbox/xmin': dataset_util.float_list_feature(xmins), 'image/object/bbox/xmax': dataset_util.float_list_feature(xmaxs), 'image/object/bbox/ymin': dataset_util.float_list_feature(ymins), 'image/object/bbox/ymax': dataset_util.float_list_feature(ymaxs), 'image/object/class/text': dataset_util.bytes_list_feature(classes_text), 'image/object/class/label': dataset_util.int64_list_feature(classes), })) return tf_sample
Hàm tạo – Hàm này tập hợp tất cả logic đã thảo luận từ trước đến nay và ghi các bản ghi vào tệp đầu ra được chỉ định của chúng tôi. Quy trình làm việc cho chức năng này như sau:
Khởi tạo các đối tượng cần thiết để bắt đầu ghi hồ sơ.
Tạo nhóm bằng cách gọi hàm tách trên khung dữ liệu.
Lặp lại từng nhóm, gọi hàm create_tf, hàm này trả về một cá thể tf.Train.Example.
Ghi vào tệp đầu ra trên mỗi lần lặp bằng cách sử dụng cá thể tfRecordWriter được khởi tạo ở đầu lệnh gọi hàm.
def generate(self, output_path, image_dir, csv_input) -> None: writer = tf.io.TFRecordWriter(output_path) path = os.path.join(image_dir) data = pd.read_csv(csv_input) grouped = self.split(data, 'filename') for group in grouped: try: tf_sample = self.create_tf(group, path) writer.write(tf_sample.SerializeToString()) except: continue logging.info('Successfully created the TFRecords: {}'.format(output_path))
Chọn Model Architecture
Tương tự như tập dữ liệu, bạn có thể sử dụng bất kỳ mô hình nào mà bạn muốn đào tạo. Đối với bài tập này, tôi đang sử dụng kiểu SSD mobilenet v2 320 * 320.
# Download model cd %ROOT_DIR% wget http://download.tensorflow.org/models/object_detection/classification/tf2/20200710/mobilenet_v2.tar.gz tar -xvf mobilenet_v2.tar.gz rm mobilenet_v2.tar.gz # Get configuration files for the model before training wget https://raw.githubusercontent.com/tensorflow/models/master/research/object_detection/configs/tf2/ssd_mobilenet_v2_320x320_coco17_tpu-8.config mv ssd_mobilenet_v2_320x320_coco17_tpu-8.config mobilenet_v2.config
Bắt đầu Training
Trước khi đào tạo mô hình, chúng ta cần thiết lập một vài siêu tham số và tệp cấu hình để API sử dụng. Trong các ô mã dưới đây, tôi đã sử dụng các siêu tham số theo đề xuất của các tác giả bài báo về mobilenet. Tuy nhiên, bạn cũng có thể thử nghiệm với những thứ đó và finetune để có được những điều tốt nhất mô hình khả thi.
Tệp cấu hình cuối cùng có một số tham số trong đó có một số tham số được thảo luận dưới đây:
fine_tune_checkpoint: "/content/mobilenet_v2/mobilenet_v2.ckpt-1" fine_tune_checkpoint_type: "classification"
Các tham số này cho API biết rằng chúng tôi đang tinh chỉnh mô hình của mình và nó sẽ tải các trọng số mô hình được lưu tại đường dẫn fine_tune_checkpoint.
optimizer
Tham số này chịu trách nhiệm cung cấp các tham số được yêu cầu bởi trình tối ưu hóa để chạy mô tả gradient. Nó cung cấp các giá trị như tốc độ học tập, tốc độ học tập khởi động, v.v.
Image_resizer
Điều này sẽ sửa kích thước của hình ảnh đầu vào vào mạng.
Tất cả các thông số cần thiết khác không được bao gồm hoặc cần được ghi đè được chỉ định bên dưới. Sau đó, chúng sẽ được ghi vào tệp cấu hình trước khi đào tạo.
# Define paths to necessary directories num_classes = 1 batch_size = 96 num_steps = 7500 num_eval_steps = 1000 train_record_path = './dataset/train.record' test_record_path = './dataset/test.record' model_dir = './training/' labelmap_path = './labelmap.pbtxt' pipeline_config_path = 'mobilenet_v2.config' fine_tune_checkpoint = '.mobilenet_v2/mobilenet_v2.ckpt-1'
Chỉnh sửa tệp cấu hình đã có trước để thực hiện học chuyển trên tập dữ liệu tùy chỉnh
import re with open(pipeline_config_path) as f: config = f.read() with open(pipeline_config_path, 'w') as f: # Set labelmap path config = re.sub('label_map_path: ".*?"', 'label_map_path: "{}"'.format(labelmap_path), config) # Set fine_tune_checkpoint path config = re.sub('fine_tune_checkpoint: ".*?"', 'fine_tune_checkpoint: "{}"'.format(fine_tune_checkpoint), config) # Set train tf-record file path config = re.sub('(input_path: ".*?)(PATH_TO_BE_CONFIGURED/train)(.*?")', 'input_path: "{}"'.format(train_record_path), config) # Set test tf-record file path config = re.sub('(input_path: ".*?)(PATH_TO_BE_CONFIGURED/val)(.*?")', 'input_path: "{}"'.format(test_record_path), config) # Set number of classes. config = re.sub('num_classes: [0-9]+', 'num_classes: {}'.format(num_classes), config) # Set batch size config = re.sub('batch_size: [0-9]+', 'batch_size: {}'.format(batch_size), config) # Set training steps config = re.sub('num_steps: [0-9]+', 'num_steps: {}'.format(num_steps), config) f.write(config)
Kiểm tra Model metrics
Sau khi đào tạo, chúng tôi cần kiểm tra các chỉ số của mô hình được đào tạo của chúng tôi để có được cái nhìn sâu sắc về
cho dù mô hình có hoạt động tốt trên dữ liệu không nhìn thấy hay không.
Để đánh giá mô hình được đào tạo, hãy chạy tập lệnh sau:
!python ./models/research/object_detection/model_main_tf2.py \ --pipeline_config_path={pipeline_config_path} \ --model_dir={model_dir} \ --checkpoint_dir={model_dir}
Dòng này trả về các giá trị của các chỉ số như độ chính xác, thu hồi và IoU cho dữ liệu không nhìn thấy.
Để hình dung các số liệu trên tensorboard, bạn có thể chạy:
load_ext tensorboard tensorboard --logdir '/content/training/'
Chạy suy luận:
image_np = load_image_into_numpy_array('dataset/images/kangaroo-108.jpg') output_dict = run_inference_for_single_image(model, image_np) vis_util.visualize_boxes_and_labels_on_image_array( image_np, output_dict['detection_boxes'], output_dict['detection_classes'], output_dict['detection_scores'], category_index, instance_masks=output_dict.get('detection_masks_reframed', None), use_normalized_coordinates=True, line_thickness=25) display(Image.fromarray(image_np))