Phân loại hình ảnh CNN trong TensorFlow với các bước và ví dụ

⚡ Tóm tắt thông minh

Mạng nơ-ron tích chập (CNN) quét ảnh bằng các bộ lọc nhỏ thay vì gán trọng số bằng nhau cho mỗi pixel, đó là lý do tại sao chúng thống trị thị giác máy tính. Hướng dẫn này sẽ giải thích từng lớp và sau đó phân loại các chữ số MNIST bằng TensorFlow.

  • 🔘 Bốn thành phần: Mỗi mạng tích chập đều bao gồm các lớp tích chập, hàm phi tuyến ReLU, lớp gộp và một lớp phân loại kết nối đầy đủ.
  • ☑️ Cơ chế tích chập: Bộ lọc 3×3 hoặc 5×5 trượt trên ảnh và phép nhân từng phần tử sẽ xây dựng bản đồ đặc trưng.
  • Ba nút điều khiển: Depth xác định số lượng bộ lọc, stride xác định khoảng cách giữa các cửa sổ, và zero-padding giữ nguyên kích thước đầu ra.
  • 🧪 PoolinHiệu ứng g: Sử dụng max pooling với cửa sổ 2×2 và bước nhảy 2, chia đôi mỗi trục, giúp giảm trọng số và hạn chế hiện tượng quá khớp.
  • 🛠️ Bảy bước xây dựng: Tải lên tập dữ liệu, sau đó định nghĩa các lớp đầu vào, tích chập, gộp, tích chập thứ hai, lớp dày đặc và lớp logit.
  • 📈 Kết quả đo được: Mô hình ước lượng được đánh giá cho thấy độ chính xác là 0.9689286 trên tập dữ liệu MNIST, cao hơn mức 96% đạt được bởi một mạng nơ-ron thông thường.

Phân loại ảnh CNN trong TensorFlow

Mạng Nơ-ron Hợp pháp là gì?

Mạng thần kinh chuyển đổiMạng nơ-ron đa lớp (CNN), còn được gọi là mạng nơ-ron tích chập (convnets) hoặc mạng nơ-ron tích chập (CNN), là một phương pháp nổi tiếng trong các ứng dụng thị giác máy tính. Nó là một lớp mạng nơ-ron sâu được sử dụng để phân tích hình ảnh. Loại kiến ​​trúc này chiếm ưu thế trong việc nhận dạng đối tượng từ hình ảnh hoặc video. Nó được sử dụng trong các ứng dụng như nhận dạng hình ảnh hoặc video, xử lý ngôn ngữ tự nhiên và hệ thống đề xuất.

Archikiến trúc của Mạng lưới thần kinh chuyển đổi

Hãy nghĩ về Facebook vài năm trước, sau khi bạn tải ảnh lên hồ sơ của mình, bạn được yêu cầu thêm tên cho khuôn mặt trên ảnh theo cách thủ công. Ngày nay, Facebook sử dụng convnet để tự động gắn thẻ bạn bè của bạn vào ảnh.

Mạng nơ-ron tích chập để phân loại hình ảnh không quá khó hiểu. Hình ảnh đầu vào được xử lý trong giai đoạn tích chập và sau đó được gán nhãn.

Kiến trúc mạng nơ-ron tích chập (convnet) điển hình có thể được tóm tắt trong hình dưới đây. Trước hết, một hình ảnh được đưa vào mạng; đây được gọi là hình ảnh đầu vào. Sau đó, hình ảnh đầu vào trải qua một loạt các bước; đây là phần tích chập của mạng. Cuối cùng, mạng nơ-ron có thể dự đoán chữ số trên hình ảnh.

Kiến trúc mạng tích chập từ đầu đến cuối, từ ảnh đầu vào, qua các giai đoạn tích chập đến chữ số được dự đoán.
Archicấu trúc của Mạng thần kinh chuyển đổi (CNN)

Một hình ảnh được tạo thành từ một mảng các điểm ảnh có chiều cao và chiều rộng. Hình ảnh xám chỉ có một kênh màu, trong khi hình ảnh màu có ba kênh (mỗi kênh dành cho màu Đỏ, Xanh lục và Xanh lam). Các kênh được xếp chồng lên nhau. Trong hướng dẫn này, bạn sẽ sử dụng hình ảnh xám chỉ có một kênh màu. Mỗi điểm ảnh có giá trị từ 0 đến 255 để phản ánh cường độ màu. Ví dụ, một điểm ảnh có giá trị bằng 0 sẽ hiển thị màu trắng, trong khi một điểm ảnh có giá trị gần 255 sẽ tối hơn.

Chúng ta hãy nhìn vào một hình ảnh được lưu trữ trong Tập dữ liệu MNISTHình ảnh bên dưới cho thấy cách biểu diễn hình ảnh bên trái dưới dạng ma trận. Lưu ý rằng ma trận gốc đã được chuẩn hóa để nằm trong khoảng từ 0 đến 1. Đối với các màu tối hơn, giá trị trong ma trận xấp xỉ 0.9 trong khi các điểm ảnh trắng có giá trị là 0.

Chữ số MNIST viết tay được hiển thị bên cạnh ma trận 28x28 pixel với các giá trị được chuẩn hóa trong khoảng từ 0 đến 1.

Hoạt động tích chập

Thành phần quan trọng nhất trong mô hình là lớp tích chập. Phần này nhằm mục đích giảm kích thước ảnh để tính toán trọng số nhanh hơn và cải thiện khả năng khái quát hóa.

Trong phần tích chập, mạng giữ các đặc điểm cơ bản của hình ảnh và loại trừ nhiễu không liên quan. Ví dụ: mô hình đang học cách nhận dạng một con voi từ một bức ảnh có ngọn núi ở hậu cảnh. Nếu bạn sử dụng mạng thần kinh truyền thống, mô hình sẽ gán trọng số cho tất cả các pixel, bao gồm cả các pixel từ núi, điều này không cần thiết và có thể đánh lừa mạng.

Thay vào đó, một Máy ảnh Mạng nơ-ron tích chập sẽ sử dụng một kỹ thuật toán học để giải thíchtracChỉ những pixel quan trọng nhất mới được chọn. Phép toán này được gọi là phép tích chập. Kỹ thuật này cho phép mạng nơ-ron học được các đặc điểm ngày càng phức tạp ở mỗi lớp. Phép tích chập chia ma trận thành các phần nhỏ để học các phần tử thiết yếu nhất trong mỗi phần.

Các thành phần của Mạng thần kinh chuyển đổi (ConvNet hoặc CNN)

Một mạng tích chập (convnet) có bốn thành phần:

  1. sự quấn lại
  2. Tính phi tuyến tính (ReLU)
  3. Pooling hoặc Lấy mẫu phụ
  4. Phân loại (Lớp được kết nối đầy đủ)

sự quấn lại

Mục đích của phép tích chập là để giải thíchtracNó sẽ học các đặc điểm của đối tượng trên ảnh một cách cục bộ. Điều này có nghĩa là mạng nơ-ron sẽ học các mẫu cụ thể trong ảnh và có thể nhận dạng chúng ở mọi nơi trong ảnh.

Phép tích chập là một phép nhân từng phần tử. Khái niệm này rất dễ hiểu. Máy tính sẽ quét một phần của hình ảnh, thường có kích thước 3×3, và nhân nó với một bộ lọc. Kết quả của phép nhân từng phần tử được gọi là bản đồ đặc trưng. Bước này được lặp lại cho đến khi toàn bộ hình ảnh được quét. Lưu ý rằng, sau phép tích chập, kích thước của hình ảnh sẽ bị giảm.

Sơ đồ bên dưới cho thấy một phần của hình ảnh được nhân với bộ lọc để tạo ra một ô duy nhất của bản đồ đặc trưng.

Phép nhân từng phần tử của một mảng ảnh 3x3 với một bộ lọc tạo ra một giá trị của bản đồ đặc trưng.

Hình ảnh động bên dưới cho thấy cùng một phép tích chập được thực hiện trên toàn bộ hình ảnh.

Bộ lọc hoạt hình trượt trên ảnh đầu vào và xây dựng bản đồ đặc trưng từng ô một.

Có rất nhiều bộ lọc khác nhau. Dưới đây, chúng tôi đã liệt kê một số trong số đó. Bạn có thể thấy rằng mỗi bộ lọc đều có một mục đích cụ thể. Lưu ý rằng trong hình bên dưới, "kernel" là từ đồng nghĩa với "filter".

Bảng liệt kê các kernel tích chập thông dụng như phát hiện cạnh, làm sắc nét và làm mờ, cùng với các ảnh đầu ra tương ứng.

Số học đằng sau tích chập

Giai đoạn tích chập sẽ áp dụng bộ lọc lên một mảng nhỏ các pixel trong ảnh. Bộ lọc sẽ di chuyển dọc theo ảnh đầu vào với hình dạng tổng quát là 3×3 hoặc 5×5. Điều này có nghĩa là mạng sẽ trượt các cửa sổ này trên toàn bộ ảnh đầu vào và tính toán phép tích chập. Hình ảnh động bên dưới cho thấy cách thức hoạt động của phép tích chập. Kích thước của mảng là 3×3, và ma trận đầu ra là kết quả của phép toán từng phần tử giữa ma trận ảnh và bộ lọc.

Hoạt ảnh từng bước minh họa quá trình lọc 3x3 bằng cách nhân các giá trị hình ảnh và cộng chúng lại thành ma trận đầu ra.

Bạn nhận thấy rằng chiều rộng và chiều cao của đầu ra có thể khác với chiều rộng và chiều cao của đầu vào. Nó xảy ra vì hiệu ứng biên giới.

Hiệu ứng viền

Hình ảnh có bản đồ đặc trưng 5×5 và bộ lọc 3×3. Chỉ có một cửa sổ ở trung tâm nơi bộ lọc có thể lọc lưới 3×3. Bản đồ đặc trưng đầu ra bị thu nhỏ đi hai ô trên mỗi trục, để lại kích thước 3×3.

Bản đồ đặc trưng 5x5 được giảm xuống còn 3x3 vì bộ lọc 3x3 không thể bao phủ hết các cạnh.

Để có kích thước đầu ra bằng với kích thước đầu vào, bạn cần thêm phần đệm. Phần đệm bao gồm việc thêm đúng số hàng và cột vào mỗi phía của ma trận. Điều này sẽ cho phép phép tích chập căn chỉnh tâm cho từng ô đầu vào. Trong hình bên dưới, ma trận đầu vào và đầu ra có cùng kích thước, 5×5.

Đầu vào là ma trận 5x5 được bao quanh bởi một vòng đệm toàn số 0, do đó phép tích chập trả về đầu ra là ma trận 5x5.

Khi bạn xác định mạng, các tính năng tích hợp được kiểm soát bởi ba tham số:

Độ sâu: Tham số này xác định số lượng bộ lọc được áp dụng trong quá trình tích chập. Trong ví dụ trước, bạn đã thấy độ sâu là 1, nghĩa là chỉ sử dụng một bộ lọc. Trong hầu hết các trường hợp, sẽ có nhiều hơn một bộ lọc. Hình ảnh động bên dưới minh họa các thao tác được thực hiện trong trường hợp sử dụng ba bộ lọc.

Ba bộ lọc riêng biệt tích chập cùng một đầu vào và tạo ra ba bản đồ đặc trưng xếp chồng lên nhau.

Sải bước: Tham số này xác định số "bước nhảy pixel" giữa hai lát cắt. Nếu bước nhảy bằng 1, cửa sổ sẽ di chuyển với khoảng cách một pixel. Nếu bước nhảy bằng 2, cửa sổ sẽ nhảy 2 pixel. Nếu bạn tăng bước nhảy, bạn sẽ có các bản đồ đặc trưng nhỏ hơn. Hai sơ đồ bên dưới so sánh bước nhảy bằng 1 với bước nhảy bằng 2.

Ví dụ sải bước 1

Cửa sổ lọc di chuyển từng pixel một trên hàng dữ liệu đầu vào với bước nhảy được đặt là 1.

sải bước 2

Bỏ qua cửa sổ lọcping Khoảng cách giữa hai pixel và bước nhảy được đặt là 2, tạo ra đầu ra ngắn hơn.

Đệm bằng số 0: Thêm đệm (padding) là thao tác thêm một số hàng và cột tương ứng vào mỗi phía của bản đồ đặc trưng đầu vào. Trong trường hợp này, đầu ra có cùng kích thước với đầu vào.

Tính phi tuyến tính (ReLU)

Sau khi kết thúc phép toán tích chập, đầu ra sẽ được áp dụng một hàm kích hoạt để cho phép tính phi tuyến tính. Hàm kích hoạt thông thường cho mạng tích chập là ReLU. Tất cả các pixel có giá trị âm sẽ được thay thế bằng 0.

Pooling Operasản xuất

Bước này rất dễ hiểu. Mục đích của việc gộp (pooling) là giảm chiều dữ liệu của ảnh đầu vào. Các bước này được thực hiện để giảm độ phức tạp tính toán của thao tác. Bằng cách giảm chiều dữ liệu, mạng neural sẽ phải tính toán ít trọng số hơn, do đó ngăn ngừa hiện tượng quá khớp (overfitting).

Ở giai đoạn này, bạn cần xác định kích thước và bước nhảy. Một cách chuẩn để gộp ảnh đầu vào là sử dụng giá trị lớn nhất của bản đồ đặc trưng. Hãy xem hình bên dưới. Quá trình gộp sẽ sàng lọc bốn ma trận con của bản đồ đặc trưng 4×4 và trả về giá trị lớn nhất. Quá trình gộp lấy giá trị lớn nhất của một mảng 2×2 và sau đó di chuyển cửa sổ này đi hai pixel. Ví dụ, ma trận con đầu tiên là [3,1,3,2], vì vậy quá trình gộp sẽ trả về giá trị lớn nhất, là 3.

Bản đồ đặc trưng 4x4 được giảm xuống thành đầu ra 2x2 bằng cách sử dụng phép gộp tối đa với cửa sổ 2x2 và bước nhảy 2.

Có một phép toán gộp khác như phép toán trung bình.

Thao tác này làm giảm đáng kể kích thước của bản đồ đặc trưng.

Các lớp được kết nối đầy đủ

Bước cuối cùng bao gồm việc xây dựng một hệ thống truyền thống mạng lưới thần kinh nhân tạo như bạn đã làm trong hướng dẫn trước. Bạn kết nối tất cả các nơ-ron từ lớp trước đến lớp tiếp theo. Bạn sử dụng hàm kích hoạt softmax để phân loại số trên ảnh đầu vào.

Tóm tắt lại

Mạng nơ-ron tích chập TensorFlow biên dịch các lớp khác nhau trước khi đưa ra dự đoán. Một mạng nơ-ron có:

  • Một lớp chập
  • Chức năng kích hoạt ReLU
  • Poolinlớp g
  • Lớp kết nối dày đặc

Các lớp tích chập áp dụng các bộ lọc khác nhau trên một vùng con của hình ảnh. Hàm kích hoạt ReLU bổ sung tính phi tuyến tính, và các lớp gộp làm giảm chiều của bản đồ đặc trưng.

Tất cả các lớp nàytracThông tin cần thiết được trích xuất từ ​​các hình ảnh. Cuối cùng, các bản đồ đặc trưng được đưa vào một lớp kết nối đầy đủ với hàm softmax để đưa ra dự đoán.

Đào tạo CNN với TensorFlow

Giờ bạn đã quen thuộc với các thành phần cơ bản của mạng nơ-ron tích chập (convnet), bạn đã sẵn sàng xây dựng một mạng nơ-ron tích chập với... TensorFlow. Chúng tôi sẽ sử dụng bộ dữ liệu MNIST để phân loại hình ảnh CNN.

Chuẩn bị dữ liệu giống như hướng dẫn trước. Bạn có thể chạy mã và chuyển trực tiếp đến kiến ​​trúc của CNN.

Bạn sẽ làm theo các bước dưới đây để phân loại hình ảnh bằng CNN:

  1. Bước 1: Tải lên tập dữ liệu
  2. Bước 2: Lớp đầu vào
  3. Bước 3: Lớp chập
  4. Bước 4: Poolinlớp g
  5. Bước 5: Lớp chập thứ hai và Pooling Lớp
  6. Bước 6: Lớp dày đặc
  7. Bước 7: Lớp đăng nhập

Ghi chú phiên bản: Các đoạn mã bên dưới nhắm đến TensorFlow 1.x. Trong TensorFlow 2, không gian tên tf.layers và tf.estimator.inputs.numpy_input_fn không còn tồn tại; các hàm tương đương là tf.keras.layers.Conv2D, MaxPoolinCác lớp g2D, Dense và Dropout được kết hợp trong một tf.keras.Model và được huấn luyện bằng model.fit(). Hãy đọc các bước để hiểu cơ chế hoạt động của từng lớp, sau đó đối chiếu chúng với API của Keras.

Bước 1: Tải lên tập dữ liệu

Bộ dữ liệu MNIST có sẵn thông qua scikit-learn. Vui lòng tải xuống và lưu trữ trong thư mục Downloads. Bạn có thể tải lên bằng lệnh fetch_mldata('MNIST original').

Ghi chú phiên bản: mldata.org đã ngừng hoạt động và hàm fetch_mldata() đã bị xóa trong scikit-learn 0.22. Trên bất kỳ bản cài đặt hiện tại nào, hãy tải các chữ số tương tự bằng cách sử dụng lấy_mở_ml Thay vào đó, sử dụng fetch_openml('mnist_784', version=1). Phần còn lại của quy trình không thay đổi.

Tạo tập huấn luyện/kiểm tra

Bạn cần chia tập dữ liệu bằng hàm train_test_split.

Quy mô các tính năng

Cuối cùng, bạn có thể điều chỉnh tỷ lệ các đặc trưng bằng MinMaxScaler như minh họa trong ví dụ phân loại hình ảnh sử dụng TensorFlow CNN bên dưới.

import numpy as np
import tensorflow as tf
from sklearn.datasets import fetch_mldata

#Change USERNAME by the username of your machine
## Windows USER
mnist = fetch_mldata('C:\\Users\\USERNAME\\Downloads\\MNIST original')
## Mac User
mnist = fetch_mldata('/Users/USERNAME/Downloads/MNIST original')

print(mnist.data.shape)
print(mnist.target.shape)
from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(mnist.data, mnist.target, test_size=0.2, random_state=42)
y_train  = y_train.astype(int)
y_test  = y_test.astype(int)
batch_size =len(X_train)

print(X_train.shape, y_train.shape,y_test.shape )
## resclae
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
# Train
X_train_scaled = scaler.fit_transform(X_train.astype(np.float64))
# test
X_test_scaled = scaler.fit_transform(X_test.astype(np.float64))
feature_columns = [tf.feature_column.numeric_column('x', shape=X_train_scaled.shape[1:])]
X_train_scaled.shape[1:]

Định nghĩa CNN

Mạng nơ-ron tích chập (CNN) sử dụng các bộ lọc trên các điểm ảnh thô của hình ảnh để học các mẫu chi tiết, khác với các mẫu tổng thể được học bởi mạng nơ-ron truyền thống. Để xây dựng một CNN, bạn cần định nghĩa:

  1. Lớp tích chập: Áp dụng n bộ lọc lên bản đồ đặc trưng. Sau phép tích chập, bạn cần sử dụng hàm kích hoạt ReLU để thêm tính phi tuyến tính cho mạng.
  2. PoolinLớp g: Bước tiếp theo sau phép tích chập là giảm kích thước bản đồ đặc trưng. Mục đích là để giảm chiều dữ liệu của bản đồ đặc trưng nhằm ngăn ngừa hiện tượng quá khớp và cải thiện tốc độ tính toán. Kỹ thuật gộp tối đa (max pooling) là kỹ thuật thông thường, chia bản đồ đặc trưng thành các vùng con (thường có kích thước 2×2) và chỉ giữ lại các giá trị lớn nhất.
  3. Các lớp được kết nối đầy đủ: Tất cả các neuron từ các lớp trước được kết nối với các lớp tiếp theo. CNN sẽ phân loại nhãn theo các đặc điểm từ các lớp tích chập và giảm với lớp gộp.

Kiến trúc CNN

  • Lớp tích chập: Áp dụng 14 bộ lọc 5×5 (ví dụ:trac(các vùng con 5×5 pixel), với hàm kích hoạt ReLU
  • Pooling Lớp: Thực hiện gộp nhóm tối đa với bộ lọc 2×2 và bước tiến là 2 (chỉ định rằng các vùng gộp nhóm không chồng lấn)
  • Lớp tích chập: Áp dụng 36 bộ lọc 5×5, có chức năng kích hoạt ReLU
  • Pooling Lớp #2: Một lần nữa, thực hiện gộp nhóm tối đa với bộ lọc 2×2 và bước tiến là 2
  • 1,764 nơ-ron, với tỷ lệ chính quy bỏ học là 0.4 (xác suất 0.4 mà bất kỳ phần tử nhất định nào sẽ bị loại bỏ trong quá trình huấn luyện)
  • Lớp dày đặc (Lớp nhật ký): 10 nơ-ron, một nơ-ron cho mỗi lớp mục tiêu chữ số (0–9).

Có ba mô-đun quan trọng cần sử dụng để tạo CNN:

  • conv2d(). Xây dựng một lớp tích chập hai chiều với số lượng bộ lọc, kích thước hạt nhân bộ lọc, phần đệm và hàm kích hoạt làm đối số.
  • max_pooling2d(). Xây dựng một lớp gộp hai chiều bằng thuật toán gộp tối đa.
  • ngu độn(). Xây dựng một lớp dày đặc với các lớp và đơn vị ẩn

Bạn sẽ định nghĩa một hàm để xây dựng mạng CNN. Chúng ta hãy xem chi tiết cách xây dựng từng khối cấu trúc trước khi đóng gói.ping mọi thứ cùng nhau trong hàm.

Bước 2: Lớp đầu vào

def cnn_model_fn(features, labels, mode):
    input_layer = tf.reshape(tensor = features["x"],shape =[-1, 28, 28, 1])

Bạn cần xác định một tensor với hình dạng của dữ liệu. Để làm được điều đó, bạn có thể sử dụng mô-đun tf.reshape. Trong mô-đun này, bạn cần khai báo tensor để định hình lại và hình dạng của tensor. Đối số đầu tiên là các tính năng của dữ liệu, được xác định trong đối số của hàm.

Một bức ảnh có chiều cao, chiều rộng và kênh. Tập dữ liệu MNIST là một bức ảnh đơn sắc có kích thước 28×28. Chúng ta đặt kích thước lô (batch size) thành -1 trong đối số shape để nó có hình dạng của các đặc trưng [“x”]. Ưu điểm là biến kích thước lô thành một siêu tham số để điều chỉnh. Nếu kích thước lô được đặt thành 7, thì tensor sẽ cung cấp 5,488 giá trị (28*28*7).

Bước 3: Lớp chập

# first Convolutional Layer
  conv1 = tf.layers.conv2d(
      inputs=input_layer,
      filters=14,
      kernel_size=[5, 5],
      padding="same",
      activation=tf.nn.relu)

Lớp tích chập đầu tiên có 14 bộ lọc với kích thước kernel 5×5 và cùng một kiểu đệm. Kiểu đệm này có nghĩa là cả tensor đầu ra và tensor đầu vào phải có cùng chiều cao và chiều rộng. TensorFlow sẽ thêm các số 0 vào các hàng và cột để đảm bảo kích thước bằng nhau.

Bạn sử dụng hàm kích hoạt ReLU. Kích thước đầu ra sẽ là [28, 28, 14].

Bước 4: Poolinlớp g

Bước tiếp theo sau phép tích chập là tính toán gộp (pooling). Phép tính gộp sẽ giảm chiều dữ liệu. Bạn có thể sử dụng module max_pooling2d với kích thước 2×2 và bước nhảy (stride) là 2. Bạn sử dụng lớp trước đó làm đầu vào. Kích thước đầu ra sẽ là [batch_size, 14, 14, 14].

# first Pooling Layer 
pool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2)

Bước 5: Lớp chập thứ hai và Pooling Lớp

Lớp tích chập thứ hai áp dụng 36 bộ lọc, cho kích thước đầu ra là [batch_size, 14, 14, 36]. Lớp gộp sử dụng cùng cửa sổ 2×2 và bước nhảy 2 như trước, do đó nó chia đôi mỗi trục không gian và hình dạng đầu ra trở thành [batch_size, 7, 7, 36].

conv2 = tf.layers.conv2d(
      inputs=pool1,
      filters=36,
      kernel_size=[5, 5],
      padding="same",
      activation=tf.nn.relu)
pool2 = tf.layers.max_pooling2d(inputs=conv2, pool_size=[2, 2], strides=2)

Bước 6: Lớp dày đặc

Tiếp theo, bạn cần định nghĩa lớp kết nối đầy đủ. Bản đồ đặc trưng phải được làm phẳng trước khi kết nối với lớp dày đặc. Bạn có thể sử dụng mô-đun reshape với kích thước 7*7*36.

Lớp dày đặc sẽ kết nối 1,764 nơ-ron. Bạn thêm hàm kích hoạt ReLU. Ngoài ra, bạn thêm một thuật ngữ điều chỉnh dropout với tỷ lệ 0.3, nghĩa là 30% các kích hoạt sẽ được đặt thành 0. Lưu ý rằng dropout chỉ diễn ra trong giai đoạn huấn luyện. Hàm cnn_model_fn có một tham số mode để khai báo xem mô hình cần được huấn luyện hay đánh giá, như được hiển thị trong ví dụ phân loại hình ảnh CNN TensorFlow bên dưới.

pool2_flat = tf.reshape(pool2, [-1, 7 * 7 * 36])

dense = tf.layers.dense(inputs=pool2_flat, units=7 * 7 * 36, activation=tf.nn.relu)
dropout = tf.layers.dropout(
      inputs=dense, rate=0.3, training=mode == tf.estimator.ModeKeys.TRAIN)

Bước 7: Lớp đăng nhập

Cuối cùng, trong ví dụ phân loại ảnh TensorFlow, bạn có thể định nghĩa lớp cuối cùng với dự đoán của mô hình. Kích thước đầu ra bằng kích thước batch cộng với 10, tổng số lớp mục tiêu.

# Logits Layer
logits = tf.layers.dense(inputs=dropout, units=10)

Bạn có thể tạo một từ điển chứa các lớp và xác suất của mỗi lớp. Hàm tf.argmax() trả về chỉ số của giá trị cao nhất trong lớp logits. Hàm softmax trả về xác suất của mỗi lớp.

predictions = {				
	# Generate predictions				
    "classes": tf.argmax(input=logits, axis=1),				
    "probabilities": tf.nn.softmax(logits, name="softmax_tensor")  }			

Bạn chỉ muốn trả về từ điển dự đoán khi chế độ được đặt thành "dự đoán". Bạn thêm đoạn mã này để hiển thị các dự đoán.

if mode == tf.estimator.ModeKeys.PREDICT:
    return tf.estimator.EstimatorSpec(mode=mode, predictions=predictions)

Bước tiếp theo là tính toán hàm mất mát của mô hình. Trong bài hướng dẫn trước, bạn đã học được rằng hàm mất mát cho mô hình đa lớp là entropy chéo. Hàm mất mát có thể dễ dàng tính toán bằng đoạn mã sau:

# Calculate Loss (for both TRAIN and EVAL modes)
loss = tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits)

Bước cuối cùng của ví dụ TensorFlow CNN là tối ưu hóa mô hình, tức là tìm ra các giá trị trọng số tốt nhất. Để làm điều đó, bạn sử dụng thuật toán tối ưu hóa gradient descent với tốc độ học là 0.001. Mục tiêu là giảm thiểu tổn thất.

optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001)
train_op = optimizer.minimize(
        loss=loss,
        global_step=tf.train.get_global_step())

Bạn đã hoàn thành việc xây dựng mạng CNN. Tuy nhiên, bạn muốn hiển thị các chỉ số hiệu suất trong chế độ đánh giá. Chỉ số hiệu suất cho mô hình phân loại đa lớp là độ chính xác. TensorFlow được trang bị một mô-đun độ chính xác nhận hai tham số: nhãn và giá trị dự đoán.

eval_metric_ops = {
      "accuracy": tf.metrics.accuracy(labels=labels, predictions=predictions["classes"])}
return tf.estimator.EstimatorSpec(mode=mode, loss=loss, eval_metric_ops=eval_metric_ops)

Đó là nó. Bạn đã tạo CNN đầu tiên của mình và bạn đã sẵn sàng gói mọi thứ vào một hàm để sử dụng nó nhằm đào tạo và đánh giá mô hình.

def cnn_model_fn(features, labels, mode):
  """Model function for CNN."""
  # Input Layer
  input_layer = tf.reshape(features["x"], [-1, 28, 28, 1])

  # Convolutional Layer
  conv1 = tf.layers.conv2d(
      inputs=input_layer,
      filters=32,
      kernel_size=[5, 5],
      padding="same",
      activation=tf.nn.relu)

  # Pooling Layer
  pool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2)

  # Convolutional Layer #2 and Pooling Layer
  conv2 = tf.layers.conv2d(
      inputs=pool1,
      filters=36,
      kernel_size=[5, 5],
      padding="same",
      activation=tf.nn.relu)
  pool2 = tf.layers.max_pooling2d(inputs=conv2, pool_size=[2, 2], strides=2)

  # Dense Layer
  pool2_flat = tf.reshape(pool2, [-1, 7 * 7 * 36])
  dense = tf.layers.dense(inputs=pool2_flat, units=7 * 7 * 36, activation=tf.nn.relu)
  dropout = tf.layers.dropout(
      inputs=dense, rate=0.4, training=mode == tf.estimator.ModeKeys.TRAIN)

  # Logits Layer
  logits = tf.layers.dense(inputs=dropout, units=10)

  predictions = {
      # Generate predictions (for PREDICT and EVAL mode)
      "classes": tf.argmax(input=logits, axis=1),
      "probabilities": tf.nn.softmax(logits, name="softmax_tensor")
  }

  if mode == tf.estimator.ModeKeys.PREDICT:
    return tf.estimator.EstimatorSpec(mode=mode, predictions=predictions)

  # Calculate Loss
  loss = tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits)

  # Configure the Training Op (for TRAIN mode)
  if mode == tf.estimator.ModeKeys.TRAIN:
    optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001)
    train_op = optimizer.minimize(
        loss=loss,
        global_step=tf.train.get_global_step())
    return tf.estimator.EstimatorSpec(mode=mode, loss=loss, train_op=train_op)

  # Add evaluation metrics Evaluation mode
  eval_metric_ops = {
      "accuracy": tf.metrics.accuracy(
          labels=labels, predictions=predictions["classes"])}
  return tf.estimator.EstimatorSpec(
      mode=mode, loss=loss, eval_metric_ops=eval_metric_ops)

Lưu ý về chức năng đã được lắp ráp: Phiên bản được đóng gói ở trên thiết lập lớp tích chập đầu tiên với 32 bộ lọc và dropout là 0.4, trong khi các đoạn mã từng bước sử dụng 14 bộ lọc và 0.3. Cả hai đều chạy, nhưng chọn một cặp giá trị và giữ chúng nhất quán để các hình dạng được in ra khớp với bảng lớp.

Các bước bên dưới cũng giống như các hướng dẫn trước.

Trước hết, bạn xác định công cụ ước tính bằng mô hình CNN để phân loại hình ảnh.

# Create the Estimator
mnist_classifier = tf.estimator.Estimator(
    model_fn=cnn_model_fn, model_dir="train/mnist_convnet_model")

Việc huấn luyện mạng CNN mất rất nhiều thời gian, do đó, bạn cần tạo một hook ghi nhật ký để lưu trữ giá trị của các lớp softmax sau mỗi 50 lần lặp.

# Set up logging for predictions
tensors_to_log = {"probabilities": "softmax_tensor"}
logging_hook = tf.train.LoggingTensorHook(tensors=tensors_to_log, every_n_iter=50)

Bạn đã sẵn sàng để ước tính mô hình. Bạn đặt kích thước lô là 100 và xáo trộn dữ liệu. Lưu ý rằng chúng ta đã đặt số bước huấn luyện là 16,000, điều này có thể mất rất nhiều thời gian để huấn luyện. Hãy kiên nhẫn.

# Train the model
train_input_fn = tf.estimator.inputs.numpy_input_fn(
    x={"x": X_train_scaled},
    y=y_train,
    batch_size=100,
    num_epochs=None,
    shuffle=True)
mnist_classifier.train(
    input_fn=train_input_fn,
    steps=16000,
    hooks=[logging_hook])

Sau khi mô hình đã được huấn luyện, bạn có thể đánh giá nó và in kết quả.

# Evaluate the model and print results
eval_input_fn = tf.estimator.inputs.numpy_input_fn(
    x={"x": X_test_scaled},
    y=y_test,
    num_epochs=1,
    shuffle=False)
eval_results = mnist_classifier.evaluate(input_fn=eval_input_fn)
print(eval_results)

Quá trình đánh giá sẽ in ra điểm kiểm tra đã được khôi phục, bước mà nó đã dừng lại và từ điển số liệu cuối cùng.

INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Starting evaluation at 2018-08-05-12:52:41
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from train/mnist_convnet_model/model.ckpt-15652
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Finished evaluation at 2018-08-05-12:52:56
INFO:tensorflow:Saving dict for global step 15652: accuracy = 0.9589286, global_step = 15652, loss = 0.13894269
{'accuracy': 0.9689286, 'loss': 0.13894269, 'global_step': 15652}

Với kiến ​​trúc hiện tại, từ điển đánh giá báo cáo độ chính xác là 0.9689286, xấp xỉ 97%. Bạn có thể thay đổi kiến ​​trúc, kích thước lô và số lần lặp để cải thiện độ chính xác. Mạng CNN đã hoạt động tốt hơn nhiều so với một mạng nơ-ron thông thường. mạng lưới thần kinh nhân tạo Hoặc hồi quy logistic: trong bài hướng dẫn về mạng nơ-ron nhân tạo, bạn đạt được độ chính xác 96%, thấp hơn so với CNN. Hiệu suất của CNN rất ấn tượng với tập dữ liệu hình ảnh lớn hơn, cả về tốc độ tính toán và độ chính xác.

Câu Hỏi Thường Gặp

Đệm hợp lệ không thêm gì cả, vì vậy đầu ra sẽ bị thu nhỏ và các pixel ở biên sẽ cung cấp dữ liệu cho ít nơ-ron hơn. Đệm giống nhau sẽ bao quanh đầu vào bằng các số 0 để đầu ra giữ nguyên chiều cao và chiều rộng của đầu vào, đó là điều mà conv2d gọi trong yêu cầu hướng dẫn này.

Không thay đổi. Các lớp tf.layers và tf.estimator.inputs.numpy_input_fn đã bị xóa. Xây dựng lại cùng một ngăn xếp với tf.keras.layers.Conv2D, MaxPooling2D, Mật độ cao và Hiện tượng mất dữ liệu bên trong một TensorFlow Sau đó, huấn luyện mô hình Keras bằng cách sử dụng model.fit() thay vì Estimator.

Các thư viện tìm kiếm tự động quét song song số lượng bộ lọc, kích thước kernel, tỷ lệ bỏ sót và tốc độ học, sau đó xếp hạng các lần chạy theo độ chính xác của quá trình xác thực. Chúng thay thế phỏng đoán bằng các so sánh có tính toán, mặc dù con người vẫn quyết định ngân sách tính toán và chỉ số quan trọng.

Vâng. Trợ lý GitHub Bản nháp này đề xuất các lớp tích chập và gộp lặp đi lặp lại cũng như đường dẫn đầu vào từ một bình luận ngắn. Hãy tự kiểm tra hình dạng đầu ra, vì các đề xuất thường kết hợp các API TensorFlow 1 đã bị loại bỏ với các API Keras hiện tại.

Việc lật, xoay, dịch chuyển và phóng to ngẫu nhiên tạo ra các biến thể mới cho mỗi hình ảnh huấn luyện, nhờ đó mạng nơ-ron được tiếp cận với nhiều ví dụ hơn và ngừng ghi nhớ từng hình ảnh riêng lẻ. Phương pháp này kết hợp tốt với dropout và thường thu hẹp khoảng cách giữa độ chính xác huấn luyện và độ chính xác kiểm chứng.

Quá trình chạy ở đây sử dụng 16,000 bước với kích thước lô là 100. Độ chính xác đạt được sớm hơn nhiều, vì vậy hãy theo dõi chỉ số đánh giá và dừng lại khi nó đạt đến mức ổn định thay vì chờ đến khi hoàn thành toàn bộ quá trình trên một máy tính chậm.

mldata.org đã ngừng hoạt động và hàm hỗ trợ đã bị loại bỏ trong scikit-learn 0.22. Thay vào đó, hãy sử dụng fetch_openml('mnist_784', version=1). Nó trả về cùng 70,000 chữ số 784 pixel đã được làm phẳng, vì vậy các bước chia tỷ lệ và tách trong hướng dẫn này vẫn hoạt động.

Chúng được đọc theo dạng batch, chiều cao, chiều rộng, số kênh. Vì vậy, 14x14 là kích thước không gian sau một bước gộp trên một hình ảnh 28x28, và 36 là số lượng bộ lọc trong lớp tích chập đó, mỗi bộ lọc có một bản đồ đặc trưng.

Tóm tắt bài viết này với: