การรู้จำหมายเลขการเรียนรู้ของเครื่อง - จากศูนย์ถึงแอปพลิเคชัน

เผยแพร่แล้ว: 2022-03-11

แมชชีนเลิร์นนิง คอมพิวเตอร์วิทัศน์ การสร้าง API ที่ทรงพลัง และการสร้าง UI ที่สวยงามเป็นสาขาที่น่าตื่นเต้นที่ได้เห็นนวัตกรรมมากมาย

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

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

เพื่อความเรียบง่าย เราจะใช้เทคโนโลยีที่ได้รับความนิยมและเรียนรู้ง่ายที่สุด ส่วนการเรียนรู้ของเครื่องจะใช้ Python สำหรับแอปพลิเคชันส่วนหลัง ในส่วนของการโต้ตอบของแอป เราจะดำเนินการผ่านไลบรารี JavaScript ที่ไม่ต้องการการแนะนำ: React

แมชชีนเลิร์นนิงเพื่อเดาตัวเลข

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

กระบวนการจดจำภาพของเราประกอบด้วยสามขั้นตอน:

  • รับภาพหลักในการฝึกซ้อม
  • ฝึกระบบเดาตัวเลขผ่านข้อมูลการฝึก
  • ทดสอบระบบด้วยข้อมูลใหม่/ไม่รู้จัก

สิ่งแวดล้อม

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

มาติดตั้งด้วยคำสั่งเทอร์มินัลต่อไปนี้:

 python3 -m venv virtualenv source virtualenv/bin/activate

แบบฝึก

ก่อนที่เราจะเริ่มเขียนโค้ด เราต้องเลือก "ครู" ที่เหมาะสมสำหรับเครื่องของเรา โดยปกติ ผู้เชี่ยวชาญด้านวิทยาศาสตร์ข้อมูลจะลองใช้แบบจำลองต่างๆ ก่อนเลือกแบบจำลองที่ดีที่สุด เราจะข้ามโมเดลขั้นสูงที่ต้องใช้ทักษะมาก และดำเนินการอัลกอริธึมเพื่อนบ้านที่ใกล้ที่สุด k

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

ภาพ: ตัวอย่างข้อมูลแมชชีนเลิร์นนิ่งที่จัดเรียงบนเครื่องบิน

ในการตรวจสอบประเภทของ Green Dot เราควรตรวจสอบประเภทของเพื่อนบ้านที่ใกล้ที่สุด k โดยที่ k คือชุดอาร์กิวเมนต์ เมื่อพิจารณาจากภาพด้านบน หาก k เท่ากับ 1, 2, 3 หรือ 4 การเดาจะเป็น สามเหลี่ยมสีดำ เนื่องจาก k เพื่อนบ้านที่ใกล้ที่สุดของจุดสีเขียวส่วนใหญ่เป็นสามเหลี่ยมสีดำ หากเราเพิ่ม k เป็น 5 วัตถุส่วนใหญ่จะเป็นสี่เหลี่ยมสีน้ำเงิน ดังนั้นการเดาจะเป็น Blue Square

มีการพึ่งพาบางอย่างที่จำเป็นในการสร้างโมเดลการเรียนรู้ของเครื่องของเรา:

  • sklearn.neighbors.KNeighborsClassifier เป็นตัวแยกประเภทที่เราจะใช้
  • sklearn.model_selection.train_test_split เป็นฟังก์ชันที่จะช่วยเราแบ่งข้อมูลออกเป็นข้อมูลการฝึกและข้อมูลที่ใช้ตรวจสอบความถูกต้องของแบบจำลอง
  • sklearn.model_selection.cross_val_score เป็นฟังก์ชันสำหรับให้คะแนนความถูกต้องของแบบจำลอง ยิ่งค่าสูง ความถูกต้องยิ่งดี
  • sklearn.metrics.classification_report เป็นฟังก์ชันที่จะแสดงรายงานทางสถิติของการคาดเดาของแบบจำลอง
  • sklearn.datasets เป็นแพ็คเกจที่ใช้ในการรับข้อมูลสำหรับการฝึกอบรม (รูปภาพของตัวเลข)
  • numpy เป็นแพ็คเกจที่ใช้กันอย่างแพร่หลายในด้านวิทยาศาสตร์ เนื่องจากเป็นวิธีที่มีประสิทธิผลและสะดวกสบายในการจัดการโครงสร้างข้อมูลหลายมิติใน Python
  • matplotlib.pyplot เป็นแพ็คเกจที่ใช้ในการแสดงข้อมูลเป็นภาพ

เริ่มต้นด้วยการติดตั้งและนำเข้าทั้งหมด:

 pip install sklearn numpy matplotlib scipy from sklearn.datasets import load_digits from sklearn.neighbors import KNeighborsClassifier from sklearn.model_selection import train_test_split, cross_val_score import numpy as np import matplotlib.pyplot as plt

ตอนนี้ เราต้องโหลดฐานข้อมูล MNIST MNIST เป็นชุดข้อมูลคลาสสิกของรูปภาพที่เขียนด้วยลายมือซึ่งใช้งานโดยสามเณรหลายพันคนในสาขาการเรียนรู้ของเครื่อง:

 digits = load_digits()

เมื่อดึงข้อมูลและพร้อมแล้ว เราสามารถย้ายไปยังขั้นตอนถัดไปของการแยกข้อมูลออกเป็นสองส่วน: การฝึกอบรม และ การทดสอบ

เราจะใช้ข้อมูล 75% เพื่อฝึกแบบจำลองของเราให้เดาตัวเลข และเราจะใช้ข้อมูลที่เหลือเพื่อทดสอบความถูกต้องของแบบจำลอง:

 (X_train, X_test, y_train, y_test) = train_test_split( digits.data, digits.target, test_size=0.25, random_state=42 )

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

มาดูกันว่าทำไมการพิจารณาช่วงของค่า k จึงจำเป็น และสิ่งนี้จะช่วยปรับปรุงความแม่นยำของแบบจำลองของเราได้อย่างไร:

 ks = np.arange(2, 10) scores = [] for k in ks: model = KNeighborsClassifier(n_neighbors=k) score = cross_val_score(model, X_train, y_train, cv=5) score.mean() scores.append(score.mean()) plt.plot(scores, ks) plt.xlabel('accuracy') plt.ylabel('k') plt.show()

การดำเนินการโค้ดนี้จะแสดงแผนภาพต่อไปนี้ซึ่งอธิบายความถูกต้องของอัลกอริทึมด้วยค่า k ที่แตกต่างกัน

ภาพ: พล็อตที่ใช้ในการทดสอบความถูกต้องของอัลกอริทึมด้วยค่า k ที่ต่างกัน

อย่างที่คุณเห็น ค่า k เท่ากับ 3 ช่วยให้มั่นใจถึงความแม่นยำสูงสุดสำหรับโมเดลและชุดข้อมูลของเรา

การใช้ Flask เพื่อสร้าง API

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

เราจะเริ่มต้นด้วยการติดตั้ง Flask และการพึ่งพาที่เกี่ยวข้องกับการประมวลผลภาพในสภาพแวดล้อมเสมือน:

 pip install Flask Pillow scikit-image

เมื่อการติดตั้งเสร็จสิ้น เราจะย้ายไปยังการสร้างไฟล์จุดเข้าใช้งานของแอป:

 touch app.py

เนื้อหาของไฟล์จะมีลักษณะดังนี้:

 import os from flask import Flask from views import PredictDigitView, IndexView app = Flask(__name__) app.add_url_rule( '/api/predict', view_func=PredictDigitView.as_view('predict_digit'), methods=['POST'] ) app.add_url_rule( '/', view_func=IndexView.as_view('index'), methods=['GET'] ) if __name__ == 'main': port = int(os.environ.get("PORT", 5000)) app.run(host='0.0.0.0', port=port)

คุณจะได้รับข้อผิดพลาดแจ้ง PredictDigitView และ IndexView ขั้นตอนต่อไปคือการสร้างไฟล์ที่จะเริ่มต้นมุมมองเหล่านี้:

 from flask import render_template, request, Response from flask.views import MethodView, View from flask.views import View from repo import ClassifierRepo from services import PredictDigitService from settings import CLASSIFIER_STORAGE class IndexView(View): def dispatch_request(self): return render_template('index.html') class PredictDigitView(MethodView): def post(self): repo = ClassifierRepo(CLASSIFIER_STORAGE) service = PredictDigitService(repo) image_data_uri = request.json['image'] prediction = service.handle(image_data_uri) return Response(str(prediction).encode(), status=200)

อีกครั้ง เราจะพบข้อผิดพลาดเกี่ยวกับการนำเข้าที่ยังไม่ได้แก้ไข แพ็คเกจ Views อาศัยสามไฟล์ที่เรายังไม่มี:

  • การตั้งค่า
  • Repo
  • บริการ

เราจะนำไปใช้ทีละรายการ

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

เนื่องจากเป็นวิธีง่ายๆ ในการปรับปรุงประสิทธิภาพของแอป แทนที่จะฝึกตัวแยกประเภททุกครั้งที่คุณได้รับคำขอ เราจะจัดเก็บเวอร์ชันที่เตรียมไว้ของตัวแยกประเภท ซึ่งช่วยให้ทำงานนอกกรอบได้:

 import os BASE_DIR = os.getcwd() CLASSIFIER_STORAGE = os.path.join(BASE_DIR, 'storage/classifier.txt')

กลไกสำหรับการตั้งค่า — รับตัวแยกประเภท — จะเริ่มต้นในแพ็คเกจถัดไปในรายการของเรา Repo เป็นคลาสที่มีสองวิธีในการดึงและอัปเดตตัวแยกประเภทที่ผ่านการฝึกอบรมโดยใช้โมดูล pickle ในตัวของ Python:

 import pickle class ClassifierRepo: def __init__(self, storage): self.storage = storage def get(self): with open(self.storage, 'wb') as out: try: classifier_str = out.read() if classifier_str != '': return pickle.loads(classifier_str) else: return None except Exception: return None def update(self, classifier): with open(self.storage, 'wb') as in_: pickle.dump(classifier, in_)

เราใกล้จะเสร็จสิ้น API ของเราแล้ว ตอนนี้มันขาดเฉพาะโมดูล บริการ จุดประสงค์ของมันคืออะไร?

  • รับลักษณนามที่ผ่านการฝึกอบรมจากการจัดเก็บ
  • เปลี่ยนภาพที่ส่งผ่านจาก UI เป็นรูปแบบที่ตัวแยกประเภทเข้าใจ
  • คำนวณการทำนายด้วยภาพที่จัดรูปแบบผ่านตัวแยกประเภท
  • กลับคำทำนาย

ลองโค้ดอัลกอริทึมนี้:

 from sklearn.datasets import load_digits from classifier import ClassifierFactory from image_processing import process_image class PredictDigitService: def __init__(self, repo): self.repo = repo def handle(self, image_data_uri): classifier = self.repo.get() if classifier is None: digits = load_digits() classifier = ClassifierFactory.create_with_fit( digits.data, digits.target ) self.repo.update(classifier) x = process_image(image_data_uri) if x is None: return 0 prediction = classifier.predict(x)[0] return prediction

ที่นี่คุณจะเห็นว่า PredictDigitService มีการพึ่งพาสองรายการ: ClassifierFactory และ process_image

เราจะเริ่มต้นด้วยการสร้างคลาสเพื่อสร้างและฝึกโมเดลของเรา:

 from sklearn.model_selection import train_test_split from sklearn.neighbors import KNeighborsClassifier class ClassifierFactory: @staticmethod def create_with_fit(data, target): model = KNeighborsClassifier(n_neighbors=3) model.fit(data, target) return model

API พร้อมสำหรับการดำเนินการ ตอนนี้เราสามารถไปยังขั้นตอนการประมวลผลภาพได้

การประมวลผลภาพ

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

Image alt: การแปลงรูปภาพที่วาดให้เป็นรูปแบบแมชชีนเลิร์นนิง

มานำเข้าตัวช่วยเพื่อบรรลุเป้าหมายนั้นกันเถอะ:

 import numpy as np from skimage import exposure import base64 from PIL import Image, ImageOps, ImageChops from io import BytesIO

เราสามารถแบ่งการเปลี่ยนแปลงออกเป็นหกส่วนที่แตกต่างกัน:

1. แทนที่พื้นหลังโปร่งใสด้วยสี

Image alt: การแทนที่พื้นหลังบนรูปภาพตัวอย่าง

 def replace_transparent_background(image): image_arr = np.array(image) if len(image_arr.shape) == 2: return image alpha1 = 0 r2, g2, b2, alpha2 = 255, 255, 255, 255 red, green, blue, alpha = image_arr[:, :, 0], image_arr[:, :, 1], image_arr[:, :, 2], image_arr[:, :, 3] mask = (alpha == alpha1) image_arr[:, :, :4][mask] = [r2, g2, b2, alpha2] return Image.fromarray(image_arr)

2. ตัดขอบที่เปิดอยู่

รูปภาพ: การตัดขอบของรูปภาพตัวอย่าง

 def trim_borders(image): bg = Image.new(image.mode, image.size, image.getpixel((0,0))) diff = ImageChops.difference(image, bg) diff = ImageChops.add(diff, diff, 2.0, -100) bbox = diff.getbbox() if bbox: return image.crop(bbox) return image

3. เพิ่มเส้นขอบที่มีขนาดเท่ากัน

รูปภาพ: การเพิ่มเส้นขอบของค่าที่ตั้งไว้ล่วงหน้าและขนาดเท่ากับรูปภาพตัวอย่าง

 def pad_image(image): return ImageOps.expand(image, border=30, fill='#fff')

4. แปลงภาพเป็นโหมดสีเทา

 def to_grayscale(image): return image.convert('L')

5. สลับสี

ภาพ: การกลับสีของภาพตัวอย่าง

 def invert_colors(image): return ImageOps.invert(image)

6. ปรับขนาดภาพเป็นรูปแบบ 8x8

รูปภาพ: การปรับขนาดรูปภาพตัวอย่างเป็นรูปแบบ 8x8

 def resize_image(image): return image.resize((8, 8), Image.LINEAR)

ตอนนี้คุณสามารถทดสอบแอพ เรียกใช้แอปพลิเคชันและป้อนคำสั่งด้านล่างเพื่อส่งคำขอด้วยอิมเมจ iStock นี้ไปยัง API:

รูปภาพ: รูปภาพสต็อกของหมายเลขแปดที่วาดด้วยมือ

 export FLASK_APP=app flask run
 curl "http://localhost:5000/api/predict" -X "POST" -H "Content-Type: application/json" -d "{\"image\": \"data:image/png;base64,$(curl "https://media.istockphoto.com/vectors/number-eight-8-hand-drawn-with-dry-brush-vector-id484207302?k=6&m=484207302&s=170667a&w=0&h=s3YANDyuLS8u2so-uJbMA2uW6fYyyRkabc1a6OTq7iI=" | base64)\"}" -i

คุณควรเห็นผลลัพธ์ต่อไปนี้:

 HTTP/1.1 100 Continue HTTP/1.0 200 OK Content-Type: text/html; charset=utf-8 Content-Length: 1 Server: Werkzeug/0.14.1 Python/3.6.3 Date: Tue, 27 Mar 2018 07:02:08 GMT 8

ภาพตัวอย่างแสดงหมายเลข 8 และแอปของเราระบุเป็นตัวเลขดังกล่าวอย่างถูกต้อง

การสร้างบานหน้าต่างการวาดผ่าน React

ในการบูตแอปพลิเคชันฟรอนท์เอนด์อย่างรวดเร็ว เราจะใช้ต้นแบบของ CRA:

 create-react-app frontend cd frontend

หลังจากตั้งค่าสถานที่ทำงานแล้ว เรายังต้องพึ่งพาการวาดตัวเลขด้วย แพ็คเกจ react-sketch ตรงกับความต้องการของเราอย่างสมบูรณ์:

 npm i react-sketch

แอปพลิเคชันมีองค์ประกอบเดียวเท่านั้น เราสามารถแบ่งองค์ประกอบนี้ออกเป็นสองส่วน: ตรรกะ และ มุมมอง

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

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

เมื่อผู้ใช้คลิกที่ รีเซ็ต ภาพสเก็ตช์จะล้าง:

 import React, { useRef, useState } from "react"; import { makePrediction } from "./api"; const App = () => { const sketchRef = useRef(null); const [error, setError] = useState(); const [prediction, setPrediction] = useState(); const handleSubmit = () => { const image = sketchRef.current.toDataURL(); setPrediction(undefined); setError(undefined); makePrediction(image).then(setPrediction).catch(setError); }; const handleClear = (e) => sketchRef.current.clear(); return null }

ตรรกะก็เพียงพอแล้ว ตอนนี้เราสามารถเพิ่มอินเทอร์เฟซแบบภาพได้:

 import React, { useRef, useState } from "react"; import { SketchField, Tools } from "react-sketch"; import { makePrediction } from "./api"; import logo from "./logo.svg"; import "./App.css"; const pixels = (count) => `${count}px`; const percents = (count) => `${count}%`; const MAIN_CONTAINER_WIDTH_PX = 200; const MAIN_CONTAINER_HEIGHT = 100; const MAIN_CONTAINER_STYLE = { width: pixels(MAIN_CONTAINER_WIDTH_PX), height: percents(MAIN_CONTAINER_HEIGHT), margin: "0 auto", }; const SKETCH_CONTAINER_STYLE = { border: "1px solid black", width: pixels(MAIN_CONTAINER_WIDTH_PX - 2), height: pixels(MAIN_CONTAINER_WIDTH_PX - 2), backgroundColor: "white", }; const App = () => { const sketchRef = useRef(null); const [error, setError] = useState(); const [prediction, setPrediction] = useState(); const handleSubmit = () => { const image = sketchRef.current.toDataURL(); setPrediction(undefined); setError(undefined); makePrediction(image).then(setPrediction).catch(setError); }; const handleClear = (e) => sketchRef.current.clear(); return ( <div className="App" style={MAIN_CONTAINER_STYLE}> <div> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <h1 className="App-title">Draw a digit</h1> </header> <div style={SKETCH_CONTAINER_STYLE}> <SketchField ref={sketchRef} width="100%" height="100%" tool={Tools.Pencil} imageFormat="jpg" lineColor="#111" lineWidth={10} /> </div> {prediction && <h3>Predicted value is: {prediction}</h3>} <button onClick={handleClear}>Clear</button> <button onClick={handleSubmit}>Guess the number</button> {error && <p style={{ color: "red" }}>Something went wrong</p>} </div> </div> ); }; export default App;

คอมโพเนนต์พร้อมแล้ว ทดสอบโดยดำเนินการและไปที่ localhost:3000 หลังจาก:

 npm run start

แอปพลิเคชันสาธิตมีให้ที่นี่ คุณยังสามารถเรียกดูซอร์สโค้ดบน GitHub

ห่อ

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

ภาพ: แอนิเมชั่นแสดงแอปที่สรุปผลซึ่งระบุตัวเลขที่เขียนด้วยลายมือ

ในกระบวนการนี้ เราได้ฝึกฝนทักษะของเราในสี่สาขา:

  • การเรียนรู้ของเครื่อง
  • การพัฒนาส่วนหลัง
  • การประมวลผลภาพ
  • การพัฒนาส่วนหน้า

ไม่มีปัญหากรณีการใช้งานซอฟต์แวร์ที่สามารถจดจำตัวเลขที่เขียนด้วยลายมือได้ตั้งแต่ซอฟต์แวร์การศึกษาและการบริหารไปจนถึงบริการไปรษณีย์และการเงิน

ดังนั้น ฉันหวังว่าบทความนี้จะกระตุ้นให้คุณพัฒนาความสามารถในการเรียนรู้ของเครื่อง การประมวลผลภาพ การพัฒนาส่วนหน้าและส่วนหลัง และใช้ทักษะเหล่านั้นในการออกแบบแอปพลิเคชันที่ยอดเยี่ยมและมีประโยชน์

หากคุณต้องการขยายความรู้เกี่ยวกับแมชชีนเลิร์นนิงและการประมวลผลภาพ คุณอาจต้องการดูบทแนะนำ Adversarial Machine Learning ของเรา