Tema Captcha bukanlah hal baru, termasuk untuk Habr. Namun, algoritma captcha berubah, seperti halnya algoritma untuk menyelesaikannya. Oleh karena itu, diusulkan untuk mengingat yang lama dan mengoperasikan captcha versi berikut:

Sepanjang jalan, pahami pekerjaan jaringan saraf sederhana dalam praktik, dan juga tingkatkan hasilnya.
Segera buat reservasi bahwa kita tidak akan terjun ke pemikiran tentang bagaimana neuron bekerja dan apa yang harus dilakukan dengan semua ini, artikel ini tidak mengklaim sebagai ilmiah, tetapi hanya menyediakan tutorial kecil.
Menari dari kompor. Alih-alih bergabung
Mungkin kata-kata seseorang akan diulang, tetapi sebagian besar buku tentang Deep Learning benar-benar dimulai dengan fakta bahwa pembaca ditawari data yang sudah disiapkan sebelumnya yang dengannya dia mulai bekerja. Entah bagaimana, MNIST - 60.000 digit tulisan tangan, CIFAR-10, dll. Setelah membaca, seseorang keluar siap ... untuk set data ini. Sama sekali tidak jelas cara menggunakan data Anda dan, yang paling penting, bagaimana meningkatkan sesuatu ketika membangun jaringan saraf Anda sendiri.
Itulah sebabnya artikel di
pyimagesearch.com tentang cara bekerja dengan data Anda sendiri, serta
terjemahannya, sangat berguna.
Tetapi seperti yang mereka katakan, lobak lobak tidak lebih manis: bahkan dengan terjemahan artikel yang dikunyah pada keras, ada banyak titik buta. Sekali lagi, dataset yang disiapkan sebelumnya ditawarkan, hanya dengan kucing, anjing, dan panda. Harus mengisi kekosongan sendiri.
Namun, artikel dan kode ini akan diambil sebagai dasarnya.
Kami mengumpulkan data tentang captcha
Tidak ada yang baru di sini. Kami membutuhkan sampel captcha, sebagai jaringan akan belajar dari mereka di bawah panduan kami. Anda dapat menambang captcha sendiri, atau Anda dapat mengambil sedikit di sini -
29.000 captcha . Sekarang Anda perlu memotong angka dari masing-masing captcha. Tidak perlu memotong semua 29.000 captcha, terutama karena 1 captcha memberikan 5 digit. 500 captcha akan lebih dari cukup.
Bagaimana cara memotong? Mungkin saja menggunakan Photoshop, tetapi lebih baik memiliki pisau yang lebih baik.
Jadi di sini adalah kode pisau python -
unduh . (untuk Windows. Pertama-tama buat folder C: \ 1 \ test dan C: \ 1 \ test-out).
Output akan berupa dump angka dari 1 hingga 9 (tidak ada nol di captcha).
Selanjutnya, Anda perlu mengurai penyumbatan ini dari angka ke dalam folder dari 1 hingga 9 dan memasukkan ke dalam setiap folder dengan nomor yang sesuai. Pekerjaan begitu-begitu. Namun dalam sehari Anda bisa mendapatkan hingga 1000 digit.
Jika, ketika memilih angka, menjadi angka yang meragukan, lebih baik untuk menghapus sampel ini. Dan tidak apa-apa jika angkanya berisik atau tidak sepenuhnya masuk ke "bingkai":



Anda perlu mengumpulkan 200 sampel setiap digit di setiap folder. Anda dapat mendelegasikan pekerjaan ini ke layanan pihak ketiga, tetapi lebih baik melakukan semuanya sendiri sehingga Anda tidak mencari nomor yang salah cocok nanti.
Jaringan saraf. Tes
Tyat, tyat, jala kami menyeret mayat ituSebelum Anda mulai bekerja dengan data Anda sendiri, lebih baik membaca artikel di atas dan menjalankan kode untuk memahami bahwa semua komponen (keras, tensorflow, dll.) Diinstal dan berfungsi dengan benar.
Kami akan menggunakan jaringan sederhana yang sintaks peluncurannya berasal dari baris perintah (!):
python train_simple_nn.py --dataset animals --model output/simple_nn.model --label-bin output/simple_nn_lb.pickle --plot output/simple_nn_plot.png
* Tensorflow dapat menulis ketika bekerja tentang kesalahan dalam file sendiri dan metode usang, Anda dapat memperbaikinya dengan tangan, atau Anda dapat mengabaikannya.
Yang utama adalah setelah program selesai, dua file muncul di folder proyek proyek: simple_nn_lb.pickle dan simple_nn.model, dan gambar hewan dengan tulisan dan tingkat pengenalan ditampilkan, misalnya:

Jaringan saraf - memiliki data
Sekarang setelah tes kesehatan jaringan telah diverifikasi, Anda dapat menghubungkan data Anda sendiri dan mulai melatih jaringan.
Masukkan folder folder dat dengan nomor yang berisi sampel yang dipilih untuk setiap digit.
Untuk kenyamanan, kami akan menempatkan folder dat di folder proyek (misalnya, di sebelah folder hewan).
Sekarang sintaks untuk memulai pembelajaran jaringan adalah:
python train_simple_nn.py --dataset dat --model output/simple_nn.model --label-bin output/simple_nn_lb.pickle --plot output/simple_nn_plot.png
Namun, masih terlalu dini untuk memulai pelatihan.
Anda perlu memperbaiki file train_simple_nn.py.
1. Di akhir file:
Ini akan menambah informasi.
2.
image = cv2.resize(image, (32, 32)).flatten()
ubah ke
image = cv2.resize(image, (16, 37)).flatten()
Di sini kita mengubah ukuran gambar input. Kenapa ukuran ini persis? Karena sebagian besar digit yang dipotong adalah dengan ukuran ini atau diperkecil. Jika Anda mengubah skala menjadi 32x32 piksel, gambar akan terdistorsi. Ya, dan mengapa melakukannya?
Selain itu, kami mendorong perubahan ini menjadi coba:
try: image = cv2.resize(image, (16, 37)).flatten() except: continue
Karena program tidak dapat mencerna beberapa gambar dan masalah Tidak ada, oleh karena itu dilewati.
3. Sekarang hal yang paling penting. Di mana ada komentar dalam kode
mendefinisikan arsitektur 3072-1024-512-3 dengan Keras
Arsitektur jaringan dalam artikel didefinisikan sebagai 3072-1024-512-3. Ini berarti bahwa jaringan menerima 3072 (32 piksel * 32 piksel * 3) pada input, lalu layer 1024, layer 512 dan pada opsi output 3 - kucing, anjing atau panda.
Dalam kasus kami, inputnya adalah 1776 (16 piksel * 37 piksel * 3), kemudian layer 1024, layer 512, pada output dari 9 varian angka.
Oleh karena itu kode kami:
model.add(Dense(1024, input_shape=(1776,), activation="sigmoid"))model.add(Dense(512, activation="sigmoid"))
* 9 output tidak perlu diindikasikan tambahan, karena program itu sendiri menentukan jumlah pintu keluar dengan jumlah folder dalam dataset.
Kami meluncurkan
python train_simple_nn.py --dataset dat --model output/simple_nn.model --label-bin output/simple_nn_lb.pickle --plot output/simple_nn_plot.png
Karena gambar dengan angka kecil, jaringan belajar dengan sangat cepat (5-10 menit) bahkan pada perangkat keras yang lemah, hanya menggunakan CPU.
Setelah menjalankan program di baris perintah, lihat hasilnya:

Ini berarti bahwa pada set pelatihan, kesetiaan tercapai - 82,19%, pada kontrol - 75,6% dan pada tes - 75,59%.
Kita perlu fokus pada indikator terakhir untuk sebagian besar. Mengapa yang lain juga penting akan dijelaskan nanti.
Mari kita juga melihat bagian grafik dari kerja jaringan saraf. Itu ada di folder keluaran proyek simple_nn_plot.png:

Lebih cepat, lebih tinggi, lebih kuat. Meningkatkan Hasil
Cukup banyak tentang pengaturan jaringan saraf, lihat di
sini .
Opsi otentik adalah sebagai berikut.
Tambahkan era.
Dalam kode kita berubah
EPOCHS = 75
pada
EPOCHS = 200
Tambah "berapa kali" jaringan akan menjalani pelatihan.
Hasil:

Dengan demikian, 93,5%, 92,6%, 92,6%.
Dalam gambar:

Di sini terlihat bahwa garis-garis biru dan merah setelah era ke-130 mulai bubar satu sama lain dan ini mengatakan bahwa peningkatan lebih lanjut dalam jumlah zaman tidak akan bekerja. Lihat ini.
Dalam kode kita berubah
EPOCHS = 200
pada
EPOCHS = 500
dan lari lagi.
Hasil:

Jadi kita punya:
99%, 95,5%, 95,5%.
Dan pada grafik:

Nah, peningkatan jumlah era jelas telah pergi ke internet. Namun, hasil ini menyesatkan.
Mari kita periksa operasi jaringan menggunakan contoh nyata.
Untuk tujuan ini, skrip predict.py ada di folder proyek. Sebelum memulai, siapkan.
Dalam folder gambar proyek, kami menempatkan file dengan gambar angka dari captcha, yang sebelumnya tidak dijumpai jaringan dalam proses pembelajaran. Yaitu perlu untuk mengambil digit bukan dari dat dataset dat.
Dalam file itu sendiri, kami memperbaiki dua baris untuk ukuran gambar default:
ap.add_argument("-w", "--width", type=int, default=16, help="target spatial dimension width") ap.add_argument("-e", "--height", type=int, default=37, help="target spatial dimension height")
Jalankan dari baris perintah:
python predict.py --image images/1.jpg --model output/simple_nn.model --label-bin output/simple_nn_lb.pickle --flatten 1
Dan kita melihat hasilnya:

Gambar lain:

Namun, itu tidak berfungsi dengan semua angka bising:

Apa yang bisa dilakukan di sini?
- Tambah jumlah salinan angka dalam folder untuk pelatihan.
- Coba metode lain.
Mari kita coba metode lain
Seperti yang dapat Anda lihat dari grafik terakhir, garis biru dan merah menyimpang di sekitar era ke-130. Ini berarti bahwa belajar setelah era ke-130 tidak efektif. Kami memperbaiki hasil pada zaman ke-130: 89,3%, 88%, 88% dan melihat apakah metode lain untuk meningkatkan kerja jaringan.
Kurangi kecepatan belajar. INIT_LR = 0.01
pada
INIT_LR = 0.001
Hasil:
41%, 39%, 39%
Baiklah, oleh.
Tambahkan lapisan tersembunyi tambahan. model.add(Dense(512, activation="sigmoid"))
pada
model.add(Dense(512, activation="sigmoid")) model.add(Dense(258, activation="sigmoid"))
Hasil:
56%, 62%, 62%
Lebih baik, tapi tidak.
Namun, jika Anda menambah jumlah era hingga 250:
84%, 83%, 83%
Pada saat yang sama, garis merah dan biru tidak lepas satu sama lain setelah era ke-130:
Hemat 250 era dan menerapkan penjarangan :
from keras.layers.core import Dropout
Masukkan penipisan di antara lapisan:
model.add(Dense(1024, input_shape=(1776,), activation="sigmoid")) model.add(Dropout(0.3)) model.add(Dense(512, activation="sigmoid")) model.add(Dropout(0.3)) model.add(Dense(258, activation="sigmoid")) model.add(Dropout(0.3))
Hasil:
53%, 65%, 65%
Nilai pertama lebih rendah daripada yang lain, ini menunjukkan bahwa jaringan tidak belajar. Untuk melakukan ini, disarankan untuk menambah jumlah era.
model.add(Dense(1024, input_shape=(1776,), activation="sigmoid")) model.add(Dropout(0.3)) model.add(Dense(512, activation="sigmoid")) model.add(Dropout(0.3))
Hasil:
88%, 92%, 92%
Dengan 1 lapisan tambahan, penipisan dan 500 era:
model.add(Dense(1024, input_shape=(1776,), activation="sigmoid")) model.add(Dropout(0.3)) model.add(Dense(512, activation="sigmoid")) model.add(Dropout(0.3)) model.add(Dense(258, activation="sigmoid"))
Hasil:
92,4%, 92,6%, 92,58%
Meskipun persentase lebih rendah dibandingkan dengan peningkatan sederhana dalam era ke 500, grafik terlihat lebih merata:

Dan jaringan memproses gambar yang sebelumnya jatuh:

Sekarang kita akan mengumpulkan semuanya menjadi satu file, yang akan memotong gambar dengan captcha di input menjadi 5 digit, menjalankan setiap digit melalui jaringan saraf dan output hasilnya ke interpreter python.
Lebih sederhana di sini. Dalam file yang memotong angka dari captcha, tambahkan file yang berhubungan dengan prediksi.
Sekarang program tidak hanya memotong captcha menjadi 5 bagian, tetapi juga menampilkan semua angka yang dikenal dalam juru bahasa:

Sekali lagi, harus diingat bahwa program tidak memberikan 100% dari hasil dan seringkali salah satu dari 5 digit salah. Tetapi ini adalah hasil yang baik, mengingat dalam pelatihan yang ditetapkan hanya ada 170-200 salinan untuk setiap nomor.
Pengakuan Captcha berlangsung 3-5 detik pada komputer berdaya sedang.
Bagaimana lagi Anda dapat mencoba meningkatkan jaringan? Anda dapat membaca di buku "Perpustakaan Keras - alat pembelajaran yang dalam" A. Dzhulli, S. Pala.
Script terakhir yang memotong captcha dan mengenali ada di
sini .
Itu dimulai tanpa parameter.
Skrip daur ulang untuk
pelatihan dan
pengujian jaringan.
Captcha untuk ujian, termasuk dengan false positive - di
sini .
Model untuk pekerjaan ada di
sini .
Angka-angka dalam folder ada di
sini .