Bygga en Instagram-robot

Innehållsförteckning

  1. Förtäring av data
  2. Återkommande neuralt nätverk
  3. GPT-2
  4. Automatiskt publicering
  5. Webb-app

Förtäring av data

Jag startade detta projekt med ett vagt mål att försöka bygga ett python-program för att simulera användaraktivitet på mitt personliga Instagram-konto, med det första målet att programmatiskt publicera bilder med bildtexter. Jag hade arbetat med Open AIs GPT-2-modell tidigare, som fungerar på en apa-se, apa-do-metod för att generera text (för bildtexten) baserat på dess träningsdata. Med det i åtanke visste jag att det första steget var att ta in ett anständigt datasätt från Instagram. Jag hade ingen aning om hur jag skulle få GPT-2s bildtexter att verkligen vara relevant för fotot i inlägget.

Tyvärr för mitt projekt har Instagrams API-funktioner varit mycket begränsade. Lösningen var att använda en Selenium-baserad webbskrapa för att skrapa riktiga Instagram-inlägg från fliken "Explore". Denna träningsdata är vad som användes för att träna bildtexten som genererar delen av botten, så de tenderar att vara partisk mot dessa data. Jag antar att Instagram tenderar att skräddarsy alla användares Utforska-flik baserat på deras surfbeteende, men eftersom jag inte använder Instagram ansåg jag att Utforska-fliken var nära standard. Av någon anledning inkluderar detta mycket Mycology och Harry Styles. Jag vet inte varför. Som ett resultat tenderar de sista bildtexterna att vara disponerade för att presentera dem.

Webbscraper i aktion, den här gången på specifika taggar

Den ursprungliga planen här var att ladda upp skrapade data till min personliga S3-hink, men jag fann att efter 10 000 skrapade inlägg, de faktiska bilderna översatt till ungefär 1,3 GB data och relaterade metadata (bildtexter, tidsstämplar, användarnamn, urval av kommentarer, etc.) till ungefär 25Mb. Detta hanterades enkelt av min lokala dator.

Återkommande neuralt nätverk

Genom en del ihållande Googling hittade jag den här artikeln som använder ett återkommande neuralt nätverk för att automatiskt generera bildtexter för foton. Jag har funnit att grundläggande kodning går igenom i flera artiklar på internet så jag är osäker på vem jag ska kreditera för det första arbetet, men den länken är den jag använde. Jag bör också notera att jag inte är en datavetare. Jag var ofta tvungen att behandla varje modell som i huvudsak en svart ruta som begränsade effektiviteten i den aktuella kodningen.

Detta nätverk är tränat i Flickr 8K-datauppsättningen som består av 8000 foton vardera med fem bildtexter som beskriver vad som finns på fotot. Tyvärr värdas denna datauppsättning inte längre av University of Illinois, men det är inte svårt att googla runt för att hitta det någon annanstans. Jag tränade den här modellen på min egen dator (super kul att få rätt version av Tensorflow och relaterade bibliotek uppradade och korrekt installerade) med en Nvidia RTX2070 Super GPU som tog mindre än en halvtimme att köra.

Detta är den del av botten som är ansvarig för att försöka identifiera vad som finns på fotot på bildtexten och som ett resultat är dess noggrannhet skev av de underliggande Flickr-träningsdata. Det tenderar att identifiera människor (deras kön efter hårlängd?), Hundar och motorcyklar, men det är något slumpmässigt för något mer abstrakt eller något med text i själva fotot, eftersom dessa inte fanns i träningsdata. En del av det roliga för mig är att försöka gissa varför modellen märkte något som den gjorde när det inte är meningsfullt på ett nominellt värde.

Den här modellen sprutar ut en bildtexter som försöker beskriva vad som finns på fotot. Noggrannheten här när den körs på faktiska Instagram-inlägg är i bästa fall tvivelaktig, så jag gjorde ett enkelt NLP-arbete för att analysera substantiven från det här bildtexten som sedan matas in i GPT-2 som nyckelord för själva bildtexten.

GPT-2

Open AIs GPT-2 är anmärkningsvärt bra på att generera text som är inställd på det korpus som du finjusterar den på. I det här fallet tränade jag det på de skrapade 10 000 faktiska Instagram-bildtexterna som jag drog från Instagrams fliken Explore. Som jag nämnde är detta starkt skev mot Harry Styles och Mycology.

Denna del av projektet skulle inte ha varit möjligt utan Max Woolfs arbete, vars gpt-2-enkla bibliotek jag använde i stor utsträckning. Vanilla GPT-2 kan ta in ett nyckelord som en hopppunkt för textgenerering, men det används bokstavligen som det första ordet i den genererade texten och baserat på RNN: s nyckelord, skulle det ha begränsat den tillbaka texttexten.

Max Woolfs skript för att koda träningsdata innan det matades in i GPT-2 var nyckeln till att länka GPT-2 och RNN. Den automatiskt analyserar träningsdata för att tagga nyckelord som gör att GPT-2 senare kan matas in dem i ett format som liknar regex-mönstermatchning (RNN: s substantiv).

Jag tränade igen denna modell på min egen hårdvara som tog ungefär 45 minuter till en timme att träna.

Automatiskt publicering

Den sista delen av pusslet var att stränga ihop var och en av modellerna och posta till Instagram (igen, super kul att få alla beroende bibliotek installerade i deras kompatibla versioner. Vill bara betona hur kul det var). Med hjälp av selen har jag använt kromdrivrutin för att simulera en mobiltelefon på mitt skrivbord för att gå igenom postflödet. Tyvärr stötte jag på ett stort problem med att få den faktiska texten till bildtexten till Instagrams textinmatningsruta.

Ett automatiskt inlägg

GPT-2 är tillräckligt bra för att den inkluderar emojis i sin genererade produktion. Jag uppskattade detta mycket eftersom emojis är en nyckelfunktion i Instagram-bildtexter, men chrome-drivrutiner send_keys-metoden kommer bara att stödja bokstavliga tangenter på ditt tangentbord, och som sådan kan det inte skicka emojis. Jag försökte många saker här. Jag försökte använda Javascript för att injicera texten i inmatningsfältet. Jag försökte simma ing Firefox (kan inte simulera mobila enheter). Den sista, smutsiga lösningen jag använder är att bokstavligen kopiera och klistra in texten i (genom python) och simma en CTRL-C, CTRL-V. För alla som följer med hemma, betyder det att om jag klickar på något annat medan jag kör denna del av programmet, bryts det. Men om det inte gör det fungerar det. Så det gör jag inte.

Webb-app

Det var en riktigt cool känsla att slutföra ett första inlägg, men jag tänkte att jag skulle ta det ett steg längre för att bygga en webbapp för att låta andra testa det också. Detta innebar en omkonfigurering av en dataintagningspipeline för att möjliggöra en enda postuppladdning. Det finns en anständig mängd detaljer jag kunde gå in här, men jag tröttnar på att skriva det här inlägget så jag ska hålla det enkelt.

Steg ett var att linda in modellen i en Flask-app som jag kunde köra lokalt, tillsammans med en frontend. Den som använder den kan förmodligen säga att jag är en back-end person som arbetar på en front-end för min första gång. Det finns mycket kopia klistrat in HTML, CSS, Javascript funktioner, etc., och jag var tvungen att lära mig om klientsidan & server sida validering, input sanitet, etc. Det är rörigt, men det fungerar.

Webbappen. Den körs på en icke-gpu EC2 så det är lite långsamt ...

Steg två var att packa in den i en mer produktionsbar Gunicorn-app och sedan lägga in dem och deras beroenden i en Docker-behållare. Lärdom här om att glömma att använda en virtuell pythonmiljö.

Steg två (eller 3 eller 4 eller vad som helst) var att skapa en annan dockningscontainer som kör NGINX som en omvänd proxy, och sedan docker som komponerar båda behållarna för att köras tillsammans igen lokalt. När jag fick det här, distribuerade jag sedan hela paketet till en EC2 som körs på mitt AWS-konto. Jag planerade inledningsvis att distribuera till ett ECS-kluster med en lastbalanseringsmekanism på plats, men jag blev lat och ville också hålla mina utgifter nere (undvika att köra flera icke-fria EC2-instanser på en gång). Kombinerat med ett domännamn som jag köpte, et-voila, en webbappversion för alla att prova.

Jag kan fortfarande ta sig an för att få lite SSL-kryptering för appen eller Google Ad Sense på plats så att jag förhoppningsvis kan få tillbaka kostnaderna för att köra servern, men idk.

Du kan följa kontot som genererar inlägg på @notdavidyu. Webbappen är tillgänglig medan jag fortfarande vill känna att betala för den på www.thegram9000.com