tek4

Autoencoder Trong Deep Learning – Tự Học TensorFlow

by - September. 21, 2021
Kiến thức
<h3 id="ftoc-heading-1" class="ftwp-heading" style="text-align: justify;">Autoencoder l&agrave; g&igrave;?</h3> <p style="text-align: justify;">Autoencoder l&agrave; một c&ocirc;ng cụ tuyệt vời để recreate một input. N&oacute;i một c&aacute;ch dễ hiểu, giả sử từ một h&igrave;nh ảnh c&oacute; thể tạo ra một bức ảnh c&oacute; li&ecirc;n quan chặt chẽ. Đầu v&agrave;o trong loại mạng neural n&agrave;y kh&ocirc;ng c&oacute; nh&atilde;n, c&oacute; nghĩa l&agrave; mạng c&oacute; khả năng học m&agrave; kh&ocirc;ng cần gi&aacute;m s&aacute;t. Ch&iacute;nh x&aacute;c hơn, đầu v&agrave;o được mạng m&atilde; h&oacute;a để chỉ tập trung v&agrave;o đặc trưng quan trọng nhất. Đ&acirc;y l&agrave; một trong những l&yacute; do tại sao autoencoder phổ biến để giảm chiều dữ liệu. B&ecirc;n cạnh đ&oacute;, autoencoder c&oacute; thể được sử dụng để tạo ra c&aacute;c m&ocirc; h&igrave;nh học tập chung (generative learning models). V&iacute; dụ, mạng neural c&oacute; thể được huấn luyện với một tập hợp c&aacute;c khu&ocirc;n mặt v&agrave; sau đ&oacute; c&oacute; thể tạo ra c&aacute;c khu&ocirc;n mặt mới.</p> <h3 id="ftoc-heading-2" class="ftwp-heading" style="text-align: justify;">Autoencoder hoạt động như thế n&agrave;o?</h3> <p style="text-align: justify;">Mục đ&iacute;ch của autoencoder l&agrave; tạo ra gi&aacute; trị input gần đ&uacute;ng bằng c&aacute;ch chỉ tập trung v&agrave;o c&aacute;c đặc trưng cần thiết. Bạn c&oacute; thể nghĩ rằng tại sao kh&ocirc;ng chỉ đơn thuần l&agrave; t&igrave;m hiểu l&agrave;m thế n&agrave;o để sao ch&eacute;p v&agrave; d&aacute;n đầu v&agrave;o để tạo đầu ra. Trong thực tế, một autoencoder l&agrave; một tập hợp c&aacute;c hạn chế buộc mạng phải t&igrave;m hiểu những c&aacute;ch thức mới để đại diện cho dữ liệu, kh&aacute;c với chỉ đơn thuần l&agrave; sao ch&eacute;p đầu ra.</p> <p style="text-align: justify;">Một autoencoder điển h&igrave;nh được x&aacute;c định với một đầu v&agrave;o, một đại diện b&ecirc;n trong v&agrave; một đầu ra (một xấp xỉ của đầu v&agrave;o). Việc học tập xảy ra trong c&aacute;c layers gắn với biểu diễn b&ecirc;n trong. Tr&ecirc;n thực tế, c&oacute; hai khối layers ch&iacute;nh tr&ocirc;ng giống như một mạng neural truyền thống. Sự kh&aacute;c biệt nhỏ l&agrave; layer chứa đầu ra phải bằng với đầu v&agrave;o. Trong h&igrave;nh b&ecirc;n dưới, đầu v&agrave;o ban đầu đi v&agrave;o khối đầu ti&ecirc;n được gọi l&agrave;&nbsp;<strong>encoder</strong>. Biểu diễn b&ecirc;n trong n&agrave;y n&eacute;n (giảm) k&iacute;ch thước của đầu v&agrave;o. Trong khối thứ hai xảy ra việc t&aacute;i tạo đầu v&agrave;o. Đ&acirc;y l&agrave; giai đoạn giải m&atilde;.</p> <p style="text-align: justify;"><img style="width: 100%;" src="../../../public_files/5fb64413-e92d-4fa8-bc4a-556cf1893f66" alt="post-autoencoder-trong-deep-learning-2" /></p> <p style="text-align: justify;">M&ocirc; h&igrave;nh sẽ cập nhật trọng số bằng c&aacute;ch giảm thiểu h&agrave;m mất m&aacute;t. M&ocirc; h&igrave;nh bị penalized nếu đầu ra t&aacute;i thiết kh&aacute;c với đầu v&agrave;o.</p> <p style="text-align: justify;">Cụ thể, h&atilde;y tưởng tượng một bức tranh c&oacute; k&iacute;ch thước 50&times;50 (tức l&agrave; 250 pixel) v&agrave; một mạng neural chỉ với một layer ẩn bao gồm một trăm neural. Việc học được thực hiện tr&ecirc;n feature map nhỏ hơn đầu v&agrave;o hai lần. N&oacute; c&oacute; nghĩa l&agrave; mạng cần phải t&igrave;m ra c&aacute;ch để t&aacute;i tạo lại 250 pixel chỉ với một vectơ neural bằng 100.</p> <h3 id="ftoc-heading-3" class="ftwp-heading" style="text-align: justify;">V&iacute; dụ về stacked autoencoder</h3> <p style="text-align: justify;">B&agrave;i viết n&agrave;y sẽ giới thiệu đến bạn c&aacute;ch sử dụng stacked autoencoder. Kiến tr&uacute;c tương tự như một mạng neural truyền thống. Đầu v&agrave;o đi đến một layer ẩn để được n&eacute;n hoặc giảm k&iacute;ch thước của n&oacute;, rồi đến c&aacute;c layers t&aacute;i tạo. Mục ti&ecirc;u l&agrave; tạo ra h&igrave;nh ảnh đầu ra gần giống với h&igrave;nh ảnh gốc. M&ocirc; h&igrave;nh phải học c&aacute;ch để đạt được nhiệm vụ của n&oacute; dưới một tập hợp c&aacute;c r&agrave;ng buộc, nghĩa l&agrave; với một dimension thấp hơn.</p> <p style="text-align: justify;">Ng&agrave;y nay, autoencoders chủ yếu được sử dụng để khử nhiễu h&igrave;nh ảnh. H&atilde;y tưởng tượng một h&igrave;nh ảnh với những vết xước, con người vẫn c&oacute; thể nhận ra nội dung. &Yacute; tưởng của việc khử nhiễu l&agrave; th&ecirc;m nhiễu v&agrave;o h&igrave;nh ảnh để buộc mạng t&igrave;m hiểu m&ocirc; h&igrave;nh đằng sau dữ liệu.</p> <p style="text-align: justify;">Một họ autoencoder hữu &iacute;ch kh&aacute;c l&agrave; variational autoencoder. Loại mạng n&agrave;y c&oacute; thể tạo ra h&igrave;nh ảnh mới. H&atilde;y tưởng tượng bạn đ&agrave;o tạo một mạng với h&igrave;nh ảnh của một người đ&agrave;n &ocirc;ng. Một mạng như vậy c&oacute; thể tạo ra những khu&ocirc;n mặt mới.</p> <h3 id="ftoc-heading-4" class="ftwp-heading" style="text-align: justify;">X&acirc;y dựng autoencoder với TensorFlow</h3> <p style="text-align: justify;">Trong b&agrave;i viết n&agrave;y, ch&uacute;ng ta&nbsp;sẽ học c&aacute;ch x&acirc;y dựng một stacked autoencoder để tạo lại h&igrave;nh ảnh.</p> <p style="text-align: justify;">Ta sẽ sử dụng tập<a href="https://www.cs.toronto.edu/~kriz/cifar.html" target="_blank" rel="noopener">&nbsp;dữ liệu CIFAR-10</a>&nbsp;chứa 60000 h&igrave;nh ảnh m&agrave;u 32&times;32. Tập dữ liệu đ&atilde; được chia th&agrave;nh 50000 h&igrave;nh ảnh để đ&agrave;o tạo v&agrave; 10000 h&igrave;nh ảnh để thử nghiệm. CIFAR-10 gồm 10 lớp dữ liệu sau đ&acirc;y:</p> <ul style="text-align: justify;"> <li>Airplane</li> <li>Automobile</li> <li>Bird</li> <li>Cat</li> <li>Deer</li> <li>Dog</li> <li>Frog</li> <li>Horse</li> <li>Ship</li> <li>Truck</li> </ul> <p style="text-align: justify;">H&atilde;y tải xuống bộ dữ liệu v&agrave; tiến h&agrave;nh giải n&eacute;n n&oacute;. Thư mục&nbsp;for-10-batches-py&nbsp;chứa năm batch dữ liệu với 10000 h&igrave;nh ảnh cho mỗi batch theo thứ tự ngẫu nhi&ecirc;n.</p> <p style="text-align: justify;">Trước khi x&acirc;y dựng v&agrave; đ&agrave;o tạo m&ocirc; h&igrave;nh của m&igrave;nh ch&uacute;ng ta cần tiền xử l&yacute; dữ liệu. C&aacute;c bước xử l&yacute; tiến h&agrave;nh như sau:</p> <ol style="text-align: justify;"> <li>Import dữ liệu.</li> <li>Chuyển đổi dữ liệu sang định dạng đen trắng</li> <li>Kết nối c&aacute;c batch dữ liệu</li> <li>X&acirc;y dựng tập dữ liệu đ&agrave;o tạo</li> <li>X&acirc;y dựng tr&igrave;nh hiển thị h&igrave;nh ảnh</li> </ol> <h4 id="ftoc-heading-5" class="ftwp-heading" style="text-align: justify;">Tiền xử l&yacute; dữ liệu</h4> <p style="text-align: justify;"><strong>Bước 1)</strong>&nbsp;Import dữ liệu.</p> <p style="text-align: justify;">Ch&uacute;ng ta c&oacute; thể upload dữ liệu l&ecirc;n bằng code sau. Code sẽ tải dữ liệu trong từ điển với dữ liệu v&agrave; nh&atilde;n.</p> <div id="urvanov-syntax-highlighter-610ff034a4850305792408" class="urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate" style="text-align: justify;" data-settings=" minimize scroll-mouseover"> <div class="urvanov-syntax-highlighter-plain-wrap"> <pre class="language-python"><code>import numpy as np import tensorflow as tf import pickle def unpickle(file): import pickle with open(file, 'rb') as fo: dict = pickle.load(fo, encoding='latin1') return dict</code></pre> </div> <div class="urvanov-syntax-highlighter-main">&nbsp;</div> </div> <p style="text-align: justify;"><strong>Bước 2)</strong>&nbsp;Chuyển đổi dữ liệu sang định dạng đen trắng.</p> <p style="text-align: justify;">Để đơn giản, ch&uacute;ng ta sẽ chuyển đổi dữ liệu sang thang độ x&aacute;m. Đ&oacute; l&agrave;, chỉ c&oacute; một chiều so với ba chiều cho h&igrave;nh ảnh m&agrave;u. Hầu hết mạng neural chỉ hoạt động với đầu v&agrave;o một chiều.</p> <div id="urvanov-syntax-highlighter-610ff034a485e050892519" class="urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate" style="text-align: justify;" data-settings=" minimize scroll-mouseover"> <div class="urvanov-syntax-highlighter-plain-wrap"> <pre class="language-python"><code>def grayscale(im): return im.reshape(im.shape[0], 3, 32, 32).mean(1).reshape(im.shape[0], -1)</code></pre> </div> <div class="urvanov-syntax-highlighter-main">&nbsp;</div> </div> <p style="text-align: justify;"><strong>Bước 3)</strong>&nbsp;Kết nối tất cả c&aacute;c batch dữ liệu</p> <p style="text-align: justify;">B&acirc;y giờ cả hai h&agrave;m đ&atilde; được tạo v&agrave; tập dữ liệu được tải, ch&uacute;ng ta c&oacute; thể viết một v&ograve;ng lặp để nối th&ecirc;m dữ liệu v&agrave;o bộ nhớ. Nếu kiểm tra kỹ th&igrave; tệp giải n&eacute;n c&oacute; dữ liệu được đặt t&ecirc;n l&agrave; data_batch_ với số thứ tự từ 1 đến 5. Ta c&oacute; thể lặp lại c&aacute;c tệp v&agrave; nối n&oacute; v&agrave;o dữ liệu.</p> <p style="text-align: justify;">Khi bước n&agrave;y ho&agrave;n th&agrave;nh, ch&uacute;ng ta chuyển đổi dữ liệu m&agrave;u sang định dạng thang độ m&agrave;u x&aacute;m. Như bạn c&oacute; thể thấy, shape của dữ liệu l&agrave; 50000 v&agrave; 1024.</p> <div id="urvanov-syntax-highlighter-610ff034a4861705895269" class="urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate" style="text-align: justify;" data-settings=" minimize scroll-mouseover"> <div class="urvanov-syntax-highlighter-plain-wrap"> <pre class="language-python"><code>#Đưa dữ liệu v&agrave;o trong bộ nhớ data, labels = [], [] for i in range(1, 6): filename = './cifar-10-batches-py/data_batch_' + str(i) open_data = unpickle(filename) if len(data) &amp;gt; 0: data = np.vstack((data, open_data['data'])) labels = np.hstack((labels, open_data['labels'])) else: data = open_data['data'] labels = open_data['labels'] data = grayscale(data) x = np.matrix(data) y = np.array(labels) print(x.shape) (50000, 1024)</code></pre> </div> <div class="urvanov-syntax-highlighter-main">&nbsp;</div> </div> <p style="text-align: justify;">Lưu &yacute;: Thay đổi&nbsp;&lsquo;./cifar-10-batches-py/data_batch_&rsquo;&nbsp;th&agrave;nh vị tr&iacute; lưu dữ liệu tr&ecirc;n m&aacute;y của bạn. V&iacute; dụ đối với m&aacute;y Windows, đường dẫn c&oacute; thể l&agrave;&nbsp;filename = &lsquo;E: \\ cifar-10-batches-py \\ data_batch_&rsquo; + str (i).</p> <p style="text-align: justify;"><strong>Bước 4)</strong>&nbsp;X&acirc;y dựng tập dữ liệu đ&agrave;o tạo</p> <p style="text-align: justify;">Để l&agrave;m cho việc đ&agrave;o tạo nhanh hơn v&agrave; dễ d&agrave;ng hơn, ta sẽ chỉ đ&agrave;o tạo một m&ocirc; h&igrave;nh tr&ecirc;n h&igrave;nh ảnh con ngựa. Ngựa l&agrave; lớp thứ bảy trong dữ liệu nh&atilde;n. Như đ&atilde; đề cập trong t&agrave;i liệu của bộ dữ liệu CIFAR-10, mỗi lớp chứa 5000 h&igrave;nh ảnh. Ta c&oacute; thể in shape của dữ liệu để x&aacute;c nhận c&oacute; 5.000 h&igrave;nh ảnh với 1024 cột.</p> <div id="urvanov-syntax-highlighter-610ff034a4864388650159" class="urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate" style="text-align: justify;" data-settings=" minimize scroll-mouseover"> <div class="urvanov-syntax-highlighter-plain-wrap"> <pre class="language-python"><code>horse_i = np.where(y == 7)[0] horse_x = x[horse_i] print(np.shape(horse_x)) (5000, 1024)</code></pre> </div> <div class="urvanov-syntax-highlighter-main">&nbsp;</div> </div> <p style="text-align: justify;"><strong>Bước 5)</strong>&nbsp;X&acirc;y dựng tr&igrave;nh hiển thị h&igrave;nh ảnh</p> <p style="text-align: justify;">Cuối c&ugrave;ng, ch&uacute;ng ta x&acirc;y dựng một h&agrave;m để vẽ c&aacute;c h&igrave;nh ảnh. Ta sẽ cần h&agrave;m n&agrave;y để in h&igrave;nh ảnh được t&aacute;i tạo từ autoencoder.</p> <p style="text-align: justify;">Một c&aacute;ch dễ d&agrave;ng để in ảnh l&agrave; sử dụng đối tượng imshow từ thư viện matplotlib. Lưu &yacute; rằng, cần chuyển đổi shape của dữ liệu từ 1024 sang 32 * 32 (tức l&agrave; định dạng của h&igrave;nh ảnh).</p> <div id="urvanov-syntax-highlighter-610ff034a4868682807543" class="urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate" style="text-align: justify;" data-settings=" minimize scroll-mouseover"> <div class="urvanov-syntax-highlighter-plain-wrap"> <pre class="language-python"><code>%matplotlib inline import matplotlib import matplotlib.pyplot as plt def plot_image(image, shape=[32, 32], cmap = "Greys_r"): plt.imshow(image.reshape(shape), cmap=cmap,interpolation="nearest") plt.axis("off")</code></pre> </div> <div class="urvanov-syntax-highlighter-main">&nbsp;</div> </div> <p style="text-align: justify;">H&agrave;m nhận 3 đối số:</p> <ul style="text-align: justify;"> <li>Image: Đầu v&agrave;o</li> <li>Shape: list, dimension của h&igrave;nh ảnh</li> <li>Cmap: chọn bản đồ m&agrave;u. Theo mặc định, m&agrave;u x&aacute;m</li> </ul> <p style="text-align: justify;">Ta c&oacute; thể thử vẽ h&igrave;nh ảnh đầu ti&ecirc;n trong tập dữ liệu. Bạn sẽ thấy một người đ&agrave;n &ocirc;ng tr&ecirc;n một con ngựa.</p> <div id="urvanov-syntax-highlighter-610ff034a486a852646423" class="urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate" style="text-align: justify;" data-settings=" minimize scroll-mouseover"> <div class="urvanov-syntax-highlighter-plain-wrap"> <pre class="language-python"><code>plot_image(horse_x[1], shape=[32, 32], cmap = "Greys_r")</code></pre> </div> <div class="urvanov-syntax-highlighter-main">&nbsp;</div> </div> <p><img style="width: 50%; display: block; margin-left: auto; margin-right: auto;" src="../../../public_files/e1575d34-17bc-44ee-80ac-8a470a27aab5" alt="post-autoencoder-trong-deep-learning-3" /></p> <h4 id="ftoc-heading-6" class="ftwp-heading" style="text-align: justify;">C&ocirc;ng cụ ước t&iacute;nh tập dữ liệu</h4> <p style="text-align: justify;">Được rồi, b&acirc;y giờ tập dữ liệu đ&atilde; sẵn s&agrave;ng để sử dụng, bạn c&oacute; thể bắt đầu sử dụng Tensorflow. Trước khi x&acirc;y dựng m&ocirc; h&igrave;nh, h&atilde;y sử dụng c&ocirc;ng cụ ước t&iacute;nh Dataset của Tensorflow để cung cấp cho mạng.</p> <p style="text-align: justify;">Bạn sẽ x&acirc;y dựng Tập dữ liệu với c&ocirc;ng cụ ước t&iacute;nh TensorFlow, cần sử dụng:</p> <ul style="text-align: justify;"> <li>from_tensor_slices</li> <li>repeat</li> <li>batch</li> </ul> <p style="text-align: justify;">M&atilde; đầy đủ để x&acirc;y dựng tập dữ liệu l&agrave;:</p> <div id="urvanov-syntax-highlighter-610ff034a486c008234042" class="urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate" style="text-align: justify;" data-settings=" minimize scroll-mouseover"> <div class="urvanov-syntax-highlighter-plain-wrap"> <pre class="language-python"><code>dataset = tf.data.Dataset.from_tensor_slices(x).repeat().batch(batch_size)</code></pre> </div> <div class="urvanov-syntax-highlighter-main">&nbsp;</div> </div> <p style="text-align: justify;">Lưu &yacute; rằng, x l&agrave; tr&igrave;nh giữ chỗ c&oacute; h&igrave;nh dạng sau:</p> <ul style="text-align: justify;"> <li>[None,n_inputs]: Đặt th&agrave;nh None v&igrave; số lượng nguồn cấp h&igrave;nh ảnh v&agrave;o mạng bằng batch size.</li> </ul> <p style="text-align: justify;">Sau đ&oacute;, bạn cần tạo tr&igrave;nh lặp.Nếu kh&ocirc;ng c&oacute; d&ograve;ng m&atilde; n&agrave;y, sẽ kh&ocirc;ng c&oacute; dữ liệu n&agrave;o đi qua pipeline.</p> <div id="urvanov-syntax-highlighter-610ff034a486e248222833" class="urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate" style="text-align: justify;" data-settings=" minimize scroll-mouseover"> <div class="urvanov-syntax-highlighter-plain-wrap"> <pre class="language-python"><code>iter = dataset.make_initializable_iterator()</code></pre> </div> <div class="urvanov-syntax-highlighter-main">&nbsp;</div> </div> <p style="text-align: justify;">B&acirc;y giờ pipeline đ&atilde; sẵn s&agrave;ng, bạn c&oacute; thể kiểm tra xem h&igrave;nh ảnh đầu ti&ecirc;n c&oacute; giống như trước đ&acirc;y kh&ocirc;ng (tức l&agrave; một người đ&agrave;n &ocirc;ng tr&ecirc;n ngựa).</p> <p style="text-align: justify;">H&atilde;y đặt batch size th&agrave;nh 1 bởi v&igrave; bạn chỉ muốn cung cấp tập dữ liệu với một h&igrave;nh ảnh. Bạn c&oacute; thể xem dimension của dữ liệu với print (sess.run (features) .shape). N&oacute; bằng (1, 1024). 1 c&oacute; nghĩa l&agrave; mỗi h&igrave;nh ảnh chỉ c&oacute; 1024 được cấp dữ liệu. Nếu batch size được đặt th&agrave;nh hai, th&igrave; hai h&igrave;nh ảnh sẽ đi qua pipeline. Nếu kh&ocirc;ng, n&oacute; sẽ b&aacute;o lỗi. Chỉ c&oacute; một h&igrave;nh ảnh tại một thời điểm c&oacute; thể chuyển đến h&agrave;m plot_image ().</p> <div id="urvanov-syntax-highlighter-610ff034a4873618908845" class="urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate" style="text-align: justify;" data-settings=" minimize scroll-mouseover"> <div class="urvanov-syntax-highlighter-plain-wrap"> <pre class="language-python"><code>##C&aacute;c tham số n_inputs = 32 * 32 BATCH_SIZE = 1 batch_size = tf.placeholder(tf.int64) x = tf.placeholder(tf.float32, shape=[None,n_inputs]) ##Bộ dữ liệu dataset = tf.data.Dataset.from_tensor_slices(x).repeat().batch(batch_size) iter = dataset.make_initializable_iterator() # create the iterator features = iter.get_next() ##In ra ảnh with tf.Session() as sess: sess.run(iter.initializer, feed_dict={x: horse_x, batch_size: BATCH_SIZE}) print(sess.run(features).shape) plot_image(sess.run(features), shape=[32, 32], cmap = "Greys_r") (1, 1024)</code></pre> </div> <div class="urvanov-syntax-highlighter-main">&nbsp;</div> </div> <p><img style="width: 50%; display: block; margin-left: auto; margin-right: auto;" src="../../../public_files/c1fac813-b648-4d34-8850-35785f940c69" alt="post-autoencoder-trong-deep-learning-4" /></p> <h3 id="ftoc-heading-7" class="ftwp-heading" style="text-align: justify;">X&acirc;y dựng mạng</h3> <p style="text-align: justify;">Đ&atilde; đến l&uacute;c x&acirc;y dựng mạng. Bạn sẽ đ&agrave;o tạo một bộ stacked autoencoder, tức l&agrave; một mạng c&oacute; nhiều layers ẩn.</p> <p style="text-align: justify;">Mạng của bạn sẽ c&oacute; một layer đầu v&agrave;o với 1024 điểm, tức l&agrave; 32&times;32, shape của h&igrave;nh ảnh.</p> <p style="text-align: justify;">Khối encoder sẽ c&oacute; một layer ẩn tr&ecirc;n c&ugrave;ng với 300 neurons, một layer trung t&acirc;m với 150 neurons. Khối decoder l&agrave; đối xứng với bộ encoder. Bạn c&oacute; thể h&igrave;nh dung mạng trong h&igrave;nh b&ecirc;n dưới. Lưu &yacute; rằng bạn c&oacute; thể thay đổi gi&aacute; trị của layer ẩn v&agrave; layer trung t&acirc;m.</p> <p style="text-align: justify;"><img style="width: 100%;" src="../../../public_files/35f0336b-4235-42cb-afea-730c67e092e2" alt="post-autoencoder-trong-deep-learning-5" /></p> <p style="text-align: justify;">X&acirc;y dựng một autoencoder giống với bất kỳ m&ocirc; h&igrave;nh học s&acirc;u n&agrave;o kh&aacute;c.</p> <p style="text-align: justify;">Bạn sẽ x&acirc;y dựng m&ocirc; h&igrave;nh theo c&aacute;c bước sau:</p> <ol style="text-align: justify;"> <li>X&aacute;c định c&aacute;c tham số</li> <li>X&aacute;c định c&aacute;c layers</li> <li>X&aacute;c định kiến ​​tr&uacute;c</li> <li>X&aacute;c định tr&igrave;nh tối ưu h&oacute;a</li> <li>Chạy m&ocirc; h&igrave;nh</li> <li>Đ&aacute;nh gi&aacute; m&ocirc; h&igrave;nh</li> </ol> <p style="text-align: justify;">Trong phần trước, ch&uacute;ng ta đ&atilde; học c&aacute;ch tạo một pipeline để cung cấp m&ocirc; h&igrave;nh, v&igrave; vậy kh&ocirc;ng cần tạo th&ecirc;m một lần nữa tập dữ liệu. Bạn sẽ x&acirc;y dựng một autoencoder c&oacute; bốn layers. Sử dụng khởi tạo Xavier. Đ&acirc;y l&agrave; một kỹ thuật để đặt c&aacute;c trọng số ban đầu bằng với phương sai của cả đầu v&agrave;o v&agrave; đầu ra. Cuối c&ugrave;ng, sử dụng h&agrave;m k&iacute;ch hoạt elu. Điều chỉnh h&agrave;m mất m&aacute;t bằng bộ điều chỉnh L2.</p> <h4 id="ftoc-heading-8" class="ftwp-heading" style="text-align: justify;">Bước 1) X&aacute;c định c&aacute;c tham số</h4> <p style="text-align: justify;">Bước đầu ti&ecirc;n cần x&aacute;c định số lượng neurons trong mỗi layer, tốc độ học v&agrave; si&ecirc;u tham số của bộ điều chỉnh.</p> <p style="text-align: justify;">Trước đ&oacute;, cần import một h&agrave;m. Đ&oacute; l&agrave; một phương ph&aacute;p tốt hơn để x&aacute;c định c&aacute;c th&ocirc;ng số của c&aacute;c dense layers. Đoạn m&atilde; dưới đ&acirc;y x&aacute;c định c&aacute;c gi&aacute; trị của kiến ​​tr&uacute;c autoencoder. Như đ&atilde; liệt k&ecirc; trước đ&acirc;y, bộ autoencoder c&oacute; hai layers, với 300 nơ-ron ở layer đầu ti&ecirc;n v&agrave; 150 ở layer thứ hai. Gi&aacute; trị của ch&uacute;ng được lưu trữ trong &nbsp;n_hidden_1 v&agrave; n_hidden_2.</p> <p style="text-align: justify;">Bạn cần x&aacute;c định tốc độ học v&agrave; si&ecirc;u tham số L2. C&aacute;c gi&aacute; trị được lưu trữ trong learning_rate v&agrave; l2_reg.</p> <div id="urvanov-syntax-highlighter-610ff034a4877707014080" class="urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate" style="text-align: justify;" data-settings=" minimize scroll-mouseover"> <div class="urvanov-syntax-highlighter-plain-wrap"> <pre class="language-python"><code>from functools import partial ## Encoder n_hidden_1 = 300 n_hidden_2 = 150 #codings ## Decoder n_hidden_3 = n_hidden_1 n_outputs = n_inputs learning_rate = 0.01 l2_reg = 0.0001</code></pre> </div> <div class="urvanov-syntax-highlighter-main">&nbsp;</div> </div> <p style="text-align: justify;">Kỹ thuật khởi tạo Xavier được gọi với đối tượng xavier_initializer từ estimator. Trong c&ugrave;ng một estimator, bạn c&oacute; thể th&ecirc;m bộ điều chỉnh với l2_regularizer.</p> <div id="urvanov-syntax-highlighter-610ff034a487b037045956" class="urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate" style="text-align: justify;" data-settings=" minimize scroll-mouseover"> <div class="urvanov-syntax-highlighter-plain-wrap"> <pre class="language-python"><code>##Khởi tạo Xavier xav_init = tf.contrib.layers.xavier_initializer() ## Định nghĩa L2 regularizer l2_regularizer = tf.contrib.layers.l2_regularizer(l2_reg)</code></pre> </div> <div class="urvanov-syntax-highlighter-main">&nbsp;</div> </div> <h4 id="ftoc-heading-9" class="ftwp-heading" style="text-align: justify;">Bước 2) X&aacute;c định c&aacute;c layers</h4> <p style="text-align: justify;">Tất cả c&aacute;c tham số của c&aacute;c dense layers đ&atilde; được thiết lập. Bạn c&oacute; thể đ&oacute;ng g&oacute;i mọi thứ trong biến dense_layer bằng c&aacute;ch sử dụng một phần đối tượng. dense_layer sử dụng k&iacute;ch hoạt ELU, khởi tạo Xavier v&agrave; ch&iacute;nh quy h&oacute;a L2.</p> <div id="urvanov-syntax-highlighter-610ff034a487d880577431" class="urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate" style="text-align: justify;" data-settings=" minimize scroll-mouseover"> <div class="urvanov-syntax-highlighter-plain-wrap"> <pre class="language-python"><code>dense_layer = partial(tf.layers.dense, activation=tf.nn.elu, kernel_initializer=xav_init, kernel_regularizer=l2_regularizer)</code></pre> </div> <div class="urvanov-syntax-highlighter-main">&nbsp;</div> </div> <h4 id="ftoc-heading-10" class="ftwp-heading" style="text-align: justify;">Bước 3) X&aacute;c định kiến ​​tr&uacute;c</h4> <p style="text-align: justify;">Nếu bạn nh&igrave;n v&agrave;o bức tranh của kiến ​​tr&uacute;c, bạn lưu &yacute; rằng mạng xếp chồng ba layers với một layer đầu ra. Đoạn m&atilde; dưới đ&acirc;y, sẽ kết nối c&aacute;c layers th&iacute;ch hợp.</p> <div id="urvanov-syntax-highlighter-610ff034a487f512434443" class="urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate" style="text-align: justify;" data-settings=" minimize scroll-mouseover"> <div class="urvanov-syntax-highlighter-plain-wrap"> <pre class="language-python"><code>hidden_1 = dense_layer(features, n_hidden_1) hidden_2 = dense_layer(hidden_1, n_hidden_2) hidden_3 = dense_layer(hidden_2, n_hidden_3) outputs = dense_layer(hidden_3, n_outputs, activation=None)</code></pre> </div> <div class="urvanov-syntax-highlighter-main">&nbsp;</div> </div> <h4 id="ftoc-heading-11" class="ftwp-heading" style="text-align: justify;">Bước 4) X&aacute;c định tr&igrave;nh tối ưu h&oacute;a</h4> <p style="text-align: justify;">Bước cuối c&ugrave;ng l&agrave; x&acirc;y dựng tr&igrave;nh tối ưu h&oacute;a. Sử dụng Mean Square Error như một h&agrave;m mất m&aacute;t. Nếu bạn nhớ lại hướng dẫn về hồi quy tuyến t&iacute;nh, bạn biết rằng MSE được t&iacute;nh to&aacute;n với sự kh&aacute;c biệt giữa đầu ra dự đo&aacute;n v&agrave; nh&atilde;n thực. Ở đ&acirc;y, nh&atilde;n l&agrave; đặc điểm do m&ocirc; h&igrave;nh cố gắng t&aacute;i tạo lại đầu v&agrave;o. Do đ&oacute;, bạn muốn gi&aacute; trị trung b&igrave;nh của tổng ch&ecirc;nh lệch b&igrave;nh phương giữa đầu ra v&agrave; đầu v&agrave;o được dự đo&aacute;n. Với TensorFlow, bạn c&oacute; thể m&atilde; h&oacute;a h&agrave;m mất m&aacute;t như sau:</p> <div id="urvanov-syntax-highlighter-610ff034a4881172172497" class="urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate" style="text-align: justify;" data-settings=" minimize scroll-mouseover"> <div class="urvanov-syntax-highlighter-plain-wrap"> <pre class="language-python"><code>loss = tf.reduce_mean(tf.square(outputs - features))</code></pre> </div> <div class="urvanov-syntax-highlighter-main">&nbsp;</div> </div> <p style="text-align: justify;">Sau đ&oacute;, bạn cần tối ưu h&oacute;a h&agrave;m mất m&aacute;t. Sử dụng tr&igrave;nh tối ưu h&oacute;a Adam để t&iacute;nh to&aacute;n gradients. H&agrave;m mục ti&ecirc;u l&agrave; giảm thiểu tổn thất.</p> <div id="urvanov-syntax-highlighter-610ff034a4886139299907" class="urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate" style="text-align: justify;" data-settings=" minimize scroll-mouseover"> <div class="urvanov-syntax-highlighter-plain-wrap"> <pre class="language-python"><code>##Tối ưu h&oacute;a loss = tf.reduce_mean(tf.square(outputs - features)) optimizer = tf.train.AdamOptimizer(learning_rate) train = optimizer.minimize(loss)</code></pre> </div> <div class="urvanov-syntax-highlighter-main">&nbsp;</div> </div> <p style="text-align: justify;">Một c&agrave;i đặt nữa trước khi đ&agrave;o tạo m&ocirc; h&igrave;nh. Sử dụng batch size l&agrave; 150, tức l&agrave; cung cấp pipeline với 150 h&igrave;nh ảnh mỗi lần lặp. Bạn cần t&iacute;nh số lần lặp lại theo c&aacute;ch thủ c&ocirc;ng.</p> <div id="urvanov-syntax-highlighter-610ff034a4888639422502" class="urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate" style="text-align: justify;" data-settings=" minimize scroll-mouseover"> <div class="urvanov-syntax-highlighter-plain-wrap"> <pre class="language-python"><code>BATCH_SIZE = 150 ###Số tập hợp batch : độ d&agrave;i của tập dữ liệu (length dataset) / k&iacute;ch thước (batch size) n_batches = horse_x.shape[0] // BATCH_SIZE print(n_batches) 33</code></pre> </div> <div class="urvanov-syntax-highlighter-main">&nbsp;</div> </div> <h4 id="ftoc-heading-12" class="ftwp-heading" style="text-align: justify;">Bước 5) Chạy m&ocirc; h&igrave;nh</h4> <p style="text-align: justify;">Cuối c&ugrave;ng nhưng kh&ocirc;ng k&eacute;m phần quan trọng, đ&agrave;o tạo model. Bạn đang đ&agrave;o tạo m&ocirc; h&igrave;nh với 100 epochs. Tức l&agrave;, m&ocirc; h&igrave;nh sẽ nh&igrave;n thấy h&igrave;nh ảnh gấp 100 lần so với trọng số được tối ưu h&oacute;a.</p> <p style="text-align: justify;">Ch&uacute;ng ta đ&atilde; quen thuộc với c&aacute;c code để đ&agrave;o tạo một m&ocirc; h&igrave;nh trong Tensorflow. Sự kh&aacute;c biệt nhỏ l&agrave; ph&acirc;n t&iacute;ch dữ liệu trước khi chạy đ&agrave;o tạo. Bằng c&aacute;ch n&agrave;y, m&ocirc; h&igrave;nh đ&agrave;o tạo nhanh hơn.</p> <p style="text-align: justify;">Qu&aacute; tr&igrave;nh đ&agrave;o tạo k&eacute;o d&agrave;i từ 2 đến 5 ph&uacute;t, t&ugrave;y thuộc v&agrave;o phần cứng m&aacute;y của bạn.</p> <div id="urvanov-syntax-highlighter-610ff034a488a103272805" class="urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate" style="text-align: justify;" data-settings=" minimize scroll-mouseover"> <div class="urvanov-syntax-highlighter-plain-wrap"> <pre class="language-python"><code>## Set params n_epochs = 100 ## Call Saver to save the model and re-use it later during evaluation saver = tf.train.Saver() with tf.Session() as sess: sess.run(tf.global_variables_initializer()) # initialise iterator with train data sess.run(iter.initializer, feed_dict={x: horse_x, batch_size: BATCH_SIZE}) print('Training...') print(sess.run(features).shape) for epoch in range(n_epochs): for iteration in range(n_batches): sess.run(train) if epoch % 10 == 0: loss_train = loss.eval() # not shown print("\r{}".format(epoch), "Train MSE:", loss_train) #saver.save(sess, "./my_model_all_layers.ckpt") save_path = saver.save(sess, "./model.ckpt") print("Model saved in path: %s" % save_path) Training... (150, 1024) 0 Train MSE: 2934.455 10 Train MSE: 1672.676 20 Train MSE: 1514.709 30 Train MSE: 1404.3118 40 Train MSE: 1425.058 50 Train MSE: 1479.0631 60 Train MSE: 1609.5259 70 Train MSE: 1482.3223 80 Train MSE: 1445.7035 90 Train MSE: 1453.8597 Model saved in path: ./model.ckpt</code></pre> </div> <div class="urvanov-syntax-highlighter-main">&nbsp;</div> </div> <h4 id="ftoc-heading-13" class="ftwp-heading" style="text-align: justify;">Bước 6) Đ&aacute;nh gi&aacute; m&ocirc; h&igrave;nh</h4> <p style="text-align: justify;">B&acirc;y giờ bạn đ&atilde; được đ&agrave;o tạo m&ocirc; h&igrave;nh của m&igrave;nh, đ&atilde; đến l&uacute;c đ&aacute;nh gi&aacute; n&oacute;.</p> <div id="urvanov-syntax-highlighter-610ff034a488f932499054" class="urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate" style="text-align: justify;" data-settings=" minimize scroll-mouseover"> <div class="urvanov-syntax-highlighter-plain-wrap"> <pre class="language-python"><code>test_data = unpickle('./cifar-10-batches-py/test_batch') test_x = grayscale(test_data['data']) #test_labels = np.array(test_data['labels'])</code></pre> </div> <div class="urvanov-syntax-highlighter-main">&nbsp;</div> </div> <p style="text-align: justify;">Bạn c&oacute; thể thử in c&aacute;c h&igrave;nh ảnh 13, đ&oacute; l&agrave; một con ngựa.</p> <div id="urvanov-syntax-highlighter-610ff034a4891430952577" class="urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate" style="text-align: justify;" data-settings=" minimize scroll-mouseover"> <div class="urvanov-syntax-highlighter-plain-wrap"> <pre class="language-python"><code>plot_image(test_x[13], shape=[32, 32], cmap = "Greys_r")</code></pre> </div> <div class="urvanov-syntax-highlighter-main">&nbsp;</div> </div> <p><img style="width: 50%; display: block; margin-left: auto; margin-right: auto;" src="../../../public_files/660fd9b9-b957-43bc-9904-d7e07d8bf399" alt="post-autoencoder-trong-deep-learning-6" /></p> <p style="text-align: justify;">Để đ&aacute;nh gi&aacute; m&ocirc; h&igrave;nh, bạn sẽ sử dụng gi&aacute; trị pixel của h&igrave;nh ảnh n&agrave;y v&agrave; xem liệu bộ m&atilde; h&oacute;a c&oacute; thể t&aacute;i tạo lại h&igrave;nh ảnh tương tự sau khi thu nhỏ 1024 pixel hay kh&ocirc;ng. Lưu &yacute; rằng, bạn x&aacute;c định một h&agrave;m để đ&aacute;nh gi&aacute; m&ocirc; h&igrave;nh tr&ecirc;n c&aacute;c bức ảnh kh&aacute;c nhau.</p> <p style="text-align: justify;">H&agrave;m nhận hai đối số:</p> <ul style="text-align: justify;"> <li>df: Nhập dữ liệu thử nghiệm</li> <li>image_number: Cho biết h&igrave;nh ảnh n&agrave;o cần nhập</li> </ul> <p style="text-align: justify;">H&agrave;m được chia th&agrave;nh ba phần:</p> <ol style="text-align: justify;"> <li>Reshape lại h&igrave;nh ảnh theo đ&uacute;ng k&iacute;ch thước, tức l&agrave; 1, 1024</li> <li>Feed the model với h&igrave;nh ảnh kh&ocirc;ng nh&igrave;n thấy, m&atilde; h&oacute;a / giải m&atilde; h&igrave;nh ảnh</li> <li>In h&igrave;nh ảnh thực v&agrave; t&aacute;i tạo</li> </ol> <div id="urvanov-syntax-highlighter-610ff034a4893913083276" class="urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate" style="text-align: justify;" data-settings=" minimize scroll-mouseover"> <div class="urvanov-syntax-highlighter-plain-wrap"> <pre class="language-python"><code>def reconstruct_image(df, image_number = 1): ## Phần 1: Định dạng lại ảnh với chiều 1, 1024 x_test = df[image_number] x_test_1 = x_test.reshape((1, 32*32)) ## Phần 2: Cho m&ocirc; h&igrave;nh học với ảnh chưa từng nh&igrave;n thấy, encode/decode ảnh with tf.Session() as sess: sess.run(tf.global_variables_initializer()) sess.run(iter.initializer, feed_dict={x: x_test_1, batch_size: 1}) ## Phần 3: In ra ảnh thật v&agrave; đ&atilde; được t&aacute;i tạo #Kh&ocirc;i phục c&aacute;c biến từ đĩa saver.restore(sess, "./model.ckpt") print("Model restored.") #T&aacute;i tạo lại ảnh outputs_val = outputs.eval() print(outputs_val.shape) fig = plt.figure() #Vẽ ra biểu đồ tr&ecirc;n thực tế ax1 = fig.add_subplot(121) plot_image(x_test_1, shape=[32, 32], cmap = "Greys_r") #Vẽ ra biểu đồ ước t&iacute;nh ax2 = fig.add_subplot(122) plot_image(outputs_val, shape=[32, 32], cmap = "Greys_r") plt.tight_layout() fig = plt.gcf()</code></pre> </div> <div class="urvanov-syntax-highlighter-main">&nbsp;</div> </div> <p style="text-align: justify;">B&acirc;y giờ h&agrave;m đ&aacute;nh gi&aacute; đ&atilde; được x&aacute;c định, bạn c&oacute; thể xem số h&igrave;nh ảnh được t&aacute;i tạo.</p> <div id="urvanov-syntax-highlighter-610ff034a4895686567546" class="urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate" style="text-align: justify;" data-settings=" minimize scroll-mouseover"> <div class="urvanov-syntax-highlighter-plain-wrap"> <pre class="language-python"><code>reconstruct_image(df =test_x, image_number = 13)</code></pre> </div> <div class="urvanov-syntax-highlighter-main">&nbsp;</div> </div> <div id="urvanov-syntax-highlighter-610ff034a4899825827640" class="urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate" style="text-align: justify;" data-settings=" minimize scroll-mouseover"> <div class="urvanov-syntax-highlighter-plain-wrap"> <pre class="language-python"><code>INFO:tensorflow:Restoring parameters from ./model.ckpt Model restored. (1, 1024)</code></pre> </div> <div class="urvanov-syntax-highlighter-main">&nbsp;</div> </div> <p style="text-align: justify;"><img style="width: 100%;" src="../../../public_files/4b41a763-7d2b-4598-8c75-989aff88f9f0" alt="post-autoencoder-trong-deep-learning-7" /></p> <h3 id="ftoc-heading-14" class="ftwp-heading" style="text-align: justify;">Kết Luận</h3> <p style="text-align: justify;">Mục đ&iacute;ch ch&iacute;nh của autoencoder l&agrave; n&eacute;n dữ liệu đầu v&agrave;o, sau đ&oacute; giải n&eacute;n n&oacute; th&agrave;nh một đầu ra giống với dữ liệu gốc.</p> <p style="text-align: justify;">Kiến tr&uacute;c của một autoencoder đối xứng với một layer trụ c&oacute; t&ecirc;n l&agrave; central layer.</p> <hr /> <p style="text-align: center;"><em><strong>Fanpage Facebook:</strong>&nbsp;<a href="https://www.facebook.com/tek4.vn/">TEK4.VN</a></em>&nbsp;</p> <p style="text-align: center;"><em><strong>Tham gia cộng đồng để chia sẻ, trao đổi v&agrave; thảo luận:</strong>&nbsp;<a href="https://www.facebook.com/groups/tek4.vn/">TEK4.VN - Học Lập Tr&igrave;nh Miễn Ph&iacute;</a></em></p>