Sådan opsættes NSFW-indholdsdetektion med Machine Learning

At lære en maskine at genkende uanstændigt indhold var ikke svært bagud, men det var bestemt svært første gang.

Her er nogle erfaringer og nogle tip og tricks, jeg afslørede, da jeg byggede en NSFW-model.

Selvom der er mange måder, dette kunne have været implementeret på, er håbet med dette indlæg at give en venlig fortælling, så andre kan forstå, hvordan denne proces kan se ud.

Hvis du er ny i ML, vil dette inspirere dig til at træne en model. Hvis du er fortrolig med det, ville jeg elske at høre, hvordan du ville være gået med at opbygge denne model og bede dig om at dele din kode.

Planen:

  1. Få masser af masser af data
  2. Mærk og rengør dataene
  3. Brug Keras og overfør læring
  4. Forbedr din model

Få masser af masser af data

Heldigvis blev der frigivet et rigtig cool sæt skrabeskripter til et NSFW-datasæt. Koden er enkel leveres allerede med mærkede datakategorier. Dette betyder, at bare at acceptere disse dataskraberens standardindstillinger vil give os 5 kategorier trukket fra hundredvis af underreddits.

Instruktionerne er ret enkle, du kan simpelthen køre de 6 venlige scripts. Vær opmærksom på dem, da du måske beslutter at ændre tingene.

Hvis du har flere underredits, som du gerne vil tilføje, skal du redigere kilde-URL'erne, før du kører trin 1.

F.eks. - Hvis du tilføjede en ny kilde til neutrale eksempler, tilføjede du listen til subreddit i nsfw_data_scraper/scripts/source_urls/neutral.txt.

Reddit er en stor ressource af indhold på nettet, da de fleste subreddits er let poliseret af mennesker for at være på mål for den subreddit.

Mærk og rengør dataene

De data, vi fik fra NSFW-dataskraberen, er allerede mærket! Men forvent nogle fejl. Især da Reddit ikke er perfekt kurateret.

Kopiering er også ret almindelig, men kan repareres uden langsom menneskelig sammenligning.

Den første ting, jeg kan lide at køre duplicate-file-finder, er den hurtigste nøjagtige filtilpasning og sletning. Det er drevet i Python.

Qarj / duplikat-fil-finder

Find duplikatfiler. Bidrag til udvikling af Qarj / duplikatfilfinder ved at oprette en konto på GitHub. github.com

Jeg kan generelt få et flertal af dubletter slået ud med denne kommando.

python dff.py --path train/path --delete

Nu fanger dette ikke billeder, der "i det væsentlige" er de samme. Til det fortaler jeg at bruge et Macpaw-værktøj kaldet "Gemini 2".

Selvom dette ser super simpelt ud, så glem ikke at grave i de automatiske duplikater, og vælg ALLE duplikaterne, indtil din Gemini-skærm erklærer "Intet tilbage" som sådan:

Det er sikkert at sige, at dette kan tage ekstrem tid, hvis du har et stort datasæt. Personligt kørte jeg det på hver klassifikation, før jeg kørte det i den overordnede mappe for at holde rimelige driftstider.

Brug Keras og overfør læring

Jeg har set på Tensorflow, Pytorch og rå Python som måder at opbygge en maskinlæringsmodel fra bunden. Men jeg ønsker ikke at opdage noget nyt, jeg vil gerne gøre noget, der allerede findes. Så jeg blev pragmatisk.

Jeg fandt Keras som den mest praktiske API til at skrive en simpel model. Selv Tensorflow er enig og arbejder i øjeblikket på at være mere Keras-lignende. Også med kun ét grafikkort vil jeg få fat i en populær allerede eksisterende model + vægte og simpelthen træne oven på den med lidt transferindlæring.

Efter lidt research valgte jeg Inception v3 vægtet med imagenet. For mig er det som at gå til den allerede eksisterende ML-butik og købe Aston Martin. Vi barberer bare det øverste lag af, så vi kan bruge den model til vores behov.

conv_base = InceptionV3( weights="imagenet", include_top=False, input_shape=(height, width, num_channels) )

Med modellen på plads tilføjede jeg 3 flere lag. Et 256 skjult neuronlag efterfulgt af et skjult 128 neuronlag efterfulgt af et sidste 5 neuronlag. Sidstnævnte er den ultimative klassifikation i de fem sidste klasser modereret af 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)

Visuelt bliver denne kode til denne:

Nogle af ovenstående kan virke underlige. Når alt kommer til alt er det ikke hver dag, du siger “glorot_uniform”. Men underlige ord til side, mine nye skjulte lag bliver regelmæssigt for at forhindre overmontering.

Jeg bruger frafald, som tilfældigt fjerner neurale veje, så ingen funktion dominerer modellen.

Derudover har jeg også tilføjet L2-regulering til det første lag.

Nu hvor modellen er færdig, forstærkede jeg mit datasæt med noget genereret agitation. Jeg roterede, skiftede, beskærede, skar, zoomede, vendte om og kanal skiftede mine træningsbilleder. Dette hjælper med at sikre, at billederne trænes gennem almindelig støj.

Alle ovenstående systemer er beregnet til at forhindre overmontering af modellen på træningsdataene. Selvom det er masser af data, vil jeg holde modellen så generaliseret til nye data som muligt.

After running this for a long time, I got around 87% accuracy on the model! That’s a pretty good version one! Let’s make it great.

Refine your model

Basic fine-tuning

Once the new layers are trained up, you can unlock some deeper layers in your Inception model for retraining. The following code unlocks everything after as of the layer 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

I ran the model for a long time with these newly unlocked layers, and once I added exponential decay (via a scheduled learning rate), the model converged on a 91% accuracy on my test data!

With 300,000 images, finding mistakes in the training data was impossible. But with a model with only 9% error, I could break down the errors by category, and then I could look at only around 5,400 images! Essentially, I could use the model to help me find misclassifications and clean the dataset!

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.

Hvis jeg kunne fremstille en fejl ... ville jeg beholde Jeff. Men ak, vi har nået 93% nøjagtighed!

Sammenfattende

Det har muligvis taget meget tid, men det var ikke svært, og det var sjovt at bygge en model. Jeg foreslår, at du tager fat i kildekoden og prøver det selv! Jeg vil sandsynligvis endda forsøge at omskole modellen med andre rammer til sammenligning.

Vis mig hvad du har. Bidrag eller? Stjernemarkér / se repoen, hvis du gerne vil se fremskridt: https://github.com/GantMan/nsfw_model

Gant Laborde er Chief Technology Strategist hos Infinite Red, en offentliggjort forfatter, adjungeret professor, verdensomspændende offentlig taler og gal videnskabsmand i uddannelse. Klapp / følg / tweet eller besøg ham på en konference.

Har du et øjeblik? Tjek et par mere:

Undgå mareridt - NSFW JS

Uanstændigt indholdskontrol på klientsiden for soul shift.infinite.red 5 ting, der suger ved fjernarbejde

Faldgruberne ved fjernarbejde + foreslåede løsninger shift.infinite.red