Con trăn tích chập zero padding

Chào mọi người. Trong bài đăng này, chúng ta sẽ tìm hiểu về Zero-Padding là gì và tại sao chúng ta lại sử dụng Convolutional Neural Networks. Trước khi đi sâu vào phần đệm, hãy thảo luận về nhân. Hạt nhân là bộ lọc mạng thần kinh di chuyển trên hình ảnh, quét từng pixel và chuyển đổi dữ liệu thành định dạng nhỏ hơn hoặc đôi khi lớn hơn. Để hỗ trợ nhân xử lý hình ảnh, phần đệm được thêm vào khung của hình ảnh để có thêm không gian cho nhân bao phủ hình ảnh. Việc thêm phần đệm vào hình ảnh do CNN xử lý cho phép phân tích hình ảnh chính xác hơn

Kết cấu giảm kích thước kênh

Lớp tích chập có một số bộ lọc và chúng được áp dụng cho đầu vào để tạo bản đồ đặc trưng tóm tắt sự hiện diện của các đặc trưng được phát hiện trong đầu vào. Khi một bộ lọc tích hợp một kênh đầu vào nhất định, nó sẽ cung cấp cho chúng ta một kênh đầu ra. Kênh đầu ra này là một ma trận pixel với các giá trị được tính toán trong quá trình tích chập xảy ra trên kênh đầu vào. Khi điều này xảy ra, kích thước của hình ảnh của chúng tôi bị giảm. Nếu zero-padding = 1, sẽ có một pixel dày xung quanh ảnh gốc với giá trị pixel = 0

Con trăn tích chập zero padding

Chúng ta sẽ bắt đầu bằng cách giải thích động cơ của việc không đệm, và sau đó chúng ta sẽ tìm hiểu chi tiết về việc đệm không thực sự là gì. Sau đó, chúng ta sẽ nói về các loại sự cố mà chúng ta có thể gặp phải nếu không sử dụng phần đệm bằng 0 và sau đó chúng ta sẽ xem cách chúng ta có thể triển khai phần đệm bằng 0 trong mã bằng Keras

Chúng ta sẽ xây dựng dựa trên một số ý tưởng mà chúng ta đã thảo luận trong bài đăng của mình về mạng nơ ron tích chập, vì vậy nếu bạn chưa thấy điều đó, hãy tiếp tục và xem thử, sau đó quay lại với ý tưởng này sau khi bạn

Convolution giảm kích thước kênh

Chúng tôi đã thấy trong bài đăng của mình trên CNN rằng mỗi lớp tích chập có một số bộ lọc mà chúng tôi xác định và chúng tôi cũng xác định kích thước của các bộ lọc này. Chúng tôi cũng đã chỉ ra cách các bộ lọc này kết hợp hình ảnh đầu vào

Khi một bộ lọc tích hợp một kênh đầu vào nhất định, nó sẽ cung cấp cho chúng ta một kênh đầu ra. Kênh đầu ra này là một ma trận pixel với các giá trị được tính toán trong quá trình tích chập xảy ra trên kênh đầu vào

Khi điều này xảy ra, kích thước của hình ảnh của chúng tôi bị giảm

Kích thước hình ảnh được giảm

Hãy kiểm tra điều này bằng cách sử dụng cùng một hình ảnh số bảy mà chúng tôi đã sử dụng trong bài đăng trước trên CNN. Nhớ lại, chúng ta có một ma trận

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
0 của các giá trị pixel từ một hình ảnh của một
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
1 từ bộ dữ liệu MNIST. Chúng tôi sẽ sử dụng bộ lọc
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
2. Điều này mang lại cho chúng tôi các mục sau đây

Một kênh đầu vào đơn

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
0 (hình ảnh thang độ xám)

0. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 40. 40. 30. 50. 20. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 40. 50. 90. 90. 90. 90. 90. 91. 01. 01. 01. 01. 00. 90. 70. 10. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 51. 01. 01. 01. 01. 01. 01. 01. 01. 01. 01. 01. 01. 01. 01. 00. 70. 10. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 91. 00. 80. 80. 80. 80. 80. 50. 20. 20. 20. 20. 20. 50. 91. 01. 00. 70. 10. 00. 00. 00. 00. 00. 00. 00. 00. 00. 10. 30. 10. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 10. 81. 01. 00. 50. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 31. 01. 00. 90. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 31. 01. 00. 90. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 40. 61. 01. 01. 00. 20. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 10. 50. 90. 90. 91. 01. 01. 01. 01. 00. 90. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 30. 50. 91. 01. 01. 01. 01. 01. 01. 01. 01. 00. 60. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 10. 71. 01. 01. 01. 00. 90. 80. 80. 30. 30. 81. 01. 00. 50. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 40. 91. 00. 90. 90. 50. 30. 10. 00. 00. 00. 00. 81. 00. 90. 20. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 71. 00. 70. 20. 00. 00. 00. 00. 00. 00. 00. 20. 91. 00. 90. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 10. 50. 00. 00. 00. 00. 00. 00. 00. 00. 00. 31. 01. 00. 70. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 51. 00. 90. 20. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 81. 01. 00. 70. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 91. 00. 90. 20. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 31. 00. 90. 30. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 81. 00. 60. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 50. 30. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 0

A

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
2 filter

A

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
5 output channel

0. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 30. 40. 60. 70. 50. 40. 10. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 30. 61. 21. 41. 61. 61. 61. 61. 91. 92. 22. 32. 12. 01. 70. 90. 50. 00. 00. 00. 00. 00. 00. 00. 00. 51. 21. 82. 62. 73. 03. 03. 03. 03. 43. 53. 84. 03. 73. 63. 22. 31. 50. 50. 10. 00. 00. 00. 00. 00. 01. 12. 13. 24. 24. 44. 74. 74. 54. 24. 03. 83. 93. 94. 14. 54. 74. 13. 11. 50. 50. 00. 00. 00. 00. 00. 01. 12. 03. 13. 63. 33. 23. 23. 12. 92. 72. 52. 52. 52. 73. 03. 94. 44. 12. 91. 40. 30. 00. 00. 00. 00. 00. 91. 42. 12. 21. 81. 71. 71. 51. 10. 80. 50. 50. 50. 81. 32. 43. 74. 54. 02. 41. 00. 00. 00. 00. 00. 00. 10. 30. 30. 30. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 11. 32. 84. 24. 72. 81. 60. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 41. 22. 93. 95. 13. 12. 20. 10. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 10. 41. 01. 31. 61. 92. 43. 74. 45. 23. 82. 50. 70. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 20. 51. 11. 72. 32. 73. 03. 43. 74. 64. 95. 24. 12. 51. 20. 00. 00. 00. 00. 00. 00. 00. 00. 00. 10. 71. 31. 92. 63. 24. 04. 44. 84. 44. 24. 54. 85. 24. 52. 71. 60. 00. 00. 00. 00. 00. 00. 00. 00. 41. 01. 82. 63. 33. 83. 93. 83. 63. 43. 02. 93. 64. 15. 03. 82. 51. 00. 00. 00. 00. 00. 00. 00. 00. 00. 81. 73. 03. 53. 73. 33. 02. 52. 21. 91. 31. 32. 43. 34. 83. 42. 30. 60. 00. 00. 00. 00. 00. 00. 00. 00. 92. 02. 73. 22. 61. 81. 30. 70. 40. 10. 00. 42. 23. 34. 63. 02. 00. 20. 00. 00. 00. 00. 00. 00. 00. 00. 71. 41. 61. 70. 70. 20. 00. 00. 00. 00. 00. 82. 53. 74. 22. 61. 50. 00. 00. 00. 00. 00. 00. 00. 00. 00. 10. 50. 20. 50. 00. 00. 00. 00. 00. 00. 71. 73. 34. 03. 62. 20. 80. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 01. 32. 34. 03. 92. 81. 60. 20. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 32. 33. 14. 53. 42. 00. 80. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 92. 63. 43. 82. 51. 20. 20. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 01. 22. 02. 82. 41. 50. 30. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 01. 01. 32. 01. 30. 60. 00. 00. 00. 00. 00. 00. 00. 0

Chúng ta có thể thấy rằng đầu ra thực sự không cùng kích thước với đầu vào ban đầu. Kích thước đầu ra là

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
5. Kênh đầu vào ban đầu của chúng tôi là
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
0 và bây giờ chúng tôi có một kênh đầu ra đã giảm kích thước xuống còn
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
5 sau khi cuộn hình ảnh. Tại sao vậy?

Với hình ảnh

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
0 của chúng tôi, bộ lọc
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
2 của chúng tôi chỉ có thể phù hợp với
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
5 vị trí có thể, không phải tất cả
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
0. Với điều này, chúng tôi nhận được kết quả đầu ra
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
5. Điều này là do những gì xảy ra khi chúng ta cuộn các cạnh của hình ảnh

Để dễ hình dung điều này, hãy xem xét một ví dụ quy mô nhỏ hơn. Ở đây chúng tôi có đầu vào có kích thước

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
44 và sau đó là bộ lọc
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
2. Hãy xem chúng ta có thể kết hợp đầu vào của mình với bộ lọc này bao nhiêu lần và kích thước đầu ra thu được sẽ là bao nhiêu

Con trăn tích chập zero padding

Điều này có nghĩa là khi bộ lọc

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
2 này hoàn thành việc cuộn đầu vào
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
44 này, nó sẽ cho chúng ta một đầu ra có kích thước
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
48

Chúng tôi thấy rằng đầu ra kết quả là

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
48, trong khi đầu vào của chúng tôi là
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
44, và một lần nữa, giống như trong ví dụ lớn hơn của chúng tôi với hình ảnh số bảy, chúng tôi thấy rằng đầu ra của chúng tôi thực sự nhỏ hơn đầu vào của chúng tôi về kích thước

Chúng ta có thể biết trước các kích thước của chúng ta sẽ thu nhỏ bao nhiêu. Nói chung, nếu hình ảnh của chúng tôi có kích thước

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
11 và chúng tôi tích hợp nó với bộ lọc
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
12, thì kích thước của kết quả đầu ra là \((n – f + 1)\) x \((n – f + 1)\

Hãy xem liệu điều này có phù hợp với ví dụ của chúng tôi ở đây không

Đầu vào của chúng tôi có kích thước

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
44, vì vậy,
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
14 sẽ là
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
15 của chúng tôi và bộ lọc của chúng tôi là
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
2, vì vậy,
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
17 sẽ là
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
18 của chúng tôi. Thay thế các giá trị này trong công thức của chúng tôi, chúng tôi có

$$(n - f + 1) = (4 - 3) + 1 = 2$$

Thật vậy, điều này mang lại cho chúng tôi một kênh đầu ra

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
48, chính xác là những gì chúng tôi đã thấy một lúc trước. Điều này cũng phù hợp với ví dụ với đầu vào lớn hơn trong số bảy, vì vậy hãy tự mình kiểm tra để xác nhận rằng công thức thực sự cho chúng ta kết quả tương tự về đầu ra có kích thước
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
5 mà chúng ta đã thấy khi kiểm tra bằng mắt.

Các vấn đề với việc giảm kích thước

Xem xét kết quả đầu ra của hình ảnh của một lần nữa. Nó không thực sự là một vấn đề lớn khi đầu ra này nhỏ hơn một chút so với đầu vào, phải không?

Chúng tôi đã không mất nhiều dữ liệu hay bất cứ thứ gì vì hầu hết các phần quan trọng của đầu vào này đều nằm ở giữa. Nhưng chúng ta có thể tưởng tượng rằng đây sẽ là vấn đề lớn hơn nếu chúng ta có dữ liệu có ý nghĩa xung quanh các cạnh của hình ảnh

Ngoài ra, chúng tôi chỉ kết hợp hình ảnh này với một bộ lọc. Điều gì xảy ra khi đầu vào ban đầu này đi qua mạng và được kết hợp bởi nhiều bộ lọc hơn khi nó di chuyển ngày càng sâu hơn?

Chà, điều sắp xảy ra là kết quả đầu ra sẽ tiếp tục trở nên ngày càng nhỏ hơn. Đây là một vấn đề

Ví dụ: nếu chúng ta bắt đầu với một hình ảnh

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
44, thì chỉ sau một hoặc hai lớp chập, kết quả đầu ra có thể trở nên gần như vô nghĩa với mức độ nhỏ của nó. Một vấn đề khác là chúng tôi đang làm mất dữ liệu có giá trị bằng cách loại bỏ hoàn toàn thông tin xung quanh các cạnh của đầu vào

Chúng ta có thể làm gì ở đây?

Không đệm để giải cứu

Không đệm là một kỹ thuật cho phép chúng tôi giữ nguyên kích thước đầu vào ban đầu. Đây là thứ mà chúng tôi chỉ định trên cơ sở từng lớp tích chập. Với mỗi lớp tích chập, giống như chúng ta xác định có bao nhiêu bộ lọc và kích thước của các bộ lọc, chúng ta cũng có thể chỉ định có sử dụng phần đệm hay không

Không đệm là gì?

Bây giờ chúng ta biết những vấn đề mà phần đệm bằng không chống lại vấn đề gì, nhưng nó thực sự là gì?

Phần đệm bằng không xảy ra khi chúng ta thêm một đường viền pixel tất cả đều có giá trị bằng 0 xung quanh các cạnh của hình ảnh đầu vào. Điều này thêm một loại đệm số 0 xung quanh bên ngoài hình ảnh, do đó có tên là đệm số không. Quay trở lại ví dụ nhỏ của chúng tôi từ trước đó, nếu chúng tôi đệm đầu vào của mình bằng đường viền gồm các pixel có giá trị bằng 0, hãy xem kích thước đầu ra thu được sẽ là bao nhiêu sau khi kết hợp đầu vào của chúng tôi

Con trăn tích chập zero padding

Chúng tôi thấy rằng kích thước đầu ra của chúng tôi thực sự là

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
44, duy trì kích thước đầu vào ban đầu. Bây giờ, đôi khi chúng ta có thể cần thêm nhiều hơn một đường viền chỉ dày một pixel. Đôi khi, chúng tôi có thể cần thêm thứ gì đó như đường viền kép hoặc đường viền ba số 0 để duy trì kích thước ban đầu của đầu vào. Điều này sẽ chỉ phụ thuộc vào kích thước của đầu vào và kích thước của các bộ lọc

Điều tốt là hầu hết các API mạng thần kinh đều tính toán kích thước của đường viền cho chúng tôi. Tất cả những gì chúng ta phải làm chỉ là xác định xem chúng ta có thực sự muốn sử dụng phần đệm trong các lớp tích chập hay không

Phần đệm hợp lệ và giống nhau

Có hai loại đệm. Một được gọi bằng tên hợp lệ. Điều này chỉ có nghĩa là không có phần đệm. Nếu chúng tôi chỉ định phần đệm hợp lệ, điều đó có nghĩa là lớp tích chập của chúng tôi sẽ hoàn toàn không đệm và kích thước đầu vào của chúng tôi sẽ không được duy trì

Loại đệm khác được gọi là giống nhau. Điều này có nghĩa là chúng tôi muốn đệm đầu vào ban đầu trước khi chúng tôi tích hợp nó để kích thước đầu ra có cùng kích thước với kích thước đầu vào

Padding TypeDescriptionImpactValidKhông có paddingKích thước giảmGiống nhauSố 0 xung quanh các cạnhKích thước giữ nguyên

Bây giờ, hãy chuyển sang Keras và xem điều này được thực hiện như thế nào trong mã

Làm việc với mã trong Keras

Chúng tôi sẽ bắt đầu với một số nhập khẩu.
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
3

Bây giờ, chúng ta sẽ tạo một CNN hoàn toàn tùy ý

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])

Nó có một lớp dày đặc, sau đó là lớp tích chập

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
17, tiếp theo là lớp đầu ra dày đặc

Chúng tôi đã chỉ định rằng kích thước đầu vào của hình ảnh được đưa vào CNN này là

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
64 và lớp tích chập đầu tiên của chúng tôi có kích thước bộ lọc là
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
2, được chỉ định trong Keras với tham số
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
66. Sau đó, lớp đối lưu thứ hai chỉ định kích thước
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
67 và lớp thứ ba,
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
68

Với mô hình này, chúng tôi chỉ định tham số có tên là

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
69 cho mỗi lớp tích chập. Chúng tôi đang đặt tham số này bằng chuỗi
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
30. Hãy nhớ từ trước đó, phần đệm hợp lệ có nghĩa là không có phần đệm

Đây thực sự là mặc định cho các lớp tích chập trong Keras, vì vậy nếu chúng tôi không chỉ định tham số này, nó sẽ mặc định là phần đệm hợp lệ. Vì chúng tôi đang sử dụng phần đệm hợp lệ ở đây, nên chúng tôi hy vọng kích thước của đầu ra từ mỗi lớp tích chập này sẽ giảm xuống

Hãy kiểm tra. Dưới đây là tóm tắt của mô hình này

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
4

Chúng ta có thể thấy hình dạng đầu ra của mỗi lớp trong cột thứ hai. Hai số nguyên đầu tiên chỉ định kích thước của đầu ra theo chiều cao và chiều rộng. Bắt đầu với lớp đầu tiên của chúng tôi, chúng tôi thấy kích thước đầu ra của chúng tôi là kích thước ban đầu của đầu vào của chúng tôi,

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
64

Khi chúng tôi đến đầu ra của lớp tích chập đầu tiên, kích thước giảm xuống

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
32 và một lần nữa ở lớp tiếp theo, nó giảm xuống còn
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
33 và cuối cùng, ở lớp tích chập cuối cùng, nó giảm xuống còn
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
34

Vì vậy, chúng tôi bắt đầu với

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
64 và kết thúc với
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
34 khi hoàn thành tất cả và kết thúc với

Ngược lại, bây giờ, chúng ta có thể tạo một mô hình thứ hai

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
1

Cái này là một bản sao chính xác của cái đầu tiên, ngoại trừ việc chúng tôi đã chỉ định phần đệm

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
37 cho mỗi lớp tích chập. Nhớ lại từ trước đó rằng cùng một phần đệm có nghĩa là chúng tôi muốn đệm đầu vào ban đầu trước khi chúng tôi tích hợp nó để kích thước đầu ra có cùng kích thước với kích thước đầu vào

Hãy xem tóm tắt của mô hình này

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
6

Một lần nữa, chúng ta có thể thấy rằng chúng ta đang bắt đầu với kích thước đầu vào là

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
64 và nếu chúng ta nhìn vào hình dạng đầu ra cho từng lớp tích chập, chúng ta sẽ thấy rằng các lớp thực sự duy trì kích thước đầu vào ban đầu ngay bây giờ

Đây là lý do tại sao chúng tôi gọi loại đệm này là cùng đệm. Cùng một phần đệm giữ cho kích thước đầu vào giống nhau

kết thúc

Bây giờ chúng ta đã hiểu phần đệm bằng 0 là gì, nó đạt được gì khi chúng ta thêm nó vào CNN của mình và cách chúng ta có thể chỉ định phần đệm trong mạng của mình bằng Keras. tôi sẽ gặp lại bạn lần sau

Không đệm trong mạng thần kinh tích chập

Chuyện gì đang xảy ra vậy mọi người? . Khái niệm bí ẩn này là cái quái gì vậy?

Con trăn tích chập zero padding

Chúng ta sẽ bắt đầu bằng cách giải thích động cơ của việc không đệm, và sau đó chúng ta sẽ tìm hiểu chi tiết về việc đệm không thực sự là gì. Sau đó, chúng ta sẽ nói về các loại sự cố mà chúng ta có thể gặp phải nếu không sử dụng phần đệm bằng 0 và sau đó chúng ta sẽ xem cách chúng ta có thể triển khai phần đệm bằng 0 trong mã bằng Keras

Chúng ta sẽ xây dựng dựa trên một số ý tưởng mà chúng ta đã thảo luận trong bài đăng của mình về mạng nơ ron tích chập, vì vậy nếu bạn chưa thấy điều đó, hãy tiếp tục và xem thử, sau đó quay lại với ý tưởng này sau khi bạn

Convolution giảm kích thước kênh

Chúng tôi đã thấy trong bài đăng của mình trên CNN rằng mỗi lớp tích chập có một số bộ lọc mà chúng tôi xác định và chúng tôi cũng xác định kích thước của các bộ lọc này. Chúng tôi cũng đã chỉ ra cách các bộ lọc này kết hợp hình ảnh đầu vào

Khi một bộ lọc tích hợp một kênh đầu vào nhất định, nó sẽ cung cấp cho chúng ta một kênh đầu ra. Kênh đầu ra này là một ma trận pixel với các giá trị được tính toán trong quá trình tích chập xảy ra trên kênh đầu vào

Khi điều này xảy ra, kích thước của hình ảnh của chúng tôi bị giảm

Kích thước hình ảnh được giảm

Hãy kiểm tra điều này bằng cách sử dụng cùng một hình ảnh số bảy mà chúng tôi đã sử dụng trong bài đăng trước trên CNN. Nhớ lại, chúng ta có một ma trận

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
0 của các giá trị pixel từ một hình ảnh của một
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
1 từ bộ dữ liệu MNIST. Chúng tôi sẽ sử dụng bộ lọc
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
2. Điều này mang lại cho chúng tôi các mục sau đây

Một kênh đầu vào đơn

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
0 (hình ảnh thang độ xám)

0. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 40. 40. 30. 50. 20. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 40. 50. 90. 90. 90. 90. 90. 91. 01. 01. 01. 01. 00. 90. 70. 10. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 51. 01. 01. 01. 01. 01. 01. 01. 01. 01. 01. 01. 01. 01. 01. 00. 70. 10. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 91. 00. 80. 80. 80. 80. 80. 50. 20. 20. 20. 20. 20. 50. 91. 01. 00. 70. 10. 00. 00. 00. 00. 00. 00. 00. 00. 00. 10. 30. 10. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 10. 81. 01. 00. 50. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 31. 01. 00. 90. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 31. 01. 00. 90. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 40. 61. 01. 01. 00. 20. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 10. 50. 90. 90. 91. 01. 01. 01. 01. 00. 90. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 30. 50. 91. 01. 01. 01. 01. 01. 01. 01. 01. 00. 60. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 10. 71. 01. 01. 01. 00. 90. 80. 80. 30. 30. 81. 01. 00. 50. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 40. 91. 00. 90. 90. 50. 30. 10. 00. 00. 00. 00. 81. 00. 90. 20. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 71. 00. 70. 20. 00. 00. 00. 00. 00. 00. 00. 20. 91. 00. 90. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 10. 50. 00. 00. 00. 00. 00. 00. 00. 00. 00. 31. 01. 00. 70. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 51. 00. 90. 20. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 81. 01. 00. 70. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 91. 00. 90. 20. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 31. 00. 90. 30. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 81. 00. 60. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 50. 30. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 0

A

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
2 filter

A

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
5 output channel

0. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 30. 40. 60. 70. 50. 40. 10. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 30. 61. 21. 41. 61. 61. 61. 61. 91. 92. 22. 32. 12. 01. 70. 90. 50. 00. 00. 00. 00. 00. 00. 00. 00. 51. 21. 82. 62. 73. 03. 03. 03. 03. 43. 53. 84. 03. 73. 63. 22. 31. 50. 50. 10. 00. 00. 00. 00. 00. 01. 12. 13. 24. 24. 44. 74. 74. 54. 24. 03. 83. 93. 94. 14. 54. 74. 13. 11. 50. 50. 00. 00. 00. 00. 00. 01. 12. 03. 13. 63. 33. 23. 23. 12. 92. 72. 52. 52. 52. 73. 03. 94. 44. 12. 91. 40. 30. 00. 00. 00. 00. 00. 91. 42. 12. 21. 81. 71. 71. 51. 10. 80. 50. 50. 50. 81. 32. 43. 74. 54. 02. 41. 00. 00. 00. 00. 00. 00. 10. 30. 30. 30. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 11. 32. 84. 24. 72. 81. 60. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 41. 22. 93. 95. 13. 12. 20. 10. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 10. 41. 01. 31. 61. 92. 43. 74. 45. 23. 82. 50. 70. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 20. 51. 11. 72. 32. 73. 03. 43. 74. 64. 95. 24. 12. 51. 20. 00. 00. 00. 00. 00. 00. 00. 00. 00. 10. 71. 31. 92. 63. 24. 04. 44. 84. 44. 24. 54. 85. 24. 52. 71. 60. 00. 00. 00. 00. 00. 00. 00. 00. 41. 01. 82. 63. 33. 83. 93. 83. 63. 43. 02. 93. 64. 15. 03. 82. 51. 00. 00. 00. 00. 00. 00. 00. 00. 00. 81. 73. 03. 53. 73. 33. 02. 52. 21. 91. 31. 32. 43. 34. 83. 42. 30. 60. 00. 00. 00. 00. 00. 00. 00. 00. 92. 02. 73. 22. 61. 81. 30. 70. 40. 10. 00. 42. 23. 34. 63. 02. 00. 20. 00. 00. 00. 00. 00. 00. 00. 00. 71. 41. 61. 70. 70. 20. 00. 00. 00. 00. 00. 82. 53. 74. 22. 61. 50. 00. 00. 00. 00. 00. 00. 00. 00. 00. 10. 50. 20. 50. 00. 00. 00. 00. 00. 00. 71. 73. 34. 03. 62. 20. 80. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 01. 32. 34. 03. 92. 81. 60. 20. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 32. 33. 14. 53. 42. 00. 80. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 92. 63. 43. 82. 51. 20. 20. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 01. 22. 02. 82. 41. 50. 30. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 00. 01. 01. 32. 01. 30. 60. 00. 00. 00. 00. 00. 00. 00. 0

Chúng ta có thể thấy rằng đầu ra thực sự không cùng kích thước với đầu vào ban đầu. Kích thước đầu ra là

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
5. Kênh đầu vào ban đầu của chúng tôi là
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
0 và bây giờ chúng tôi có một kênh đầu ra đã giảm kích thước xuống còn
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
5 sau khi cuộn hình ảnh. Tại sao vậy?

Với hình ảnh

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
0 của chúng tôi, bộ lọc
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
2 của chúng tôi chỉ có thể phù hợp với
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
5 vị trí có thể, không phải tất cả
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
0. Với điều này, chúng tôi nhận được kết quả đầu ra
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
5. Điều này là do những gì xảy ra khi chúng ta cuộn các cạnh của hình ảnh

Để dễ hình dung điều này, hãy xem xét một ví dụ quy mô nhỏ hơn. Ở đây chúng tôi có đầu vào có kích thước

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
44 và sau đó là bộ lọc
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
2. Hãy xem chúng ta có thể kết hợp đầu vào của mình với bộ lọc này bao nhiêu lần và kích thước đầu ra thu được sẽ là bao nhiêu

Con trăn tích chập zero padding

Điều này có nghĩa là khi bộ lọc

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
2 này hoàn thành việc cuộn đầu vào
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
44 này, nó sẽ cho chúng ta một đầu ra có kích thước
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
48

Chúng tôi thấy rằng đầu ra kết quả là

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
48, trong khi đầu vào của chúng tôi là
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
44, và một lần nữa, giống như trong ví dụ lớn hơn của chúng tôi với hình ảnh số bảy, chúng tôi thấy rằng đầu ra của chúng tôi thực sự nhỏ hơn đầu vào của chúng tôi về kích thước

Chúng ta có thể biết trước các kích thước của chúng ta sẽ thu nhỏ bao nhiêu. Nói chung, nếu hình ảnh của chúng tôi có kích thước

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
11 và chúng tôi tích hợp nó với bộ lọc
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
12, thì kích thước của kết quả đầu ra là \((n – f + 1)\) x \((n – f + 1)\

Hãy xem liệu điều này có phù hợp với ví dụ của chúng tôi ở đây không

Đầu vào của chúng tôi có kích thước

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
44, vì vậy,
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
14 sẽ là
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
15 của chúng tôi và bộ lọc của chúng tôi là
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
2, vì vậy,
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
17 sẽ là
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
18 của chúng tôi. Thay thế các giá trị này trong công thức của chúng tôi, chúng tôi có

$$(n - f + 1) = (4 - 3) + 1 = 2$$

Thật vậy, điều này mang lại cho chúng tôi một kênh đầu ra

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
48, chính xác là những gì chúng tôi đã thấy một lúc trước. Điều này cũng phù hợp với ví dụ với đầu vào lớn hơn trong số bảy, vì vậy hãy tự mình kiểm tra để xác nhận rằng công thức thực sự cho chúng ta kết quả tương tự về đầu ra có kích thước
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
5 mà chúng ta đã thấy khi kiểm tra bằng mắt.

Các vấn đề với việc giảm kích thước

Xem xét kết quả đầu ra của hình ảnh của một lần nữa. Nó không thực sự là một vấn đề lớn khi đầu ra này nhỏ hơn một chút so với đầu vào, phải không?

Chúng tôi đã không mất nhiều dữ liệu hay bất cứ thứ gì vì hầu hết các phần quan trọng của đầu vào này đều nằm ở giữa. Nhưng chúng ta có thể tưởng tượng rằng đây sẽ là vấn đề lớn hơn nếu chúng ta có dữ liệu có ý nghĩa xung quanh các cạnh của hình ảnh

Ngoài ra, chúng tôi chỉ kết hợp hình ảnh này với một bộ lọc. Điều gì xảy ra khi đầu vào ban đầu này đi qua mạng và được kết hợp bởi nhiều bộ lọc hơn khi nó di chuyển ngày càng sâu hơn?

Chà, điều sắp xảy ra là kết quả đầu ra sẽ tiếp tục trở nên ngày càng nhỏ hơn. Đây là một vấn đề

Ví dụ: nếu chúng ta bắt đầu với một hình ảnh

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
44, thì chỉ sau một hoặc hai lớp chập, kết quả đầu ra có thể trở nên gần như vô nghĩa với mức độ nhỏ của nó. Một vấn đề khác là chúng tôi đang làm mất dữ liệu có giá trị bằng cách loại bỏ hoàn toàn thông tin xung quanh các cạnh của đầu vào

Chúng ta có thể làm gì ở đây?

Không đệm để giải cứu

Không đệm là một kỹ thuật cho phép chúng tôi giữ nguyên kích thước đầu vào ban đầu. Đây là thứ mà chúng tôi chỉ định trên cơ sở từng lớp tích chập. Với mỗi lớp tích chập, giống như chúng ta xác định có bao nhiêu bộ lọc và kích thước của các bộ lọc, chúng ta cũng có thể chỉ định có sử dụng phần đệm hay không

Không đệm là gì?

Bây giờ chúng ta biết những vấn đề mà phần đệm bằng không chống lại vấn đề gì, nhưng nó thực sự là gì?

Phần đệm bằng không xảy ra khi chúng ta thêm một đường viền pixel tất cả đều có giá trị bằng 0 xung quanh các cạnh của hình ảnh đầu vào. Điều này thêm một loại đệm số 0 xung quanh bên ngoài hình ảnh, do đó có tên là đệm số không. Quay trở lại ví dụ nhỏ của chúng tôi từ trước đó, nếu chúng tôi đệm đầu vào của mình bằng đường viền gồm các pixel có giá trị bằng 0, hãy xem kích thước đầu ra thu được sẽ là bao nhiêu sau khi kết hợp đầu vào của chúng tôi

Con trăn tích chập zero padding

Chúng tôi thấy rằng kích thước đầu ra của chúng tôi thực sự là

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
44, duy trì kích thước đầu vào ban đầu. Bây giờ, đôi khi chúng ta có thể cần thêm nhiều hơn một đường viền chỉ dày một pixel. Đôi khi, chúng tôi có thể cần thêm thứ gì đó như đường viền kép hoặc đường viền ba số 0 để duy trì kích thước ban đầu của đầu vào. Điều này sẽ chỉ phụ thuộc vào kích thước của đầu vào và kích thước của các bộ lọc

Điều tốt là hầu hết các API mạng thần kinh đều tính toán kích thước của đường viền cho chúng tôi. Tất cả những gì chúng ta phải làm chỉ là xác định xem chúng ta có thực sự muốn sử dụng phần đệm trong các lớp tích chập hay không

Phần đệm hợp lệ và giống nhau

Có hai loại đệm. Một được gọi bằng tên hợp lệ. Điều này chỉ có nghĩa là không có phần đệm. Nếu chúng tôi chỉ định phần đệm hợp lệ, điều đó có nghĩa là lớp tích chập của chúng tôi sẽ hoàn toàn không đệm và kích thước đầu vào của chúng tôi sẽ không được duy trì

Loại đệm khác được gọi là giống nhau. Điều này có nghĩa là chúng tôi muốn đệm đầu vào ban đầu trước khi chúng tôi tích hợp nó để kích thước đầu ra có cùng kích thước với kích thước đầu vào

Padding TypeDescriptionImpactValidKhông có paddingKích thước giảmGiống nhauSố 0 xung quanh các cạnhKích thước giữ nguyên

Bây giờ, hãy chuyển sang Keras và xem điều này được thực hiện như thế nào trong mã

Làm việc với mã trong Keras

Chúng tôi sẽ bắt đầu với một số nhập khẩu.
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
3

Bây giờ, chúng ta sẽ tạo một CNN hoàn toàn tùy ý

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])

Nó có một lớp dày đặc, sau đó là lớp tích chập

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
17, tiếp theo là lớp đầu ra dày đặc

Chúng tôi đã chỉ định rằng kích thước đầu vào của hình ảnh được đưa vào CNN này là

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
64 và lớp tích chập đầu tiên của chúng tôi có kích thước bộ lọc là
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
2, được chỉ định trong Keras với tham số
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
66. Sau đó, lớp đối lưu thứ hai chỉ định kích thước
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
67 và lớp thứ ba,
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
68

Với mô hình này, chúng tôi chỉ định tham số có tên là

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
69 cho mỗi lớp tích chập. Chúng tôi đang đặt tham số này bằng chuỗi
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
30. Hãy nhớ từ trước đó, phần đệm hợp lệ có nghĩa là không có phần đệm

Đây thực sự là mặc định cho các lớp tích chập trong Keras, vì vậy nếu chúng tôi không chỉ định tham số này, nó sẽ mặc định là phần đệm hợp lệ. Vì chúng tôi đang sử dụng phần đệm hợp lệ ở đây, nên chúng tôi hy vọng kích thước của đầu ra từ mỗi lớp tích chập này sẽ giảm xuống

Hãy kiểm tra. Dưới đây là tóm tắt của mô hình này

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
4

Chúng ta có thể thấy hình dạng đầu ra của mỗi lớp trong cột thứ hai. Hai số nguyên đầu tiên chỉ định kích thước của đầu ra theo chiều cao và chiều rộng. Bắt đầu với lớp đầu tiên của chúng tôi, chúng tôi thấy kích thước đầu ra của chúng tôi là kích thước ban đầu của đầu vào của chúng tôi,

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
64

Khi chúng tôi đến đầu ra của lớp tích chập đầu tiên, kích thước giảm xuống

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
32 và một lần nữa ở lớp tiếp theo, nó giảm xuống còn
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
33 và cuối cùng, ở lớp tích chập cuối cùng, nó giảm xuống còn
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
34

Vì vậy, chúng tôi bắt đầu với

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
64 và kết thúc với
model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
34 khi hoàn thành tất cả và kết thúc với

Ngược lại, bây giờ, chúng ta có thể tạo một mô hình thứ hai

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
1

Cái này là một bản sao chính xác của cái đầu tiên, ngoại trừ việc chúng tôi đã chỉ định phần đệm

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
37 cho mỗi lớp tích chập. Nhớ lại từ trước đó rằng cùng một phần đệm có nghĩa là chúng tôi muốn đệm đầu vào ban đầu trước khi chúng tôi tích hợp nó để kích thước đầu ra có cùng kích thước với kích thước đầu vào

Hãy xem tóm tắt của mô hình này

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
6

Một lần nữa, chúng ta có thể thấy rằng chúng ta đang bắt đầu với kích thước đầu vào là

model_valid = Sequential([
    Dense(16, input_shape=(20,20,3), activation='relu'),
    Conv2D(32, kernel_size=(3,3), activation='relu', padding='valid'),
    Conv2D(64, kernel_size=(5,5), activation='relu', padding='valid'),
    Conv2D(128, kernel_size=(7,7), activation='relu', padding='valid'),
    Flatten(),
    Dense(2, activation='softmax')
])
64 và nếu chúng ta nhìn vào hình dạng đầu ra cho từng lớp tích chập, chúng ta sẽ thấy rằng các lớp thực sự duy trì kích thước đầu vào ban đầu ngay bây giờ

Đây là lý do tại sao chúng tôi gọi loại đệm này là cùng đệm. Cùng một phần đệm giữ cho kích thước đầu vào giống nhau

kết thúc

Bây giờ chúng ta đã hiểu phần đệm bằng 0 là gì, nó đạt được gì khi chúng ta thêm nó vào CNN của mình và cách chúng ta có thể chỉ định phần đệm trong mạng của mình bằng Keras. tôi sẽ gặp lại bạn lần sau

đố

expand_more chevron_left

Gửi đi

Con trăn tích chập zero padding
Thông báo DEEPLIZARD thông báo

Kết quả bài kiểm tra

tài nguyên

expand_more chevron_left

Hãy bắt đầu bằng cách giải thích động lực cho phần đệm bằng không và sau đó chúng ta đi vào chi tiết về phần đệm bằng không thực sự là gì. Sau đó, chúng tôi nói về các loại sự cố mà chúng tôi có thể gặp phải nếu chúng tôi không sử dụng phần đệm bằng 0 và sau đó chúng ta xem cách chúng tôi có thể triển khai phần đệm bằng 0 trong mã bằng cách sử dụng Keras. Chúng tôi xây dựng dựa trên một số ý tưởng mà chúng tôi đã thảo luận trong video của mình về Mạng thần kinh chuyển đổi, vì vậy nếu bạn chưa xem, hãy tiếp tục và xem thử rồi quay lại xem video này sau khi bạn hoàn thành video đó. https. //youtube. be/YRhxdVk_sIs 🕒🦎 PHẦN VIDEO 🦎🕒 00. 00 Chào mừng đến với DEEPLIZARD - Tới deeplizard. com cho tài nguyên học tập 00. 30 Trợ giúp deeplizard thêm dấu thời gian video - Xem ví dụ trong phần mô tả 13. 18 Collective Intelligence and DEEPLIZARD HIVEMIND 💥🦎 TÀI NGUYÊN CỘNG ĐỒNG DEEPLIZARD 🦎💥 👋 Xin chào, chúng tôi là Chris và Mandy, những người tạo ra deeplizard. 👀 XEM VLOG CỦA CHÚNG TÔI. 🔗 https. //youtube. com/deeplizardvlog 👉 Truy cập trang web để biết thêm tài liệu học tập. 🔗 https. //thằn lằn sâu. com 💻 ĐĂNG KÝ ĐỂ ĐƯỢC TẢI XUỐNG TRUY CẬP CÁC TỆP MÃ 🔗 https. //thằn lằn sâu. com/resources 🧠 Hỗ trợ trí tuệ tập thể, tham gia tổ ong deeplizard. 🔗 https. //thằn lằn sâu. com/hivemind 🧠 Sử dụng mã DEEPLIZARD khi thanh toán để được giảm giá 15% cho đơn hàng Neurohacker đầu tiên của bạn 👉 Sử dụng biên lai của bạn từ Neurohacker để được giảm giá cho các khóa học deeplizard 🔗 https. //tin tặc thần kinh. com/shop?rfsn=6488344. d171c6 ❤️🦎 Xin gửi lời cảm ơn đặc biệt đến các thuật toán đa hình sau đây của deeplizard hivemind. Tammy Mano Prime Ling Li 🚀 Nâng cao trí tuệ tập thể bằng cách chia sẻ video này trên mạng xã hội. 👀 Theo dõi deeplizard. vlog của chúng tôi. https. //youtube. com/deeplizardvlog Facebook. https. //Facebook. com/deeplizard Instagram. https. // mạng xã hội. com/deeplizard Twitter. https. //twitter. com/deeplizard Patreon. https. // patreon. com/deeplizard YouTube. https. //youtube. com/deeplizard 🎓 Học sâu với deeplizard. Từ điển học sâu - https. //thằn lằn sâu. com/course/ddcpailzrd Nguyên tắc cơ bản về học sâu - https. //thằn lằn sâu. com/course/dlcpailzrd Tìm hiểu TensorFlow - https. //thằn lằn sâu. com/course/tfcpailzrd Tìm hiểu PyTorch - https. //thằn lằn sâu. com/course/ptcpailzrd Xử lý ngôn ngữ tự nhiên - https. //thằn lằn sâu. com/course/txtcpailzrd Học tăng cường - https. //thằn lằn sâu. com/course/rlcpailzrd Mạng đối thủ sáng tạo - https. //thằn lằn sâu. com/course/gacpailzrd 🎓 Các khóa học khác. Nguyên tắc cơ bản về DL cổ điển - https. //thằn lằn sâu. com/learn/video/gZmobeGL0Yg Triển khai Deep Learning - https. //thằn lằn sâu. com/learn/video/SI1hVGvbbZ4 Khoa học dữ liệu - https. //thằn lằn sâu. com/learn/video/d11chG7Z-xk Giao dịch - https. //thằn lằn sâu. com/learn/video/ZpfCK_uHL9Y 🛒 Xem các sản phẩm mà deeplizard đề xuất trên Amazon. 🔗 https. // amazon. com/shop/deeplizard 🎵 deeplizard sử dụng nhạc của Kevin MacLeod 🔗 https. //youtube. com/channel/UCSZXFhRIx6b0dFX3xS8L1yQ ❤️ Hãy sử dụng những kiến ​​thức thu được từ nội dung deeplizard cho mục đích tốt chứ không phải điều ác