ตัวเข้ารหัสอัตโนมัติใน TensorFlow พร้อมตัวอย่าง
⚡ สรุปอย่างชาญฉลาด
Autoencoders บีบอัดข้อมูลอินพุตให้เป็นรูปแบบการแสดงผลภายในที่เล็กลง จากนั้นจึงสร้างมันขึ้นมาใหม่ โดยเรียนรู้คุณลักษณะที่สำคัญที่สุดโดยไม่ต้องใช้ป้ายกำกับ ตัวอย่างนี้แสดงการเรียงซ้อนเลเยอร์ Dense สี่ชั้นใน TensorFlow และสร้างภาพม้า CIFAR-10 ขึ้นมาใหม่

Autoencoder ใน Deep Learning คืออะไร?
An ตัวเข้ารหัสอัตโนมัติ เป็นเครื่องมือสำหรับการเรียนรู้การเข้ารหัสข้อมูลอย่างมีประสิทธิภาพ ไม่ได้รับการดูแล ลักษณะเช่นนั้น มันเป็นประเภทหนึ่งของ โครงข่ายประสาทเทียม ซึ่งช่วยให้คุณเรียนรู้การแสดงข้อมูลชุดต่างๆ สำหรับการลดมิติ โดยการฝึกโครงข่ายประสาทเทียมให้ละเลยสัญญาณรบกวน เป็นเครื่องมือที่ยอดเยี่ยมสำหรับการสร้างข้อมูลป้อนเข้าขึ้นใหม่
กล่าวโดยง่าย เครื่องจักรจะรับภาพหนึ่งภาพ แล้วสร้างภาพที่ใกล้เคียงกันขึ้นมาได้ อินพุตในโครงข่ายประสาทเทียมประเภทนี้ไม่มีป้ายกำกับ หมายความว่าโครงข่ายสามารถเรียนรู้ได้โดยไม่ต้องมีการกำกับดูแล กล่าวให้แม่นยำยิ่งขึ้น อินพุตจะถูกเข้ารหัสโดยโครงข่ายเพื่อให้เน้นเฉพาะคุณลักษณะที่สำคัญที่สุดเท่านั้น นี่เป็นหนึ่งในเหตุผลที่ทำให้ Autoencoder เป็นที่นิยมสำหรับการลดมิติข้อมูล นอกจากนี้ Autoencoder ยังสามารถใช้สร้างแบบจำลองการเรียนรู้แบบสร้างสรรค์ได้ ตัวอย่างเช่น โครงข่ายประสาทเทียมสามารถฝึกฝนด้วยชุดใบหน้า แล้วสร้างใบหน้าใหม่ได้
โปรแกรมเข้ารหัสอัตโนมัติ TensorFlow ทำงานอย่างไร
วัตถุประสงค์ของโปรแกรมเข้ารหัสอัตโนมัติคือเพื่อสร้างการประมาณอินพุตโดยเน้นไปที่คุณสมบัติที่จำเป็นเท่านั้น คุณอาจคิดว่าทำไมไม่เพียงแค่เรียนรู้วิธีคัดลอกและวางอินพุตเพื่อสร้างเอาต์พุตเท่านั้น ที่จริงแล้ว โปรแกรมเข้ารหัสอัตโนมัติคือชุดของข้อจำกัดที่บังคับให้เครือข่ายเรียนรู้วิธีใหม่ๆ ในการแสดงข้อมูล แตกต่างจากการคัดลอกเอาต์พุตเพียงอย่างเดียว
โดยทั่วไปแล้ว ออโตเอนโคเดอร์จะถูกกำหนดด้วยอินพุต การแสดงผลภายใน และเอาต์พุต (ค่าประมาณของอินพุต) การเรียนรู้เกิดขึ้นในเลเยอร์ที่เชื่อมต่อกับการแสดงผลภายใน ที่จริงแล้ว มีบล็อกเลเยอร์หลักสองบล็อกซึ่งดูคล้ายกับโครงข่ายประสาทเทียมแบบดั้งเดิม ความแตกต่างเล็กน้อยคือเลเยอร์ที่ประกอบด้วยเอาต์พุตจะต้องมีขนาดเท่ากับอินพุต ในแผนภาพด้านล่าง อินพุตดั้งเดิมจะเข้าสู่บล็อกแรกที่เรียกว่าเอนโคเดอร์ การแสดงผลภายในนี้จะบีบอัด (ลด) ขนาดของอินพุต ในบล็อกที่สองจะเกิดการสร้างอินพุตขึ้นใหม่ นี่คือขั้นตอนการถอดรหัส

แบบจำลองจะอัปเดตน้ำหนักโดยลดฟังก์ชันการสูญเสียให้เหลือน้อยที่สุด โมเดลจะถูกลงโทษหากเอาต์พุตของการสร้างใหม่แตกต่างจากอินพุต
กล่าวโดยสรุป ลองนึกภาพภาพที่มีขนาด 50×50 พิกเซล (เช่น 2,500 พิกเซล) และโครงข่ายประสาทเทียมที่มีเพียงชั้นซ่อนเร้นชั้นเดียวซึ่งประกอบด้วยเซลล์ประสาทหนึ่งร้อยเซลล์ การเรียนรู้เกิดขึ้นบนแผนที่คุณลักษณะซึ่งมีขนาดเล็กกว่าอินพุตถึงยี่สิบห้าเท่า นั่นหมายความว่าโครงข่ายจำเป็นต้องหาวิธีสร้างภาพ 2,500 พิกเซลขึ้นมาใหม่โดยใช้เวกเตอร์ของเซลล์ประสาทเพียง 100 เซลล์เท่านั้น
ตัวอย่างการเข้ารหัสอัตโนมัติแบบซ้อน
ในบทเรียนเรื่อง Autoencoder นี้ คุณจะได้เรียนรู้วิธีการใช้ Stacked Autoencoder โครงสร้างของสถาปัตยกรรมนี้คล้ายกับโครงข่ายประสาทเทียมแบบดั้งเดิม ข้อมูลนำเข้าจะถูกส่งไปยังเลเยอร์ที่ซ่อนอยู่เพื่อทำการบีบอัดหรือลดขนาด จากนั้นจึงไปยังเลเยอร์การสร้างภาพใหม่ เป้าหมายคือการสร้างภาพเอาต์พุตที่ใกล้เคียงกับภาพต้นฉบับมากที่สุด โมเดลจะต้องเรียนรู้วิธีการทำงานให้สำเร็จภายใต้ข้อจำกัดต่างๆ นั่นคือ ด้วยมิติที่ต่ำกว่า
ปัจจุบัน Autoencoder ใน Deep Learning ส่วนใหญ่ใช้เพื่อลดสัญญาณรบกวนในภาพ ลองนึกภาพภาพที่มีรอยขีดข่วน มนุษย์ยังคงสามารถจดจำเนื้อหาได้ แนวคิดของการใช้ autoencoder ลดสัญญาณรบกวนคือการเพิ่มสัญญาณรบกวนให้กับภาพเพื่อบังคับให้เครือข่ายเรียนรู้รูปแบบที่อยู่เบื้องหลังข้อมูล
ตระกูล Autoencoder ที่มีประโยชน์อีกตระกูลหนึ่งคือ การเรียนรู้ลึก ๆ Variational Autoencoder (VAOC) คือโครงข่ายประสาทเทียมแบบออโตเอนโคเดอร์ (Autoencoder) ประเภทนี้สามารถสร้างภาพใหม่ได้ ลองนึกภาพว่าคุณฝึกโครงข่ายด้วยภาพของผู้ชาย โครงข่ายดังกล่าวสามารถสร้างใบหน้าใหม่ได้
ตารางด้านล่างนี้แสดงตำแหน่งของออโตเอนโคเดอร์แบบเรียงซ้อนที่สร้างขึ้นในบทช่วยสอนนี้ เทียบกับตระกูลอื่นๆ ที่คุณอาจพบเจอ เพื่อให้เปรียบเทียบข้อจำกัดที่แต่ละตระกูลเพิ่มเข้ามาได้ง่าย
| ประเภทออโตเอนโคเดอร์ | เพิ่มข้อจำกัด | การใช้งานทั่วไป |
|---|---|---|
| ยังไม่เสร็จสมบูรณ์ / ซ้อนกัน | ชั้นการเข้ารหัสแคบกว่าชั้นอินพุต | การลดมิติ, คุณสมบัติเพิ่มเติมtracการ |
| ดีนอยส์ซิ่ง | มีการเพิ่มสัญญาณรบกวนเข้าไปในอินพุต แต่เป้าหมายสะอาด | การปรับปรุงภาพและสัญญาณ |
| กระจัดกระจาย | บทลงโทษเกี่ยวกับจำนวนหน่วยที่ใช้งานอยู่ | คุณลักษณะที่ตีความได้และอิงตามส่วนประกอบ |
| แปรผัน | ชั้นการเข้ารหัสเรียนรู้การกระจายความน่าจะเป็น | การสร้างตัวอย่างใหม่ |
วิธีสร้างตัวเข้ารหัสอัตโนมัติด้วย TensorFlow
ในบทช่วยสอนนี้ คุณจะได้เรียนรู้วิธีสร้างตัวเข้ารหัสอัตโนมัติแบบเรียงซ้อนเพื่อสร้างรูปภาพขึ้นมาใหม่
คุณจะใช้ชุดข้อมูล CIFAR-10 ซึ่งประกอบด้วยภาพสีขนาด 32x32 จำนวน 60000 ภาพ ชุดข้อมูล Autoencoder ได้ถูกแบ่งออกเป็น 50000 ภาพสำหรับฝึกฝนและ 10000 ภาพสำหรับทดสอบแล้ว โดยมีคลาสสูงสุดสิบคลาส:
- เครื่องบิน
- Automobile
- นก
- แคท
- กวาง
- สุนัข
- กบ
- ม้า
- เรือ
- รถบรรทุก
คุณต้องดาวน์โหลดรูปภาพจาก หน้าชุดข้อมูล CIFAR-10 และแตกไฟล์ซิป โฟลเดอร์ cifar-10-batches-py จะประกอบด้วยข้อมูลห้าชุด ชุดละ 10000 ภาพ เรียงลำดับแบบสุ่ม
ก่อนที่คุณจะสร้างและฝึกโมเดลของคุณ คุณต้องใช้การประมวลผลข้อมูลบางอย่างก่อน คุณจะดำเนินการดังต่อไปนี้:
- นำเข้าข้อมูล
- แปลงข้อมูลเป็นรูปแบบขาวดำ
- ผนวกแบทช์ทั้งหมด
- สร้างชุดข้อมูลการฝึกอบรม
- สร้างโปรแกรมสร้างภาพ
หมายเหตุเกี่ยวกับเวอร์ชัน: โค้ดในบทช่วยสอนนี้ใช้กับ TensorFlow 1.x ใน TensorFlow 2 โมดูล tf.contrib ไม่มีอยู่อีกต่อไปแล้ว และ placeholder, session และ initializable iterator จะอยู่ใน tf.compat.v1 การเรียกใช้ tf.compat.v1.disable_v2_behavior() หลังจากนำเข้าโมดูลเป็นวิธีที่เร็วที่สุดในการรันโค้ดโดยไม่เปลี่ยนแปลง
การประมวลผลภาพล่วงหน้า
ขั้นตอนที่ 1) นำเข้าข้อมูล
ตามเว็บไซต์อย่างเป็นทางการ คุณสามารถอัปโหลดข้อมูลได้โดยใช้โค้ดต่อไปนี้ โค้ด Autoencoder จะโหลดข้อมูลลงในพจนานุกรมที่มีทั้งข้อมูลและป้ายกำกับ โปรดทราบว่าโค้ดนี้เป็นฟังก์ชัน
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
ขั้นตอนที่ 2) แปลงข้อมูลเป็นรูปแบบขาวดำ
เพื่อความง่าย คุณจะแปลงข้อมูลเป็นระดับสีเทา นั่นคือมีเพียงมิติเดียวต่อสามสำหรับภาพสี โครงข่ายประสาทเทียมส่วนใหญ่ใช้งานได้กับอินพุตมิติเดียวเท่านั้น
def grayscale(im): return im.reshape(im.shape[0], 3, 32, 32).mean(1).reshape(im.shape[0], -1)
ขั้นตอนที่ 3) ผนวกชุดงานทั้งหมด
เมื่อสร้างฟังก์ชันทั้งสองและโหลดชุดข้อมูลเรียบร้อยแล้ว คุณสามารถเขียนลูปเพื่อเพิ่มข้อมูลลงในหน่วยความจำได้ หากตรวจสอบอย่างละเอียด ไฟล์ที่คลายซิปแล้วซึ่งมีข้อมูลจะมีชื่อว่า data_batch_ โดยมีหมายเลขตั้งแต่ 1 ถึง 5 ต่อท้าย คุณสามารถวนลูปผ่านไฟล์ต่างๆ และเพิ่มข้อมูลลงในตัวแปร data ได้
เมื่อทำขั้นตอนนี้เสร็จแล้ว คุณจะแปลงข้อมูลสีเป็นรูปแบบขาวดำ ดังที่คุณเห็น รูปทรงของข้อมูลคือ 50000 และ 1024 พิกเซล ขนาด 32*32 ถูกรวมเข้าเป็น 1024 แล้ว
# Load the data into memory data, labels = [], [] ## Loop over the b for i in range(1, 6): filename = './cifar-10-batches-py/data_batch_' + str(i) open_data = unpickle(filename) if len(data) > 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)
หมายเหตุ เปลี่ยน './cifar-10-batches-py/data_batch_' เป็นตำแหน่งที่ตั้งจริงของไฟล์ของคุณ ตัวอย่างเช่น สำหรับไฟล์ Windows เครื่อง เส้นทางอาจเป็น filename = 'E:\cifar-10-batches-py\data_batch_' + str(i)
ขั้นตอนที่ 4) สร้างชุดข้อมูลการฝึกอบรม
เพื่อให้การฝึกฝนรวดเร็วและง่ายขึ้น คุณจะฝึกฝนโมเดลโดยใช้เฉพาะภาพม้าเท่านั้น ม้ามีป้ายกำกับหมายเลข 7 ในข้อมูลป้ายกำกับ ดังที่ระบุไว้ในเอกสารประกอบของชุดข้อมูล CIFAR-10 แต่ละคลาสประกอบด้วยภาพ 5000 ภาพ คุณสามารถพิมพ์โครงสร้างของข้อมูลเพื่อยืนยันว่ามีภาพ 5,000 ภาพและ 1024 คอลัมน์ ดังแสดงในขั้นตอนตัวอย่าง TensorFlow Autoencoder ด้านล่าง
horse_i = np.where(y == 7)[0]
horse_x = x[horse_i]
print(np.shape(horse_x))
(5000, 1024)
ขั้นตอนที่ 5) สร้างโปรแกรมสร้างภาพ
สุดท้าย คุณสร้างฟังก์ชันเพื่อลงจุดรูปภาพ คุณจะต้องใช้ฟังก์ชันนี้เพื่อพิมพ์รูปภาพที่สร้างขึ้นใหม่จากโปรแกรมเข้ารหัสอัตโนมัติ
วิธีง่ายๆ ในการแสดงภาพคือการใช้ฟังก์ชัน imshow() จากไลบรารี Matplotlib โปรดทราบว่า คุณต้องแปลงขนาดของข้อมูลจาก 1024 เป็น 32*32 (เช่น รูปแบบของภาพ)
# To plot pretty figures %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")
ฟังก์ชันรับ 3 อาร์กิวเมนต์:
- รูปภาพ: ข้อมูลนำเข้า
- รูปร่าง: รายการแสดงขนาดของภาพ
- Cmap: เลือกแผนที่สี โดยค่าเริ่มต้นจะเป็นสีเทา
คุณสามารถลองพล็อตรูปภาพแรกในชุดข้อมูลได้ คุณควรเห็นชายคนหนึ่งขี่ม้า
plot_image(horse_x[1], shape=[32, 32], cmap = "Greys_r")
คำสั่งนี้แสดงภาพขนาดย่อขาวดำดังที่แสดงด้านล่าง และยืนยันว่าการปรับรูปร่างจากค่า 1024 กลับไปเป็นภาพขนาด 32×32 นั้นถูกต้อง
ตั้งค่าตัวประมาณการชุดข้อมูล
เอาล่ะ ตอนนี้ชุดข้อมูลพร้อมใช้งานแล้ว คุณสามารถเริ่มใช้ TensorFlow ได้เลย ก่อนที่จะสร้างโมเดล ให้ใช้ตัวประมาณค่าชุดข้อมูล (Dataset estimator) ของ TensorFlow เพื่อป้อนข้อมูลให้กับเครือข่าย
คุณจะสร้างชุดข้อมูลด้วยตัวประมาณค่า TensorFlow เพื่อฟื้นฟูจิตใจของคุณ คุณต้องใช้:
- จาก_tensor_slices
- ทำซ้ำ
- ชุด
รหัสเต็มในการสร้างชุดข้อมูลคือ:
dataset = tf.data.Dataset.from_tensor_slices(x).repeat().batch(batch_size)
โปรดทราบว่า x เป็นตัวแปรแทนที่มีรูปร่าง [None,n_inputs] มิติแรกถูกตั้งค่าเป็น None เนื่องจากจำนวนภาพที่ป้อนเข้าสู่เครือข่ายเท่ากับขนาดแบทช์ ซึ่งจะถูกกำหนดในระหว่างการทำงานเท่านั้น สำหรับรายละเอียดเพิ่มเติม โปรดดูบทช่วยสอนเกี่ยวกับ การถดถอยเชิงเส้นด้วย TensorFlow.
หลังจากนั้นคุณจะต้องสร้างตัววนซ้ำ หากไม่มีโค้ดบรรทัดนี้ จะไม่มีข้อมูลใดผ่านไปป์ไลน์
iter = dataset.make_initializable_iterator() # create the iteratorfeatures = iter.get_next()
ตอนนี้ไปป์ไลน์พร้อมแล้ว คุณสามารถตรวจสอบได้ว่าภาพแรกเหมือนเดิมหรือไม่ (เช่น คนขี่ม้า)
คุณตั้งค่าขนาดแบทช์เป็น 1 เพราะคุณต้องการป้อนภาพเพียงภาพเดียวลงในชุดข้อมูล คุณสามารถดูขนาดของข้อมูลได้ด้วยคำสั่ง print(sess.run(features).shape) ซึ่งจะมีค่าเท่ากับ (1, 1024) เลข 1 หมายความว่าภาพเดียวที่มีค่า 1024 จะถูกป้อนเข้าไปในแต่ละครั้ง หากตั้งค่าขนาดแบทช์เป็น 2 ภาพสองภาพจะถูกส่งผ่านไปป์ไลน์ อย่าเปลี่ยนขนาดแบทช์ มิฉะนั้นจะเกิดข้อผิดพลาด เพราะมีเพียงภาพเดียวเท่านั้นที่สามารถส่งไปยังฟังก์ชัน plot_image() ได้ในแต่ละครั้ง
## Parameters n_inputs = 32 * 32 BATCH_SIZE = 1 batch_size = tf.placeholder(tf.int64) # using a placeholder x = tf.placeholder(tf.float32, shape=[None,n_inputs]) ## Dataset dataset = tf.data.Dataset.from_tensor_slices(x).repeat().batch(batch_size) iter = dataset.make_initializable_iterator() # create the iterator features = iter.get_next() ## Print the image with tf.Session() as sess: # feed the placeholder with data 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)
ไปป์ไลน์ส่งคืนค่า rider เดียวกันกับที่พล็อตโดยตรงจากเมทริกซ์ NumPy ซึ่งพิสูจน์ได้ว่า placeholder, iterator และ batch size เชื่อมต่อกันอย่างถูกต้อง
สร้างเครือข่าย
ถึงเวลาสร้างเครือข่าย คุณจะฝึกตัวเข้ารหัสอัตโนมัติแบบเรียงซ้อน ซึ่งก็คือเครือข่ายที่มีเลเยอร์ที่ซ่อนอยู่หลายชั้น
เครือข่ายของคุณจะมีเลเยอร์อินพุตหนึ่งเลเยอร์ที่มี 1024 จุด หรือก็คือขนาด 32×32 ซึ่งเป็นรูปร่างของภาพ
บล็อกตัวเข้ารหัสจะมีเลเยอร์ซ่อนเร้นด้านบนหนึ่งชั้นที่มีนิวรอน 300 ตัว และเลเยอร์กลางที่มีนิวรอน 150 ตัว บล็อกตัวถอดรหัสจะสมมาตรกับบล็อกตัวเข้ารหัส คุณสามารถดูภาพรวมของเครือข่ายได้ในแผนภาพด้านล่าง โปรดทราบว่าคุณสามารถเปลี่ยนค่าของเลเยอร์ซ่อนเร้นและเลเยอร์กลางได้
การสร้างโปรแกรมเข้ารหัสอัตโนมัตินั้นคล้ายคลึงกับโมเดลการเรียนรู้เชิงลึกอื่นๆ มาก
คุณจะสร้างแบบจำลองโดยทำตามขั้นตอนเหล่านี้:
- กำหนดพารามิเตอร์
- กำหนดเลเยอร์
- กำหนดสถาปัตยกรรม
- กำหนดการเพิ่มประสิทธิภาพ
- เรียกใช้โมเดล
- ประเมินแบบจำลอง
ในส่วนก่อนหน้านี้ คุณได้เรียนรู้วิธีสร้างไปป์ไลน์เพื่อป้อนข้อมูลให้กับโมเดล ดังนั้นจึงไม่จำเป็นต้องสร้างชุดข้อมูลอีกครั้ง คุณจะสร้างออโตเอนโคเดอร์ที่มีสี่เลเยอร์ คุณจะใช้การเริ่มต้นแบบ Xavier ซึ่งเป็นเทคนิคในการกำหนดค่าน้ำหนักเริ่มต้นตามความแปรปรวนของทั้งอินพุตและเอาต์พุต สุดท้าย คุณจะใช้ฟังก์ชันการกระตุ้น ELU และปรับค่าฟังก์ชันความสูญเสียด้วยตัวควบคุม L2
ขั้นตอนที่ 1) กำหนดพารามิเตอร์
ขั้นตอนแรกหมายถึงการกำหนดจำนวนเซลล์ประสาทในแต่ละชั้น อัตราการเรียนรู้ และไฮเปอร์พารามิเตอร์ของเรกูลาร์ไลเซอร์
ก่อนหน้านั้น คุณต้องนำเข้าฟังก์ชันบางส่วนก่อน นี่เป็นวิธีการที่ดีกว่าในการกำหนดพารามิเตอร์ของเลเยอร์หนาแน่น โค้ดด้านล่างกำหนดค่าของสถาปัตยกรรมออโตเอนโคเดอร์ ดังที่ได้กล่าวไว้ก่อนหน้านี้ เอนโคเดอร์มีสองชั้น โดยมี 300 นิวรอนในชั้นแรกและ 150 นิวรอนในชั้นที่สอง ค่าของพวกมันถูกเก็บไว้ใน n_hidden_1 และ n_hidden_2
คุณต้องกำหนดอัตราการเรียนรู้และพารามิเตอร์ L2 โดยค่าต่างๆ จะถูกเก็บไว้ในตัวแปร learning_rate และ l2_reg
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
เทคนิคการเริ่มต้นแบบ Xavier จะถูกเรียกใช้ด้วยอ็อบเจ็กต์ xavier_initializer จาก contrib ของตัวประมาณค่า ในตัวประมาณค่าเดียวกันนี้ คุณสามารถเพิ่ม regularizer ด้วย l2_regularizer ได้
## Define the Xavier initialization xav_init = tf.contrib.layers.xavier_initializer() ## Define the L2 regularizer l2_regularizer = tf.contrib.layers.l2_regularizer(l2_reg)
หมายเหตุเกี่ยวกับเวอร์ชัน: tf.contrib ถูกลบออกใน TensorFlow 2 แล้ว ฟังก์ชันทดแทนโดยตรงคือ tf.keras.initializers.GlorotUniform() สำหรับ xavier_initializer() และ tf.keras.regularizers.l2() สำหรับ l2_regularizer()
ขั้นตอนที่ 2) กำหนดเลเยอร์
พารามิเตอร์ทั้งหมดของเลเยอร์หนาแน่นได้รับการตั้งค่าแล้ว คุณสามารถบรรจุทุกอย่างลงในตัวแปร dense_layer โดยใช้ object partial จากนั้น dense_layer จะใช้การเปิดใช้งาน ELU การเริ่มต้น Xavier และการปรับค่า L2 ในทุกการเรียกใช้
## Create the dense layer
dense_layer = partial(tf.layers.dense,
activation=tf.nn.elu,
kernel_initializer=xav_init,
kernel_regularizer=l2_regularizer)
ขั้นตอนที่ 3) กำหนดโครงสร้างสถาปัตยกรรม
หากคุณดูแผนภาพของสถาปัตยกรรม คุณจะสังเกตได้ว่าเครือข่ายประกอบด้วยสามชั้น โดยมีชั้นเอาต์พุตอยู่ด้านบน ในโค้ดด้านล่าง คุณจะเชื่อมต่อชั้นต่างๆ ที่เหมาะสม ตัวอย่างเช่น ชั้นแรกจะคำนวณผลคูณดอทระหว่างเมทริกซ์คุณลักษณะอินพุตและเมทริกซ์ที่มีน้ำหนัก 300 ตัว หลังจากคำนวณผลคูณดอทแล้ว ผลลัพธ์จะถูกส่งไปยังฟังก์ชันการกระตุ้น ELU ผลลัพธ์จะกลายเป็นอินพุตของชั้นถัดไป นั่นคือเหตุผลที่คุณใช้มันในการคำนวณ hidden_2 และอื่นๆ การคูณเมทริกซ์จะเหมือนกันสำหรับแต่ละชั้นเนื่องจากคุณใช้ฟังก์ชันการกระตุ้นเดียวกัน โปรดทราบว่าชั้นสุดท้าย เอาต์พุต ไม่ได้ใช้ฟังก์ชันการกระตุ้น ซึ่งก็สมเหตุสมผลเพราะนี่คืออินพุตที่สร้างขึ้นใหม่
## Make the mat mul 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)
ขั้นตอนที่ 4) กำหนดการเพิ่มประสิทธิภาพ
ขั้นตอนสุดท้ายคือการสร้างตัวปรับแต่ง (optimizer) คุณใช้ค่าความคลาดเคลื่อนกำลังสองเฉลี่ย (Mean Square Error หรือ MSE) เป็นฟังก์ชันความสูญเสีย หากคุณจำบทเรียนเกี่ยวกับการถดถอยเชิงเส้นได้ คุณจะรู้ว่า MSE คำนวณจากความแตกต่างระหว่างผลลัพธ์ที่คาดการณ์ไว้กับป้ายกำกับจริง ในที่นี้ ป้ายกำกับคือคุณลักษณะ (feature) เพราะแบบจำลองพยายามสร้างอินพุตขึ้นมาใหม่ ดังนั้น คุณต้องการค่าเฉลี่ยของผลรวมของความแตกต่างกำลังสองระหว่างผลลัพธ์ที่คาดการณ์ไว้กับอินพุต ด้วย TensorFlow คุณสามารถเขียนโค้ดฟังก์ชันความสูญเสียได้ดังนี้:
loss = tf.reduce_mean(tf.square(outputs - features))
จากนั้น คุณต้องปรับฟังก์ชันความสูญเสียให้เหมาะสม คุณใช้ตัวปรับแต่ง Adam เพื่อคำนวณเกรเดียนต์ ฟังก์ชันเป้าหมายคือการลดความสูญเสียให้เหลือน้อยที่สุด
## Optimize
loss = tf.reduce_mean(tf.square(outputs - features))
optimizer = tf.train.AdamOptimizer(learning_rate)
train = optimizer.minimize(loss)
การตั้งค่าอื่นก่อนการฝึกโมเดล คุณต้องการใช้ขนาดแบตช์ 150 ซึ่งก็คือป้อนไปป์ไลน์ด้วยรูปภาพ 150 รูปในแต่ละการวนซ้ำ คุณต้องคำนวณจำนวนการวนซ้ำด้วยตนเอง นี่เป็นเรื่องเล็กน้อยที่ต้องทำ:
ถ้าคุณต้องการประมวลผลภาพ 150 ภาพในแต่ละครั้ง และคุณทราบว่ามีภาพทั้งหมด 5000 ภาพในชุดข้อมูล จำนวนรอบการประมวลผลจะเท่ากับ 5000 หารด้วย 150 Python คุณสามารถรันโค้ดต่อไปนี้และตรวจสอบให้แน่ใจว่าผลลัพธ์คือ 33:
BATCH_SIZE = 150 ### Number of batches : length dataset / batch size n_batches = horse_x.shape[0] // BATCH_SIZE print(n_batches) 33
ขั้นตอนที่ 5) รันโมเดล
สุดท้ายนี้ ให้ฝึกโมเดล คุณจะฝึกโมเดลด้วยจำนวน 100 รอบ นั่นหมายความว่าโมเดลจะเห็นภาพ 100 ครั้งในขณะที่ปรับค่าถ่วงน้ำหนักให้เหมาะสม
คุณคุ้นเคยกับโค้ดสำหรับฝึกโมเดลใน TensorFlow อยู่แล้ว ความแตกต่างเล็กน้อยคือการส่งข้อมูลผ่านท่อก่อนเริ่มการฝึก ในวิธีนี้ โมเดลจะฝึกได้เร็วขึ้น
คุณสนใจที่จะพิมพ์การสูญเสียหลังจากสิบยุคเพื่อดูว่าแบบจำลองกำลังเรียนรู้บางอย่างหรือไม่ (เช่น การสูญเสียกำลังลดลง) การฝึกอบรมจะใช้เวลา 2 ถึง 5 นาที ขึ้นอยู่กับฮาร์ดแวร์เครื่องของคุณ
## 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
ขั้นตอนที่ 6) ประเมินแบบจำลอง
เมื่อคุณฝึกฝนโมเดลเสร็จแล้ว ก็ถึงเวลาประเมินผล คุณต้องนำเข้าชุดข้อมูลทดสอบจากไฟล์ /cifar-10-batches-py/
test_data = unpickle('./cifar-10-batches-py/test_batch') test_x = grayscale(test_data['data']) #test_labels = np.array(test_data['labels'])
หมายเหตุ สำหรับ Windows เครื่อง รหัสจะกลายเป็น test_data = unpickle(r”E:\cifar-10-batches-py\test_batch”)
คุณสามารถลองพิมพ์ภาพที่ 13 ซึ่งเป็นภาพม้าได้
plot_image(test_x[13], shape=[32, 32], cmap = "Greys_r")
กราฟยืนยันว่าชุดข้อมูลทดสอบโหลดได้อย่างถูกต้อง และภาพที่ 13 อยู่ในกลุ่มเดียวกับที่ใช้ฝึกโมเดล
ในการประเมินโมเดล คุณจะใช้ค่าพิกเซลของภาพนี้และดูว่าตัวเข้ารหัสสามารถสร้างภาพเดียวกันขึ้นมาใหม่ได้หรือไม่หลังจากย่อขนาดเหลือ 1024 พิกเซล โปรดทราบว่า คุณกำหนดฟังก์ชันเพื่อประเมินโมเดลกับภาพต่างๆ โมเดลควรทำงานได้ดีที่สุดกับภาพม้าเท่านั้น
ฟังก์ชันรับสองอาร์กิวเมนต์:
- df: นำเข้าข้อมูลทดสอบ
- image_number: ระบุหมายเลขรูปภาพที่จะนำเข้า
ฟังก์ชั่นแบ่งออกเป็นสามส่วน:
- ปรับรูปร่างรูปภาพให้เป็นมิติที่ถูกต้อง เช่น 1, 1024
- ป้อนโมเดลด้วยภาพที่มองไม่เห็น เข้ารหัส/ถอดรหัสรูปภาพ
- พิมพ์ภาพจริงและสร้างใหม่
def reconstruct_image(df, image_number = 1): ## Part 1: Reshape the image to the correct dimension i.e 1, 1024 x_test = df[image_number] x_test_1 = x_test.reshape((1, 32*32)) ## Part 2: Feed the model with the unseen image, encode/decode the image with tf.Session() as sess: sess.run(tf.global_variables_initializer()) sess.run(iter.initializer, feed_dict={x: x_test_1, batch_size: 1}) ## Part 3: Print the real and reconstructed image # Restore variables from disk. saver.restore(sess, "./model.ckpt") print("Model restored.") # Reconstruct image outputs_val = outputs.eval() print(outputs_val.shape) fig = plt.figure() # Plot real ax1 = fig.add_subplot(121) plot_image(x_test_1, shape=[32, 32], cmap = "Greys_r") # Plot estimated ax2 = fig.add_subplot(122) plot_image(outputs_val, shape=[32, 32], cmap = "Greys_r") plt.tight_layout() fig = plt.gcf()
เมื่อกำหนดฟังก์ชันการประเมินแล้ว ตอนนี้คุณสามารถดูภาพที่สร้างขึ้นใหม่หมายเลขสิบสามได้เลย
reconstruct_image(df =test_x, image_number = 13)
INFO:tensorflow:Restoring parameters from ./model.ckpt
Model restored.
(1, 1024)
ภาพนี้แสดงภาพทดสอบต้นฉบับทางด้านซ้ายและภาพที่ได้จากออโตเอนโคเดอร์ทางด้านขวา ทำให้สามารถประเมินการสูญเสียรายละเอียดเล็กๆ น้อยๆ หลังจากการบีบอัดจาก 1024 เป็น 150 ได้อย่างง่ายดาย




