Menggunakan VGG untuk pengecaman muka dan jantina

Mary-Kate Olsen
Lepaskan: 2024-11-06 10:45:03
asal
982 orang telah melayarinya

Using VGGfor face and gender recognition

Cara membina projek Python pengecaman wajah dan jantina menggunakan pembelajaran mendalam dan VGG16.

Apakah pembelajaran mendalam?

Pembelajaran mendalam ialah subkategori pembelajaran mesin, rangkaian saraf dengan tiga atau lebih lapisan. Rangkaian saraf ini cuba mensimulasikan tingkah laku otak manusia dengan belajar daripada sejumlah besar data. Walaupun rangkaian saraf dengan satu lapisan masih boleh membuat ramalan anggaran, lapisan tersembunyi tambahan boleh membantu mengoptimumkan dan memperhalusi untuk ketepatan.

Pembelajaran mendalam meningkatkan automasi dengan melaksanakan tugas tanpa campur tangan manusia. Pembelajaran mendalam boleh didapati dalam pembantu digital, alat kawalan jauh TV berdaya suara, pengesanan penipuan kad kredit dan kereta pandu sendiri.

Membina projek Python

** Lihat kod penuh di GitHub: https://github.com/alexiacismaru/face-recognition

Muat turun Set Data Wajah VGG16 dan fail XML Haar Cascade yang digunakan untuk pengesanan muka yang akan digunakan untuk prapemprosesan dalam tugas pengecaman muka.

faceCascade = cv2.CascadeClassifier(os.path.join(base_path, "haarcascade_frontal_face_default.xml")) # haar cascade detects faces in images

vgg_face_dataset_url = "http://www.robots.ox.ac.uk/~vgg/data/vgg_face/vgg_face_dataset.tar.gz"

with request.urlopen(vgg_face_dataset_url) as r, open(os.path.join(base_path, "vgg_face_dataset.tar.gz"), 'wb') as f:
  f.write(r.read())

# extract VGG dataset
with tarfile.open(os.path.join(base_path, "vgg_face_dataset.tar.gz")) as f:
  f.extractall(os.path.join(base_path))

# download Haar Cascade for face detection
trained_haarcascade_url = "https://raw.githubusercontent.com/opencv/opencv/master/data/haarcascades/haarcascade_frontalface_default.xml"
with request.urlopen(trained_haarcascade_url) as r, open(os.path.join(base_path, "haarcascade_frontalface_default.xml"), 'wb') as f:
    f.write(r.read())
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Muat dan proses secara terpilih beberapa imej untuk set subjek yang dipratentukan daripada Set Data Wajah VGG.

# populate the list with the files of the celebrities that will be used for face recognition
all_subjects = [subject for subject in sorted(os.listdir(os.path.join(base_path, "vgg_face_dataset", "files"))) if subject.startswith("Jesse_Eisenberg") or subject.startswith("Sarah_Hyland") or subject.startswith("Michael_Cera") or subject.startswith("Mila_Kunis") and subject.endswith(".txt")]

# define number of subjects and how many pictures to extract
nb_subjects = 4
nb_images_per_subject = 40
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Lelar melalui fail setiap subjek dengan membuka fail teks yang dikaitkan dengan subjek dan membaca kandungannya. Setiap baris dalam fail ini mengandungi URL ke imej. Untuk setiap URL (yang menghala ke imej), kod cuba memuatkan imej menggunakan urllib dan menukarnya menjadi tatasusunan NumPy.

images = []

for subject in all_subjects[:nb_subjects]:
  with open(os.path.join(base_path, "vgg_face_dataset", "files", subject), 'r') as f:
    lines = f.readlines()

  images_ = []
  for line in lines:
    url = line[line.find("http://"): line.find(".jpg") + 4]

    try:
      res = request.urlopen(url)
      img = np.asarray(bytearray(res.read()), dtype="uint8")
      # convert the image data into a format suitable for OpenCV
      # images are colored 
      img = cv2.imdecode(img, cv2.IMREAD_COLOR)
      h, w = img.shape[:2]
      images_.append(img)
      cv2_imshow(cv2.resize(img, (w // 5, h // 5)))

    except:
      pass

    # check if the required number of images has been reached
    if len(images_) == nb_images_per_subject:
      # add the list of images to the main images list and move to the next subject
      images.append(images_)
      break
Salin selepas log masuk
Salin selepas log masuk

Pengesanan muka disediakan

Using VGGfor face and gender recognition

  1. Cari satu atau lebih wajah dalam imej dan masukkan ke dalam kotak.
  2. Pastikan wajah konsisten dengan pangkalan data, seperti geometri dan fotometrik.
  3. Ekstrak ciri dari muka yang boleh digunakan untuk tugas pengecaman.
  4. Padankan wajah dengan satu atau lebih wajah yang dikenali dalam pangkalan data yang disediakan.
# create arrays for all 4 celebrities
jesse_images = []
michael_images = []
mila_images = []
sarah_images = []

faceCascade = cv2.CascadeClassifier(os.path.join(base_path, "haarcascade_frontalface_default.xml"))

# iterate over the subjects
for subject, images_ in zip(all_subjects, images):

  # create a grayscale copy to simplify the image and reduce computation
  for img in images_:
    img_ = img.copy()
    img_gray = cv2.cvtColor(img_, cv2.COLOR_BGR2GRAY)
    faces = faceCascade.detectMultiScale(
        img_gray,
        scaleFactor=1.2,
        minNeighbors=5,
        minSize=(30, 30),
        flags=cv2.CASCADE_SCALE_IMAGE
    )
    print("Found {} face(s)!".format(len(faces)))

    for (x, y, w, h) in faces:
        cv2.rectangle(img_, (x, y), (x+w, y+h), (0, 255, 0), 10)

    h, w = img_.shape[:2]
    resized_img = cv2.resize(img_, (224, 224))
    cv2_imshow(resized_img)

    if "Jesse_Eisenberg" in subject:
        jesse_images.append(resized_img)
    elif "Michael_Cera" in subject:
        michael_images.append(resized_img)
    elif "Mila_Kunis" in subject:
        mila_images.append(resized_img)
    elif "Sarah_Hyland" in subject:
        sarah_images.append(resized_img)
Salin selepas log masuk
Salin selepas log masuk

Kaedah detectMultiScale mengecam muka dalam imej. Ia kemudian mengembalikan koordinat segi empat tepat di mana ia percaya wajah terletak. Untuk setiap muka, segi empat tepat dilukis di sekelilingnya dalam imej, menunjukkan lokasi wajah itu. Setiap imej diubah saiz kepada 224x224 piksel.

Pisah set data kepada set latihan dan pengesahan:

  • Set latihan digunakan untuk melatih model pembelajaran mesin. Ia digunakan untuk mempelajari corak, ciri dan hubungan dalam data. Model melaraskan parameternya untuk meminimumkan ralat dalam ramalan atau klasifikasi yang dibuat pada data latihan.
  • Set pengesahan menilai prestasi model pada set data baharu. Ini membantu dalam menyemak sejauh mana model membuat generalisasi kepada data yang tidak kelihatan. Set pengesahan hendaklah set bebas yang tidak digunakan semasa latihan model. Mencampurkan/menggunakan maklumat daripada set pengesahan semasa latihan boleh membawa kepada keputusan yang condong.
faceCascade = cv2.CascadeClassifier(os.path.join(base_path, "haarcascade_frontal_face_default.xml")) # haar cascade detects faces in images

vgg_face_dataset_url = "http://www.robots.ox.ac.uk/~vgg/data/vgg_face/vgg_face_dataset.tar.gz"

with request.urlopen(vgg_face_dataset_url) as r, open(os.path.join(base_path, "vgg_face_dataset.tar.gz"), 'wb') as f:
  f.write(r.read())

# extract VGG dataset
with tarfile.open(os.path.join(base_path, "vgg_face_dataset.tar.gz")) as f:
  f.extractall(os.path.join(base_path))

# download Haar Cascade for face detection
trained_haarcascade_url = "https://raw.githubusercontent.com/opencv/opencv/master/data/haarcascades/haarcascade_frontalface_default.xml"
with request.urlopen(trained_haarcascade_url) as r, open(os.path.join(base_path, "haarcascade_frontalface_default.xml"), 'wb') as f:
    f.write(r.read())
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Pembesaran Data

Ketepatan model pembelajaran mendalam bergantung pada kualiti, kuantiti dan makna kontekstual data latihan. Ini adalah salah satu cabaran yang paling biasa dalam membina model pembelajaran mendalam dan ia boleh menelan kos dan memakan masa. Syarikat menggunakan penambahan data untuk mengurangkan pergantungan pada contoh latihan untuk membina model berketepatan tinggi dengan cepat.

Penambahan data bermaksud meningkatkan jumlah data secara buatan dengan menjana titik data baharu daripada data sedia ada. Ini termasuk menambahkan perubahan kecil pada data atau menggunakan model pembelajaran mesin untuk menjana titik data baharu dalam ruang terpendam data asal untuk menguatkan set data.

Sintetik mewakili data yang dijana secara buatan tanpa menggunakan imej dunia sebenar dan ia dihasilkan oleh Generative Adversarial Networks.

Ditambah terbit daripada imej asal dengan beberapa jenis transformasi geometri kecil (seperti terbalik, terjemahan, putaran atau penambahan bunyi) untuk meningkatkan kepelbagaian set latihan.

# populate the list with the files of the celebrities that will be used for face recognition
all_subjects = [subject for subject in sorted(os.listdir(os.path.join(base_path, "vgg_face_dataset", "files"))) if subject.startswith("Jesse_Eisenberg") or subject.startswith("Sarah_Hyland") or subject.startswith("Michael_Cera") or subject.startswith("Mila_Kunis") and subject.endswith(".txt")]

# define number of subjects and how many pictures to extract
nb_subjects = 4
nb_images_per_subject = 40
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Pembesaran data meningkatkan prestasi model ML melalui set data yang lebih pelbagai dan mengurangkan kos operasi yang berkaitan dengan pengumpulan data:

  • Selak Kiri-Kanan: Imej terbalik secara rawak secara mendatar dengan kebarangkalian 0.7. Ini mensimulasikan variasi disebabkan oleh orientasi subjek yang berbeza dalam imej.
  • Putaran: Imej diputar sedikit (sehingga 10 darjah dalam kedua-dua arah) dengan kebarangkalian 0.7. Ini menambahkan kebolehubahan pada set data dengan mensimulasikan pose kepala yang berbeza.
  • Penukaran Skala Kelabu: Dengan kebarangkalian 0.1, imej ditukar kepada skala kelabu. Ini memastikan model boleh memproses dan belajar daripada imej tanpa mengira maklumat warnanya.
  • Pensampelan: Kaedah sampel(50) menjana 50 imej tambahan daripada set asal. Ini mengembangkan set data, menyediakan lebih banyak data untuk model untuk dipelajari.

Melaksanakan model VGG16

VGG16 ialah rangkaian saraf konvolusi yang digunakan secara meluas untuk pengecaman imej. Ia dianggap sebagai salah satu seni bina model penglihatan komputer terbaik. Ia terdiri daripada 16 lapisan neuron buatan yang memproses imej secara berperingkat untuk meningkatkan ketepatan. Dalam VGG16, "VGG" merujuk kepada Kumpulan Geometri Visual Universiti Oxford, manakala "16" merujuk kepada 16 lapisan berwajaran rangkaian.

VGG16 digunakan untuk pengecaman imej dan pengelasan imej baharu. Versi rangkaian VGG16 pra-latihan dilatih pada lebih satu juta imej daripada pangkalan data visual ImageNet. VGG16 boleh digunakan untuk menentukan sama ada imej mengandungi item tertentu, haiwan, tumbuhan dan banyak lagi.

Seni bina VGG16

Using VGGfor face and gender recognition

Terdapat 13 lapisan konvolusi, lima lapisan Max Pooling dan tiga lapisan Padat. Ini menghasilkan 21 lapisan dengan 16 pemberat, bermakna ia mempunyai 16 lapisan parameter yang boleh dipelajari. VGG16 mengambil saiz tensor input sebagai 224x244. Model ini memfokuskan pada mempunyai lapisan lilitan penapis 3x3 dengan langkah 1. Ia sentiasa menggunakan padding yang sama dengan lapisan maxpool penapis 2x2 langkah 2.

Lapisan Penukaran-1 mempunyai 64 penapis, Penukaran-2 mempunyai 128 penapis, Penukaran-3 mempunyai 256 penapis, Penukaran 4 dan Penukaran 5 mempunyai 512 penapis dan tiga lapisan bersambung sepenuhnya di mana dua lapisan pertama mempunyai 4096 saluran setiap satu, yang ketiga melaksanakan klasifikasi ILSVRC 1000 hala dan mengandungi 1000 saluran (satu untuk setiap kelas). Lapisan terakhir ialah lapisan maksimum lembut.

Mula menyediakan model asas.

faceCascade = cv2.CascadeClassifier(os.path.join(base_path, "haarcascade_frontal_face_default.xml")) # haar cascade detects faces in images

vgg_face_dataset_url = "http://www.robots.ox.ac.uk/~vgg/data/vgg_face/vgg_face_dataset.tar.gz"

with request.urlopen(vgg_face_dataset_url) as r, open(os.path.join(base_path, "vgg_face_dataset.tar.gz"), 'wb') as f:
  f.write(r.read())

# extract VGG dataset
with tarfile.open(os.path.join(base_path, "vgg_face_dataset.tar.gz")) as f:
  f.extractall(os.path.join(base_path))

# download Haar Cascade for face detection
trained_haarcascade_url = "https://raw.githubusercontent.com/opencv/opencv/master/data/haarcascades/haarcascade_frontalface_default.xml"
with request.urlopen(trained_haarcascade_url) as r, open(os.path.join(base_path, "haarcascade_frontalface_default.xml"), 'wb') as f:
    f.write(r.read())
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Untuk memastikan model akan mengklasifikasikan imej dengan betul, kita perlu memanjangkan model dengan lapisan tambahan.

# populate the list with the files of the celebrities that will be used for face recognition
all_subjects = [subject for subject in sorted(os.listdir(os.path.join(base_path, "vgg_face_dataset", "files"))) if subject.startswith("Jesse_Eisenberg") or subject.startswith("Sarah_Hyland") or subject.startswith("Michael_Cera") or subject.startswith("Mila_Kunis") and subject.endswith(".txt")]

# define number of subjects and how many pictures to extract
nb_subjects = 4
nb_images_per_subject = 40
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Lapisan 2D Penggabungan Purata Global memekatkan peta ciri yang diperoleh daripada VGG16 menjadi satu vektor 1D bagi setiap peta. Ia memudahkan output dan mengurangkan jumlah parameter, membantu dalam pencegahan overfitting.

Lapisan padat ialah jujukan lapisan bersambung sepenuhnya (Padat) yang ditambahkan. Setiap lapisan mengandungi bilangan unit tertentu (1024, 512, dan 256), dipilih berdasarkan amalan biasa dan percubaan. Lapisan ini memproses lagi ciri yang diekstrak oleh VGG16.

Lapisan Padat terakhir (Lapisan Output) menggunakan pengaktifan sigmoid yang sesuai untuk klasifikasi binari (dua kelas kami ialah 'perempuan' dan 'lelaki').

Pengoptimuman Adam

Algoritma Pengoptimuman Adam ialah lanjutan daripada prosedur penurunan kecerunan stokastik untuk mengemas kini berat rangkaian berulang berdasarkan data latihan. Kaedah ini cekap apabila menangani masalah besar yang melibatkan banyak data atau parameter. Ia memerlukan kurang ingatan dan cekap.

Algoritma ini menggabungkan dua metodologi penurunan kecerunan: momentum dan Pembiakan Purata Purata Akar (RMSP).

Momentum ialah algoritma yang digunakan untuk membantu mempercepatkan algoritma penurunan kecerunan menggunakan purata wajaran eksponen bagi kecerunan.

Using VGGfor face and gender recognition

Root mean square prop ialah algoritma pembelajaran adaptif yang cuba menambah baik AdaGrad dengan mengambil "purata bergerak eksponen".

Using VGGfor face and gender recognition

Memandangkan mt dan vt mempunyai kedua-duanya dimulakan sebagai 0 (berdasarkan kaedah di atas), diperhatikan bahawa mereka mendapat kecenderungan untuk 'berat sebelah ke arah 0' kerana kedua-dua β1 & β2 ≈ 1. Pengoptimum ini membetulkan masalah ini dengan mengira 'bias-diperbetulkan' mt dan vt. Ini juga dilakukan untuk mengawal berat semasa mencapai minimum global untuk mengelakkan ayunan tinggi apabila berhampirannya. Formula yang digunakan ialah:

Using VGGfor face and gender recognition

Secara intuitif, kami menyesuaikan diri dengan penurunan kecerunan selepas setiap lelaran supaya ia kekal terkawal dan tidak berat sebelah sepanjang proses, maka dinamakan Adam.

Sekarang, bukannya parameter berat biasa kami mt dan vt, kami mengambil parameter berat pembetulan berat sebelah (m_hat)t dan (v_hat)t. Meletakkannya ke dalam persamaan am kita, kita dapat:

Using VGGfor face and gender recognition

Sumber: Geeksforgeeks, https://www.geeksforgeeks.org/adam-optimizer/

faceCascade = cv2.CascadeClassifier(os.path.join(base_path, "haarcascade_frontal_face_default.xml")) # haar cascade detects faces in images

vgg_face_dataset_url = "http://www.robots.ox.ac.uk/~vgg/data/vgg_face/vgg_face_dataset.tar.gz"

with request.urlopen(vgg_face_dataset_url) as r, open(os.path.join(base_path, "vgg_face_dataset.tar.gz"), 'wb') as f:
  f.write(r.read())

# extract VGG dataset
with tarfile.open(os.path.join(base_path, "vgg_face_dataset.tar.gz")) as f:
  f.extractall(os.path.join(base_path))

# download Haar Cascade for face detection
trained_haarcascade_url = "https://raw.githubusercontent.com/opencv/opencv/master/data/haarcascades/haarcascade_frontalface_default.xml"
with request.urlopen(trained_haarcascade_url) as r, open(os.path.join(base_path, "haarcascade_frontalface_default.xml"), 'wb') as f:
    f.write(r.read())
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Sediakan prapemprosesan data imej, pembesaran dan latihan model dalam konteks pembelajaran yang mendalam.

faceCascade = cv2.CascadeClassifier(os.path.join(base_path, "haarcascade_frontal_face_default.xml")) # haar cascade detects faces in images

vgg_face_dataset_url = "http://www.robots.ox.ac.uk/~vgg/data/vgg_face/vgg_face_dataset.tar.gz"

with request.urlopen(vgg_face_dataset_url) as r, open(os.path.join(base_path, "vgg_face_dataset.tar.gz"), 'wb') as f:
  f.write(r.read())

# extract VGG dataset
with tarfile.open(os.path.join(base_path, "vgg_face_dataset.tar.gz")) as f:
  f.extractall(os.path.join(base_path))

# download Haar Cascade for face detection
trained_haarcascade_url = "https://raw.githubusercontent.com/opencv/opencv/master/data/haarcascades/haarcascade_frontalface_default.xml"
with request.urlopen(trained_haarcascade_url) as r, open(os.path.join(base_path, "haarcascade_frontalface_default.xml"), 'wb') as f:
    f.write(r.read())
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
  • zaman: bilangan zaman menentukan jumlah keseluruhan set data latihan akan dihantar ke hadapan dan ke belakang melalui rangkaian saraf. Model akan melalui data latihan sebanyak 10 kali. Epok ialah satu pembentangan lengkap set data untuk dipelajari kepada mesin pembelajaran.
  • saiz_batch: parameter ini mentakrifkan bilangan sampel yang disebarkan melalui rangkaian pada satu masa. Di sini, kami menggunakan saiz kelompok 30, bermakna model akan mengambil 30 imej pada satu masa, memprosesnya, mengemas kini pemberat, dan kemudian meneruskan ke kumpulan 30 imej seterusnya.

Prestasi model dinilai dengan membuat ramalan pada set pengesahan. Ini memberi gambaran tentang sejauh mana model itu melaksanakan data yang tidak kelihatan. Ambang digunakan pada ramalan ini untuk mengklasifikasikan setiap imej kepada satu daripada dua kelas (“lelaki” atau “perempuan”).

# populate the list with the files of the celebrities that will be used for face recognition
all_subjects = [subject for subject in sorted(os.listdir(os.path.join(base_path, "vgg_face_dataset", "files"))) if subject.startswith("Jesse_Eisenberg") or subject.startswith("Sarah_Hyland") or subject.startswith("Michael_Cera") or subject.startswith("Mila_Kunis") and subject.endswith(".txt")]

# define number of subjects and how many pictures to extract
nb_subjects = 4
nb_images_per_subject = 40
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Buat matriks kekeliruan untuk menggambarkan ketepatan.

images = []

for subject in all_subjects[:nb_subjects]:
  with open(os.path.join(base_path, "vgg_face_dataset", "files", subject), 'r') as f:
    lines = f.readlines()

  images_ = []
  for line in lines:
    url = line[line.find("http://"): line.find(".jpg") + 4]

    try:
      res = request.urlopen(url)
      img = np.asarray(bytearray(res.read()), dtype="uint8")
      # convert the image data into a format suitable for OpenCV
      # images are colored 
      img = cv2.imdecode(img, cv2.IMREAD_COLOR)
      h, w = img.shape[:2]
      images_.append(img)
      cv2_imshow(cv2.resize(img, (w // 5, h // 5)))

    except:
      pass

    # check if the required number of images has been reached
    if len(images_) == nb_images_per_subject:
      # add the list of images to the main images list and move to the next subject
      images.append(images_)
      break
Salin selepas log masuk
Salin selepas log masuk

Untuk klasifikasi binari, keluk Ciri Operasi Penerima (ROC) dan Kawasan Di Bawah Keluk (AUC) berguna untuk memahami pertukaran antara kadar positif benar dan kadar positif palsu.

# create arrays for all 4 celebrities
jesse_images = []
michael_images = []
mila_images = []
sarah_images = []

faceCascade = cv2.CascadeClassifier(os.path.join(base_path, "haarcascade_frontalface_default.xml"))

# iterate over the subjects
for subject, images_ in zip(all_subjects, images):

  # create a grayscale copy to simplify the image and reduce computation
  for img in images_:
    img_ = img.copy()
    img_gray = cv2.cvtColor(img_, cv2.COLOR_BGR2GRAY)
    faces = faceCascade.detectMultiScale(
        img_gray,
        scaleFactor=1.2,
        minNeighbors=5,
        minSize=(30, 30),
        flags=cv2.CASCADE_SCALE_IMAGE
    )
    print("Found {} face(s)!".format(len(faces)))

    for (x, y, w, h) in faces:
        cv2.rectangle(img_, (x, y), (x+w, y+h), (0, 255, 0), 10)

    h, w = img_.shape[:2]
    resized_img = cv2.resize(img_, (224, 224))
    cv2_imshow(resized_img)

    if "Jesse_Eisenberg" in subject:
        jesse_images.append(resized_img)
    elif "Michael_Cera" in subject:
        michael_images.append(resized_img)
    elif "Mila_Kunis" in subject:
        mila_images.append(resized_img)
    elif "Sarah_Hyland" in subject:
        sarah_images.append(resized_img)
Salin selepas log masuk
Salin selepas log masuk

Kesimpulan

Kesimpulannya, dengan menggunakan pembelajaran mendalam dan algoritma pemprosesan imej anda boleh membina projek Python yang mengenali wajah manusia dan boleh mengkategorikannya sama ada lelaki atau perempuan.

Atas ialah kandungan terperinci Menggunakan VGG untuk pengecaman muka dan jantina. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:dev.to
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!