{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# **Schriftfarbenvorhersager**\n", "\n", "Erstellt von Christoph Graml" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# ***Einleitung*** \n", "\n", "Ihr werdet mit diesem Notebook ein Machine Learning Projekt von Anfang bis Ende umsetzen. Das heißt zu Beginn schreiben wir ein Tool, mit dem Daten gesammelt werden, daraufhin programmieren wir ein vereinfachtes neuronales Netz, welches mit den gesammelten Daten trainiert wird und am Ende analysieren wir die Vorhersagen des Netzes.\n", "\n", "Es handelt sich dabei um mein erstes ML-Projekt, welches ich 2017 als Einstieg in Machine Learning umgesetzt habe. \n", "Inspiriert bzw. die Idee dazu kam durch dieses [Video](https://youtu.be/I74ymkoNTnw?t=425)\n", "\n", "\n", "# ***Idee***\n", "Die Idee besteht darin, ein vereinfachtes neuronales Netz zu trainieren, welches für jede Hintergrundfarbe die am besten lesbare Schriftfarbe (weiß oder schwarz) vorhersagt.\n", "Es liegt somit ein einfacher Klassifizierungsfall vor. Das neuronale Netz klassifiziert die Hintergrundfarbe und teilt diese einer \"Schriftfarbenklasse\" (schwarz oder weiß) zu. \n", "\n", "Die Eingabe ist dabei der RGB-Wert der Hintergrundfarbe. Ein RGB-Wert besteht eigentlich aus 3 Werten, jeweils zwischen 0 und 255. Die 3 Werte untergliedern sich in einen **R**ot-, **G**rün- und **B**lau-Wert. Sie geben an wie sehr die Farbe \"vorhanden\" sein soll (0 bedeutet nicht \"vorhanden\", 255 bedeutet \"vorhanden\"). Ein RGB-Wert von 0,0,0 steht für schwarz (0 \"Rot\", 0 \"Grün\", 0 \"Blau\") und ein RGB-Wert von 255,255,255 für weiß (255 \"Rot\", 255 \"Grün\", 255 \"Blau\"). \n", "Ähnlich steht ein RGB-Wert von 255,0,0 für ein kräftiges Rot. \n", "\n", "\n", "![rgb.png](images/rgb.png)\n", "\n", "\n", "*(Für mehr Infos zu RGB lese dir den [Wikipedia-Artikel](https://de.wikipedia.org/wiki/RGB-Farbraum) durch)*" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# ***Start***\n", "\n", "Zu Beginn müssen wir uns um die Daten kümmern. Das heißt wir benötigen einen Datensatz.\n", "Wie ich es jedoch schon versprochen hatte, laden wir keinen Datensatz einfach aus dem Internet herunter, sondern erstellen uns ein Tool, mit welchen wir selbst Daten sammeln können.\n", "Dazu gebe ich die nachfolgende Methode vor. Die Methode kann Hintergrundfarben, welche sie übergeben bekommt anzeigen.\n", "\n", "---\n", "\n", "## **Hinweis**\n", "In diesem gesamten Notebook befinden sich in den Code-Teile immer wieder drei Punkte \"**. . .**\" .\n", "Diese musst du mit Code ersetzen. Dabei kannst/musst du auch mehrere Zeilen verwenden." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": {}, "colab_type": "code", "collapsed": true, "id": "47JqXxyJILfN" }, "outputs": [], "source": [ "\"\"\"fuehre die beiden nachfolgenden Befehle aus, falls matplotlib und Pillow noch nicht installiert sind\"\"\"\n", "# !pip install matplotlib\n", "# !pip install Pillow\n", "\n", "%matplotlib inline \n", "import matplotlib.pyplot as plt \n", "from PIL import Image, ImageDraw \n", "from IPython.display import clear_output\n", "\n", "def farbeAnzeigen(rgb, textfarbe=''):\n", " \"\"\"Zeigt die uebergebene Hintergrundfarbe mit beiden/der Schriftfarbe an\n", " Args:\n", " rgb (tuple): Hintergrundfarbe:\n", " - ein Tuple der Laenge 3\n", " - fuer den rot-/gruen-/blau- Wert je ein int zwischen 0 un 255\n", " textfarbe (string, standardmaessig=''): Schriftfarbe\n", " Wenn der string...\n", " ... gleich 'w', dann wird nur eine weisse Schrift auf der Hintergrundfarbe angezeigt\n", " ... gleich 's', dann wird nur eine schwarze Schrift auf der Hintergrundfarbe angezeigt\n", " ... weder 's' noch 'w', dann wird eine schwarze und weisse Schrift auf der Hintergrundfarbe angezeigt\n", " \"\"\"\n", "\n", " \n", " \n", " clear_output() # Löscht die vorherige 'farbenAnzeige'\n", " # Neues Bild erstellen\n", " img = Image.new('RGB', (100, 30), color = rgb) \n", " d = ImageDraw.Draw(img) \n", " d.rectangle((0,0,99,29), fill=None, outline=(0))\n", "\n", " # Den Text mit der uebergebenen Farbe darstellen\n", " if textfarbe == 's':\n", " d.text((30,10), \"Schwarz\", fill=(0,0,0))\n", " elif textfarbe == 'w':\n", " d.text((35,10), \"Weiß\", fill=(255,255,255))\n", " else:\n", " d.text((10,10), \"Schwarz\", fill=(0,0,0)) \n", " d.text((60,10), \"Weiß\", fill=(255,255,255)) \n", "\n", " # Das Bild anzeigen\n", " plt.rcParams[\"figure.figsize\"] = (10, 5)\n", " plt.axis(\"off\") \n", " plt.imshow(img) \n", " plt.show()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": {}, "colab_type": "code", "collapsed": false, "id": "Uuw6jLBcUgLt" }, "outputs": [], "source": [ "farbeAnzeigen((123,211,180))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": {}, "colab_type": "code", "collapsed": false, "id": "Vu-9gxKUUgDB" }, "outputs": [], "source": [ "farbeAnzeigen((234,123,99), 'w')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": {}, "colab_type": "code", "collapsed": false, "id": "ktTpI_84710T", "scrolled": true }, "outputs": [], "source": [ "farbeAnzeigen((234,123,99), 's')" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "zYwqfUqnUx_p" }, "source": [ "# ***Tool zum Daten sammeln*** \n", "Um nun Daten zu sammeln und einen Datensatz zu erstellen, können wir die Methode *farbeAnzeigen* verwenden. Der Nutzer soll eine zufällige Hintergrundfarbe angezeigt bekommen und kann daraufhin mit einer Eingabe bestimmen, ob die weiße oder schwarze Schriftfarbe darauf besser aussieht. Somit werden Daten gelabelt, welche daraufhin zum trainieren einer KI verwendet werden können.\n", "\n", "\n", "---\n", "\n", "\n", "\n", "So sollte das fertige Tool zum Datensammeln aussehen:\n", "\n", "![daten_sammeln.png](images/daten_sammeln.png)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": {}, "colab_type": "code", "collapsed": true, "id": "D3QFk2HoILVj" }, "outputs": [], "source": [ "\"\"\"fuehre den nachfolgenden Befehl aus, falls numpy noch nicht installiert ist\"\"\"\n", "# !pip install numpy\n", "\n", "import numpy as np\n", "import random\n", "\n", "def datenSammeln():\n", " # Liste, welche die Hintergrundfarben mit Label enthaelt\n", " daten = []\n", "\n", " while True:\n", " # erstelle eine zufaellige RGB-Farbe (3 Wert) mit Hilfe von random.randint(...)\n", " # lerne hier mehr über diese Funktion: https://docs.python.org/3/library/random.html#random.randint\n", " zufallsRGB = (..., ..., ...)\n", "\n", " # zeige nun die neue Hintergrundfarbe mit sowohl weissem als auch schwarzen Text darauf an, \n", " # sodass man vergleichen kann, welche Schriftfarbe besser aussieht.\n", " # Verwende hierzu die farbeAnzeigen-Methode\n", " farbeAnzeigen(...)\n", "\n", " # Der Betrachter kann die bessere Textfarbe eingeben\n", " print(\"Bitte bessere Textfarbe eingeben: s -> schwarz oder w -> weiss\")\n", " print(\"Zum Beenden einfach Enter drücken!\")\n", " textfarbe = input().lower()\n", "\n", " # Die Textfarbe und die Hintergrundfarbe werden in den Datensatz aufgenommen, \n", " # wenn keine Textfarbe eingegeben wurde (das Daten sammeln also beendet wurde), \n", " # wird der Datensatz als np.array zurueckgegeben.\n", " if textfarbe == ...: \n", " # Eingabe gleich schwarz (ergänze das if-Statement)\n", " # Die 0 in der hinzufuegenden Datenzeile ist das Label fuer schwarz\n", " daten.append([zufallsRGB[0], zufallsRGB[1], zufallsRGB[2], 0])\n", " elif textfarbe == ...: \n", " # Eingabe gleich weiss (ergänze das if-Statement und die hinzufuegende Datenzeile)\n", " # Die 1 in der hinzufuegenden Datenzeile ist das Label fuer weiss\n", " daten.append([..., ..., ..., 1])\n", " else:\n", " # gibt den Datensatz als np.array zurueck\n", " return np.array(daten)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": {}, "colab_type": "code", "collapsed": true, "id": "C-js3TkCILTi" }, "outputs": [], "source": [ "# Nun solltest du mit deiner Methode datenSammeln() Daten sammeln koennen, \n", "# welche am Ende auch noch zurueckgegeben werden\n", "# Probiere es doch gleich mal aus!\n", "\n", "daten = datenSammeln()\n", "print(daten)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# ***Daten***\n", "Die nun von dir gesammelten Daten haben folgendes Format:\n", "\n", "