Naučiti stroj prepoznavati nepristojan sadržaj u retrospektivi nije bilo teško, ali sigurno je bilo teško po prvi put.
Evo nekoliko naučenih lekcija i nekoliko savjeta i trikova koje sam otkrio tijekom izrade NSFW modela.
Iako postoji mnogo načina na koje se to moglo provesti, nada se ovog posta pružiti prijateljski narativ kako bi drugi mogli razumjeti kako ovaj proces može izgledati.
Ako ste novi u ML-u, ovo će vas nadahnuti da obučite model. Ako ste ga upoznali, volio bih čuti kako biste krenuli u izgradnju ovog modela i zamoliti vas da podijelite svoj kôd.
Plan:
- Dobijte puno podataka
- Označite i očistite podatke
- Koristite Keras i prenesite učenje
- Pročistite svoj model
Dobijte puno podataka
Srećom, objavljen je stvarno kul set skripti za struganje za NSFW skup podataka. Kôd je jednostavan, već dolazi s označenim kategorijama podataka. To znači da će nam samo prihvaćanje zadanih postavki ovog strugača podataka dati 5 kategorija izvučenih iz stotina podredita.
Upute su vrlo jednostavne, možete jednostavno pokrenuti 6 prijateljskih skripti. Obratite pažnju na njih jer možete odlučiti promijeniti stvari.
Ako imate više podredita koje biste željeli dodati, trebali biste urediti izvorne URL-ove prije izvođenja 1. koraka.
Npr. - Ako biste dodali novi izvor neutralnih primjera, dodali biste na popis subreditita unsfw_data_scraper/scripts/source_urls/neutral.txt
.
Reddit je sjajan resurs sadržaja na webu, budući da ljudi većinom nadziru većinu subreditova kako bi bili na meti tog podredita.
Označite i očistite podatke
Podaci koje smo dobili od strugača podataka NSFW već su označeni! Ali očekujte neke pogreške. Pogotovo jer Reddit nije savršeno kuriran.
Umnožavanje je također prilično često, ali ispravljivo bez spore ljudske usporedbe.
Prvo što volim pokrenuti je duplicate-file-finder
koje je najbrže točno podudaranje i brisanje datoteka. Pokreće se u Pythonu.
Qarj / tražilica duplikata datoteka
Pronađite duplicirane datoteke. Doprinite razvoju Qarj / duplicate-file-finder stvaranjem računa na GitHubu. github.com
Ovom naredbom uglavnom mogu izbaciti većinu duplikata.
python dff.py --path train/path --delete
Ovo ne zahvaća slike koje su "u biti" iste. Zbog toga se zalažem za korištenje Macpaw alata nazvanog "Gemini 2".

Iako ovo izgleda super jednostavno, ne zaboravite kopati po automatskim duplikatima i odabrati SVE duplikate sve dok vaš zaslon Blizanaca ne proglasi "Ništa preostalo" tako:

Sigurno je reći da ovo može potrajati ekstremno puno vremena ako imate ogroman skup podataka. Osobno sam ga pokrenuo na svakoj klasifikaciji prije nego što sam ga pokrenuo na roditeljskoj mapi kako bih zadržao razumno vrijeme rada.
Koristite Keras i prenesite učenje
Gledao sam na Tensorflow, Pytorch i raw Python kao na načine za izgradnju modela strojnog učenja od nule. Ali ne želim otkriti nešto novo, želim učinkovito učiniti nešto već postojeće. Pa sam otišao pragmatičan.
Otkrio sam da je Keras najpraktičniji API za pisanje jednostavnog modela. Čak se i Tensorflow slaže i trenutno radi na tome da bude više nalik Kerasu. Također, sa samo jednom grafičkom karticom ugrabit ću popularni već postojeći model + utezi i jednostavno trenirati na vrhu uz neko učenje transfera.
Nakon malo istraživanja odabrao sam Inception v3 ponderiran imagenet-om. Za mene je to poput odlaska u već postojeću trgovinu ML i kupnje Aston Martina. Samo ćemo obrijati gornji sloj kako bismo taj model mogli koristiti prema svojim potrebama.
conv_base = InceptionV3( weights="imagenet", include_top=False, input_shape=(height, width, num_channels) )

S postavljenim modelom dodao sam još 3 sloja. 256 skrivenih slojeva neurona, nakon kojih slijedi sloj skrivenih 128 neurona, nakon čega slijedi završni sloj od 5 neurona. Potonje je krajnje svrstavanje u pet završnih razreda koje moderira softmax.
# Add 256 x = Dense(256, activation="relu", kernel_initializer=initializers.he_normal(seed=None), kernel_regularizer=regularizers.l2(.0005))(x) x = Dropout(0.5)(x) # Add 128 x = Dense(128,activation='relu', kernel_initializer=initializers.he_normal(seed=None))(x) x = Dropout(0.25)(x) # Add 5 predictions = Dense(5, kernel_initializer="glorot_uniform", activation="softmax")(x)
Vizualno se ovaj kod pretvara u ovo:

Nešto od gore navedenog može se činiti čudnim. Napokon, nije svakodnevno kad kažete “glorot_uniform”. Ali neobične riječi na stranu, moji se novi skriveni slojevi reguliraju kako bi se spriječilo prekomjerno opremanje.
Koristim odustajanje, koje će nasumično ukloniti živčane putove, tako da niti jedna značajka ne dominira modelom.

Uz to, dodao sam i regulaciju L2 na prvi sloj.
Sad kad je model gotov, nadopunio sam svoj skup podataka uz generiranu agitaciju. Rotirao sam, pomicao, obrezivao, preusmjeravao, zumirao, okretao i kanalom pomicao svoje slike za trening. To pomaže u osiguranju da su slike obučene kroz uobičajeni šum.
Svi gore navedeni sustavi imaju za cilj spriječiti prekomjerno uklapanje modela u podatke o treningu. Čak i ako se radi o toni podataka, želim model zadržati što je moguće generaliziranijim za nove podatke.

Nakon dugotrajnog rada, dobio sam oko 87% preciznosti na modelu! To je prilično dobra verzija! Učinimo to sjajnim.
Pročistite svoj model
Osnovno fino podešavanje
Nakon što se novi slojevi uvježbaju, možete otključati neke dublje slojeve u svom početnom modelu za prekvalifikaciju. Sljedeći kôd otključava sve nakon sloja conv2d_56
.
set_trainable = False for layer in conv_base.layers: if layer.name == 'conv2d_56': set_trainable = True if set_trainable: layer.trainable = True else: layer.trainable = False
Dugo sam vodio model s ovim novootključanim slojevima, a kad sam dodao eksponencijalno propadanje (putem zakazane brzine učenja), model se konvergirao s 91% točnosti na mojim testnim podacima!
S 300.000 slika bilo je nemoguće pronaći pogreške u podacima o treningu. Ali s modelom s samo 9% pogreške, mogao bih raščlaniti pogreške po kategorijama, a zatim bih mogao pogledati samo oko 5400 slika! U osnovi bih mogao koristiti model da mi pomogne pronaći pogrešne klasifikacije i očistiti skup podataka!
Technically, this would find false negatives only. Doing nothing for bias on the false positives, but with something that detects NSFW content, I imagine recall is more important than precision.
The most important part of refining
Even if you have a lot of test data, it’s usually pulled from the same well. The best test is to make it easy for others to use and check your model. This works best in open source and simple demos. I released //nsfwjs.com which helped the community identify bias, and the community did just that!

The community got two interesting indicators of bias fairly quickly. The fun one was that Jeffrey Goldblum kept getting miscategorized, and the not-so-fun one was that the model was overly sensitive to females.
Once you start getting into hundreds of thousands of images, it’s hard for one person (like moi) to identify where an issue might be. Even if I looked through a thousand images in detail for bias, I wouldn’t have even scratched the surface of the dataset as a whole.
That’s why it’s important to speak up. Misclassifying Jeff Goldblum is an entertaining data point, but identifying, documenting, and filing a ticket with examples does something powerful and good. I was able to get to work on fixing the bias.
With new images, improved training, and better validation I was able to retrain the model over a few weeks and attain a much better outcome. The resulting model was far more accurate in the wild. Well, unless you laughed as hard as I did about the Jeff Goldblum issue.
Kad bih mogao proizvesti jednu manu ... zadržao bih Jeffa. Ali nažalost, postigli smo 93% preciznosti!

U sažetku
Moglo bi vam trebati puno vremena, ali nije bilo teško i bilo je zabavno izgraditi model. Predlažem da zgrabite izvorni kod i isprobate ga sami! Vjerojatno ću čak pokušati prekvalificirati model s drugim okvirima za usporedbu.
Pokaži mi što imaš. Doprinositi ili? Označite zvjezdicom / gledajte repo ako želite vidjeti napredak: https://github.com/GantMan/nsfw_model

Gant Laborde glavni je tehnološki strateg u tvrtki Infinite Red, objavljeni autor, dodatni profesor, svjetski javni govornik i ludi znanstvenik na obuci. Pljeskajte / slijedite / tweetujte ili ga posjetite na konferenciji.
Imaš minutu? Pogledajte još nekoliko:
Izbjegavaj noćne more - NSFW JS
Client-side indecent content checking for the soulshift.infinite.red5 Things that Suck about Remote Work
The Pitfalls of Remote Work + Proposed Solutionsshift.infinite.red