1. Tổng quan
Hướng dẫn này đã được cập nhật cho Tensorflow 2.2!
Trong lớp học lập trình này, bạn sẽ tìm hiểu cách xây dựng và huấn luyện một mạng nơron nhận dạng các chữ số viết tay. Đồng thời, trong quá trình cải thiện mạng nơron để đạt được độ chính xác 99%, bạn cũng sẽ khám phá những công cụ thương mại mà các chuyên gia về học sâu sử dụng để huấn luyện mô hình của họ một cách hiệu quả.
Lớp học lập trình này sử dụng tập dữ liệu MNIST, một tập hợp gồm 60.000 chữ số được gắn nhãn khiến nhiều thế hệ tiến sĩ luôn bận rộn trong gần hai thập kỷ. Bạn sẽ giải bài toán có dưới 100 dòng mã Python / TensorFlow.
Kiến thức bạn sẽ học được
- Mạng nơron là gì và cách huấn luyện mạng nơron đó
- Cách xây dựng mạng nơron 1 lớp cơ bản bằng tf.keras
- Cách thêm các lớp khác
- Cách thiết lập lịch tốc độ học tập
- Cách xây dựng mạng nơron tích chập
- Cách sử dụng các kỹ thuật chính quy: bỏ cuộc, chuẩn hoá hàng loạt
- Thế nào là quá tải
Bạn cần có
Chỉ là một trình duyệt. Bạn có thể tổ chức hội thảo này hoàn toàn bằng Google Colaboratory.
Phản hồi
Vui lòng cho chúng tôi biết nếu bạn thấy có gì thiếu trong phòng thí nghiệm này hoặc nếu bạn cho rằng điều đó cần được cải thiện. Chúng tôi xử lý ý kiến phản hồi thông qua các vấn đề trên GitHub [ feedback link].
2. Bắt đầu nhanh với Google Colaboratory
Phòng thí nghiệm này sử dụng Google Colaboratory và bạn không cần phải thiết lập. Bạn có thể chạy ứng dụng này từ Chromebook. Vui lòng mở tệp bên dưới rồi thực thi các ô để làm quen với sổ tay Colab.
Dưới đây là hướng dẫn bổ sung:
Chọn phần phụ trợ GPU
Trong trình đơn Colab, hãy chọn Thời gian chạy > Thay đổi loại thời gian chạy rồi chọn GPU. Kết nối với môi trường thời gian chạy sẽ tự động diễn ra trong lần thực thi đầu tiên, hoặc bạn có thể dùng tính năng "Kết nối" ở góc trên bên phải.
Thực thi trên sổ tay
Thực thi lần lượt từng ô bằng cách nhấp vào một ô và sử dụng Shift-ENTER. Bạn cũng có thể chạy toàn bộ sổ tay bằng Thời gian chạy > Chạy tất cả
Mục lục
Tất cả sổ tay đều có mục lục. Bạn có thể mở mục này bằng mũi tên màu đen ở bên trái.
Các ô bị ẩn
Một số ô sẽ chỉ hiển thị tiêu đề. Đây là một tính năng của sổ tay dành riêng cho Colab. Bạn có thể nhấp đúp vào chúng để xem mã bên trong nhưng thường không được thú vị lắm. Thường có các hàm hỗ trợ hoặc trực quan hoá. Bạn vẫn cần phải chạy các ô này để các hàm bên trong được xác định.
3. Huấn luyện mạng nơron
Trước tiên, chúng ta sẽ xem một chuyến tàu mạng nơron. Vui lòng mở sổ tay bên dưới rồi di chuyển qua tất cả các ô. Đừng chú ý đến mã, chúng tôi sẽ bắt đầu giải thích sau.
Khi bạn thực thi sổ tay, hãy tập trung vào hình ảnh trực quan. Hãy xem phần giải thích bên dưới.
Dữ liệu huấn luyện
Chúng tôi có một tập dữ liệu gồm các chữ số viết tay đã được gắn nhãn để chúng tôi biết mỗi hình đại diện cho điều gì, tức là một số từ 0 đến 9. Trong sổ tay, bạn sẽ thấy một phần trích dẫn:
Mạng nơron chúng ta sẽ xây dựng phân loại các chữ số viết tay trong 10 lớp của chúng (0, .., 9). Việc phân loại sẽ được thực hiện dựa trên các tham số nội bộ cần có giá trị chính xác để việc phân loại hoạt động tốt. "Giá trị chính xác" này được học thông qua một quá trình huấn luyện trong đó yêu cầu phải sử dụng một "tập dữ liệu được gắn nhãn" với hình ảnh và câu trả lời đúng có liên quan.
Làm thế nào để chúng ta biết được liệu mạng nơron đã được huấn luyện có hoạt động tốt hay không? Việc sử dụng tập dữ liệu huấn luyện để kiểm tra mạng là hành vi gian lận. Thực tế cho thấy tập dữ liệu đó nhiều lần trong quá trình huấn luyện và chắc chắn sẽ mang lại hiệu quả rất cao. Chúng tôi cần một tập dữ liệu được gắn nhãn khác, chưa từng thấy trong quá trình huấn luyện, để đánh giá "thực tế" hiệu suất của mạng. Tập dữ liệu này được gọi là "tập dữ liệu xác thực"
Đào tạo
Trong quá trình huấn luyện, mỗi lần một lô dữ liệu huấn luyện, các tham số mô hình nội bộ sẽ được cập nhật và mô hình ngày càng cải thiện khả năng nhận dạng các chữ số viết tay. Bạn có thể thấy điều này trên biểu đồ huấn luyện:
Ở bên phải là "độ chính xác" chỉ đơn giản là tỷ lệ phần trăm số chữ số được nhận dạng chính xác. Nó tăng lên theo tiến độ đào tạo, như vậy là tốt.
Ở bên trái, chúng ta có thể thấy "giảm". Để thúc đẩy hoạt động đào tạo, chúng ta sẽ xác định "mất mát" , đại diện cho mức độ kém hiệu quả của hệ thống trong việc nhận dạng các chữ số và cố gắng giảm thiểu nó. Như bạn thấy ở đây, tổn thất giảm dần đối với cả dữ liệu huấn luyện và dữ liệu xác thực khi quá trình huấn luyện diễn ra: như vậy thì tốt. Điều đó có nghĩa là mạng nơron đang học.
Trục X biểu thị số "thời gian bắt đầu của hệ thống" hoặc lặp lại thông qua toàn bộ tập dữ liệu.
Dự đoán
Khi mô hình được huấn luyện, chúng ta có thể sử dụng mô hình đó để nhận dạng các chữ số viết tay. Hình ảnh tiếp theo cho thấy hiệu suất của công cụ này trên một vài chữ số được hiển thị từ phông chữ cục bộ (dòng đầu tiên) và sau đó là trên 10.000 chữ số của tập dữ liệu xác thực. Lớp được dự đoán sẽ xuất hiện bên dưới từng chữ số, bằng màu đỏ nếu giá trị đó không chính xác.
Như bạn có thể thấy, mô hình ban đầu này chưa tốt lắm nhưng vẫn nhận dạng chính xác một số chữ số. Độ chính xác xác thực cuối cùng của nó là khoảng 90%, điều này không quá tệ đối với mô hình đơn giản mà chúng tôi đang bắt đầu,nhưng điều đó vẫn có nghĩa là nó thiếu 1000 chữ số xác thực trong số 10.000. Số liệu hiển thị vượt trội hơn nhiều, đó là lý do có vẻ như tất cả các câu trả lời đều sai (màu đỏ).
Tensor
Dữ liệu được lưu trữ trong ma trận. Hình ảnh thang màu xám 28x28 pixel nằm vừa trong ma trận hai chiều 28x28. Nhưng đối với hình ảnh màu, chúng ta cần nhiều kích thước hơn. Có 3 giá trị màu cho mỗi pixel (Đỏ, Xanh lục, Xanh dương), do đó sẽ cần có bảng ba chiều với các kích thước [28, 28, 3]. Và để lưu trữ một lô 128 ảnh màu, cần có một bảng 4 chiều với các kích thước [128, 28, 28, 3].
Các bảng đa chiều này được gọi là "tensor" và danh sách kích thước của các kích thước này là "hình dạng" của chúng.
4. [THÔNG TIN]: mạng nơron 101
Tóm tắt
Nếu bạn đã biết tất cả những thuật ngữ in đậm trong đoạn tiếp theo, thì bạn có thể chuyển sang bài tập tiếp theo. Nếu bạn chỉ mới bắt đầu sử dụng công nghệ học sâu, vui lòng đọc tiếp.
Đối với các mô hình được xây dựng dưới dạng một trình tự các lớp, Keras cung cấp API tuần tự. Ví dụ: thuật toán phân loại hình ảnh sử dụng ba lớp dày đặc có thể được viết trong Keras như sau:
model = tf.keras.Sequential([
tf.keras.layers.Flatten(input_shape=[28, 28, 1]),
tf.keras.layers.Dense(200, activation="relu"),
tf.keras.layers.Dense(60, activation="relu"),
tf.keras.layers.Dense(10, activation='softmax') # classifying into 10 classes
])
# this configures the training of the model. Keras calls it "compiling" the model.
model.compile(
optimizer='adam',
loss= 'categorical_crossentropy',
metrics=['accuracy']) # % of correct answers
# train the model
model.fit(dataset, ... )
Một lớp dày đặc
Các chữ số viết tay trong tập dữ liệu MNIST là hình ảnh thang màu xám 28x28 pixel. Cách đơn giản nhất để phân loại chúng là sử dụng 28x28=784 pixel làm đầu vào cho mạng nơron 1 lớp.
Mỗi "nơ-ron" trong mạng nơron thực hiện tổng có trọng số của tất cả dữ liệu đầu vào, thêm một hằng số có tên là "độ lệch" rồi cung cấp kết quả thông qua một số "hàm kích hoạt" phi tuyến tính. "trọng số" và "sai lệch" là các tham số sẽ được xác định thông qua quá trình huấn luyện. Ban đầu, các giá trị này được khởi tạo bằng các giá trị ngẫu nhiên.
Hình trên biểu diễn một mạng nơron 1 lớp với 10 nơron đầu ra vì chúng ta muốn phân loại các chữ số thành 10 lớp (từ 0 đến 9).
Bằng phép nhân ma trận
Dưới đây là cách lớp mạng nơron, xử lý một tập hợp hình ảnh, có thể được biểu diễn bằng phép nhân ma trận:
Sử dụng cột trọng số đầu tiên trong ma trận trọng số W, chúng tôi tính tổng trọng số của tất cả các pixel của hình ảnh đầu tiên. Tổng này tương ứng với nơron thứ nhất. Sử dụng cột trọng số thứ hai, chúng ta làm tương tự cho nơron thứ hai và tiếp tục cho đến nơron thứ 10. Sau đó, chúng ta có thể lặp lại thao tác cho 99 hình ảnh còn lại. Nếu chúng ta gọi X là ma trận chứa 100 hình ảnh của chúng ta, thì tất cả các tổng có trọng số cho 10 nơron của chúng ta, được tính trên 100 hình ảnh chỉ đơn giản là X.W, một phép nhân ma trận.
Bây giờ, mỗi nơron phải thêm độ lệch (hằng số). Vì chúng ta có 10 nơron, nên chúng ta có 10 hằng số sai lệch. Chúng ta sẽ gọi vectơ này gồm 10 giá trị là b. Bạn phải thêm mã này vào từng dòng của ma trận đã tính trước đó. Sử dụng một chút phép màu tên là "phát sóng" chúng ta sẽ viết mã này bằng một dấu cộng đơn giản.
Cuối cùng, chúng tôi cũng áp dụng một chức năng kích hoạt, ví dụ: "softmax" (được giải thích bên dưới) và có được công thức mô tả mạng nơron 1 lớp, áp dụng cho 100 hình ảnh:
Ở Keras
Với các thư viện mạng nơron cấp cao như Keras, chúng ta sẽ không cần triển khai công thức này. Tuy nhiên, điều quan trọng là phải hiểu rằng lớp mạng nơron chỉ là một loạt các phép nhân và phép cộng. Trong Keras, một lớp dày đặc sẽ được viết là:
tf.keras.layers.Dense(10, activation='softmax')
Tìm hiểu sâu
Việc liên kết các lớp mạng nơron không hề đơn giản. Lớp đầu tiên tính tổng các pixel có trọng số. Các lớp tiếp theo tính tổng có trọng số của kết quả của các lớp trước.
Sự khác biệt duy nhất, ngoài số lượng tế bào thần kinh, sẽ là lựa chọn chức năng kích hoạt.
Các hàm kích hoạt: relu, softmax và sigmoid
Bạn thường sẽ sử dụng "relu" cho tất cả các lớp trừ các lớp cuối cùng. Lớp cuối cùng trong thuật toán phân loại sẽ dùng "softmax" để kích hoạt tài khoản.
Lại là một "nơron" tính tổng có trọng số của tất cả các đầu vào, rồi cộng một giá trị được gọi là "độ lệch" rồi cung cấp kết quả thông qua hàm kích hoạt.
Hàm kích hoạt phổ biến nhất có tên là "RELU" cho Đơn vị tuyến tính đã chỉnh sửa. Đây là một hàm rất đơn giản như bạn có thể thấy trong biểu đồ ở trên.
Chức năng kích hoạt truyền thống trong mạng nơron là "sigmoid" nhưng là "relu" đã được chứng minh là có thuộc tính hội tụ tốt hơn hầu như ở mọi nơi và hiện đang được ưa dùng.
Kích hoạt Softmax để phân loại
Lớp cuối cùng của mạng nơron chúng ta có 10 nơron vì chúng ta muốn phân loại các chữ số viết tay thành 10 lớp (0,..9). Nó sẽ xuất ra 10 số từ 0 đến 1 đại diện cho xác suất của chữ số này là 0, 1, 2, v.v. Để thực hiện việc này, trên lớp cuối cùng, chúng ta sẽ sử dụng hàm kích hoạt có tên là "softmax".
Áp dụng softmax trên một vectơ được thực hiện bằng cách lấy luỹ thừa của từng phần tử rồi chuẩn hoá vectơ, thường bằng cách chia vectơ cho "L1" của vectơ chuẩn (tức là tổng các giá trị tuyệt đối) để các giá trị được chuẩn hoá cộng lại bằng 1 và có thể được hiểu là xác suất.
Đầu ra của lớp cuối cùng, trước khi kích hoạt đôi khi được gọi là "logits". Nếu vectơ này là L = [L0, L1, L2, L3, L4, L5, L6, L7, L8, L9], thì:
Tổn thất entropy
Giờ đây, mạng nơron của chúng ta tạo ra các dự đoán từ hình ảnh đầu vào, chúng ta cần đo lường mức độ tốt của chúng, tức là khoảng cách giữa những gì mạng cho chúng ta biết và các câu trả lời chính xác, thường được gọi là "nhãn". Hãy nhớ rằng chúng tôi có nhãn chính xác cho tất cả hình ảnh trong tập dữ liệu.
Bất kỳ khoảng cách nào cũng được, nhưng đối với các bài toán phân loại, khoảng cách được gọi là "khoảng cách entropy chéo" là cách hiệu quả nhất. Chúng tôi sẽ gọi đây là lỗi của mình hay "mất mát" hàm:
Xuống kiểu chuyển màu
"Huấn luyện" mạng nơron thực ra là sử dụng hình ảnh và nhãn huấn luyện để điều chỉnh trọng số và độ chệch sao cho giảm thiểu hàm mất entropy. Dưới đây là cách thức hoạt động.
Entropy chéo là một hàm của trọng số, độ chệch, pixel của hình ảnh huấn luyện và lớp đã biết của hình ảnh đó.
Nếu chúng ta tính các đạo hàm riêng của entropy chéo tương đối với tất cả các trọng số và tất cả độ chệch, chúng ta sẽ có được độ dốc, được tính cho một hình ảnh, nhãn, giá trị hiện tại của trọng số và độ chệch. Hãy nhớ rằng chúng ta có thể có hàng triệu trọng số và độ lệch, vì vậy việc tính toán độ dốc nghe có vẻ mất nhiều công sức. Thật may là TensorFlow đã giúp chúng tôi làm việc này. Thuộc tính toán học của dải chuyển màu là nó trỏ "lên trên". Vì muốn đi tới nơi có giá trị chéo entropy thấp, nên chúng ta đi theo hướng ngược lại. Chúng tôi cập nhật trọng số và độ chệch theo một phần nhỏ của độ dốc. Sau đó, chúng ta làm tương tự nhiều lần bằng cách sử dụng các lô hình ảnh và nhãn huấn luyện tiếp theo trong một vòng lặp huấn luyện. Hy vọng rằng giá trị này hội tụ đến một nơi mà giá trị chéo entropy là tối thiểu, mặc dù không có gì đảm bảo rằng giá trị tối thiểu này là duy nhất.
Hành động theo lô nhỏ và động lượng
Bạn có thể tính toán độ dốc của mình chỉ trên một hình ảnh ví dụ và cập nhật ngay lập tức trọng số và độ chệch, nhưng làm như vậy trên một loạt, ví dụ 128 hình ảnh sẽ tạo ra một độ dốc thể hiện tốt hơn các hạn chế do các hình ảnh mẫu khác nhau áp đặt và do đó có khả năng hội tụ về phía giải pháp nhanh hơn. Kích thước của lô nhỏ là một tham số có thể điều chỉnh.
Kỹ thuật này, đôi khi được gọi là "giảm độ dốc ngẫu nhiên" có một lợi ích khác thực tế hơn: xử lý các lô cũng có nghĩa là làm việc với các ma trận lớn hơn và các ma trận này thường dễ tối ưu hoá trên GPU và TPU hơn.
Tuy nhiên, sự hội tụ vẫn có thể hơi hỗn loạn và thậm chí có thể dừng nếu vectơ chuyển màu đều bằng 0. Có phải điều đó có nghĩa là chúng tôi đã tìm ra mức tối thiểu không? Không phải lúc nào cũng vậy. Thành phần độ dốc có thể bằng 0 trên giá trị tối thiểu hoặc tối đa. Với vectơ độ dốc có hàng triệu phần tử, nếu tất cả các phần tử đều bằng 0, xác suất mà mọi số 0 đều tương ứng với giá trị tối thiểu và không có phần tử nào trong số đó đạt điểm tối đa là khá nhỏ. Trong một không gian có nhiều chiều, các điểm yên khá phổ biến và chúng tôi không muốn dừng lại ở đó.
Hình minh hoạ: một điểm yên xe. Độ dốc là 0 nhưng không phải là giá trị nhỏ nhất theo mọi hướng. (Ghi nhận tác giả hình ảnh Wikimedia: Của Nicoguaro – Tác phẩm riêng, CC BY 3.0)
Giải pháp là thêm động lượng vào thuật toán tối ưu hoá để thuật toán có thể vượt qua các điểm an toàn mà không dừng lại.
Bảng thuật ngữ
Lô hoặc lô nhỏ: quá trình huấn luyện luôn được thực hiện trên các lô dữ liệu và nhãn huấn luyện. Làm như vậy sẽ giúp thuật toán hội tụ. "Lô" thường là chiều đầu tiên của tensor dữ liệu. Ví dụ: tensor có hình dạng [100, 192, 192, 3] chứa 100 hình ảnh có kích thước 192x192 pixel với ba giá trị mỗi pixel (RGB).
mất entropy chéo: một hàm mất đặc biệt thường dùng trong thuật toán phân loại.
lớp dày đặc: một lớp nơron trong đó mỗi nơron được kết nối với tất cả các nơron trong lớp trước.
tính năng: đầu vào của mạng nơron đôi khi được gọi là "tính năng". Nghệ thuật xác định các phần nào của tập dữ liệu (hoặc tổ hợp các phần) cần đưa vào mạng nơron để có được các dự đoán chính xác được gọi là "kỹ thuật tính năng".
nhãn: tên khác của "lớp học" hoặc câu trả lời chính xác trong một bài toán phân loại được giám sát
tốc độ học tập: tỷ lệ độ dốc mà theo đó trọng số và độ chệch được cập nhật ở mỗi lần lặp lại của vòng lặp huấn luyện.
logit: dữ liệu đầu ra của một lớp nơron trước khi áp dụng hàm kích hoạt được gọi là "logit". Thuật ngữ này bắt nguồn từ "hàm logistic" còn gọi là "hàm sigmoid" từng là chức năng kích hoạt phổ biến nhất. "Đầu ra nơron trước hàm logistic" đã được rút ngắn thành "logits".
loss: hàm lỗi so sánh đầu ra của mạng nơron với câu trả lời đúng
nơ-ron: tính toán tổng có trọng số của các giá trị đầu vào, thêm độ chệch và cung cấp kết quả thông qua một hàm kích hoạt.
mã hoá một nóng: lớp 3/5 được mã hoá dưới dạng một vectơ gồm 5 phần tử, tất cả đều là số 0, ngoại trừ phần thứ 3 là 1.
relu: đơn vị tuyến tính đã chỉnh sửa. Một hàm kích hoạt phổ biến cho nơron.
sigmoid: một hàm kích hoạt khác từng phổ biến và hiện vẫn hữu ích trong các trường hợp đặc biệt.
softmax: một hàm kích hoạt đặc biệt hoạt động trên một vectơ, tăng hiệu số giữa thành phần lớn nhất và tất cả các thành phần khác, đồng thời chuẩn hoá vectơ có tổng bằng 1 để có thể hiểu vectơ đó là vectơ xác suất. Được dùng làm bước cuối cùng trong thuật toán phân loại.
tensor: "tensor" giống như ma trận nhưng có số lượng kích thước tuỳ ý. Tensor 1 chiều là một vectơ. Tensor 2 chiều là một ma trận. Và sau đó bạn có thể có các tensor với 3, 4, 5 hoặc nhiều chiều.
5. Chúng ta hãy bắt đầu với mã
Quay lại sổ tay học tập. Bây giờ, chúng ta hãy đọc mã.
Hãy xem qua toàn bộ ô trong sổ tay này.
"Thông số" ô
Kích thước lô, số khoảng thời gian huấn luyện và vị trí của các tệp dữ liệu được xác định tại đây. Các tệp dữ liệu được lưu trữ trong bộ chứa Google Cloud Storage (GCS), do vậy địa chỉ của tệp bắt đầu bằng gs://
Cell "Nhập"
Tất cả thư viện Python cần thiết đều được nhập vào đây, bao gồm cả TensorFlow và matplotlib để trực quan hoá.
Ô "tiện ích trực quan hoá [RUN ME]****"
Ô này chứa mã trực quan không thú vị. Mã này được thu gọn theo mặc định, nhưng bạn có thể mở mã và xem mã khi có thời gian bằng cách nhấp đúp vào mã.
Cell "tf.data.Dataset: phân tích cú pháp tệp và chuẩn bị tập dữ liệu huấn luyện và xác thực"
Ô này sử dụng API tf.data.Dataset để tải tập dữ liệu MNIST tạo thành các tệp dữ liệu. Bạn không cần phải dành quá nhiều thời gian cho ô này. Nếu bạn quan tâm đến API tf.data.Dataset, hãy tham khảo hướng dẫn sau đây để giải thích về API này: Quy trình dữ liệu tốc độ TPU. Hiện tại, có những nội dung cơ bản như sau:
Hình ảnh và nhãn (câu trả lời chính xác) từ tập dữ liệu MNIST được lưu trữ trong bản ghi có độ dài cố định trong 4 tệp. Có thể tải các tệp bằng chức năng bản ghi cố định chuyên dụng:
imagedataset = tf.data.FixedLengthRecordDataset(image_filename, 28*28, header_bytes=16)
Chúng ta hiện có một tập dữ liệu gồm các byte ảnh. Các thẻ này cần được giải mã thành hình ảnh. Chúng ta định nghĩa một hàm để thực hiện việc này. Hình ảnh không được nén nên hàm không cần giải mã bất cứ thứ gì (về cơ bản, decode_raw
không làm gì). Sau đó, hình ảnh này được chuyển đổi sang các giá trị dấu phẩy động từ 0 đến 1. Chúng ta có thể đổi hình dạng nó ở đây dưới dạng hình ảnh 2D nhưng thực sự chúng ta giữ nó dưới dạng một mảng pixel phẳng có kích thước 28*28 vì đó là những gì lớp dày đặc ban đầu của chúng ta mong đợi.
def read_image(tf_bytestring):
image = tf.io.decode_raw(tf_bytestring, tf.uint8)
image = tf.cast(image, tf.float32)/256.0
image = tf.reshape(image, [28*28])
return image
Chúng ta áp dụng hàm này cho tập dữ liệu bằng cách sử dụng .map
và thu được một tập dữ liệu gồm các hình ảnh:
imagedataset = imagedataset.map(read_image, num_parallel_calls=16)
Chúng ta thực hiện cùng một kiểu đọc và giải mã cho nhãn, đồng thời .zip
hình ảnh và nhãn cùng nhau:
dataset = tf.data.Dataset.zip((imagedataset, labelsdataset))
Chúng ta hiện có một tập dữ liệu gồm các cặp (hình ảnh, nhãn). Đây là điều mà mô hình của chúng ta mong đợi. Chúng ta chưa sẵn sàng sử dụng ngôn ngữ này trong chức năng huấn luyện:
dataset = dataset.cache()
dataset = dataset.shuffle(5000, reshuffle_each_iteration=True)
dataset = dataset.repeat()
dataset = dataset.batch(batch_size)
dataset = dataset.prefetch(tf.data.experimental.AUTOTUNE)
API tf.data.Dataset có tất cả chức năng tiện ích cần thiết để chuẩn bị tập dữ liệu:
.cache
sẽ lưu tập dữ liệu vào bộ nhớ đệm trong RAM. Đây là một tập dữ liệu nhỏ nên sẽ hoạt động tốt. .shuffle
trộn bài với một vùng đệm gồm 5.000 phần tử. Bạn cần phải xáo trộn dữ liệu huấn luyện một cách hiệu quả. .repeat
lặp lại tập dữ liệu. Chúng tôi sẽ đào tạo về mã này nhiều lần (nhiều thời gian bắt đầu của hệ thống). .batch
kéo nhiều hình ảnh và nhãn lại với nhau thành một lô nhỏ. Cuối cùng, .prefetch
có thể dùng CPU để chuẩn bị lô tiếp theo trong khi lô hiện tại đang được huấn luyện trên GPU.
Tập dữ liệu xác thực được chuẩn bị theo cách tương tự. Bây giờ, chúng ta đã sẵn sàng để xác định mô hình và sử dụng tập dữ liệu này để huấn luyện mô hình đó.
Cell "Keras Model" (Mô hình Cell)
Tất cả mô hình của chúng ta sẽ là trình tự các lớp thẳng, vì vậy, chúng ta có thể sử dụng kiểu tf.keras.Sequential
để tạo các mô hình đó. Ban đầu ở đây, nó là một lớp dày đặc. Nó có 10 tế bào thần kinh vì chúng tôi đang phân loại các chữ số viết tay thành 10 lớp. Chiến dịch này sử dụng "softmax" vì đây là lớp cuối cùng trong thuật toán phân loại.
Mô hình Keras cũng cần biết hình dạng của dữ liệu đầu vào. Bạn có thể sử dụng tf.keras.layers.Input
để xác định giá trị này. Ở đây, vectơ đầu vào là các vectơ phẳng có giá trị điểm ảnh dài 28*28.
model = tf.keras.Sequential(
[
tf.keras.layers.Input(shape=(28*28,)),
tf.keras.layers.Dense(10, activation='softmax')
])
model.compile(optimizer='sgd',
loss='categorical_crossentropy',
metrics=['accuracy'])
# print model layers
model.summary()
# utility callback that displays training curves
plot_training = PlotTraining(sample_rate=10, zoom=1)
Việc định cấu hình mô hình được thực hiện trong Keras bằng cách sử dụng hàm model.compile
. Ở đây, chúng tôi sử dụng trình tối ưu hoá cơ bản 'sgd'
(Giảm độ chuyển màu ngẫu nhiên). Mô hình phân loại yêu cầu hàm mất entropy, có tên là 'categorical_crossentropy'
ở Keras. Cuối cùng, chúng tôi yêu cầu mô hình này tính toán chỉ số 'accuracy'
. Đây là tỷ lệ phần trăm hình ảnh được phân loại chính xác.
Keras cung cấp tiện ích model.summary()
rất hữu ích để in thông tin chi tiết của mô hình mà bạn đã tạo. Người hướng dẫn tử tế của bạn đã thêm tiện ích PlotTraining
(được định nghĩa trong ô "tiện ích trực quan hoá"). Tiện ích này sẽ hiển thị nhiều đường cong huấn luyện trong quá trình đào tạo.
Ô "Đào tạo và xác thực mô hình"
Đây là nơi quá trình huấn luyện diễn ra, bằng cách gọi model.fit
và truyền cả tập dữ liệu huấn luyện và tập dữ liệu xác thực. Theo mặc định, Keras chạy một vòng xác thực vào cuối mỗi thời gian bắt đầu của hệ thống.
model.fit(training_dataset, steps_per_epoch=steps_per_epoch, epochs=EPOCHS,
validation_data=validation_dataset, validation_steps=1,
callbacks=[plot_training])
Trong Keras, bạn có thể thêm các hành vi tuỳ chỉnh trong quá trình huấn luyện bằng cách sử dụng lệnh gọi lại. Đó là cách chúng tôi triển khai kế hoạch đào tạo về việc cập nhật linh động cho hội thảo này.
Ô "Trực quan hoá nội dung dự đoán"
Sau khi mô hình được huấn luyện, chúng ta có thể nhận thông tin dự đoán từ mô hình đó bằng cách gọi model.predict()
:
probabilities = model.predict(font_digits, steps=1)
predicted_labels = np.argmax(probabilities, axis=1)
Ở đây, chúng tôi đã chuẩn bị một bộ chữ số in được kết xuất từ phông chữ trên máy để thử nghiệm. Hãy nhớ rằng mạng nơron trả về vectơ có 10 xác suất từ "softmax" cuối cùng. Để có nhãn, chúng ta phải tìm hiểu xác suất nào cao nhất. np.argmax
từ thư viện numpy sẽ thực hiện việc đó.
Để hiểu tại sao tham số axis=1
lại cần thiết, hãy nhớ rằng chúng tôi đã xử lý một loạt gồm 128 hình ảnh và do đó mô hình sẽ trả về 128 vectơ xác suất. Hình dạng của tensor đầu ra là [128, 10]. Chúng tôi đang tính toán argmax trên 10 xác suất được trả về cho mỗi hình ảnh, do đó, axis=1
(trục đầu tiên là 0).
Mô hình đơn giản này đã nhận dạng 90% chữ số. Không tệ, nhưng giờ đây bạn sẽ cải thiện đáng kể điều này.
6. Thêm lớp
Để cải thiện độ chính xác của nhận dạng, chúng ta sẽ thêm nhiều lớp vào mạng nơron.
Chúng ta giữ Softmax làm hàm kích hoạt trên lớp cuối cùng vì đó là hàm phù hợp nhất để phân loại. Tuy nhiên, trên các lớp trung gian, chúng ta sẽ sử dụng hàm kích hoạt cổ điển nhất: sigmoid:
Ví dụ: mô hình của bạn có thể có dạng như sau (đừng quên dấu phẩy, tf.keras.Sequential
sẽ lấy danh sách các lớp được phân tách bằng dấu phẩy):
model = tf.keras.Sequential(
[
tf.keras.layers.Input(shape=(28*28,)),
tf.keras.layers.Dense(200, activation='sigmoid'),
tf.keras.layers.Dense(60, activation='sigmoid'),
tf.keras.layers.Dense(10, activation='softmax')
])
Xem phần "tóm tắt" mô hình của bạn. Hàm này hiện có số lượng thông số nhiều hơn ít nhất 10 lần. Đáng lẽ phải tốt hơn gấp 10 lần! Nhưng vì một lý do nào đó, video không phải ...
Có vẻ như sự mất mát cũng đã ảnh hưởng đến mái nhà. Đã xảy ra lỗi.
7. Đặc biệt chú ý đến các mạng sâu
Bạn vừa mới trải nghiệm mạng nơron, như mọi người từng thiết kế mạng nơron vào những năm 80 và 90. Vậy nên, chẳng có gì ngạc nhiên khi họ từ bỏ ý tưởng này và mở ra cái tên "mùa đông do AI tạo". Thật vậy, khi bạn thêm các lớp, mạng nơron ngày càng gặp nhiều khó khăn hơn để hội tụ.
Hoá ra các mạng nơron sâu với nhiều lớp (20, 50, thậm chí 100 lớp ngày nay) có thể hoạt động thực sự tốt, cung cấp một vài thủ thuật bẩn trong toán học để khiến chúng hội tụ. Việc phát hiện ra những thủ thuật đơn giản này là một trong những lý do dẫn đến sự phục hồi của công nghệ học sâu vào những năm 2010.
Kích hoạt RELU
Hàm kích hoạt sigmoid thực sự gặp vấn đề trong các mạng sâu. Nó nén tất cả các giá trị từ 0 đến 1 và khi bạn làm như vậy nhiều lần, các đầu ra nơron và độ dốc của chúng có thể biến mất hoàn toàn. Đơn vị tuyến tính này được đề cập đến vì nhiều lý do trong quá khứ, nhưng các mạng hiện đại sử dụng RELU (Đơn vị tuyến tính đã chỉnh sửa) có dạng như sau:
Mặt khác, relu có đạo hàm bằng 1, ít nhất ở vế phải. Khi kích hoạt RELU, ngay cả khi độ dốc từ một số nơron có thể bằng 0, thì sẽ luôn có những gradient khác tạo ra rõ ràng và quá trình huấn luyện có thể tiếp tục với tốc độ phù hợp.
Trình tối ưu hoá hiệu quả hơn
Trong các không gian rất cao như ở đây – chúng ta có thứ tự 10.000 trọng số và độ chệch – "điểm an toàn" là thường xuyên. Đây là các điểm không phải là điểm cực tiểu cục bộ, nhưng ở đó độ dốc vẫn bằng 0 và trình tối ưu hoá giảm độ dốc vẫn bị treo ở đó. TensorFlow có nhiều trình tối ưu hoá, trong đó có một số trình tối ưu hoá hoạt động với nhiều quán tính và sẽ lướt qua các điểm an toàn một cách an toàn.
Khởi tạo ngẫu nhiên
Bản thân việc tạo ra độ sai lệch về trọng số trước khi huấn luyện là một lĩnh vực nghiên cứu, với nhiều bài báo đã xuất bản về chủ đề này. Bạn có thể xem tất cả các trình khởi tạo có trong Keras tại đây. May mắn là Keras thực hiện đúng theo mặc định và sử dụng trình khởi tạo 'glorot_uniform'
là tốt nhất trong hầu hết các trường hợp.
Bạn không cần phải làm gì cả vì Keras đã làm đúng cách.
NaN ^
Công thức chéo entropy liên quan đến logarit và log(0) không phải là số (NaN, sự cố số nếu bạn muốn). Đầu vào cho chéo entropy có thể bằng 0 không? Dữ liệu đầu vào đến từ softmax, về cơ bản là số mũ và số mũ không bao giờ bằng 0. Vậy nên chúng tôi an toàn!
Thật à? Trong thế giới tuyệt đẹp của toán học, chúng ta sẽ được an toàn, nhưng trong thế giới máy tính, exp(-150), được biểu diễn ở định dạng float32, bằng ZERO và các sự cố chéo entropy.
May mắn là bạn không cần phải làm gì ở đây vì Keras sẽ xử lý việc này và tính toán softmax theo sau là entropy chéo theo cách đặc biệt cẩn thận để đảm bảo độ ổn định về số học và tránh NaN đáng sợ.
Thành công?
Bây giờ, bạn sẽ đạt được độ chính xác là 97%. Mục tiêu của hội thảo này là đạt trên 99% đáng kể, vì vậy hãy tiếp tục nỗ lực nhé.
Nếu bạn gặp khó khăn, sau đây là giải pháp tại thời điểm này:
8. Mô hình phân bổ giảm dựa trên tỷ lệ học tập
Không biết chúng ta có thể đào tạo nhanh hơn không? Tốc độ học mặc định trong trình tối ưu hoá Adam là 0,001. Hãy thử tăng ngân sách.
Chạy nhanh hơn có vẻ không giúp ích nhiều hơn, và tất cả những tiếng ồn này là gì?
Các đường cong huấn luyện thực sự rất nhiễu và hãy xem cả hai đường cong xác thực: chúng đang nhảy lên và xuống. Điều này có nghĩa là chúng tôi đang làm quá nhanh. Chúng ta có thể quay lại tốc độ trước đây, nhưng có cách tốt hơn.
Giải pháp hay là bắt đầu nhanh và giảm tốc độ học theo cấp số nhân. Trong Keras, bạn có thể thực hiện việc này bằng lệnh gọi lại tf.keras.callbacks.LearningRateScheduler
.
Mã hữu ích để sao chép-dán:
# lr decay function
def lr_decay(epoch):
return 0.01 * math.pow(0.6, epoch)
# lr schedule callback
lr_decay_callback = tf.keras.callbacks.LearningRateScheduler(lr_decay, verbose=True)
# important to see what you are doing
plot_learning_rate(lr_decay, EPOCHS)
Đừng quên sử dụng lr_decay_callback
bạn đã tạo. Thêm phương thức này vào danh sách các lệnh gọi lại trong model.fit
:
model.fit(..., callbacks=[plot_training, lr_decay_callback])
Tác động của thay đổi nhỏ này thật đáng kinh ngạc. Bạn thấy rằng hầu hết tiếng ồn đã biến mất và độ chính xác của bài kiểm thử hiện đã trên 98% một cách bền vững.
9. Bỏ học, quá tải
Mô hình hiện có vẻ đang hội tụ tốt. Hãy thử tìm hiểu kỹ hơn nữa.
Như thế có giúp ích cho bạn không?
Không thực sự, độ chính xác vẫn bị mắc kẹt ở 98% và xem xét tổn thất xác thực. Tăng lên! Thuật toán học tập chỉ hoạt động dựa trên dữ liệu huấn luyện và tối ưu hoá lượng dữ liệu huấn luyện bị mất cho phù hợp. Nó không bao giờ thấy dữ liệu xác thực, vì vậy, không có gì đáng ngạc nhiên khi sau một thời gian hoạt động của nó không còn ảnh hưởng đến việc mất dữ liệu xác thực, khiến dữ liệu xác thực ngừng giảm và đôi khi thậm chí khôi phục trở lại.
Điều này không ảnh hưởng ngay đến khả năng nhận dạng trong thực tế của mô hình, nhưng sẽ khiến bạn không thể chạy nhiều lần lặp lại và thường là một dấu hiệu cho thấy quá trình huấn luyện không còn mang lại hiệu quả tích cực nữa.
Sự ngắt kết nối này thường được gọi là "kết hợp quá mức" và khi nhìn thấy, bạn có thể thử áp dụng kỹ thuật điều chỉnh hoá có tên là "dropout". Kỹ thuật bỏ học sẽ bắn các nơron ngẫu nhiên ở mỗi lần huấn luyện.
Nó có làm việc không?
Tiếng ồn lại xuất hiện (không ngạc nhiên khi biết cách hoạt động của hiệu ứng bỏ ngang). Mức độ mất xác thực dường như không còn tăng nữa, nhưng nhìn chung, mức độ này cao hơn so với khi không có lượt bỏ ngang. Độ chính xác của việc xác thực đã giảm xuống một chút. Đây là một kết quả không hề dễ chịu.
Có vẻ như tỷ lệ bỏ ngang không phải là giải pháp chính xác, hoặc có thể là "trang bị quá mức" là một khái niệm phức tạp hơn và một số nguyên nhân không phù hợp với tình trạng "bỏ qua" sửa không?
"overfitting" (Kết hợp quá mức) là gì? Tình trạng quá mức xảy ra khi mạng nơron học "không tốt", theo cách phù hợp với các ví dụ huấn luyện nhưng không hiệu quả lắm đối với dữ liệu trong thế giới thực. Có những kỹ thuật điều chỉnh (như bỏ qua) có thể thúc đẩy mô hình học hỏi theo cách hiệu quả hơn, nhưng việc áp dụng quá mức cũng có thể phát triển sâu hơn.
Tình trạng suy hao quá mức cơ bản xảy ra khi một mạng nơron có quá nhiều mức độ tự do cho vấn đề đang được giải quyết. Hãy tưởng tượng chúng ta có nhiều nơron đến mức mạng có thể lưu trữ tất cả hình ảnh huấn luyện của chúng ta trong đó rồi nhận ra chúng bằng cách so khớp mẫu. Quá trình này sẽ hoàn toàn không hoạt động trên dữ liệu thực tế. Mạng nơron phải có phần hạn chế để nó buộc phải khái quát hoá những gì nó học được trong quá trình huấn luyện.
Nếu bạn có rất ít dữ liệu huấn luyện, thì ngay cả một mạng nhỏ cũng có thể học thuộc lòng và bạn sẽ thấy trạng thái "quá tải". Nói chung, bạn luôn cần nhiều dữ liệu để huấn luyện mạng nơron.
Cuối cùng, nếu bạn đã làm xong mọi thứ trong cuốn sách, thử nghiệm với các kích thước mạng khác nhau để đảm bảo mức độ tự do của mạng bị hạn chế, áp dụng bỏ qua và huấn luyện dựa trên nhiều dữ liệu, bạn có thể vẫn bị mắc kẹt ở mức hiệu suất mà dường như không có gì cải thiện được. Điều này có nghĩa là mạng nơron không thể trích xuất thêm thông tin từ dữ liệu của bạn, như trong trường hợp của chúng ta ở đây.
Bạn có nhớ cách chúng ta sử dụng hình ảnh được làm phẳng thành một vectơ không? Đó thực sự là một ý tưởng tệ. Các chữ số viết tay được tạo thành từ hình dạng và chúng tôi đã loại bỏ thông tin hình dạng khi làm phẳng các pixel. Tuy nhiên, có một loại mạng nơron có thể tận dụng thông tin hình dạng: mạng tích chập. Hãy thử xem.
Nếu bạn gặp khó khăn, sau đây là giải pháp tại thời điểm này:
10. [INFO] mạng tích chập
Tóm tắt
Nếu bạn đã biết tất cả những thuật ngữ in đậm trong đoạn tiếp theo, thì bạn có thể chuyển sang bài tập tiếp theo. Nếu bạn chỉ mới bắt đầu sử dụng mạng nơron tích chập, vui lòng đọc tiếp.
Hình minh hoạ: lọc một hình ảnh có hai bộ lọc liên tiếp có kích thước 4x4x3=48 trọng số có thể học.
Sau đây là giao diện của một mạng nơron tích chập đơn giản trong Keras:
model = tf.keras.Sequential([
tf.keras.layers.Reshape(input_shape=(28*28,), target_shape=(28, 28, 1)),
tf.keras.layers.Conv2D(kernel_size=3, filters=12, activation='relu'),
tf.keras.layers.Conv2D(kernel_size=6, filters=24, strides=2, activation='relu'),
tf.keras.layers.Conv2D(kernel_size=6, filters=32, strides=2, activation='relu'),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(10, activation='softmax')
])
Trong một lớp của mạng tích chập, một "nơron" tính tổng các pixel có trọng số ngay phía trên, chỉ qua một vùng nhỏ của hình ảnh. Phương pháp này thêm độ chệch và cung cấp giá trị tổng thông qua một hàm kích hoạt, giống như một nơron trong một lớp dày đặc thông thường. Sau đó, thao tác này được lặp lại trên toàn bộ hình ảnh với cùng trọng số. Hãy nhớ rằng trong các lớp dày đặc, mỗi nơron có trọng số riêng. Ở đây, một "bản vá" trọng lượng trượt qua hình ảnh theo cả hai hướng ("cụm chập"). Đầu ra có nhiều giá trị như pixel trong hình ảnh (tuy nhiên, cần có một số khoảng đệm ở các cạnh). Đây là một thao tác lọc. Trong hình minh hoạ ở trên, nó sử dụng bộ lọc có trọng số 4x4x3=48.
Tuy nhiên, 48 trọng số là không đủ. Để thêm nhiều bậc tự do hơn, chúng tôi lặp lại thao tác tương tự với một tập hợp trọng số mới. Thao tác này sẽ tạo ra một tập hợp đầu ra mới của bộ lọc. Hãy đặt tên đó là "kênh" tương tự với các kênh R,G,B trong hình ảnh đầu vào.
Hai (hoặc nhiều) tập hợp trọng số có thể được tổng hợp dưới dạng một tensor bằng cách thêm một chiều mới. Điều này cho chúng ta hình dạng chung của tensor trọng số cho một lớp tích chập. Do số lượng kênh đầu vào và đầu ra là tham số, nên chúng ta có thể bắt đầu xếp chồng và tạo chuỗi các lớp tích chập.
Hình minh hoạ: một mạng nơron tích chập biến đổi các "hình lập phương" vào các "khối" khác dữ liệu.
Số tích chập chậm, gộp tối đa
Bằng cách thực hiện các phép tích chập với một bước tiến 2 hoặc 3, chúng ta cũng có thể thu nhỏ khối dữ liệu thu được theo kích thước ngang của nó. Có hai cách phổ biến để làm việc này:
- Tích chập sải chân: bộ lọc trượt như trên nhưng có sải chân >1
- Gộp tối đa: một cửa sổ trượt áp dụng thao tác MAX (thường là trên 2x2 bản vá, lặp lại sau mỗi 2 pixel)
Hình minh hoạ: việc trượt cửa sổ tính toán 3 pixel thì giá trị đầu ra sẽ giảm đi. Tích chập sải chân hoặc gộp nhóm tối đa (tối đa trên cửa sổ 2x2 trượt với một sải chân là 2) là một cách thu gọn khối dữ liệu theo kích thước ngang.
Lớp cuối cùng
Sau lớp tích chập cuối cùng, dữ liệu ở dạng "khối". Có hai cách để nuôi dưỡng chất này thông qua lớp dày đặc cuối cùng.
Bước đầu tiên là làm phẳng khối dữ liệu thành một vectơ, sau đó đưa khối dữ liệu đó lên lớp softmax. Đôi khi, bạn thậm chí có thể thêm một lớp dày đặc trước lớp softmax. Việc này thường tốn kém về số lượng trọng số. Lớp dày đặc ở cuối một mạng chập có thể chứa hơn một nửa trọng số của toàn bộ mạng nơron.
Thay vì sử dụng lớp dày đặc đắt tiền, chúng ta cũng có thể chia "khối" dữ liệu nhận được vào nhiều phần như chúng ta có lớp, lấy trung bình giá trị của các lớp đó và cung cấp các giá trị này thông qua hàm kích hoạt Softmax. Cách tạo đầu phân loại này không có trọng số. Trong Keras, có một lớp cho định dạng này: tf.keras.layers.GlobalAveragePooling2D()
.
Chuyển đến phần tiếp theo để xây dựng một mạng tích chập cho bài toán đang thực hiện.
11. Mạng tích chập
Hãy cùng xây dựng một mạng tích chập để nhận dạng chữ số viết tay. Chúng ta sẽ sử dụng 3 lớp tích chập ở trên cùng – lớp đọc dữ liệu mềm truyền thống ở dưới cùng và kết nối chúng với một lớp được kết nối đầy đủ:
Lưu ý rằng các lớp tích chập thứ hai và thứ ba có một bước tiến là hai, giải thích tại sao chúng giảm số lượng giá trị đầu ra từ 28x28 xuống 14x14 và sau đó là 7x7.
Hãy viết mã Keras.
Cần đặc biệt chú ý trước lớp tích chập đầu tiên. Thật vậy, thiết bị này mong đợi có một "khối" 3D nhưng cho đến nay tập dữ liệu của chúng tôi đã được thiết lập cho các lớp dày đặc và tất cả các pixel của hình ảnh được làm phẳng thành một vectơ. Chúng ta cần đặt lại hình dạng chúng trở lại thành hình ảnh 28x28x1 (1 kênh cho hình ảnh thang màu xám):
tf.keras.layers.Reshape(input_shape=(28*28,), target_shape=(28, 28, 1))
Bạn có thể sử dụng dòng này thay vì lớp tf.keras.layers.Input
mà bạn đã có từ trước đến nay.
Trong Keras, cú pháp cho lớp tích chập được kích hoạt "relu" là:
tf.keras.layers.Conv2D(kernel_size=3, filters=12, padding='same', activation='relu')
Đối với tích chập có sải chân, bạn sẽ viết:
tf.keras.layers.Conv2D(kernel_size=6, filters=24, padding='same', activation='relu', strides=2)
Để làm phẳng một khối dữ liệu thành một vectơ sao cho một lớp dày đặc có thể sử dụng nó:
tf.keras.layers.Flatten()
Và đối với lớp dày đặc, cú pháp không thay đổi:
tf.keras.layers.Dense(200, activation='relu')
Mô hình của bạn có phá vỡ rào cản độ chính xác 99% không? Gần đúng... nhưng hãy xem đường cong về tổn thất xác thực. Thiết bị này có đổ chuông không?
Ngoài ra, hãy xem các dự đoán. Lần đầu tiên, bạn sẽ thấy hầu hết trong số 10.000 chữ số kiểm thử hiện đã được nhận dạng chính xác. Chỉ còn khoảng 41⁄2 hàng phát hiện sai (khoảng 110 chữ số trong số 10.000)
Nếu bạn gặp khó khăn, sau đây là giải pháp tại thời điểm này:
12. Ngừng tham gia lần nữa
Các chương trình đào tạo trước đó cho thấy các dấu hiệu rõ ràng của tình trạng quá tải (mà vẫn thiếu độ chính xác 99%). Chúng ta có nên thử thoát ra lần nữa không?
Lần này mọi việc thế nào rồi?
Có vẻ như việc bỏ ngang đã giải quyết được lần này. Tỷ lệ xác thực không còn tăng nữa và độ chính xác cuối cùng phải trên 99%. Xin chúc mừng!
Lần đầu tiên áp dụng phương pháp bỏ học, chúng tôi nghĩ rằng mình đã gặp vấn đề quá mức, trong khi thực tế vấn đề nằm ở kiến trúc của mạng nơron. Chúng tôi không thể tiến xa hơn nếu không có các lớp tích chập và không có gì làm được điều đó.
Lần này, có vẻ như việc sử dụng quá mức là nguyên nhân của vấn đề và việc bỏ ngang thực sự hữu ích. Hãy nhớ rằng, có nhiều yếu tố có thể gây ra sự ngắt kết nối giữa đường cong mất tập huấn và xác thực, cùng với sự mất mát về xác thực ngày càng tăng. Tình trạng quá mức (quá nhiều mức độ tự do, bị mạng sử dụng kém) chỉ là một trong những trường hợp đó. Nếu tập dữ liệu quá nhỏ hoặc kiến trúc của mạng nơron không đầy đủ, thì bạn có thể thấy hành vi tương tự trên đường cong tổn hao, nhưng tình trạng bỏ ngang sẽ không giúp ích.
13. Chuẩn hoá theo lô
Cuối cùng, hãy thử thêm quy trình chuẩn hoá theo lô.
Đó là lý thuyết, trên thực tế bạn chỉ cần nhớ một vài quy tắc:
Bây giờ, hãy chơi theo cuốn sách và thêm một lớp chuẩn theo lô trên mỗi lớp mạng nơron nhưng là lớp cuối cùng. Không thêm vào "softmax" cuối cùng lớp. Ở đó sẽ không hữu ích.
# Modify each layer: remove the activation from the layer itself.
# Set use_bias=False since batch norm will play the role of biases.
tf.keras.layers.Conv2D(..., use_bias=False),
# Batch norm goes between the layer and its activation.
# The scale factor can be turned off for Relu activation.
tf.keras.layers.BatchNormalization(scale=False, center=True),
# Finish with the activation.
tf.keras.layers.Activation('relu'),
Độ chính xác hiện tại ra sao?
Chỉ cần tinh chỉnh một chút (BATCH_SIZE=64, tham số phân rã tốc độ học 0.666, tỷ lệ bỏ trên lớp dày đặc 0.3) và một chút may mắn, bạn có thể đạt 99,5%. Tỷ lệ học tập và tỷ lệ bỏ cuộc được điều chỉnh theo các "phương pháp hay nhất" để sử dụng quy tắc theo lô:
- Quy chuẩn theo lô giúp mạng nơron hội tụ và thường giúp bạn tập luyện nhanh hơn.
- Quy tắc theo lô là một trình chuẩn hoá. Thông thường, bạn có thể giảm số lượt bỏ ngang mà mình sử dụng hoặc thậm chí hoàn toàn không sử dụng tính năng thoát.
Sổ tay giải pháp có thời gian huấn luyện là 99,5%:
14. Đào tạo trên đám mây bằng phần cứng mạnh mẽ: Nền tảng AI
Bạn sẽ tìm thấy phiên bản mã có sẵn trên đám mây trong thư mục mlengine trên GitHub, cùng với hướng dẫn chạy mã trên Google Cloud AI Platform. Trước khi có thể thực hiện phần này, bạn sẽ phải tạo tài khoản Google Cloud và bật tính năng thanh toán. Các nguồn lực cần thiết để hoàn thành phòng thí nghiệm này nên không quá vài đô la (giả sử 1 giờ huấn luyện trên một GPU). Cách chuẩn bị cho tài khoản của bạn:
- Tạo một dự án Google Cloud Platform ( http://cloud.google.com/console).
- Bật tính năng thanh toán.
- Cài đặt các công cụ dòng lệnh cho GCP ( SDK GCP tại đây).
- Tạo một bộ chứa Google Cloud Storage (đặt vào khu vực
us-central1
). Tệp này sẽ được dùng để triển khai mã huấn luyện và lưu trữ mô hình đã huấn luyện. - Bật các API cần thiết và yêu cầu hạn mức cần thiết (chạy lệnh huấn luyện một lần và bạn sẽ nhận được thông báo lỗi cho biết nội dung cần bật).
15. Xin chúc mừng!
Bạn đã xây dựng được mạng nơron đầu tiên của mình và huấn luyện nó đến độ chính xác 99%. Các kỹ thuật được học trong quá trình này không dành riêng cho tập dữ liệu MNIST, thực tế được sử dụng rộng rãi khi làm việc với mạng nơron. Đây là "ghi chú của Thừa phát lại" như một món quà chia tay thẻ phòng thí nghiệm, trong phiên bản hoạt hình. Bạn có thể sử dụng công cụ này để ghi nhớ những kiến thức đã học:
Các bước tiếp theo
- Sau khi các mạng nơron được kết nối đầy đủ và tích chập, bạn nên tìm hiểu phần mạng nơron lặp lại.
- Để chạy quy trình huấn luyện hoặc suy luận trên đám mây trên cơ sở hạ tầng phân tán, Google Cloud cung cấp Nền tảng AI.
- Cuối cùng, chúng tôi rất mong nhận được ý kiến phản hồi của bạn. Vui lòng cho chúng tôi biết nếu bạn thấy có gì thiếu trong phòng thí nghiệm này hoặc nếu bạn cho rằng điều đó cần được cải thiện. Chúng tôi xử lý ý kiến phản hồi thông qua các vấn đề trên GitHub [ feedback link].
Tác giả: Martin GörnerTwitter: @martin_gorner |
Tất cả hình ảnh hoạt hình trong bản quyền của phòng thí nghiệm này: alexpokusay / 123RF stock ảnh