การจัดประเภทรูปภาพของ CNN ใน TensorFlow พร้อมขั้นตอนและตัวอย่าง
Convolutional Neural Network คืออะไร?
โครงข่ายประสาทเทียมหรือที่เรียกว่า Convnets หรือ CNN เป็นวิธีการที่รู้จักกันดีในแอปพลิเคชันวิชันคอมพิวเตอร์ ซึ่งเป็นกลุ่มของเครือข่ายประสาทเทียมเชิงลึกที่ใช้ในการวิเคราะห์ภาพ สถาปัตยกรรมประเภทนี้มักใช้ในการจดจำวัตถุจากภาพหรือวิดีโอ ใช้ในแอปพลิเคชัน เช่น การจดจำภาพหรือวิดีโอ การประมวลผลภาษาประสาทเทียม เป็นต้น
Archiการสอนโครงข่ายประสาทเทียมแบบ Convolutional
ลองนึกถึง Facebook เมื่อไม่กี่ปีก่อน หลังจากที่คุณอัปโหลดรูปภาพไปยังโปรไฟล์ของคุณแล้ว คุณจะถูกขอให้เพิ่มชื่อให้กับใบหน้าบนรูปภาพด้วยตนเอง ปัจจุบัน Facebook ใช้ Convnet เพื่อแท็กเพื่อนของคุณในภาพโดยอัตโนมัติ
เครือข่ายประสาทเทียมแบบ Convolution สำหรับการจำแนกภาพนั้นเข้าใจได้ไม่ยาก ภาพอินพุตจะถูกประมวลผลในระหว่างขั้นตอนการ Convolution จากนั้นจึงกำหนดป้ายกำกับในภายหลัง
สถาปัตยกรรม Convnet ทั่วไปสามารถสรุปได้ในภาพด้านล่าง ก่อนอื่น รูปภาพจะถูกผลักไปที่เครือข่าย ซึ่งเรียกว่ารูปภาพอินพุต จากนั้น รูปภาพอินพุตจะผ่านขั้นตอนที่ไม่มีที่สิ้นสุด นี่คือส่วน Convolution ของเครือข่าย ในที่สุด เครือข่ายประสาทเทียมสามารถทำนายตัวเลขบนรูปภาพได้

รูปภาพประกอบด้วยอาร์เรย์พิกเซลที่มีความสูงและความกว้าง ภาพระดับสีเทามีเพียงช่องเดียว ในขณะที่ภาพสีมีสามช่อง (แต่ละช่องสำหรับสีแดง เขียว และน้ำเงิน) ช่องจะซ้อนกัน ในบทช่วยสอนนี้ คุณจะใช้ภาพระดับสีเทาที่มีเพียงช่องเดียวเท่านั้น แต่ละพิกเซลมีค่าตั้งแต่ 0 ถึง 255 เพื่อสะท้อนถึงความเข้มของสี ตัวอย่างเช่น พิกเซลเท่ากับ 0 จะแสดงเป็นสีขาว ในขณะที่พิกเซลที่มีค่าใกล้ 255 จะเข้มกว่า
เรามาดูภาพที่เก็บไว้ใน ชุดข้อมูล MNIST- รูปภาพด้านล่างแสดงวิธีการแสดงรูปภาพด้านซ้ายในรูปแบบเมทริกซ์ โปรดทราบว่าเมทริกซ์ดั้งเดิมถูกกำหนดมาตรฐานให้อยู่ระหว่าง 0 ถึง 1 สำหรับสีเข้มกว่า ค่าในเมทริกซ์จะอยู่ที่ประมาณ 0.9 ในขณะที่พิกเซลสีขาวมีค่าเป็น 0
การดำเนินการแบบคอนโวลูชั่น
องค์ประกอบที่สำคัญที่สุดในแบบจำลองคือเลเยอร์แบบหมุนวน ส่วนนี้มีจุดมุ่งหมายเพื่อลดขนาดของภาพเพื่อการคำนวณน้ำหนักที่รวดเร็วขึ้นและปรับปรุงลักษณะทั่วไปของภาพ
ในระหว่างส่วนที่บิดเบี้ยว เครือข่ายจะเก็บคุณลักษณะที่สำคัญของภาพไว้และแยกสัญญาณรบกวนที่ไม่เกี่ยวข้องออก ตัวอย่างเช่น แบบจำลองกำลังเรียนรู้วิธีจดจำช้างจากภาพที่มีภูเขาอยู่เบื้องหลัง หากคุณใช้โครงข่ายประสาทเทียมแบบเดิม โมเดลจะกำหนดน้ำหนักให้กับพิกเซลทั้งหมด รวมถึงพิกเซลที่มาจากภูเขาซึ่งไม่จำเป็นและอาจทำให้เครือข่ายเข้าใจผิดได้
แทน Keras เครือข่ายประสาทเทียมแบบ Convolutional จะใช้เทคนิคทางคณิตศาสตร์เพื่อแยกเฉพาะพิกเซลที่เกี่ยวข้องมากที่สุด การดำเนินการทางคณิตศาสตร์นี้เรียกว่า Convolution เทคนิคนี้ช่วยให้เครือข่ายสามารถเรียนรู้คุณลักษณะที่ซับซ้อนมากขึ้นในแต่ละเลเยอร์ Convolution จะแบ่งเมทริกซ์ออกเป็นชิ้นเล็กๆ เพื่อเรียนรู้องค์ประกอบที่สำคัญที่สุดในแต่ละชิ้น
ส่วนประกอบของโครงข่ายประสาทเทียมแบบ Convolutional (ConvNet หรือ CNN)
Convnets มีสี่องค์ประกอบ
- บิด
- ไม่เป็นเชิงเส้น (ReLU)
- Pooling หรือการสุ่มตัวอย่างย่อย
- การจำแนกประเภท (เลเยอร์ที่เชื่อมต่ออย่างเต็มที่)
บิด
วัตถุประสงค์ของการบิดคือเพื่อแยกคุณสมบัติของวัตถุบนรูปภาพในเครื่อง หมายความว่าเครือข่ายจะเรียนรู้รูปแบบเฉพาะภายในรูปภาพและจะสามารถจดจำได้ทุกที่ในภาพ
การม้วนภาพคือการคูณแบบองค์ประกอบ แนวคิดนี้เข้าใจง่าย คอมพิวเตอร์จะสแกนส่วนหนึ่งของภาพ ซึ่งโดยปกติจะมีขนาด 3×3 แล้วคูณกับตัวกรอง ผลลัพธ์ของการคูณแบบองค์ประกอบเรียกว่าแผนผังคุณลักษณะ ขั้นตอนนี้จะทำซ้ำจนกว่าจะสแกนภาพทั้งหมด โปรดทราบว่าหลังจากการม้วนภาพ ขนาดของภาพจะลดลง
ด้านล่างมี URL เพื่อดูว่าการบิดทำงานอย่างไร
มีหลายช่องทางให้เลือก ด้านล่างนี้เราแสดงรายการบางช่อง คุณจะเห็นว่าตัวกรองแต่ละตัวมีวัตถุประสงค์เฉพาะ หมายเหตุในภาพด้านล่าง เคอร์เนลเป็นคำพ้องของตัวกรอง
เลขคณิตเบื้องหลังการบิด
เฟสคอนโวลูชั่นจะใช้ฟิลเตอร์กับอาร์เรย์พิกเซลขนาดเล็กภายในภาพ ฟิลเตอร์จะเคลื่อนไปตามภาพอินพุตโดยมีรูปร่างทั่วไป 3×3 หรือ 5×5 ซึ่งหมายความว่าเครือข่ายจะเลื่อนหน้าต่างเหล่านี้ไปทั่วภาพอินพุตทั้งหมดและคำนวณคอนโวลูชั่น ภาพด้านล่างแสดงการทำงานของคอนโวลูชั่น ขนาดของแพตช์คือ 3×3 และเมทริกซ์เอาต์พุตคือผลลัพธ์ของการทำงานแบบแยกองค์ประกอบระหว่างเมทริกซ์ภาพและฟิลเตอร์
คุณสังเกตเห็นว่าความกว้างและความสูงของผลลัพธ์อาจแตกต่างจากความกว้างและความสูงของอินพุต มันเกิดขึ้นเพราะเอฟเฟกต์เส้นขอบ
เอฟเฟกต์เส้นขอบ
รูปภาพมีแผนผังคุณสมบัติ 5×5 และฟิลเตอร์ 3×3 ตรงกลางมีเพียงหน้าต่างเดียวเท่านั้นที่ตัวกรองสามารถคัดกรองตารางขนาด 3×3 ได้ แผนผังคุณลักษณะเอาต์พุตจะย่อขนาดสองไทล์พร้อมกับมิติ 3×3
หากต้องการให้มิติเอาต์พุตเหมือนกับมิติอินพุต คุณต้องเพิ่มช่องว่างภายใน การเติมประกอบด้วยการเพิ่มจำนวนแถวและคอลัมน์ที่ถูกต้องในแต่ละด้านของเมทริกซ์ มันจะช่วยให้การบิดจัดกึ่งกลางพอดีกับไทล์อินพุตทุกอัน ในภาพด้านล่าง เมทริกซ์อินพุต/เอาท์พุตจะมีขนาดเท่ากันคือ 5×5
เมื่อคุณกำหนดเครือข่าย คุณลักษณะที่สับสนจะถูกควบคุมโดยพารามิเตอร์สามตัว:
- ความลึก: กำหนดจำนวนตัวกรองที่จะใช้ระหว่างการคอนโวลูชั่น ในตัวอย่างก่อนหน้านี้ คุณจะเห็นความลึก 1 ซึ่งหมายความว่าใช้ตัวกรองเพียงตัวเดียว ในกรณีส่วนใหญ่ มีตัวกรองมากกว่าหนึ่งตัว รูปภาพด้านล่างแสดงการดำเนินการที่ดำเนินการในสถานการณ์ที่มีตัวกรองสามตัว
- ก้าวย่าง:กำหนดจำนวน "การกระโดดของพิกเซล" ระหว่างสองส่วน หากก้าวเท่ากับ 1 หน้าต่างจะเคลื่อนที่ด้วยระยะแพร่กระจายของพิกเซลเท่ากับ 2 หากก้าวเท่ากับ XNUMX หน้าต่างจะกระโดด XNUMX พิกเซล หากคุณเพิ่มระยะก้าว คุณจะมีแผนที่คุณลักษณะที่เล็กลง
ตัวอย่างก้าวที่ 1
ก้าว 2
- Zero-padding:การแพดดิ้งคือการดำเนินการเพิ่มจำนวนแถวและคอลัมน์ที่สอดคล้องกันในแต่ละด้านของแผนที่ฟีเจอร์อินพุต ในกรณีนี้ เอาต์พุตจะมีมิติเดียวกันกับอินพุต
ไม่เป็นเชิงเส้น (ReLU)
เมื่อสิ้นสุดการดำเนินการคอนโวลูชั่น เอาต์พุตจะอยู่ภายใต้ฟังก์ชันการเปิดใช้งานเพื่ออนุญาตให้เกิดความไม่เชิงเส้น ฟังก์ชันการเปิดใช้งานทั่วไปสำหรับคอนโวลูชั่นคือ Relu พิกเซลทั้งหมดที่มีค่าลบจะถูกแทนที่ด้วยศูนย์
Pooling Operaการ
ขั้นตอนนี้เข้าใจง่าย วัตถุประสงค์ของการรวมกลุ่มคือเพื่อลดมิติของภาพอินพุต ขั้นตอนเหล่านี้ทำขึ้นเพื่อลดความซับซ้อนในการคำนวณของการดำเนินการ การลดมิติทำให้เครือข่ายมีน้ำหนักในการคำนวณน้อยลง จึงป้องกันไม่ให้เกิดการโอเวอร์ฟิตติ้ง
ในขั้นตอนนี้ คุณต้องกำหนดขนาดและระยะก้าว วิธีมาตรฐานในการรวมภาพอินพุตคือการใช้ค่าสูงสุดของแผนที่คุณลักษณะ ดูภาพด้านล่าง "การรวม" จะคัดกรองซับเมทริกซ์สี่ตัวของแผนที่คุณลักษณะ 4×4 และส่งกลับค่าสูงสุด การรวมจะใช้ค่าสูงสุดของอาร์เรย์ 2×2 จากนั้นย้ายหน้าต่างนี้ไปสองพิกเซล ตัวอย่างเช่น ซับเมทริกซ์แรกคือ [3,1,3,2] การรวมจะส่งคืนค่าสูงสุดซึ่งคือ 3
มีการดำเนินการรวมกลุ่มอีกอย่างหนึ่ง เช่น ค่าเฉลี่ย
การดำเนินการนี้จะลดขนาดของแผนที่คุณลักษณะอย่างจริงจัง
เลเยอร์ที่เชื่อมต่ออย่างเต็มที่
ขั้นตอนสุดท้ายประกอบด้วยการสร้างแบบดั้งเดิม โครงข่ายประสาทเทียม เหมือนที่คุณทำในบทช่วยสอนก่อนหน้านี้ คุณเชื่อมต่อเซลล์ประสาททั้งหมดจากเลเยอร์ก่อนหน้าไปยังเลเยอร์ถัดไป คุณใช้ฟังก์ชันการเปิดใช้งาน softmax เพื่อจัดประเภทหมายเลขบนรูปภาพอินพุต
สรุป:
เครือข่าย TensorFlow Convolutional Neural รวบรวมเลเยอร์ต่างๆ ก่อนทำการคาดการณ์ โครงข่ายประสาทเทียมมี:
- ชั้นที่บิดเบี้ยว
- ฟังก์ชั่นการเปิดใช้งาน Relu
- Poolinชั้นกรัม
- ชั้นที่เชื่อมต่อกันอย่างหนาแน่น
เลเยอร์คอนโวลูชั่นใช้ฟิลเตอร์ที่แตกต่างกันกับซับรีเจียนของภาพ ฟังก์ชันการเปิดใช้งาน Relu เพิ่มความไม่เป็นเชิงเส้น และเลเยอร์การรวมกลุ่มจะลดมิติของแผนที่คุณลักษณะ
เลเยอร์ทั้งหมดนี้ดึงข้อมูลสำคัญจากรูปภาพ ในที่สุด แผนที่คุณลักษณะจะถูกป้อนไปยังเลเยอร์หลักที่เชื่อมต่ออย่างสมบูรณ์ด้วยฟังก์ชัน softmax เพื่อทำการคาดการณ์
ฝึกอบรม CNN ด้วย TensorFlow
ตอนนี้คุณคุ้นเคยกับ Building Block ของ Convnet แล้ว คุณก็พร้อมที่จะสร้างมันแล้ว TensorFlow- เราจะใช้ชุดข้อมูล MNIST สำหรับการจำแนกรูปภาพของ CNN
การเตรียมข้อมูลจะเหมือนกับบทช่วยสอนก่อนหน้านี้ คุณสามารถรันโค้ดและข้ามไปยังสถาปัตยกรรมของ CNN ได้โดยตรง
คุณจะทำตามขั้นตอนด้านล่างเพื่อจัดหมวดหมู่รูปภาพโดยใช้ CNN:
ขั้นตอนที่ 1: อัปโหลดชุดข้อมูล
ขั้นตอนที่ 2: เลเยอร์อินพุต
ขั้นตอนที่ 3: เลเยอร์ Convolutional
ขั้นตอนที่ 4: Poolinชั้นกรัม
ขั้นตอนที่ 5: เลเยอร์ Convolutional ที่สองและ Poolinก. เลเยอร์
ขั้นตอนที่ 6: ชั้นหนาแน่น
ขั้นตอนที่ 7: Logit Layer
ขั้นตอนที่ 1: อัปโหลดชุดข้อมูล
ชุดข้อมูล MNIST พร้อมใช้งานกับ scikit เพื่อเรียนรู้เกี่ยวกับสิ่งนี้ URL- กรุณาดาวน์โหลดและเก็บไว้ในการดาวน์โหลด คุณสามารถอัปโหลดด้วย fetch_mldata('MNIST original')
สร้างชุดฝึก/ชุดทดสอบ
คุณต้องแบ่งชุดข้อมูลด้วย train_test_split
ปรับขนาดคุณสมบัติ
สุดท้าย คุณสามารถปรับขนาดฟีเจอร์ด้วย MinMaxScaler ดังที่แสดงในการจัดหมวดหมู่รูปภาพด้านล่างโดยใช้ตัวอย่าง TensorFlow CNN
import numpy as np
import tensorflow as tf
from sklearn.datasets import fetch_mldata
#Change USERNAME by the username of your machine
## Windows USER
mnist = fetch_mldata('C:\\Users\\USERNAME\\Downloads\\MNIST original')
## Mac User
mnist = fetch_mldata('/Users/USERNAME/Downloads/MNIST original')
print(mnist.data.shape)
print(mnist.target.shape)
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(mnist.data, mnist.target, test_size=0.2, random_state=42)
y_train = y_train.astype(int)
y_test = y_test.astype(int)
batch_size =len(X_train)
print(X_train.shape, y_train.shape,y_test.shape )
## resclae
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
# Train
X_train_scaled = scaler.fit_transform(X_train.astype(np.float64))
# test
X_test_scaled = scaler.fit_transform(X_test.astype(np.float64))
feature_columns = [tf.feature_column.numeric_column('x', shape=X_train_scaled.shape[1:])]
X_train_scaled.shape[1:]
กำหนดซีเอ็นเอ็น
CNN ใช้ตัวกรองบนพิกเซลดิบของภาพเพื่อเรียนรู้รูปแบบรายละเอียดเมื่อเปรียบเทียบกับรูปแบบทั่วไปด้วยเครือข่ายประสาทแบบดั้งเดิม ในการสร้าง CNN คุณต้องกำหนดสิ่งต่อไปนี้:
- เลเยอร์แบบหมุนวน: ใช้ตัวกรองจำนวน n ตัวกับแผนผังคุณลักษณะ หลังจากการบิด คุณต้องใช้ฟังก์ชันการเปิดใช้งาน Relu เพื่อเพิ่มความไม่เป็นเชิงเส้นให้กับเครือข่าย
- Poolinเลเยอร์ g: ขั้นตอนถัดไปหลังจากการม้วนรวมคือการลดการสุ่มตัวอย่างคุณลักษณะสูงสุด วัตถุประสงค์คือเพื่อลดมิติของแผนที่คุณลักษณะเพื่อป้องกันการโอเวอร์ฟิตติ้งและปรับปรุงความเร็วในการคำนวณ การรวมค่าสูงสุดเป็นเทคนิคทั่วไปซึ่งแบ่งแผนที่คุณลักษณะออกเป็นภูมิภาคย่อย (โดยปกติจะมีขนาด 2×2) และเก็บเฉพาะค่าสูงสุดเท่านั้น
- เลเยอร์ที่เชื่อมต่อกันอย่างสมบูรณ์: นิวรอนทั้งหมดจากเลเยอร์ก่อนหน้าจะเชื่อมต่อกับเลเยอร์ถัดไป CNN จะจัดประเภทป้ายกำกับตามคุณลักษณะจากเลเยอร์คอนโวลูชั่นและลดลงด้วยเลเยอร์การรวมกลุ่ม
สถาปัตยกรรม CNN
- Convolutional Layer: ใช้ตัวกรอง 14 5×5 (แยกภูมิภาคย่อย 5×5 พิกเซล) พร้อมฟังก์ชันการเปิดใช้งาน ReLU
- Poolinเลเยอร์ g: ดำเนินการรวมกลุ่มสูงสุดด้วยตัวกรอง 2×2 และก้าวที่ 2 (ซึ่งระบุว่าภูมิภาคที่รวมกลุ่มจะไม่ทับซ้อนกัน)
- Convolutional Layer: ใช้ตัวกรอง 36 5×5 พร้อมฟังก์ชันการเปิดใช้งาน ReLU
- Pooling เลเยอร์ #2: ทำการรวมค่าสูงสุดอีกครั้งด้วยตัวกรอง 2×2 และก้าว 2
- เซลล์ประสาท 1,764 ตัว โดยมีอัตราการทำให้เป็นมาตรฐานของการหยุดกลางคันที่ 0.4 (ความน่าจะเป็น 0.4 ที่องค์ประกอบที่กำหนดจะถูกทิ้งระหว่างการฝึก)
- เลเยอร์หนาแน่น (Logits Layer): 10 เซลล์ประสาท หนึ่งเซลล์สำหรับแต่ละคลาสเป้าหมายหลัก (0–9)
มีโมดูลที่สำคัญสามโมดูลที่ใช้ในการสร้าง CNN:
- Conv2d() สร้างเลเยอร์ Convolutional สองมิติโดยมีจำนวนตัวกรอง ขนาดเคอร์เนลตัวกรอง ช่องว่างภายใน และฟังก์ชันการเปิดใช้งานเป็นอาร์กิวเมนต์
- max_pooling2d() สร้างเลเยอร์การรวมกลุ่มสองมิติโดยใช้อัลกอริทึม max-pooling
- หนาแน่น(). สร้างชั้นที่หนาแน่นด้วยชั้นและหน่วยที่ซ่อนอยู่
คุณจะกำหนดฟังก์ชันเพื่อสร้าง CNN เรามาดูรายละเอียดวิธีการสร้างแต่ละ Building Block ก่อนรวมทุกอย่างเข้าด้วยกันในฟังก์ชัน
ขั้นตอนที่ 2: เลเยอร์อินพุต
def cnn_model_fn(features, labels, mode):
input_layer = tf.reshape(tensor = features["x"],shape =[-1, 28, 28, 1])
คุณต้องกำหนดเทนเซอร์ด้วยรูปร่างของข้อมูล เพื่อสิ่งนั้น คุณสามารถใช้โมดูล tf.reshape ในโมดูลนี้ คุณจะต้องประกาศเทนเซอร์เพื่อปรับรูปร่างและรูปร่างของเทนเซอร์ อาร์กิวเมนต์แรกคือคุณลักษณะของข้อมูล ซึ่งกำหนดไว้ในอาร์กิวเมนต์ของฟังก์ชัน
รูปภาพมีส่วนสูง ความกว้าง และช่องสัญญาณ ชุดข้อมูล MNIST เป็นภาพเดี่ยวขนาด 28×28 เราตั้งค่าขนาดแบทช์เป็น -1 ในอาร์กิวเมนต์รูปร่างเพื่อให้มีรูปร่างตามคุณสมบัติ [“x”] ข้อดีคือทำให้ไฮเปอร์พารามิเตอร์ขนาดแบตช์ปรับแต่งได้ หากตั้งค่าขนาดแบตช์เป็น 7 เทนเซอร์จะป้อนค่า 5,488 (28*28*7)
ขั้นตอนที่ 3: เลเยอร์ Convolutional
# first Convolutional Layer
conv1 = tf.layers.conv2d(
inputs=input_layer,
filters=14,
kernel_size=[5, 5],
padding="same",
activation=tf.nn.relu)
เลเยอร์ Convolutional แรกมีตัวกรอง 14 ตัวที่มีขนาดเคอร์เนล 5 × 5 โดยมีช่องว่างภายในเท่ากัน การเติมที่เหมือนกันหมายความว่าทั้งเทนเซอร์เอาท์พุตและเทนเซอร์อินพุตควรมีความสูงและความกว้างเท่ากัน Tensorflow จะเพิ่มศูนย์ให้กับแถวและคอลัมน์เพื่อให้แน่ใจว่ามีขนาดเท่ากัน
คุณใช้ฟังก์ชันการเปิดใช้งาน Relu ขนาดผลงานจะเป็น [28, 28, 14]
ขั้นตอนที่ 4: Poolinชั้นกรัม
ขั้นตอนถัดไปหลังจากการม้วนข้อมูลคือการคำนวณแบบรวมกลุ่ม การคำนวณแบบรวมกลุ่มจะลดมิติของข้อมูล คุณสามารถใช้โมดูล max_pooling2d ที่มีขนาด 2×2 และ stride เท่ากับ 2 โดยใช้เลเยอร์ก่อนหน้าเป็นอินพุต ขนาดเอาต์พุตจะเป็น [batch_size, 14, 14, 14]
# first Pooling Layer pool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2)
ขั้นตอนที่ 5: เลเยอร์ Convolutional ที่สองและ Poolinก. เลเยอร์
เลเยอร์ Convolutional ที่สองมีตัวกรอง 32 ตัว โดยมีขนาดเอาต์พุตเท่ากับ [batch_size, 14, 14, 32] เลเยอร์การรวมกลุ่มจะมีขนาดเท่ากับก่อนหน้านี้ และรูปร่างเอาต์พุตคือ [batch_size, 14, 14, 18]
conv2 = tf.layers.conv2d(
inputs=pool1,
filters=36,
kernel_size=[5, 5],
padding="same",
activation=tf.nn.relu)
pool2 = tf.layers.max_pooling2d(inputs=conv2, pool_size=[2, 2], strides=2)
ขั้นตอนที่ 6: ชั้นหนาแน่น
จากนั้น คุณจะต้องกำหนดเลเยอร์ที่เชื่อมต่อโดยสมบูรณ์ แผนผังคุณลักษณะจะต้องถูกทำให้เรียบก่อนจึงจะเชื่อมต่อกับเลเยอร์ที่มีความหนาแน่นสูงได้ คุณสามารถใช้การปรับรูปร่างโมดูลด้วยขนาด 7*7*36
ชั้นหนาแน่นจะเชื่อมต่อเซลล์ประสาท 1764 ตัว คุณเพิ่มฟังก์ชันการเปิดใช้งาน Relu นอกจากนี้ คุณยังเพิ่มเงื่อนไขการทำให้เป็นมาตรฐานของการออกจากกลางคันด้วยอัตรา 0.3 ซึ่งหมายความว่า 30 เปอร์เซ็นต์ของน้ำหนักจะถูกตั้งค่าเป็น 0 โปรดทราบว่าการออกจากกลางคันจะเกิดขึ้นในระหว่างระยะการฝึกเท่านั้น ฟังก์ชัน cnn_model_fn มีโหมดอาร์กิวเมนต์เพื่อประกาศว่าโมเดลจำเป็นต้องได้รับการฝึกฝนหรือประเมินตามที่แสดงในตัวอย่างการจัดหมวดหมู่รูปภาพ CNN ด้านล่าง TensorFlow
pool2_flat = tf.reshape(pool2, [-1, 7 * 7 * 36])
dense = tf.layers.dense(inputs=pool2_flat, units=7 * 7 * 36, activation=tf.nn.relu)
dropout = tf.layers.dropout(
inputs=dense, rate=0.3, training=mode == tf.estimator.ModeKeys.TRAIN)
ขั้นตอนที่ 7: Logit Layer
สุดท้ายในตัวอย่างการจัดหมวดหมู่ภาพ TensorFlow คุณสามารถกำหนดเลเยอร์สุดท้ายด้วยการทำนายของแบบจำลอง รูปร่างผลลัพธ์จะเท่ากับขนาดแบทช์และ 10 ซึ่งเป็นจำนวนรูปภาพทั้งหมด
# Logits Layer logits = tf.layers.dense(inputs=dropout, units=10)
คุณสามารถสร้างพจนานุกรมที่มีคลาสและความน่าจะเป็นของแต่ละคลาสได้ โมดูล tf.argmax() พร้อมส่งคืนค่าสูงสุดหากเลเยอร์ logit ฟังก์ชัน softmax จะคืนค่าความน่าจะเป็นของแต่ละคลาส
predictions = {
# Generate predictions
"classes": tf.argmax(input=logits, axis=1),
"probabilities": tf.nn.softmax(logits, name="softmax_tensor") }
คุณต้องการส่งกลับการทำนายพจนานุกรมเมื่อตั้งค่าโหมดเป็นการคาดการณ์เท่านั้น คุณเพิ่มรหัสนี้เพื่อแสดงการคาดการณ์
if mode == tf.estimator.ModeKeys.PREDICT:
return tf.estimator.EstimatorSpec(mode=mode, predictions=predictions)
ขั้นตอนต่อไปคือการคำนวณการสูญเสียของโมเดล ในบทช่วยสอนสุดท้าย คุณจะได้เรียนรู้ว่าฟังก์ชันการสูญเสียสำหรับโมเดลมัลติคลาสคือเอนโทรปีแบบไขว้ การสูญเสียสามารถคำนวณได้ง่ายๆ ด้วยโค้ดต่อไปนี้:
# Calculate Loss (for both TRAIN and EVAL modes) loss = tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits)
ขั้นตอนสุดท้ายของตัวอย่าง TensorFlow CNN คือการปรับโมเดลให้เหมาะสม นั่นคือการค้นหาค่าน้ำหนักที่ดีที่สุด เพื่อทำเช่นนั้น คุณจะใช้เครื่องมือเพิ่มประสิทธิภาพการไล่ระดับสีที่มีอัตราการเรียนรู้ 0.001 วัตถุประสงค์คือเพื่อลดการสูญเสียให้น้อยที่สุด
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001)
train_op = optimizer.minimize(
loss=loss,
global_step=tf.train.get_global_step())
คุณทำ CNN เสร็จแล้ว อย่างไรก็ตาม คุณต้องการแสดงหน่วยวัดประสิทธิภาพระหว่างโหมดการประเมิน ตัวชี้วัดประสิทธิภาพสำหรับโมเดลหลายคลาสคือตัวชี้วัดความแม่นยำ Tensorflow ติดตั้งโมดูลที่มีความแม่นยำพร้อมอาร์กิวเมนต์ 2 รายการ ป้ายกำกับ และค่าที่คาดการณ์ไว้
eval_metric_ops = {
"accuracy": tf.metrics.accuracy(labels=labels, predictions=predictions["classes"])}
return tf.estimator.EstimatorSpec(mode=mode, loss=loss, eval_metric_ops=eval_metric_ops)
แค่นั้นแหละ. คุณสร้าง CNN แรกและพร้อมที่จะรวมทุกอย่างไว้ในฟังก์ชันเพื่อใช้ในการฝึกและประเมินโมเดล
def cnn_model_fn(features, labels, mode):
"""Model function for CNN."""
# Input Layer
input_layer = tf.reshape(features["x"], [-1, 28, 28, 1])
# Convolutional Layer
conv1 = tf.layers.conv2d(
inputs=input_layer,
filters=32,
kernel_size=[5, 5],
padding="same",
activation=tf.nn.relu)
# Pooling Layer
pool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2)
# Convolutional Layer #2 and Pooling Layer
conv2 = tf.layers.conv2d(
inputs=pool1,
filters=36,
kernel_size=[5, 5],
padding="same",
activation=tf.nn.relu)
pool2 = tf.layers.max_pooling2d(inputs=conv2, pool_size=[2, 2], strides=2)
# Dense Layer
pool2_flat = tf.reshape(pool2, [-1, 7 * 7 * 36])
dense = tf.layers.dense(inputs=pool2_flat, units=7 * 7 * 36, activation=tf.nn.relu)
dropout = tf.layers.dropout(
inputs=dense, rate=0.4, training=mode == tf.estimator.ModeKeys.TRAIN)
# Logits Layer
logits = tf.layers.dense(inputs=dropout, units=10)
predictions = {
# Generate predictions (for PREDICT and EVAL mode)
"classes": tf.argmax(input=logits, axis=1),
"probabilities": tf.nn.softmax(logits, name="softmax_tensor")
}
if mode == tf.estimator.ModeKeys.PREDICT:
return tf.estimator.EstimatorSpec(mode=mode, predictions=predictions)
# Calculate Loss
loss = tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits)
# Configure the Training Op (for TRAIN mode)
if mode == tf.estimator.ModeKeys.TRAIN:
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001)
train_op = optimizer.minimize(
loss=loss,
global_step=tf.train.get_global_step())
return tf.estimator.EstimatorSpec(mode=mode, loss=loss, train_op=train_op)
# Add evaluation metrics Evaluation mode
eval_metric_ops = {
"accuracy": tf.metrics.accuracy(
labels=labels, predictions=predictions["classes"])}
return tf.estimator.EstimatorSpec(
mode=mode, loss=loss, eval_metric_ops=eval_metric_ops)
ขั้นตอนด้านล่างนี้เหมือนกับบทช่วยสอนก่อนหน้านี้
ก่อนอื่น คุณกำหนดตัวประมาณด้วยโมเดล CNN สำหรับการจัดหมวดหมู่ภาพ
# Create the Estimator
mnist_classifier = tf.estimator.Estimator(
model_fn=cnn_model_fn, model_dir="train/mnist_convnet_model")
CNN ใช้เวลาหลายครั้งในการฝึก ดังนั้น คุณจึงสร้าง Logging hook เพื่อจัดเก็บค่าของเลเยอร์ softmax ทุกๆ 50 รอบ
# Set up logging for predictions
tensors_to_log = {"probabilities": "softmax_tensor"}
logging_hook = tf.train.LoggingTensorHook(tensors=tensors_to_log, every_n_iter=50)
คุณพร้อมที่จะประมาณแบบจำลองแล้ว คุณตั้งค่าขนาดชุดงานเป็น 100 และสับเปลี่ยนข้อมูล โปรดทราบว่าเรากำหนดขั้นตอนการฝึกไว้ที่ 16.000 ซึ่งอาจใช้เวลานานมากในการฝึก จงอดทน
# Train the model
train_input_fn = tf.estimator.inputs.numpy_input_fn(
x={"x": X_train_scaled},
y=y_train,
batch_size=100,
num_epochs=None,
shuffle=True)
mnist_classifier.train(
input_fn=train_input_fn,
steps=16000,
hooks=[logging_hook])
เมื่อโมเดลได้รับการฝึกฝนแล้ว คุณสามารถประเมินและพิมพ์ผลลัพธ์ได้
# Evaluate the model and print results
eval_input_fn = tf.estimator.inputs.numpy_input_fn(
x={"x": X_test_scaled},
y=y_test,
num_epochs=1,
shuffle=False)
eval_results = mnist_classifier.evaluate(input_fn=eval_input_fn)
print(eval_results)
INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Starting evaluation at 2018-08-05-12:52:41
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from train/mnist_convnet_model/model.ckpt-15652
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Finished evaluation at 2018-08-05-12:52:56
INFO:tensorflow:Saving dict for global step 15652: accuracy = 0.9589286, global_step = 15652, loss = 0.13894269
{'accuracy': 0.9689286, 'loss': 0.13894269, 'global_step': 15652}
ด้วยสถาปัตยกรรมปัจจุบัน คุณจะได้รับความแม่นยำ 97% คุณสามารถเปลี่ยนสถาปัตยกรรม ขนาดชุด และจำนวนการวนซ้ำเพื่อปรับปรุงความแม่นยำได้ เครือข่ายประสาทเทียม CNN มีประสิทธิภาพดีกว่า ANN หรือการถดถอยแบบลอจิสติกส์มาก ในบทช่วยสอนเกี่ยวกับเครือข่ายประสาทเทียม คุณได้รับความแม่นยำ 96% ซึ่งต่ำกว่า CNN ประสิทธิภาพของ CNN นั้นน่าประทับใจด้วยภาพที่ใหญ่ขึ้น เซ็ตทั้งในด้านการคำนวณความเร็วและความแม่นยำ
สรุป
เครือข่ายประสาทเทียมแบบ Convolutional ทำงานได้ดีมากในการประเมินภาพ สถาปัตยกรรมประเภทนี้ใช้เป็นหลักในการจดจำวัตถุจากรูปภาพหรือวิดีโอ
ในการสร้าง TensorFlow CNN คุณต้องทำตามเจ็ดขั้นตอน:
ขั้นตอนที่ 1: อัพโหลดชุดข้อมูล:
ชุดข้อมูล MNIST พร้อมใช้งานพร้อมกับ scikit เพื่อเรียนรู้ กรุณาดาวน์โหลดและเก็บไว้ในการดาวน์โหลด คุณสามารถอัปโหลดด้วย fetch_mldata('MNIST original')
ขั้นตอนที่ 2: เลเยอร์อินพุต:
ขั้นตอนนี้จะปรับเปลี่ยนรูปร่างของข้อมูล รูปร่างจะเท่ากับรากที่สองของจำนวนพิกเซล ตัวอย่างเช่น หากรูปภาพมี 156 พิกเซล รูปร่างก็จะเป็น 26×26 คุณต้องระบุว่ารูปภาพมีสีหรือไม่ หากใช่ รูปร่างจะมีค่า 3 โดยที่ 3 สำหรับ RGB จะเป็น 1 มิฉะนั้นจะเป็น XNUMX
input_layer = tf.reshape(tensor = features["x"],shape =[-1, 28, 28, 1])
ขั้นตอนที่ 3: ชั้น Convolution
ถัดไปคุณต้องสร้างเลเยอร์แบบบิดเบี้ยว คุณใช้ตัวกรองที่แตกต่างกันเพื่อให้เครือข่ายเรียนรู้คุณลักษณะที่สำคัญ คุณระบุขนาดของเคอร์เนลและจำนวนตัวกรอง
conv1 = tf.layers.conv2d(
inputs=input_layer,
filters=14,
kernel_size=[5, 5],
padding="same",
activation=tf.nn.relu)
ขั้นตอนที่ 4: Poolinชั้นกรัม
ในขั้นตอนที่สาม คุณจะเพิ่มเลเยอร์การรวมกลุ่ม เลเยอร์นี้จะลดขนาดของอินพุต โดยจะทำเช่นนั้นโดยใช้ค่าสูงสุดของเมทริกซ์ย่อย ตัวอย่างเช่น หากเมทริกซ์ย่อยคือ [3,1,3,2] การรวมกลุ่มจะคืนค่าสูงสุด ซึ่งคือ 3
pool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2)
ขั้นตอนที่ 5: เพิ่ม Convolutional Layer และ Poolinก. เลเยอร์
ในขั้นตอนนี้ คุณสามารถเพิ่มเลเยอร์ Conv. และเลเยอร์ Pooling ได้มากเท่าที่ต้องการ Google ใช้สถาปัตยกรรมที่มีเลเยอร์ Conv. มากกว่า 20 เลเยอร์
ขั้นตอนที่ 6: ชั้นหนาแน่น
ขั้นตอนที่ 6 ทำให้เลเยอร์ก่อนหน้าเรียบเพื่อสร้างเลเยอร์ที่เชื่อมต่อกันอย่างสมบูรณ์ ในขั้นตอนนี้ คุณสามารถใช้ฟังก์ชันการเปิดใช้งานอื่นและเพิ่มเอฟเฟกต์การออกกลางคันได้
pool2_flat = tf.reshape(pool2, [-1, 7 * 7 * 36])
dense = tf.layers.dense(inputs=pool2_flat, units=7 * 7 * 36, activation=tf.nn.relu)
dropout = tf.layers.dropout(
inputs=dense, rate=0.3, training=mode == tf.estimator.ModeKeys.TRAIN)
ขั้นตอนที่ 7: เลเยอร์ Logit
ขั้นตอนสุดท้ายคือการทำนาย
logits = tf.layers.dense(inputs=dropout, units=10)











