Форум программистов, компьютерный форум, киберфорум
Наши страницы

2018.05.26 Новый метод как быстро набрать новые данные для кошки

Войти
Регистрация
Восстановить пароль
Оценить эту запись

2018.05.26 Новый метод как быстро набрать новые данные для кошки

Запись от jvf размещена 26.05.2018 в 17:03

Вчера я написал и пожаловался, что данные набирать сложно. Да, скриншоты делать просто. И потом разобрать их -- это не такая сложная задача. Но вот когда речь о домашних животных, то всё проблематичнее.

Рядом с камерой кошка вообще может не ходить.

Нам нужно что-то придумать, чтобы как можно быстрее собирать данные, чтобы не ждать сто лет.

Одну из идей предложил VTsaregorodtsev "Добавление зеркально отражённых снимков легко и просто удвоит объём данных". Спасибо за эту мысль, надо будет её реализовать.

Мне же пришла в голову следующую идея: я уже написал нейронную сеть, пусть не такая правильная, пусть не такая изящная. Но всё же она уже работает и различает кошку от не кошки.

Поэтому мы можем, когда сеть видит кошку, то проигрывать звук. Я поворачиваю голову, и если действительно вижу кошку, то кидаю ей лакомство. Вскоре мой кот только и будет, что вертеться перед камерой, и задача будет выполнена.

Я эту вещь и написал вчера:

У нас уже есть два работающих алгоритма: первый предсказывает кошку на основе координат (83 процента точности). Второй -- на основе свёрточной нейронной сети (87 процентов точности)

machine.make_prediction_with_pandas(x, y, w, h, frame.shape, file_size) - функция, которая предсказыает, есть ли кошка на камере или нет, на основе x, y, w, h -- координаты, которые увидел датчик движения. frame.shape - размер изображения, что видит веб-камера, file_size - размер файла, которые получится, если вырезать то, что увидел датчик движения из основного изображения, чтобы убрать ненужные вещи, а оставить только то, что нам нужно.

machine.give_prediction_file_2(frame[new_y1:new_y2, new_x1:new_x2]) - это функция, которая предсказывает, есть ли кошка или нет, на основе свёрточной нейронной сети. У нас есть изображение frame (то, что видит веб-камера,), и мы вырезаем в ней прямоугольник размером new_y1, new_y2, new_x1, new_x2 (что заметил датчик движения). И сохраняем этот прямоугольник.

Python
1
2
3
mpred1 = machine.make_prediction_with_pandas(x, y, w, h, frame.shape, file_size)
        
mpred2 = machine.give_prediction_file_2(frame[new_y1:new_y2, new_x1:new_x2])
Если один из алгоритмов видит кошку с вероятностью более 50 процентов, то играем звук. Это делаем с помощью функции myDirs.play_sound()
Python
1
2
3
4
5
6
7
8
if mpred > 50:  
            mpath = myDirs.AI_THINK_CAT
            print("Кошка ", mpred)
            myDirs.play_sound()
 
        else:
            print("Кошки нет ", mpred)
            mpath = myDirs.AI_THINK_NOT_CAT
А вот это наша функция для проигрывания звука:
Python
1
2
3
4
5
    def play_sound(self):
 
        song = pyglet.media.load('test.wav')
        song.play()
        pyglet.app.run()
Таким образом любой человек может набрать много данных о своём животном с помощью веб-камеры и развлекаться с данными так, как хочет.

Следующий момент: в прошлом блоге я поделился ссылкой на человека, который имеет степень Phd в машинном обучении. Он написал, что правильные графики, которые очень хорошо описывают модель, должны выглядеть приблизительно так (де, это помогает избавиться от переобучения):

http://img1.imagilive.com/0717/mnist_099671_train_val_loss_acc.png

И вот так:
http://img1.imagilive.com/0717/learningrates.jpg

Я решил запустить свою модель, о которой говорил в прошлом блоге (свёрточную нейронную сеть для распознавания кошки), на своём компьютере, и убедился, что моя модель, доученная на VGG16, очень сильно отличается от того, что должно быть.

Вот мои картинки:
доучиваем сеть с 1024 слоями на последнем слое:
https://imgur.com/a/dTc4ZzG

доучиваем сеть с 256 нейронами на последнем слое:
https://imgur.com/a/bellmDP

доучиваем сеть VGG16 с 128 нейронами на последнем слое:
https://imgur.com/a/GmyauT1

доучиваем сеть VGG16 32 слоями на последнем слое:
https://imgur.com/a/EmeBU24

Видно, что всё, что у нас получилось -- не так хорошо, как должно быть. Но у нас мало данных. Может быть, что-то изменится, когда я наберу по 1 тысяче картинок на каждом классе.

Я решил использовать сеть с 32 нейронами на последнем слое, потому что она даёт наилучший результат на тестовых данных: 85,7 процентов. А также она больше походит на правильный график, который показал человек с Phd в машинном обучении. В то же время 32 нейрона на последнем слое -- это довольно мало, то есть работать будет быстро.

Да, это не самый лучший вариант, но я могу пока и на нём набирать данные, а потом надо будет смотреть, что можно сделать ещё.


2. Интересные видео о машинном обучении

Распознавание объектов на изображениях | Глубокие нейронные сети на Python

https://www.youtube.com/watch?v=5GdtghjJ3-U


1. Для распознавания изображения мы будем использовать следующую нейронную сеть:
изображение -> свой свёртки -> слой свёртки -> слой подвыборки -> слой свёртки -> слой свёртки -> слой подвыборки -> полносвязный список -> полносвязный слой

На каждом слое используется 32 карты признаков. Каждая матрица -- это матрица размера 3 на 3.

Слой подвыборки -- 32 матрица размером 2 на 2.

Вот код:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
import numpy
from keras.datasets import cifar10
from keras.models import Sequential
from keras.layers import Dense, Flatten, Activation
from keras.layers import Dropout
from keras.layers.convolutional import Conv2D, MaxPooling2D
from keras.utils import np_utils
from keras.optimizers import SGD
 
# Задаем seed для повторяемости результатов
numpy.random.seed(42)
 
# Загружаем данные
(X_train, y_train), (X_test, y_test) = cifar10.load_data()
# Размер мини-выборки
batch_size = 32
# Количество классов изображений
nb_classes = 10
# Количество эпох для обучения
nb_epoch = 25
# Размер изображений
img_rows, img_cols = 32, 32
# Количество каналов в изображении: RGB
img_channels = 3
 
# Нормализуем данные
X_train = X_train.astype('float32')
X_test = X_test.astype('float32')
X_train /= 255
X_test /= 255
 
# Преобразуем метки в категории
Y_train = np_utils.to_categorical(y_train, nb_classes)
Y_test = np_utils.to_categorical(y_test, nb_classes)
 
# Создаем последовательную модель
model = Sequential()
# Первый сверточный слой
model.add(Conv2D(32, (3, 3), padding='same',
                        input_shape=(32, 32, 3), activation='relu'))
# Второй сверточный слой
model.add(Conv2D(32, (3, 3), activation='relu', padding='same'))
# Первый слой подвыборки
model.add(MaxPooling2D(pool_size=(2, 2)))
# Слой регуляризации Dropout
model.add(Dropout(0.25))
 
# Третий сверточный слой
model.add(Conv2D(64, (3, 3), padding='same', activation='relu'))
# Четвертый сверточный слой
model.add(Conv2D(64, (3, 3), activation='relu'))
# Второй слой подвыборки
model.add(MaxPooling2D(pool_size=(2, 2)))
# Слой регуляризации Dropout
model.add(Dropout(0.25))
# Слой преобразования данных из 2D представления в плоское
model.add(Flatten())
# Полносвязный слой для классификации
model.add(Dense(512, activation='relu'))
# Слой регуляризации Dropout
model.add(Dropout(0.5))
# Выходной полносвязный слой
model.add(Dense(nb_classes, activation='softmax'))
 
# Задаем параметры оптимизации
sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='categorical_crossentropy',
              optimizer=sgd,
              metrics=['accuracy'])
# Обучаем модель
model.fit(X_train, Y_train,
              batch_size=batch_size,
              epochs=nb_epoch,
              validation_split=0.1,
              shuffle=True,
              verbose=2)
 
# Оцениваем качество обучения модели на тестовых данных
scores = model.evaluate(X_test, Y_test, verbose=0)
print("Точность работы на тестовых данных: %.2f%%" % (scores[1]*100))
В качестве активации мы используем функцию relu. Эта функция даём максимум на промежутке от 0 до x. Исследования показали http://www.cs.toronto.edu/%7Efritz/absps/imagenet.pdf , что эта функция очень быстрая для больших нейронных сетей.

Однако функция relu не всегда самая лучшая, о чём написано здесь: http://cs231n.github.io/neural-networks-1/#nn

Unfortunately, ReLU units can be fragile during training and can “die”. For example, a large gradient flowing through a ReLU neuron could cause the weights to update in such a way that the neuron will never activate on any datapoint again. If this happens, then the gradient flowing through the unit will forever be zero from that point on. That is, the ReLU units can irreversibly die during training since they can get knocked off the data manifold. For example, you may find that as much as 40% of your network can be “dead” (i.e. neurons that never activate across the entire training dataset) if the learning rate is set too high. With a proper setting of the learning rate this is less frequently an issue.

Также мы используем функцию Dropout -- это техника для предотвращения переобучения. Мы случайным образом выбрасываем определённый процент. Она помогает избавиться от переобучения. Основная идея -- нейроны с заданной вероятностью отключаются.

Оставшиеся нейроны обучаются распознавать необходимые признаки без участия соседних.

Параметр shuffle, установленный в True, - библиотека Keras в начале каждого обучения будет перемешивать данные, чтобы они шли в разном порядке. Это повышает качестве обучения, так как мы используем оптимизатор "SGD".

2. Интересные тексты о машинном обучении

https://www.kaggle.com/arthurtok/int...lity-reduction

По этой ссылке рассказывается о том, как сократить размерность наших данных. "Если мы сможем перенести наши данные из более высокомерного пространства в более низкое, сохраняя большую часть соответствующей информации, это облегчит жизнь нашим методам обучения".

Мы загружаем наш код из базы данных MNIST.

В тренировочной базе у нас 42 тысячи значений, каждое -- массив из 785 значений, то есть у нас 42 тысячи картинок.

PCA - это линейная трансформация, цель которой -- уменьшить размерность, сохранив большую часть полезной информации.

Итак, у нас есть 785 значений, каждое -- это точка на изображении. Но оказывается, что мы можем заменить 785 значений на 200, потому что почти ту же картинку могут показывать всего 200 параметров.

Подробнее о PCA написано здесь: http://stats.stackexchange.com/a/140579/3277

Там говорится, что PCA не выбирает некоторые характеристики и не отбрасывает другие. Вместо этого он обобщает старые характеристики, сжимает их, чтобы в сжатой форме показывать приблизительно то же самое. И это положительно скажется потом на машинных алгоритмах обучения.
Размещено в Без категории
Просмотров 346 Комментарии 1
Всего комментариев 1

Комментарии

  1. Старый комментарий
    Цитата:
    momentum=0.9
    Прикольно смотреть на устойчивость мифов (или с потолка взятых констант), когда ровно 2 года назад (в мае 2016) люди из Стэнфорда показали, что оптимальный (с точки зрения скорости сходимости) коэффициент может быть даже отрицательным в случае обучения нейронки на асинхронной системе (хоть на многоядернике, хоть на кластере, хоть где ещё - но именно при асинхронных апдейтах весов).
    Хотя, если у Вас всё только на видюхе считается - можете в меньшей степени задумываться над выбором значения этой константы.
    Запись от VTsaregorodtsev размещена 27.05.2018 в 22:12 VTsaregorodtsev вне форума
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru