Trong bài tutorial trước (Xây dựng mô hình Deep learning với Mid-level APIs), chúng ta đã làm quen với việc sử dụng feed_dict nhằm truy xuất dữ liệu để huấn luyện mô hình. Tuy nhiên, nhược điểm lớn nhất của phương pháp này là có tốc độ xử lý chậm do chúng ta phải đợi dữ liệu của batch tiếp theo [1].

Để khắc phục nhược điểm trên, TensorFlow đã giới thiệu tf.data API nhằm tăng hiệu suất và tiết kiệm thời gian trong quá trình huấn luyện bằng cách cho phép truy xuất và xử lý dữ liệu một cách song song. Theo kết quả mô phỏng của Wallarm Research thì việc sử dụng tf.data API có thể giúp chúng ta tiết kiệm được 20-30% thời gian huấn luyện so với khi sử dụng feed_dict [2]:

tf.data API bao gồm hai thành phần chính [3]:

– tf.data.Datasets: dùng đễ lưu trữ dữ liệu. Ở đây, chúng ta có thể hiểu dữ liệu là một chuỗi các phần tử mà mỗi phần tử gồm 1 hoặc nhiều Tensor objects

– tf.data.Iterator: dùng để truy xuất dữ liệu trong datasets (truy xuất từng phần tử một)

1) Datasets

Datasets có thể được tạo ra từ các nguồn khác nhau như từ numpy, từ các tensors, placeholder, các TFRecord format hoặc trực tiếp từ các files. Đoạn code sau là một ví dụ mô tả việc tạo Datasets từ numpy và tensors sử dụng hàm from_tensor_slices():

Sau khi load dữ liệu vào Dataset, chúng ta có thể sử dụng một số hàm của tf.data API để thực hiện các bước xử lý dữ liệu cần thiết (xem thêm tại đây):

– batch(batch_size,..): được dùng để chia dữ liệu thành các mini_batch

– filter(predicate): lọc dữ liệu theo điều kiện quy định bởi predicate

– map(map_funcs,..): thực thi hàm map_funcs với từng phần tử của dataset

– repeat(count): lặp lại Dataset với số lần được quy định bởi count

– shuffle(buffer_size,…): dùng để shuffle các phần tử của dataset một cách ngẫu nhiên. Trong đó, buffer_size quy định kích thước của sampling buffer ( buffer_size nên lớn hơn hoặc bằng với kích thước của dataset)

– zip(datasets): kết hợp các datasets để tạo thành một Dataset mới. Hàm này thường được sử dụng để tạo dataset có dạng (data, label)

Đoạn code sau là một ví dụ về cách sử dụng một số hàm của Dataset:

Như vậy, khi không sử dụng hàm shuffle() thì cả hai lần chạy đều cho kết quả giống nhau còn khi sử dụng shuffle() thì các lần chạy sẽ trả về kết quả khác nhau. Lưu ý: ví dụ trên được dùng để minh họa sự khác nhau khi không sử dụng và sử dụng shuffle(). Trong thực tế chúng ta thường Shuffle data trước khi sử dụng hàm batch()

2) Iterator

Iterator được sử dụng để truy xuất dữ liệu của Datasets. Hiện tại Tensorflow hỗ trợ 4 cấp độ của Iterator theo thứ tự tăng dần như sau:

– One-shot Iterator: là iterator đơn giản nhất, hỗ trợ việc truy xuất dữ liệu của một Dataset với một nguồn dữ liệu duy nhất.

Lưu ý: lỗi OutOfRangeError xuất hiện khi chúng ta truy xuất dữ liệu vượt quá kích thước của Dataset. Thông thường, với mỗi epoch trong quá trình huấn luyện Model, chúng ta sử dụng hàm repeat() để truy xuất lại Dataset từ dữ liệu đầu.

– Initializable Iterator: Khác với One-shot Iterator, Initializable Iterator cho phép chúng ta tạo một dynamic dataset mà data source có thể thay đổi tại runtime. Tuy nhiên, trước khi sử dụng Iterator này, chúng ta phải sử dụng lệnh iterator.initializer:

– Reinitializable Iterator: thay vì chỉ sử dụng 1 dataset như Initializable Iterator, Reinitializable Iterator cho phép chúng ta thay đổi giữa các datasets. Iterator này thường được sử dụng với các Datasets objects có cùng một cấu trúc (ví dụ như train_dataset, valid_dataset và test_dataset)

– Feedable Iterator: Feedable Iterator cho phép chúng ta thay đổi giữa các interators thay vì giữa các datasets như trong Reinitializable Iterator.

3) Thay thế feed_dict bằng tf.data API

Khi sử dụng tf.data API, chúng ta thay thế các placeholder của input và output data trực tiếp bằng dữ liệu từ iterator.get_next(). Sau đó, loại bỏ feed_dict khi huấn luyện mô hình. Quá trình này được mô tả trong đoạn code dưới đây, với việc sử dụng sẵn chương trình Phân loại Wine dataset đã trình bày trong bài tutorial Xây dựng mô hình Deep learning với Mid-level APIs:

Như vậy, trong bài tutorial này chúng ta đã cùng tìm hiểu về cách tạo Datasets, tìm hiểu sự khác nhau giữa các Iterators và cách sử dụng tf.data API để thay thế cho feed_dict nhằm tăng hiệu quả và tiết kiệm thời gian trong quá trình huấn luyện. Các bạn có thể tham khảo Colab notebook của tutorial này trên trang Github của ItechSeeker tại đây. Ngoài ra, các bạn có thể tham khảo một ví dụ phức tạp hơn về cách sử dụng Data input pipeline thay thế cho feed_dict tại bài tutorial Huấn luyện mô hình Seq2seq sử dụng Data Pipeline.

 

Tài liệu tham khảo:

[1] http://www.programmersought.com/article/1339534134/

[2] https://lab.wallarm.com/tensorflow-dataset-api-for-increasing-training-speed-of-neural-networks-43a3050f2080

[3] https://www.tensorflow.org/guide/datasets

Tháng Năm 9, 2019
ITechSeeker