Форматиране на данните за TensorFlow
Част 1 от тази серия от блогове демонстрира предимствата на използването на релационна база данни за съхраняване и извършване на изследване на данни на изображения с помощта на прости SQL изрази. В този урок, част 2, данните, използвани в първа част, ще бъдат достъпни от база данни на MariaDB Server и ще бъдат преобразувани в структурите от данни, необходими на TensorFlow. Резултатите от прилагането на модела за класифициране на нови изображения ще бъдат съхранени в релационна таблица за по-нататъшен анализ.
Това е кратък урок за програма TensorFlow с подробностите, описани, докато вървим. Ако не сте запознати с основните понятия, добро място да започнете е този урок за TensorFlow, „Основна класификация:Класифицирайте изображения на дрехи“. Тук се използват някои от примерите и кода в урока.
Необходими са допълнителни пакети
Необходими са някои допълнителни пакети за изграждане и обучение на модела за класификация на изображения:
- Тушия внедрява двоични протоколи за сериализиране и десериализиране на обектна структура на Python.
- NumPy осигурява поддръжка за големи, многоизмерни масиви и матрици, заедно с математически функции от високо ниво за работа с тези масиви.
- TensorFlow е библиотека на Python за бързи числени изчисления. Това е основна библиотека, която може да се използва за създаване на модели за дълбоко обучение директно или чрез използване на библиотеки с обвивки, които опростяват процеса, изграден върху TensorFlow.
- Керас е библиотека за невронни мрежи с отворен код, написана на Python.
импортиране на pickleimport numpy като npimport tensorflow като tffrom tensorflow import kerasprint('Tensorflow версия:', tf.__version__)print('Numpy версия:', np.__version__) Версия на Tensorflow:2.0.0Numpy версия:1 предварително>Извличане на изображения
След като пакетите бъдат импортирани, следващата стъпка е да извлечете обучаващите изображения от базата данни и да разделите данните на две numpy масиви. Първо, трябва да инициализираме масивите от обучителни изображения (train_images) и обучителни етикети (train_labels). Тъй като вече сме векторизирали изображенията, можем да използваме атрибута img_vector, за да попълним масива train_images със SQL израза по-долу.
# Инициализирайте numpy arraystrain_images =np.empty((60000,28,28), dtype='uint8')train_labels =np.empty((60000), dtype='uint8')# Извлечете обучаващите изображения от databasesql="SELECT img_label, img_vector, img_idx \FROM tf_images INNER JOIN img_use ON img_use =use_id \WHERE use_name ='Training'"cur.execute(sql)result =cur.fetchall()# Попълване на numpy ray ред[2] съдържа индекса на изображението за ред в резултат:nparray =pickle.loads(row[1])train_images[row[2]] =nparraytrain_labels[row[2]] =row[0]По подобен начин изображенията за тестване могат да бъдат извлечени от базата данни. numpy използваните в този случай масиви са test_images и test_labels. В този случай тестовите данни са 10 000 изображения с разделителна способност 28×28 пиксела.
# Инициализирайте numpy arraystest_images =np.empty((10000,28,28), dtype='uint8')test_labels =np.empty((10000), dtype='uint8')# Извлечете тестовите изображения от databasesql="SELECT img_label, img_vector, img_idx \FROM tf_images INNER JOIN img_use ON img_use =use_id \WHERE use_name ='Testing'"cur.execute(sql)result =cur.fetchall()# Попълване на numpy ray ред[2] съдържа индекса на изображението за ред в резултат:nparray =pickle.loads(row[1])test_images[row[2]] =nparraytest_labels[row[2]] =row[0]И накрая, всяко изображение е съпоставено с един етикет. Имената на етикетите се съхраняват в таблицата с категории и се зареждат в масива class_names:
sql="SELECT class_name FROM category"cur.execute(sql)class_names =cur.fetchall()Обработете предварително данните
Данните трябва да бъдат предварително обработени преди обучение на мрежата. Ако прегледате първото изображение в набора за обучение, ще видите, че стойностите на пикселите попадат в диапазона от 0 до 255:
plt.figure()plt.imshow(train_images[0])plt.colorbar()plt.grid(False)plt.show()
горе:изображение от набор от данни на fashion_mnistПреди да подадете изображенията към модела на невронната мрежа, стойностите трябва да бъдат мащабирани в диапазон от 0 до 1. За да направите това, разделете стойностите на 255. Важно е наборът за обучение и наборът за тестване да бъдат предварително обработени по един и същ начин .
Можете да използвате matplotlib за да покажете първите 25 изображения, за да проверите дали данните са в правилния формат и са готови за изграждане и обучение на мрежата:
train_images =train_images / 255.0test_images =test_images / 255.0plt.figure(figsize=(10,10))for i in range(25):plt.subplot(5,5,i+1)plt.xticks([ ])plt.yticks([])plt.grid(False)plt.imshow(train_images[i], cmap=plt.cm.binary)plt.xlabel(class_names[train_labels[i]])plt.show()предварително>
горе:изображения от набор от данни на fashion_mnistИзграждане на модела
След като данните са предварително обработени в две подмножества, можете да продължите с обучение по модел. Този процес включва „захранване“ на алгоритъма с данни за обучение. Алгоритъмът ще обработи данните и ще изведе модел, който е в състояние да намери целева стойност (атрибут) в нови данни – тоест, класифицира изображението, представено на невронната мрежа.
Повечето невронни мрежи за дълбоко обучение се произвеждат чрез свързване на прости слоеве.
Първият слой в мрежата трансформира формата на изображението от двуизмерен масив (от 28 на 28 пиксела) в едномерен масив (от 28 * 28 =784 пиксела). Този слой няма параметри за научаване; той само преформатира данните.
След като пикселите са изравнени, мрежата се състои от два напълно свързани слоя, които трябва да бъдат активирани. В невронна мрежа функцията за активиране е отговорна за трансформирането на сумирания претеглен вход от възела в активирането на възела или изхода за този вход.
Първият плътен слой има 128 възела (или неврони) и използва метод за активиране на Rectified Linear Unit (ReLU). Ректифицираната линейна функция за активиране е линейна функция на парчета, която ще изведе директно входа, ако е положителен, в противен случай ще изведе нула.
Вторият (и последен) слой е softmax слой с 10 възела. Функцията softmax извежда вектор, който представлява вероятностните разпределения на списък с потенциални резултати. Връща масив от 10 вероятностни резултата, които сумират до 1. Всеки възел съдържа резултат, който показва вероятността текущото изображение да принадлежи към един от 10-те класа.
Повечето слоеве, като tf.keras.layers.Dense, имат параметри, които се научават по време на обучение.
model =keras.Sequential([keras.layers.Flatten(input_shape=(28, 28)),keras.layers.Dense(128, activation='relu'),keras.layers.Dense(10, activation='softmax')])Компилиране на модела
Стъпката за компилиране на модела се използва за добавяне на още няколко настройки, преди да е готов за обучение. В този случай следните настройки са активирани.
- Оптимизатор – Актуализира модела въз основа на данните, които вижда, и функцията му за загуба (вижте по-долу).
- Функция загуба – Измерва колко точен е моделът по време на тренировка. Искате да минимизирате тази функция, за да „насочите“ модела в правилната посока.
- Показатели – Следете стъпките за обучение и тестване. Следващият пример използва точността, частта от изображенията, които са правилно класифицирани.
model.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])Обучение на модела
Обучението на модела на невронната мрежа изисква следните стъпки.
- Предаване на данните за обучение към модела.
- Моделът се научава да свързва изображения и етикети.
- Направете прогнози за набор от тестове.
- Проверете дали предвижданията съвпадат с етикетите от масива test_labels.
За да започнете обучение, извикайте метода model.fit – наречен така, защото той „напасва“ модела към данните за обучение:
model.fit(train_images, train_labels, epochs=10)Влак върху 60000 пробиEpoch 1/1060000/60000 [================================] - 5s 83us/проба - загуба:0,4964 - точност:0,8236Epoch 2/1060000/60000 [================================] - 4s 65us/проба - загуба:0,3735 - точност:0,8642Epoch 3/1060000/60000 [================================] - 3s 55us/проба - загуба:0,3347 - точност:0,8773Epoch 4/1060000/60000 [================================] - 3s 56us/проба - загуба:0,3106 - точност:0,8861Epoch 5/1060000/60000 [================================] - 3s 58us/проба - загуба:0,2921 - точност:0,8924s - загуба:0,2928 - точност - ETA:0s - загуба:0,2925 - accuracyEpoch 6/1060=000 [==60 ==========================] - 3s 57us/проба - загуба:0,2796 - точност:0,8969sEpoch 7/1060000/60000 [==============================] - 4s 70us/проба - загуба:0,2659 - точност:0,9007Epoch 8/1060000/60000 [===============================] - 4s 61us/проба - загуба:0,2548 - точност:0,9042Epoch 9/1060000/60000 [ ==============================] - 4s 61us/проба - загуба:0,2449 - точност:0,9084Epoch 10/1060000/60000 [==============================] - 5s 76us/проба - загуба:0,2358 - точност:0,9118В края на всяка епоха невронната мрежа се оценява спрямо набора за валидиране. За това се отнасят загубата и точността.
Оценете точността и прогнозирайте
За да оцените общата точност на модела, изчислете средната стойност от всичките десет поява на стойността на точността, в този случай 88%.
След това изпълнете model.evaluate на тестовия набор, за да получите прогнозната точност на обучената невронна мрежа върху невиждани по-рано данни.
test_loss, test_acc =model.evaluate(test_images, test_labels, verbose=2)10000/1 - 0s - загуба:0,2766 - точност:0,8740Наборът от тестови данни е по-малко точен от набора от данни за обучение. В този случай тази разлика между точността на обучението и точността на теста представлява прекомерно монтиране. Обратното е недостатъчно оборудване. Ако искате да научите повече по тази тема, препоръчвам Прекомерно оборудване срещу недостатъчно оборудване:концептуално обяснение от Will Koehrsen.
В този момент можем да направим някои прогнози за изображенията в нашия набор от данни за обучение.
predictions =model.predict(test_images)predictions[0]array([1.90860412e-08, 8.05085235e-11, 1.56402713e-08, 1.66699390e-10,7.8699390e-10,7.8699390e-10,7.8699390e-10,7.869412e-08,8699606060606060606060606 -08, 1.20656565e-02,3.80084719e-09, 9.87929940e-01], dtype=float32)Резултатът от model.predict е масив от 10 числа с вероятността екземпляр, принадлежащ към всеки клас. Запазването на резултатите в базата данни на MariaDB за по-нататъшен анализ и отчитане е добра идея. По-долу е даден пример за това как да итерирате масива с прогнози, за да създадете кортеж и след това да го вмъкнете в prediction_results таблица.
sql ="INSERT INTO prediction_results (img_idx, img_use, тениска_горнище, панталон, пуловер, рокля, палто, сандал, риза, маратонки, чанта, глезена, етикет) СТОЙНОСТИ (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s);"i =0за ред в прогнози:insert_tuple =(str(i), str(2), str (ред[0]), str(ред[1]), str(ред[2]), str(ред[3]), str(ред[4]), str(ред[5]), str(ред [6]), str(ред[7]), str(ред[8]), str(ред[9]), str(test_labels[i]))cur.execute(sql, insert_tuple)conn.commit() i +=1Още веднъж може да се използва прост SQL израз, за да се провери дали данните са заредени.
sql ="ИЗБЕРЕТЕ тениска_горнище, панталон, пуловер, рокля, палто, сандал, риза, маратонка, чанта, глезена, име_на класа като 'Етикет на теста'FROM prediction_results ПРИСЪЕДИНЕТЕ категории НА етикет =class_idx КЪДЕ img_idx =1"display( p. read_sql(sql,conn) )
Тениска_горе | Панталон | Пуловер | Рокля | Палто | Сандал | Риза | Маратонки | Чанта | Обувка на глезена | Етикет за тестване |
0,00001 | 0.0 | 0,997912 | 0.0 | 0,001267 | 0.0 | 0,00081 | 0.0 | 0.0 | 0.0 | Пуловер |
Начертаване на прогнози
Няколко функции за начертаване за показване на прогнозите са дефинирани по-долу (графични функции).
Нека извлечем ново изображение от набора за тестване и да покажем класификацията на невронната мрежа въз основа на вероятността за прогнозиране.
sql ="ИЗБЕРЕТЕ img_idx, етикет ОТ prediction_results КЪДЕ img_idx =1"cur.execute(sql)result =cur.fetchone()plt.figure(figsize=(6,3))plt.subplot(1,2, 1)plot_image(резултат[0], прогнози[резултат[0]], test_labels, test_images)plt.subplot(1,2,2)plot_value_array(резултат[0], прогнози[резултат[0]], test_labels)plt. show()
горе:изображение от набор от данни на fashion_mnist
В този случай моделът успя да класифицира изображението правилно със 100% точност. След това нека изпълним заявка, за да извлечем първите 15 изображения от набора за тестване и да ги класифицираме.
sql ="ИЗБЕРЕТЕ img_idx, етикет ОТ ОГРАНИЧЕНИЕ НА прогнозните_резултати 15"num_rows =5num_cols =3plt.figure(figsize=(2*2*num_cols, 2*num_rows))cur.execute(sql)result(sql)result(cur) за ред в резултат:plt.subplot(брой_редове, 2*брой_кола, 2*ред[0]+1)plot_image(ред[0], прогнози[ред[0]], test_labels, test_images)plt.subplot(брой_редове, 2 *num_cols, 2*row[0]+2)plot_value_array(row[0], predictions[row[0]], test_labels)plt.tight_layout()plt.show()
горе:изображения от набор от данни на fashion_mnist
Както можете да видите, ще има случаи, в които моделът може да е грешен, както е показано в последния ред, лява колона. В този случай маратонка е класифицирана като сандал (в червено).
В обобщение
Въпреки че интеграцията между TensorFlow и MariaDB Server е лесна, ползите от тази интеграция са значителни:
- Използването на релационни данни в рамките на машинното обучение може да намали сложността на внедряването. И специалистите по данни, и инженерите по данни могат да използват общ език, за да изпълняват задачи по спорове и проучване на данни.
- Ефективността, постигната при достъп, актуализиране, вмъкване, манипулиране и модифициране на данни, може да ускори времето за пускане на пазара.
- Възможността за съхраняване на резултатите от модела обратно в базата данни позволява на крайните потребители и анализатори да изпълняват заявки и отчети, използвайки удобни инструменти за отчитане като Tableau.
Лиценз на MIT
Наборът от данни Fashion MNIST (fashion_mnist), използван от този блог, е лицензиран под лиценза на MIT, Copyright © 2017 Zalando SE, https://tech.zalando.com
Изходният код, използван от този блог, е адаптиран от урока „Основна класификация:Класифицирайте изображения на дрехи“, който е лицензиран под лиценза на MIT, авторско право (c) 2017 Франсоа Шоле.
С настоящото се предоставя безплатно разрешение на всяко лице, което получава копие на този софтуер и свързаните с него файлове с документация („Софтуерът“), да работи със Софтуера без ограничения, включително без ограничение правата за използване, копиране, модифициране, сливане , публикува, разпространява, подлицензира и/или продава копия на Софтуера и да разрешава на лицата, на които е предоставен Софтуерът, да правят това при следните условия:
Горното известие за авторски права и това известие за разрешение ще бъдат включени във всички копия или значителни части от Софтуера.
СОФТУЕРЪТ СЕ ПРЕДОСТАВЯ „КАКТО Е“, БЕЗ ГАРАНЦИЯ ОТ КАКВЪВ ВИД, ИЗРИЧНА ИЛИ ПОДРАЗНАЧАВАНА, ВКЛЮЧВАЩА, НО НЕ ОГРАНИЧЕНА ДО ГАРАНЦИИТЕ ЗА ПРОДАЖБА, ПРИГОДНОСТ ЗА КОНКРЕТНА ЦЕЛ И НЕНАРУШЕНИЕ. В НИКАКЪВ СЛУЧАЙ АВТОРИТЕ ИЛИ ПРИТЕЖАТЕЛИТЕ НА АВТОРСКИ ПРАВА НЕ НОСАТ ОТГОВОРНОСТ ЗА ВСЯКАКВИ ИСК, ЩЕТИ ИЛИ ДРУГА ОТГОВОРНОСТ, ДАЛИ ПРИ ДЕЙСТВИЕ НА ДОГОВОР, ДЕРЕКТ ИЛИ ПО ДРУГОЙ СТРАХ, ПРОИЗТИШАЩИ ОТ, ИЗВЪН ИЛИ ВЪВ СВЪРЗВАНЕТО НА ДРУГАТА СВЪРЗАНИЯ СОФТУЕР.
Препратки
Преобразувайте собствено изображение в изображение на MNIST
matplotlib:урок за изображения
5 начина, по които AI трансформира клиентското изживяване
Дигитализацията преоткрива бизнеса
Какво е класификация на изображения?
Въведение в Python Библиотека за дълбоко обучение TensorFlow
Графични функции
def plot_image(i, predictions_array, true_label, img):predictions_array, true_label, img =predictions_array, true_label[i], img[i]plt.grid(False)plt.xticks([])plt.yticks([ ])plt.imshow(img, cmap=plt.cm.binary)predicted_label =np.argmax(predictions_array)if predicted_label ==true_label:color ='blue'else:color ='red'plt.xlabel("{} { :2.0f}% ({})".format(имена_на_класове[предвиден_етикет],100*np.max(предвиден_масив),имена_на_класове[истински_етикет]),цвет=цвят)def plot_value_array(i, predictions_array, true_label, true_label):predictionslabel_array =predictions_array, true_label[i]plt.grid(False)plt.xticks(range(10))plt.yticks([])thisplot =plt.bar(range(10), predictions_array, color="#777777")plt .ylim([0, 1])predicted_label =np.argmax(predictions_array)thisplot[predicted_label].set_color('red')thisplot[true_label].set_color('blue')