โครงข่ายประสาทเทียมสำหรับการจำแนกประเภทด้วยเทนเซอร์โฟลว์

โหนดต้นทาง: 1570297

บทความนี้เผยแพร่โดยเป็นส่วนหนึ่งของไฟล์ Blogathon วิทยาศาสตร์ข้อมูล

ในบทความนี้ ฉันจะสร้างโมเดลโครงข่ายประสาทเทียมด้วย TensorFlow เพื่อแก้ปัญหาการจำแนกประเภท มาสำรวจร่วมกันว่าเราจะจัดการกับปัญหาการจำแนกประเภทใน Tensorflow ได้อย่างไร แต่ก่อนอื่น ฉันต้องการให้แน่ใจว่าเราสามารถตอบคำถามเหล่านี้ได้:

คือ โครงข่ายประสาทเทียม?

วัตถุประสงค์หลักของโครงข่ายประสาทเทียมคือการพยายามค้นหาความสัมพันธ์ระหว่างคุณลักษณะในชุดข้อมูล และประกอบด้วยชุดของอัลกอริทึมที่เลียนแบบการทำงานของสมองมนุษย์ “เซลล์ประสาท” ในโครงข่ายประสาทเทียมเป็นฟังก์ชันทางคณิตศาสตร์ที่รวบรวมและจัดประเภทข้อมูลตามสถาปัตยกรรมเฉพาะ

การจำแนกประเภทคืออะไร?

ปัญหาการจำแนกประเภทเกี่ยวข้องกับการทำนายว่าบางสิ่งเป็นของชั้นหนึ่งหรือไม่ กล่าวอีกนัยหนึ่ง ขณะที่ทำอย่างนั้น เราพยายามที่จะเห็นบางสิ่งบางอย่างไม่ทางใดก็ทางหนึ่ง

ประเภทของการจำแนกประเภท

  • สมมติว่าคุณต้องการทำนายว่าบุคคลนั้นเป็นโรคเบาหวานหรือไม่ หากคุณกำลังเผชิญสถานการณ์แบบนี้ มีความเป็นไปได้สองทางใช่ไหม? ที่เรียกว่า การจำแนกไบนารี
  • สมมติว่าคุณต้องการระบุว่ารูปถ่ายเป็นของเล่น คน หรือแมว ใช่ไหม นี้เรียกว่า การจำแนกหลายชั้น เพราะมีทางเลือกมากกว่าสองทาง
  • สมมติว่าคุณต้องการตัดสินใจว่าควรกำหนดหมวดหมู่ใดให้กับบทความ ถ้าอย่างนั้นจะเรียกว่า การจำแนกหลายฉลากเนื่องจากบทความหนึ่งสามารถกำหนดหมวดหมู่ได้มากกว่าหนึ่งหมวดหมู่ ลองใช้คำอธิบายของเราผ่านบทความนี้ เราอาจกำหนดหมวดหมู่ เช่น "การเรียนรู้เชิงลึก TensorFlow การจำแนกประเภท" ฯลฯ ให้กับบทความนี้

ตอนนี้ เราสามารถก้าวไปข้างหน้าได้เพราะเรามีความเข้าใจร่วมกันเกี่ยวกับปัญหาที่เราจะดำเนินการแก้ไข ดังนั้นถึงเวลาสำหรับการเข้ารหัส ฉันหวังว่าคุณจะเขียนมันกับฉันเพราะวิธีเดียวที่จะทำให้ดีขึ้น ทำผิดพลาดน้อยลงคือเขียนโค้ดให้มากขึ้น

เรากำลังเริ่มต้นด้วยการนำเข้าไลบรารีที่เราจะใช้:

นำเข้า numpy เป็น np นำเข้าแพนด้าเป็น pd นำเข้า matplotlib.pyplot เป็น plt นำเข้าเทนเซอร์โฟลว์เป็น tf พิมพ์ (tf.__version__)

การสร้างชุดข้อมูล

ถึงเวลาสร้างชุดข้อมูลเพื่อทำงาน:

จาก sklearn.datasets นำเข้า make_circles ตัวอย่าง = 1000 X, y = make_circles (ตัวอย่าง, เสียง = 0.03, random_state = 42)

เราได้สร้างข้อมูลแล้ว มาดูข้อมูลเพิ่มเติมกัน

พิมพ์ (X >>[[ 0.75424625 0.23148074] [-0.75615888 0.15325888] [-0.81539193 0.17328203] ... [-0.13690036 -0.81001183] [ 0.67036156 -0.76750154] [ 0.28105665 0.96382443]]
พิมพ์(y) >> [1 1 1 1 0 1 1 1 1 0]

โอเค เราได้เห็นชุดข้อมูลของเราในรายละเอียดมากขึ้นแล้ว แต่เรายังไม่รู้อะไรเกี่ยวกับมันเลยใช่ไหม นั่นคือเหตุผลที่ขั้นตอนสำคัญอย่างหนึ่งคือการเป็นหนึ่งเดียวกับข้อมูล และการแสดงภาพเป็นวิธีที่ดีที่สุดในการทำเช่นนี้

วงกลม = pd.DataFrame({ 'X0' : X[:, 0], 'X1' : X[:, 1], 'label' : y}) circle.head()
โครงข่ายประสาทเทียมสำหรับการจำแนกประเภทด้วยหัวข้อมูลเทนเซอร์โฟลว์

มีคำถามหนึ่งเกิดขึ้น เรากำลังจัดการกับฉลากประเภทใด?

circle.label.value_counts() >> 1 500 0 500 ชื่อ: label, dtype: int64

ดูเหมือนว่าเรากำลังเผชิญกับ ปัญหาการจำแนกเลขฐานสองเนื่องจากเรามี 2 ป้ายกำกับ (0 และ 1)

plt.scatter(X[:,0], X[:,1], c = y, cmap = plt.cm.RdYlBu)
โครงข่ายประสาทเทียมสำหรับการจำแนกประเภทด้วยพล็อตกระจายเทนเซอร์โฟลว์

ดังที่ได้กล่าวไว้ข้างต้น วิธีที่ดีที่สุดในการทำให้ข้อมูลเป็นหนึ่งเดียวคือการสร้างภาพข้อมูล ตอนนี้พล็อตบอกตัวเองว่าเราต้องสร้างแบบจำลองประเภทใด เราจะสร้างแบบจำลองที่สามารถแยกแยะจุดสีน้ำเงินจากจุดสีแดงได้

ก่อนสร้างโมเดลโครงข่ายประสาทเทียม เราต้องตรวจสอบรูปร่างของคุณสมบัติอินพุตและเอาต์พุตของเรา พวกเขาจะต้องเหมือนกัน!

พิมพ์(X.รูปร่าง y.รูปร่าง) พิมพ์(เลน(X), เลน(y)) >> (1000, 2) (1000,) 1000 1000

เรามีค่าเท่ากันสำหรับแต่ละคุณลักษณะ แต่รูปร่างของ X แตกต่างกันอย่างไร ทำไม ลองตรวจสอบดู

X[0], y[0] >> (อาร์เรย์([0.75424625, 0.23148074]), 1)

ตกลง เรามีฟีเจอร์ 2 X สำหรับ 1 ปี เพื่อให้เราก้าวต่อไปได้โดยไม่มีปัญหา

ขั้นตอนในการสร้างแบบจำลองโครงข่ายประสาทเทียมสำหรับการจำแนกประเภทด้วยเทนเซอร์โฟลว์

ใน TensorFlow มีขั้นตอนคงที่สำหรับการสร้างแบบจำลอง:

  • การสร้างแบบจำลอง – รวมเลเยอร์ของ Neural Network โดยใช้ Functional หรือ Sequential API
  • กำลังรวบรวมโมเดล – กำหนดวิธีการวัดประสิทธิภาพของแบบจำลอง และวิธีปรับปรุง (ฟังก์ชันการสูญเสียและตัวเพิ่มประสิทธิภาพ)
  • การติดตั้งโหมดl – ให้ตัวแบบค้นหารูปแบบในข้อมูล

เราจะใช้ Sequential API เอาล่ะ มาเริ่มกันเลย

tf.สุ่ม.set_seed(42)
model_1 = tf.keras.Sequential([tf.keras.layers.Dense(1)])

model_1.compile (สูญเสีย = tf.keras.losses.BinaryCrossentropy (),

#เราใช้ไบนารีเป็นฟังก์ชันการสูญเสียเพราะเรากำลังทำงานกับ 2 คลาส

 เครื่องมือเพิ่มประสิทธิภาพ = tf.keras.optimizers.SGD(), #SGD ย่อมาจาก Stochastic Gradient Descent metrics = ['accuracy']) model_1.fit(X, y, epochs = 5)
>> Epoch 1/5 32/32 [==============================] - 1 วินาที 1ms/ขั้นตอน - ขาดทุน: 2.8544 - ความแม่นยำ: 0.4600 Epoch 2/5 32/32 [==============================] - 0s 2ms/ขั้นตอน - การสูญเสีย : 0.7131 - ความแม่นยำ: 0.5430 Epoch 3/5 32/32 [==============================] - 0s 2ms/ขั้นตอน - การสูญเสีย: 0.6973 - ความแม่นยำ: 0.5090 Epoch 4/5 32/32 [==============================] - 0s 2ms / ขั้นตอน - การสูญเสีย: 0.6950 - ความแม่นยำ: 0.5010 Epoch 5/5 32/32 [==============================] - 0s 1ms/ขั้นตอน - สูญเสีย: 0.6942 - ความแม่นยำ: 0.4830

ความแม่นยำของโมเดลอยู่ที่ประมาณ 50% ซึ่งโดยทั่วไปหมายถึงโมเดลนั้นแค่คาดเดา เรามาลองฝึกกันให้นานขึ้น

model_1.fit(X, y, epochs = 200, verbose = 0) #เราตั้งค่า verbose = 0 เพื่อลบขั้นตอนการฝึกอบรม ) model_1.evaluate(X, y)
>> 32/32 [==============================] - 0s 1ms/ขั้นตอน - การสูญเสีย: 0.6935 - ความแม่นยำ: 0.5000 [0.6934829950332642, 0.5]

แม้จะผ่านไป 200 ยุค ก็ยังคงทำงานเหมือนคาดเดา ขั้นตอนต่อไปคือการเพิ่มเลเยอร์และการฝึกให้นานขึ้น

tf.สุ่ม.set_seed(42)
model_2 = tf.keras.Sequential([ tf.keras.layers.Dense(1), tf.keras.layers.Dense(1) ]) model_2.compile(loss = tf.keras.losses.BinaryCrossentropy(), ตัวเพิ่มประสิทธิภาพ = tf.keras.optimizers.SGD(), metrics = ['accuracy']) model_2.fit(X, y, epochs = 100, verbose = 0)
 model_2.ประเมิน(X,y)
>> 32/32 [==============================] - 0s 1ms/ขั้นตอน - การสูญเสีย: 0.6933 - ความแม่นยำ: 0.5000 [0.6933314800262451, 0.5]

ยังคงไม่มีการเปลี่ยนแปลงแม้แต่น้อย ดูเหมือนว่ามีบางอย่างผิดปกติ

การปรับปรุงโครงข่ายประสาทเทียมสำหรับแบบจำลองการจำแนกประเภทด้วยเทนเซอร์โฟลว์

มีหลายวิธีในการปรับปรุงแบบจำลองในขั้นตอนต่างๆ:

  • การสร้างแบบจำลอง – เพิ่มเลเยอร์เพิ่มจำนวนหน่วยที่ซ่อนอยู่ (เซลล์ประสาท) เปลี่ยนฟังก์ชั่นการเปิดใช้งานของแต่ละเลเยอร์
  • การรวบรวมแบบจำลอง – ลองใช้ฟังก์ชันการปรับให้เหมาะสมที่แตกต่างกัน เช่น ใช้ Adam() แทน SGD()
  • การติดตั้งรุ่น – เราสามารถเพิ่มจำนวนยุคได้

มาลองกัน เพิ่มเซลล์ประสาท และพยายาม อาดัม เพิ่มประสิทธิภาพ

tf.สุ่ม.set_seed(42)
model_3 = tf.keras.Sequential([ tf.keras.layers.Dense(100), # เพิ่ม 100 เซลล์ประสาทที่หนาแน่น tf.keras.layers.Dense(10), # เพิ่มอีกชั้นหนึ่งด้วย 10 เซลล์ประสาท tf.keras.layers.Dense (1) ]) model_3.compile(loss=tf.keras.losses.BinaryCrossentropy(), optimizer=tf.keras.optimizers.Adam(), metrics=['accuracy']) model_3.fit(X, y, epochs =100, ละเอียด=0)
model_3.evaluate(X,y) >> 32/32 [==============================] - 0s 1ms/ขั้นตอน - การสูญเสีย: 0.6980 - ความแม่นยำ: 0.5080 [0.6980254650115967, 0.5080000162124634]

ยังไม่ดีขึ้น! ลองนึกภาพข้อมูลเพื่อดูว่าเกิดอะไรขึ้น

เห็นภาพโมเดลโครงข่ายประสาทเทียม

เพื่อให้เห็นภาพการคาดการณ์ของแบบจำลองของเรา เราจะสร้างฟังก์ชัน plot_decision_boundary() ซึ่ง:

  • ใช้โมเดล คุณสมบัติ และป้ายกำกับที่ได้รับการฝึกอบรม
  • สร้าง meshgrid ของค่า X ต่างๆ
  • ทำการทำนายข้ามเมชกริด
  • พล็อตคำทำนายด้วยเส้น

หมายเหตุ  ฟังก์ชันนี้ได้รับการดัดแปลงมาจากแหล่งข้อมูลสองแห่ง:

ซีเอส231n ทำด้วยพื้นฐาน ML 

def plot_decision_boundary(model, X, y): # กำหนดขอบเขตแกนของพล็อตและสร้าง meshgrid x_min, x_max = X[:, 0].min() - 0.1, X[:, 0].max() + 0.1 y_min, y_max = X[:, 1].min() - 0.1, X[:, 1].max() + 0.1 xx, yy = np.meshgrid(np.linspace(x_min, x_max, 100), np .linspace(y_min, y_max, 100)) # สร้างค่า X (เราจะทำนายสิ่งเหล่านี้ทั้งหมด) x_in = np.c_[xx.ravel(), yy.ravel()] # ทำการคาดคะเนโดยใช้การฝึกอบรม model y_pred = model.predict(x_in) # ตรวจสอบ multi-class
 ถ้า len(y_pred[0]) > 1: print("ทำการจัดประเภทหลายคลาส...") # เราต้องปรับรูปแบบการคาดการณ์ของเราเพื่อให้พร้อมสำหรับการลงจุด y_pred = np.argmax(y_pred, axis=1).reshape( xx.shape) อื่นๆ: print("ทำ binary classifcation...") y_pred = np.round(y_pred).reshape(xx.shape) # พล็อตกรอบการตัดสินใจ plt.contourf(xx, yy, y_pred, cmap=plt. cm.RdYlBu, อัลฟา=0.7) plt.scatter(X[:, 0], X[:, 1], c=y, s=40, cmap=plt.cm.RdYlBu) plt.xlim(xx.min( ), xx.max()) plt.ylim(yy.min(), yy.max()) plot_decision_boundary(model_3, X, y)
ขอบเขตการตัดสินใจ

นี่มัน! การแสดงภาพอีกครั้งแสดงให้เราเห็นว่ามีอะไรผิดปกติและต้องทำอย่างไร? โมเดลของเรากำลังพยายามวาดเส้นตรงผ่านข้อมูล แต่ข้อมูลของเราไม่สามารถแยกด้วยเส้นตรงได้ มีบางอย่างที่ขาดหายไปในปัญหาการจัดหมวดหมู่ของเราหรือไม่? มันคืออะไร?

นี่ไม่ใช่เชิงเส้น! เราต้องการเส้นไม่เชิงเส้นบางเส้น ตอนนี้คุณอาจจะสับสน ถ้าคุณคิดว่าคุณไม่เคยเห็นฟังก์ชันแบบนั้นมาก่อน คุณคิดผิดเพราะคุณมี มาดูกันเลย การแสดงภาพทำงานได้ดีขึ้นเสมอ!

มีฟังก์ชั่นการเปิดใช้งานบางอย่างใน Neural Network ที่เราสามารถใช้ได้เช่น เรลู, sigmoid. มาสร้างสรรค์กันหน่อย ของเล่นเทนเซอร์ และตรวจสอบการทำงานเหล่านั้น

ฟังก์ชันการเปิดใช้งานสำหรับโครงข่ายประสาทเทียม

A = tf.cast(tf.range(-12,12), tf.float32) พิมพ์ (A) >> tf.Tensor( [-12. -11. -10. -9. -8. -7. - 6. -5. -4. -3. -2. -1. 0. 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.] รูปร่าง=(24,), dtype=float32)

มาดูกันว่าของเล่นเทนเซอร์ของเราหน้าตาเป็นอย่างไร?

plt.พล็อต(A)
ฟังก์ชันการเปิดใช้งานสำหรับโครงข่ายประสาทเทียม

หน้าตาเป็นแบบนี้นี่เอง! 

ตอนนี้ มาสร้างฟังก์ชันการเปิดใช้งานใหม่เพื่อดูว่ามันทำอะไรกับเทนเซอร์ของเรา

ซิกมอยด์:

def sigmoid(x): คืนค่า 1 / (1 + tf.exp(-x)) sigmoid(A) plt.plot(sigmoid(A))
ฟังก์ชันซิกมอยด์

เส้นไม่ตรง!

เรลู:

ตอนนี้เรามาดูกันว่า ReLu ทำอะไรได้บ้าง? Relu เปลี่ยนค่าลบทั้งหมดเป็น 0 และค่าบวกจะเหมือนเดิม

def relu(x): คืนค่า tf.maximum(0,x) plt.plot(relu(A))
เรลู

ไม่ตรงอีกเส้น!

ตอนนี้คุณได้เห็นฟังก์ชันการเปิดใช้งานแบบไม่เชิงเส้นแล้ว และนี่คือสิ่งที่จะได้ผลสำหรับเรา โมเดลไม่สามารถเรียนรู้อะไรในชุดข้อมูลที่ไม่ใช่เชิงเส้นพร้อมฟังก์ชันการเปิดใช้งานเชิงเส้นได้! หากได้เรียนรู้สิ่งนี้ ก็ถึงเวลาแบ่งข้อมูลของเราออกเป็นชุดฝึกอบรมและทดสอบ และสร้างแบบจำลองที่แข็งแกร่ง

X_train, y_train = X[:800], y[:800] X_test, y_test = X[800:], y[800:] X_train.shape, X_test.shape >>((800, 2), (200, 2 ))

 

เยี่ยมมาก ตอนนี้เรามีชุดการฝึกและการทดสอบแล้ว มาสร้างแบบจำลองข้อมูลการฝึกและประเมินว่าแบบจำลองของเราได้เรียนรู้อะไรบ้างในชุดทดสอบ

tf.สุ่ม.set_seed(42)
model_4 = tf.keras.Sequential([ tf.keras.layers.Dense(4, การเปิดใช้งาน = 'relu'), #เราอาจจะทำให้มันถูกต้อง "tf.keras.activations.relu" ด้วย tf.keras.layers.Dense (4 , การเปิดใช้งาน = 'relu'), tf.keras.layers.Dense (1, การเปิดใช้งาน = 'sigmoid') ]) model_4.compile (การสูญเสีย = tf.keras.losses.binary_crossentropy, เครื่องมือเพิ่มประสิทธิภาพ = tf.keras.optimizers.Adam ( lr = 0.01), เมตริก = ['ความแม่นยำ']) model_4.fit(X_train, y_train, epochs = 25, verbose = 0)

ประเมินแบบจำลอง

การสูญเสีย ความแม่นยำ = model_4.evaluate(X_test, y_test) พิมพ์ (f' การสูญเสียแบบจำลองในชุดทดสอบ: {loss}') พิมพ์ (f' ความถูกต้องของแบบจำลองในชุดทดสอบ: {100*ความแม่นยำ}')
>> 7/7 [==============================] - 0s 2ms/ขั้นตอน - สูญเสีย: 0.1247 - ความแม่นยำ: 1.0000 การสูญเสียแบบจำลองในชุดทดสอบ: 0.1246885135769844 ความแม่นยำของแบบจำลองในชุดทดสอบ: 100.0

โว้ว! แม่นยำ 100%! มาดูผลลัพธ์นี้กันดีกว่า

plt.figure(figsize=(12, 6)) plt.subplot(1, 2, 1) plt.title("Train") plot_decision_boundary(model_4, X=X_train, y=y_train) plt.subplot(1, 2, 2) plt.title("ทดสอบ") plot_decision_boundary(model_4, X=X_test, y=y_test) plt.show()
โครงข่ายประสาทเทียมแบบไบนารีสำหรับการจำแนกประเภทด้วยเทนเซอร์โฟลว์

ด้วยการปรับแต่งเพียงเล็กน้อย แบบจำลองของเรากำลังทำนายวงกลมสีน้ำเงินและสีแดงได้เกือบสมบูรณ์แบบ

สรุป

ลองมาดูสั้น ๆ ว่าเรากำลังพูดถึงอะไรในบทความนี้ เรามาดูวิธีเข้าหางานการจำแนกประเภทใน Neural Network ด้วย TensorFlow ร่วมกัน เราสร้างแบบจำลอง 3 แบบด้วยวิธีแรกที่นึกได้ และด้วยความช่วยเหลือของการแสดงภาพ เราจึงตระหนักว่าเราผิดตรงไหน เราสำรวจความเป็นเส้นตรง ไม่เชิงเส้น และสุดท้าย เราจึงสามารถสร้างแบบจำลองทั่วไปได้ สิ่งที่ฉันพยายามแสดงด้วยรหัสเหล่านี้ทั้งหมดและขั้นตอนที่ฉันติดตามคือไม่มีสิ่งใดที่ถูกต้องหรือคงที่ 100 เปอร์เซ็นต์ ทุกอย่างยังคงเปลี่ยนแปลงทุกวัน หากต้องการเดาว่าปัญหาใดที่คุณน่าจะเผชิญในข้อมูลประเภทใด และเพื่อดูว่าชุดค่าผสมใดนำไปสู่ผลลัพธ์ที่ดีกว่า สิ่งที่คุณต้องทำคือเขียนโค้ดจำนวนมากขึ้นและได้รับประสบการณ์

ฉันหวังว่าบทความนี้จะเป็นประโยชน์กับคุณเล็กน้อยและมีส่วนสนับสนุน

สื่อที่แสดงในบทความนี้ไม่ใช่ของ Analytics Vidhya และใช้ดุลยพินิจของผู้เขียน

ที่มา: https://www.analyticsvidhya.com/blog/2021/11/neural-network-for-classification-with-tensorflow/

ประทับเวลา:

เพิ่มเติมจาก การวิเคราะห์ วิทยา