Keras - обучение сети распознаванию рукописных цифр | #8 нейросети на Python

Создаем полносвязную сеть в Keras для распознавания рукописных цифр из базы MNIST. Рассматриваются вопросы подготовки тестовой, обучающей и проверочной выборок. Критерий качества (loss function) - категориальная кросс-энтропия (categorical_crossentropy). Добавление метрики 'accuracy' - доля правильно распознанных образцов. Использование параметра validation_split - для выделения из обучающей выборки набора наблюдений для валидации. Оценка качества работы обученной сети на тестовом множестве.
Телеграм-канал: t.me/machine_learning_selfedu
Инфо-сайт: proproprogs.ru
Исходник (lesson 8. keras_digits.py): github.com/selfedu-rus/neural...
Документация по Keras: ru-keras.com

Пікірлер: 170

  • @user-xj1vc6oo7k
    @user-xj1vc6oo7k4 жыл бұрын

    Прекрасное сочетание чистой речи, без всяких причмокиваний и слов паразитов, с четким и понятным изложением. Случайно набрел на канал да так заслушался, что весь блок про нейросети на одном дыхании и посмотрел. Талантище!

  • @mmm43kir

    @mmm43kir

    3 жыл бұрын

    да. Для меня это лучший сериал 2020 года.

  • @user-of4dn2wz1k
    @user-of4dn2wz1k3 жыл бұрын

    Многие платные курсы в разы хуже чем этот, спасибо автору++

  • @komazmt
    @komazmt2 жыл бұрын

    Здравствуйте, во-первых, конечно хочу сказать огромное спасибо за ценные знания и приятную подачу. Я новичок, но у меня всё получилось. Вообще я хотел распознавать цифры при помощи веб-камеры в реальном времени. Обученную модель сохранил в файл, далее загрузил в другом проекте где при помощи openCV получал видео с вебки, обрабатывал и преобразовывал в вид (28, 28, 1). Но нейросеть упорно видела везде пять. Изрисовал много бумаги, отдалял-приближал, перекрутил кучу настроек в cv2, сдался и лёг спать. Но потом встал, включил компьютер, инвертнул цвет с чёрного на белый и всё заработало. Сейчас пишу коммент и думаю, что всё логично, что «пустоты» фона это в массивах нули, соответственно чёрный цвет, а сами контуры цифр белые с максимальными значениями. Но догадаться было просто удачей😆

  • @-USER_NAME
    @-USER_NAME Жыл бұрын

    Почти три года ( день в день) изучаю программирование, посидел на разных языках. Но сильнее ваших уроков не встречал . И вот почему. Есть уроки которые объясняют очень простые вещи подробно , таких процентов 70 . Есть уроки которые объясняют ребята с большим опытом ,но они ценят свое время и чаще воспринимают это как способ доп заработка поэтому кратенько сухо . Ещё бывают, толком сам не понял начинает объяснять вижу подчёркнута добрая часть кода , оп затемнение и проект компилируется, у них ,а я плююсь пытаюсь найти решение проблем с версией корявого кода и тд . И получается в первом случае слишком низкий уровень во втором слишком высокий к которому ещё нужно хорошо подготовиться . Но вот чтоб так подробно, такие сложные вещи, это что то не с этой планеты . Спасибо вам большое, счастья,здоровья, долгих лет . 😁

  • @paulkarkarin466
    @paulkarkarin466 Жыл бұрын

    Очень мало людей в русско-язычном сегменте, которые с таким качеством как автор делятся материалом по машинному обучению (я нейросети отношу туда же). Рассказчиков-то много, но талантливых учителей в этой области - единицы. Всего два насчитал, включая автора этого канала.

  • @andrewmaishev2834
    @andrewmaishev28343 жыл бұрын

    Спасибо огромное! Материал подаёте очень подробно и ясно - и это ваш козырь! Изучаю НС пока только по вашему каналу. Пожалуйста, не останавливайтесь :)

  • @user-zt4wx1ks6z
    @user-zt4wx1ks6z Жыл бұрын

    Сергей, Вы большой молодец. Спасибо за курсы!!! Я очень рад, что нашел Ваш канал=)

  • @NizZerbergmaN
    @NizZerbergmaN2 жыл бұрын

    Настолько шикарный контент, что даже такой куркуль как я подписываюсь как спонсор канала.

  • @Vivavatnik
    @Vivavatnik3 жыл бұрын

    спасибо! классно, четко, грамотно, доходчиво. Очень сложно найти что-то столь же детализировано, для новичков, еще и на русском, спасибо!

  • @eswcpoker6562
    @eswcpoker65624 жыл бұрын

    отличный канал . Хотелось бы в дальнейшем видео про обучение с подкреплением увидеть на python

  • @maximbravtsev3648
    @maximbravtsev3648 Жыл бұрын

    Огромное спасибо за объяснение базовых основ!

  • @sledleo
    @sledleo Жыл бұрын

    Шеф, супер тема! И подача просто огонь, даже тупым как я доходит слёту! Спасибо за труды и просвещение нас недалеких!!! Респект!!!!

  • @TyomaStrum
    @TyomaStrum3 жыл бұрын

    Очень хорошее пояснение, поймет любой, поверьте, даже я в свои 15 лет

  • @user-xv4bo4te5w
    @user-xv4bo4te5w4 ай бұрын

    Привет, Автор. Не знаю, найдешь ли ты мой комментарий в столь большом количестве уведомлений. Да и не помню, писал ли я тебе что-то подобное...Прости, память на мелочи у меня ужасна😅 Но хочу сказать огромное спасибо за данный плейлист. А также прошу никогда не удалять его. Настолько понятное и бесплатное объяснение я больше нигде не найду. Спасибо за твои труды. Не смотря на малый доход, ты все равно создал его. Еще раз спасибо❤

  • @viktorpavlov4499
    @viktorpavlov44993 жыл бұрын

    Спасибо большое за урок!

  • @user-qe5gw9yh8g
    @user-qe5gw9yh8g3 жыл бұрын

    превосходный материал и его подача

  • @RaceOTT
    @RaceOTT Жыл бұрын

    Повторив НС из видео, в блоке "model.compile" выходила ошибка "ValueError: Error when checking input: expected flatten_input to have 4 dimensions, but got array with shape (60000, 28, 28)" Почитав комменты, проставил "Flatten(input_shape=(28, 28))" - без единички в конце и всё заработало. А так, большое спасибо автору за очень классные видео!

  • @user-uf3qh3fr7d
    @user-uf3qh3fr7d Жыл бұрын

    Спасибо четко объясняешь)

  • @user-gp5hg2xu2s
    @user-gp5hg2xu2s2 жыл бұрын

    супер уроки!

  • @user-ni9dc6fs5y
    @user-ni9dc6fs5y9 ай бұрын

    Невероятно крутой канал! Всё очень понятно объясняет автор. Возник вопрос: а как убирать ошибки, которые рассмотрели в конце? Надеюсь, следующий урок про это!

  • @user-gx1zf3nf5y
    @user-gx1zf3nf5y Жыл бұрын

    Спасибо большое!

  • @hinomuratomisaburo4901
    @hinomuratomisaburo49013 жыл бұрын

    Блин круто 😃👈👈

  • @RomanUnreal
    @RomanUnreal5 ай бұрын

    Если у кого не получается такая же точность распознавания, проверьте, может у вас закончились вычислительные единицы гугл колаб, он теперь ПЛАТНЫЙ.

  • @user-ju1gt8zr5p
    @user-ju1gt8zr5p8 ай бұрын

    Я люблю тебя, лучшее обяснение. Где ты работаеш?

  • @annaponomarova3472
    @annaponomarova34723 жыл бұрын

    Amazing!!!!!!!!

  • @user-he5bd6zs6n
    @user-he5bd6zs6n9 ай бұрын

    Спасибо. Хороший материал. Не совсем понятно,как интерпретировать выходные значения вероятности (тайм код 19.33) Это что за цифры проценты или ещё что-то? По идее сумма вероятностей всех классов не может быть больше 1. А здесь 4.78..., 5,05...., 9,99.... итд. Эти цифры как нибудь соотносятся с метрикой точности?

  • @freshmen5491
    @freshmen54914 жыл бұрын

    Знаю что автор в отпуске, но как можно с ним связаться. Не сейчас, а вообще🙂

  • @vladimirtyushkin8580
    @vladimirtyushkin85802 жыл бұрын

    Спасибо за лекци, очень интересно но есть один вопрос, почему после обучения модели, для предикшена нужен трехмерный тензор,а не Flatten из пикселей изображения?

  • @selfedu_rus

    @selfedu_rus

    2 жыл бұрын

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

  • @irvinexxi
    @irvinexxi2 жыл бұрын

    Ребята, ставя лайки этому видео, главное помните: что кликнуть надо нечетное количество раз.

  • @ivanuppercube931
    @ivanuppercube9312 жыл бұрын

    а можно каким то образом подключить похожую нейросеть в игровой движок?

  • @antonevdokimov8218
    @antonevdokimov82183 жыл бұрын

    🔥🔥🔥🔥🔥🔥🔥🔥🔥

  • @user-lu8vw1ud1f
    @user-lu8vw1ud1f3 жыл бұрын

    Спасибо за видео. Подскажите можно ли картинку закинуть с помощью js в питон, который обработает и результат передаст назад в js?

  • @selfedu_rus

    @selfedu_rus

    3 жыл бұрын

    можно, посмотрите в сторону Ajax

  • @sergeygetto7480
    @sergeygetto74802 жыл бұрын

    Пробовал с различным числом слоёв и нейронов. В принципе 128 подходят отлично, единственное, что дало небольшой + к верным ответам нейронной сети - это количество эпох. На самом деле много делать не надо, так как начинает скакать шанс на дополнительной выборке, а так самый оптимальный найденный вариант около 7 эпох.

  • @selfedu_rus

    @selfedu_rus

    2 жыл бұрын

    Да, верно, это очень простая задачка, вроде "Hello World!" в программировании. Ради интереса попробуйте распознать базу изображений CIFAR-10, там намного сложнее )

  • @sergeygetto7480

    @sergeygetto7480

    2 жыл бұрын

    @@selfedu_rus На самом деле я жду конца курса, я хочу быстро пройтись, а после заострить внимание на том, что мне действительно нужно. Так как лучший учитель это практика. Ваши видео на самом деле крайне подробные. Условно говоря я не мог понять, что такое производные посмотрев порядка 15 видео, на вашем же понял. Тоже самое и с нейронными сетями, да и на самом деле сначала писать, а потом разбираться тоже хорошая практика, как раз подходящая для программирования)

  • @user-tb4pe2tt8e
    @user-tb4pe2tt8e4 жыл бұрын

    Спасибо очень интересно!

  • @deadmorose4741
    @deadmorose47416 ай бұрын

    А есть ссылка на итоговый коллаб?

  • @user-of3pm6oi1m
    @user-of3pm6oi1m2 жыл бұрын

    В данный момент mnist не скачивается с помощью данной команды: (x_train, y_train), (x_test, y_test) = mnist.load_data() Как я понял, там какая-то проблема в самом keras, скоро должны пофиксить. А пока проблему удалось решить путем скачивания набора данных mnist напрямую и его импорта таким образом: path = './mnist.npz' f = np.load(path) x_train, y_train = f['x_train'], f['y_train'] x_test, y_test = f['x_test'], f['y_test'] f.close()

  • @dimapugach5586
    @dimapugach55862 жыл бұрын

    Спасибо за прекрасный курс, прошел весь и появился вопрос: как преобразовать изображение в формате .png, чтобы можно было его пропустить через эту сеть?

  • @selfedu_rus

    @selfedu_rus

    2 жыл бұрын

    Такой вопрос в телеграм-канал лучше

  • @dimapugach5586

    @dimapugach5586

    2 жыл бұрын

    @@selfedu_rus можно ссылку в таком случае?

  • @sergeyperevozchik3733
    @sergeyperevozchik37332 жыл бұрын

    -Индекс получается седьмой. Может все таки восьмой?

  • @user-cc1yw4pv3e
    @user-cc1yw4pv3e2 жыл бұрын

    эмм, неужели ни у кого не было проблем с импортом tensorflow? "Another metric with the same name already exists."

  • @user-jb1mv6kq4l
    @user-jb1mv6kq4l2 жыл бұрын

    А можно после обучения нс закинуть туда изображение с соответствующим разрешением или написать код в котором можно будет самим нарисовать цифру? И как это реализовать?

  • @selfedu_rus

    @selfedu_rus

    2 жыл бұрын

    да и на следующем занятии я это показываю

  • @user-uk4ww6ln7q
    @user-uk4ww6ln7q Жыл бұрын

    А validation_split каждый раз одни и теже отки берет? Или каждый раз разные? Есть ли какой-нить seed у этого параметра?

  • @selfedu_rus

    @selfedu_rus

    Жыл бұрын

    насколько помню, разбивает случайным образом

  • @user-ir2hh9lr1q
    @user-ir2hh9lr1q3 жыл бұрын

    Спасибо за видео. Скажите если у меня картинка на которой изображено 7+8, 5+3, 4+1 можно ли вашим способом оцифровать всю картинку или надо по одной цифре задавать?

  • @selfedu_rus

    @selfedu_rus

    3 жыл бұрын

    Смотря как ставить задачу. Если распознавание чисел на изображении, то лучше обучить НС распознавать цифры, и реализовать предобработку по выделению цифр из числа. Так будет быстрее и надежнее.

  • @user-ir2hh9lr1q

    @user-ir2hh9lr1q

    3 жыл бұрын

    @@selfedu_rus а этот метод где то уже показан? Я сколько смотрю у всех по одной цифре

  • @selfedu_rus

    @selfedu_rus

    3 жыл бұрын

    @@user-ir2hh9lr1q Это уже вы сами должны реализовать, используя знания по цифровой обработке изображений.

  • @md5alx
    @md5alx3 жыл бұрын

    Спасибо огромное за Ваш труд!!! Вопрос можно ?? Как распознавать десятичные числа и выше. Как пример число 123456. Спасибо.

  • @selfedu_rus

    @selfedu_rus

    3 жыл бұрын

    Есть несколько способов. Первый самый просто (или сложный). Сначала нужно выполнить предобработку изображения и выделить каждую цифру числа, потом распознать. Второй сложнее. Составить обучающую выборку всех используемых чисел в задаче и обучить НС их распознавать. Но это не всегда возможно - чисел очень много!

  • @user-ni9dc6fs5y

    @user-ni9dc6fs5y

    9 ай бұрын

    ​@@selfedu_rusздравствуйте! А как научить разделять изображение на отдельные числа?

  • @selfedu_rus

    @selfedu_rus

    9 ай бұрын

    @@user-ni9dc6fs5y Это уже нужно применять различные техники из обработки изображений (целое научное направление). Многое зависит от решаемой задачи.

  • @mar_kha
    @mar_kha2 жыл бұрын

    Собираюсь посмотреть видео, но прежде, хочу спросить: 🖥️ Есть ли приложение для распознавания русского рукописного текста и перевода в текстовый формат? Те, что я находила: - функционал ограничен (распознование только английского текста) - некорректны (вместо текста какие-то квакозябры) ___ Устроилась лаборантом на кафедру информатики. Дали задание: набрать рукописные конспекты в Word (составлял профессор, которому сделали операцию на глазах, и сам он не в состоянии справиться с работой). В одном учебном пособии (а их минимум 5 штук) около сотни страниц рукописного текста! Я конечно могу набрать - не проблема, да вот хотелось бы оптимизировать процесс (всё-таки на программиста учусь не ради "корочки" , а чтоб быть полезной обществу) ___ И вот я здесь, чтоб самостоятельно (почти - ещё у преподавателей буду консультироваться) разобраться в теме нейросетей, и разработать приложение (цель амбициозная, но мне необходимо поспешить - неизвестно, сколько профессору жить осталось). Надеюсь данное видео поможет разобраться со сложившейся ситуацией

  • @selfedu_rus

    @selfedu_rus

    2 жыл бұрын

    FineReader лучшая прога по распознаванию

  • @mar_kha

    @mar_kha

    2 жыл бұрын

    @@selfedu_rus Спасибо) Решила набрать текст голосом

  • @user-kg7pn2sn6t
    @user-kg7pn2sn6t10 ай бұрын

    Большое спасибо, Сергей, классно объясняете. Остался вопрос, на который чат gtp так и не ответил правильно: почему кросс энтропия? Ведь значения ноль при умножении на логарифм пресказания убирает из ошибки, а это ошибка и её нужно уменьшать. Чат ответил, что не участвует в предсказании, поэтому не нужен.

  • @selfedu_rus

    @selfedu_rus

    10 ай бұрын

    Спасибо! Практика показала, что кросс-энтропия приводит к хорошим результатам в задачах классификации (часто бинарной). Когда один класс хорошо прогнозируется, то оба слагаемых устремляются к нулю, и наоброт.

  • @user-kg7pn2sn6t

    @user-kg7pn2sn6t

    10 ай бұрын

    Спасибо. Такой ход мыслей у меня был как догадка.

  • @user-kg7pn2sn6t
    @user-kg7pn2sn6t10 ай бұрын

    Ещё раз большое спасибо за классные лекции. По этой лекции остался вопрос по синкасису питона. Нигде не нашёл правила, по которому если координатами списка является список с булевыми компонентами, где у вас maska, то в операторе присваивания выделяются только компоненты true. Это действительно есть такой синтаксис? Он только у python?

  • @selfedu_rus

    @selfedu_rus

    10 ай бұрын

    Спасибо! Про True - это порядок работы библиотеки NumPy, которая совместно применяется с Keras и Tensorflow

  • @user-kg7pn2sn6t

    @user-kg7pn2sn6t

    10 ай бұрын

    Большое спасибо. Сидим с сыном и разбираемся. Очень интересно.

  • @sergeyv1534
    @sergeyv15343 жыл бұрын

    22:51 Можете пояснить этот момент с маской более подробно? Почему был выбран вариант записи «mask = pred == y_test» в противовес «mask = pred != y_test»? Инверсия маски при помощи тильды «~» - это синтаксис самого Keras (в самом Python такого не встречал)? Попробовал оба варианта (во втором случае с «!=» также убиралась тильда «~») - существенных отличий в результате не заметил.

  • @selfedu_rus

    @selfedu_rus

    3 жыл бұрын

    так работают списки пакета numpy, мы им можем передавать (в качестве индексов) булевый массив и он вернет только те элементы, где стоит True

  • @sergeyv1534

    @sergeyv1534

    3 жыл бұрын

    @@selfedu_rus Если правильно понимаю, особых различий в формах записи нет: «mask = pred == y_test» далее индекс с «~» и «mask = pred != y_test» указание индекса без «~».

  • @selfedu_rus

    @selfedu_rus

    3 жыл бұрын

    @@sergeyv1534 да, все верно

  • @alexanderdushenin7035
    @alexanderdushenin70353 жыл бұрын

    Добрый вечер. Подскажите, пожалуйста: 1) Почему у меня при распознавании тестовой выборки (model.evaluate(x_test,y_test_cat)) значение метрики составляет 8% (а не 97%, как у Вас)? 2) Для чего мы делим на 255? То, что стандартизация - это я понимаю. Непонятно, что мы в итоге подаём на вход НС

  • @selfedu_rus

    @selfedu_rus

    3 жыл бұрын

    На первый вопрос сложно ответить вот так вот. Если метрика такая же как и в видео, и выборка та же самая, то значение должно быть близко к 97% Если не так - где то ошибка. По второму вопросу. Деление на 255 - это стандартизация входных данных, чтобы они менялись в диапазоне от 0 до 1. Это делается, чтобы диапазон входных значений при обучении и при эксплуатации НС был одним и тем же - это важно. Ну а подаем на вход НС стандартизированную обучающую выборку (изображения цифр).

  • @alexanderdushenin7035

    @alexanderdushenin7035

    3 жыл бұрын

    Спасибо. По поводу второго вопроса - я имел в виду принцип подачи изображения на НС. Но, посмотрев следующее видео, я все понял)

  • @user-cc7fi2ul3z
    @user-cc7fi2ul3z3 жыл бұрын

    Здравствуйте, а как импортирвать датасет, который у меня на компьютере лежит?

  • @selfedu_rus

    @selfedu_rus

    3 жыл бұрын

    Загрузить как файл, а потом преобразовать в формат массива numpy. Эту операцию, обычно, с помощью пакета Pandas делают.

  • @user-yi6kc5ys2n
    @user-yi6kc5ys2n3 жыл бұрын

    Спасибо за подробный рассказ! Уточню один момент - когда мы проверяем сеть на одном изображении превращаем вектор в трехмерный тензор - это потому что стандартно изображения мы должны подавать в виде трехмерного тензора (длина, ширина, каналы), так? Но почему, когда мы прогоняем всю тестовую выборку через сеть, то уже не делаем такого расширения?

  • @selfedu_rus

    @selfedu_rus

    3 жыл бұрын

    Тестовая выборка тоже имеет вид трехмерного тензора. Когда мы их загружаем mnist.load_data(), то на выходе уже имеем нужный формат.

  • @user-yi6kc5ys2n

    @user-yi6kc5ys2n

    3 жыл бұрын

    @@selfedu_rus тогда не соображу пока, почему отдельный элемент этой же выборки не в нужном формате?

  • @user-yi6kc5ys2n

    @user-yi6kc5ys2n

    3 жыл бұрын

    Наверное, понял. Тестовая выборка в данном случае представлена, как 10000 слоев двумерных массивов и в целом это трёхмерный тензор. А если из неё вырезать одно изображение, то это будет двумерный массив. Правильно?

  • @selfedu_rus

    @selfedu_rus

    3 жыл бұрын

    @@user-yi6kc5ys2n да, верно!

  • @MurzNN
    @MurzNN9 ай бұрын

    Будет ли разница в результатах, если подавать вектор по вертикальным строкам изображения, а не горизонтальным? И можно ли подавать трёхмерный входящий вектор? Т.е. не построчно изображение, а сразу в двух измерениях?

  • @selfedu_rus

    @selfedu_rus

    9 ай бұрын

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

  • @vladislavkondak3055
    @vladislavkondak30553 жыл бұрын

    Добрый день. Можно ли этой же нейронной сетью распознать произвольную фотографию? Если да, то как это сделать?

  • @selfedu_rus

    @selfedu_rus

    3 жыл бұрын

    Это будет не лучшее решение. Для обработки изображений рекомендуется использовать сверточные сети (об этом дальше в курсе). Мало того, существуют стандартные структуры сверточных НС VGG-16 и VGG-19, поставляемые с Keras, которые хорошо решают эту задачу. (Также см. в этом курсе).

  • @vladislavkondak3055

    @vladislavkondak3055

    3 жыл бұрын

    @@selfedu_rus Спасибо!

  • @utka111
    @utka111 Жыл бұрын

    Здравствуйте, Сергей! Как можно с вами связаться? Можете дать e-mail?

  • @tsoer2976
    @tsoer29763 жыл бұрын

    Добрый день хочу уточнить. Нет у меня, четкого понимая, время на видео 13:29 компиляция модели. аргумент optimezator='adam' необходим, чтобы находить лямбда(шаг), аргумент loss='categorial_crossentropy' нужен для формирования функции которая вычисляет ошибку. Последний для формирования отчета хорошо ли обучена наша модель. Если не верно прошу Вас объяснить, где и почему. Спасибо за видео

  • @selfedu_rus

    @selfedu_rus

    3 жыл бұрын

    Не совсем. Оптимизиатор - это способ улучшить алгоритм градиентного спуска, при этом шаг сходимости определен по умолчанию как 0,001 (вроде бы, см. документацию по Keras). Если шаг нужно поменять, то следует создать свой оптимизатор адам с помощью класса Adam(lr=0,01) - здесь lr - шаг сходимости. Далее, про функцию потерь верно, а метрика - это процент ошибок. Мы определяем дополнительно свои метрики, т.к. именно они нам нужны для анализа работы сети. Но градиентный спуск не может их минимизировать напрямую, т.к. там отсутствуют частные производные. Поэтому выбираем функцию потерь, которая, как нам кажется, будет минимизировать нужную нам метрику, в данном случае accuracy. Примерно так.

  • @tsoer2976

    @tsoer2976

    3 жыл бұрын

    @@selfedu_rus Тогда совсем не понял. Как происходит обратное распространение ошибки? Если смотреть ваше уроки. То оптимизатор нам не нужен. Для получения коэффициентов(весов) достаточно рассчитать фикцию потерь и множить ее на производную функции выхода слоя. В какой момент нам становится необходим оптимизатор? То есть я вижу логику, так взяли случайные веса прошли вперед по сети -> получили выход -> сравнили с результатом и получили ошибку с помощью фикции loss-> откорректировали веса обратным распространением. Конец первой эпохи и так идем по всему дата сету. После сделали оценку качества модели. Скажите где я пропускаю градиентный спуск совсем запутался

  • @selfedu_rus

    @selfedu_rus

    3 жыл бұрын

    @@tsoer2976 В объяснении алгоритма back propagation его и нет - там только стандартный градиентный спуск. Оптимизатор модифицирует градиентный спуск для более быстрого нахождения точки минимума. Некоторую инофрмацию об этом можно посмотреть здесь kzread.info/dash/bejne/qnikx5uEnLzQabQ.html

  • @1980PaulL
    @1980PaulL3 жыл бұрын

    У меня ошибку выдает Error when checking input: expected flatten_11_input to have 4 dimensions, but got array with shape (60000, 28, 28) после попытки обучить модель (model.fit(x_train, y_train_cat, batch_size=32, epochs=5, validation_split=0.2))

  • @selfedu_rus

    @selfedu_rus

    3 жыл бұрын

    у вас входной тензор 4-х мерный, а должен быть 3-х мерный

  • @1980PaulL

    @1980PaulL

    3 жыл бұрын

    @@selfedu_rus, я заменил Flatten(input_shape=(28,28,1) на Flatten(input_shape=(28,28), все заработало. И цифры правильно распознает

  • @fedor_vaskin
    @fedor_vaskin Жыл бұрын

    Здравствуйте! Сергей, подскажите, пожалуйста, используется ли здесь у Вас норма обучения? Где её нужно указывать? Не очень понял этот момент.

  • @selfedu_rus

    @selfedu_rus

    Жыл бұрын

    Что такое "норма обучения"? Впервые слышу.

  • @fedor_vaskin

    @fedor_vaskin

    Жыл бұрын

    @@selfedu_rus обычно отмечают как "мю".

  • @selfedu_rus

    @selfedu_rus

    Жыл бұрын

    @@fedor_vaskin шаг обучения? он в Keras в градиентном спуске автоматически реализован с поправкой на используемый оптимизатор

  • @fedor_vaskin

    @fedor_vaskin

    Жыл бұрын

    @@selfedu_rus спасибо! То есть его в ручную самому никак не поменять, чтобы "поиграть" с разными шагами, посмотреть, как шаг влияет на обучаемость сети?

  • @selfedu_rus

    @selfedu_rus

    Жыл бұрын

    в настройках метода fit можно для выбранного оптимизатора менять начальное значение шага (только тогда оптимизатор должен быть создан как объект, например, Adam(lr=0.0001), здесь lr - начальный шаг... точно название параметра не помню, посмотрите в документации)

  • @nikolaydd6219
    @nikolaydd62192 жыл бұрын

    4:40 Что значит: нейрон bias это смещение? Кто и куда смещается? Смотрел другие модели нейронал, там небыло такого нейрона

  • @selfedu_rus

    @selfedu_rus

    2 жыл бұрын

    см. 2-е занятие (по XOR) там я это подробно объясняю

  • @nikolaydd6219

    @nikolaydd6219

    2 жыл бұрын

    @@selfedu_rus Спасибо. Я смотрел но не понял)

  • @user-nk2ms3rs4s
    @user-nk2ms3rs4s7 ай бұрын

    Здравствуйте, спасибо за видео. А вот если у меня есть целая строка из цифр (5 штук), находящихся постоянно на разных расстояниях. Как я могу обучить ai на распознавание строки, пускай даже фиксированного размера.

  • @selfedu_rus

    @selfedu_rus

    7 ай бұрын

    думаю, это неэффективный подход к задаче, не нужно смотреть на НС, как на универсальный решатель всего, сначала выделите эти цифры и скармливайте их потом НС для распознавания P.S. FineReader в ранних версиях распознавал тексты без всяких НС и делал это великолепно!

  • @YbisZX

    @YbisZX

    2 ай бұрын

    @@selfedu_rus Вы используете функцию to_categorical(), но она только номера в one-hot векторы преобразовывает. А если нужно буквы распознавать? Я сам написал факторизацию под символы, но неужели в keras нет готового решения для перевода любых обозначений классов в категории? # Категоризация любых обозначений классов в one-hot векторы y_set = np.unique(y_train) # желательно объединить y_train с y_test (не потерять редкие классы) y_train_cat = np.array([y_set==y for y in y_train]).astype('float64') y_test_cat = np.array([y_set==y for y in y_test]).astype('float64') # Восстановление обозначений классов по векторам softmax: y_pred = y_set[np.argmax(y_pred_cat, axis=1)]

  • @user-zf1ck5ul4s
    @user-zf1ck5ul4s2 жыл бұрын

    Здравствуйте! Спасибо за ваш прекрасный канал. Решил поэкспериментировать с вашим кодом где я преобразую 784 просто в строку без этих вот команд. Результат вроде бы должен быть одним и тем же. Но при обучении очень высокая ошибка, а у вас она порядка тысячной.. у меня больше 2-х. Почему так? Вы может и не ответите мне, но я все же рискну и спрошу у вас))) import os os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' import numpy as np import matplotlib.pyplot as plt from tensorflow.keras.datasets import mnist # библиотека базы выборок Mnist from tensorflow import keras from tensorflow.keras.layers import Dense, Flatten (x_train, y_train), (x_test, y_test) = mnist.load_data() # стандартизация входных данных x_train = x_train / 255 x_train_my = x_train.flatten() x_test = x_test / 255 x_test_my = x_test.flatten() y_train_cat = keras.utils.to_categorical(y_train, 10) y_test_cat = keras.utils.to_categorical(y_test, 10) plt.imshow(x_train[2], cmap=plt.cm.binary) plt.show() x_train_my_2 = [] x_test_my_2 = [] for i in range(0, int(len(x_train_my)/784)): x_train_my_2.append(x_train_my[i:784 + i]) for ii in range(0, int(len(x_test_my)/784)): x_test_my_2.append(x_test_my[ii:784 + ii]) j = 59999 print(len(x_train_my_2[j])) print(y_train_cat[j]) model = keras.Sequential() model.add(Dense(128, input_shape=(784,), activation='relu')) model.add(Dense(10, activation='softmax')) print(model.summary()) model.compile(optimizer=keras.optimizers.Adam(0.001), loss='categorical_crossentropy', metrics=['accuracy']) model.fit(np.array(x_train_my_2), y_train_cat, batch_size=32, epochs=5, validation_split=0.2) model.evaluate(np.array(x_test_my_2), y_test_cat) А вот что выдает при обучении: Epoch 1/5 1500/1500 [==============================] - 4s 3ms/step - loss: 2.3098 - accuracy: 0.1074 - val_loss: 2.3103 - val_accuracy: 0.1040 Epoch 2/5 1500/1500 [==============================] - 3s 2ms/step - loss: 2.3006 - accuracy: 0.1151 - val_loss: 2.3081 - val_accuracy: 0.1073 Epoch 3/5 1500/1500 [==============================] - 4s 2ms/step - loss: 2.2931 - accuracy: 0.1226 - val_loss: 2.3148 - val_accuracy: 0.1024 Epoch 4/5 1500/1500 [==============================] - 4s 2ms/step - loss: 2.2795 - accuracy: 0.1344 - val_loss: 2.3242 - val_accuracy: 0.1042 Epoch 5/5 1500/1500 [==============================] - 4s 2ms/step - loss: 2.2580 - accuracy: 0.1529 - val_loss: 2.3411 - val_accuracy: 0.1020 очевидно что ничего не распознается правильно

  • @selfedu_rus

    @selfedu_rus

    2 жыл бұрын

    Проверьте в строчке x_train_my = x_train.flatten() возможно здесь структура тензора нарушается, он должен быть (batch_size, count_digits), а вы все в один вектор развертываете. И, насколько я помню, на вход можно подавать изображение, а затем, применять слой Flatten - это разные вещи (с вашей реализацией).

  • @user-zf1ck5ul4s

    @user-zf1ck5ul4s

    2 жыл бұрын

    @@selfedu_rus спасибо вам большое что ответили) У меня как раз и была цель для лучшего понимания развернуть все это в один вектор. Чтобы потом получив весовые коэффициенты организовать просто путем перемножения матриц проверит нейросеть что она выдает те же значения. Потому что например в матлабе пакет neiral network toolbox вводит своих пользователей в заблуждение и получив весовые коэффициенты оттуда и применяя функции активации получается абсолютно другой результат. А следовательно обученную нейронную сеть у них нельзя использовать в других программах. Вот поэтому я решил проверить на это же Keras) буду разбираться. Спасибо ещё раз вам огромное за столь быстрый ответ)

  • @wian39
    @wian392 жыл бұрын

    Добрый день. Пробую распознать свои рукописные цифры данной нейросетью. Создаю список с названиями файлов и загружаю изображения (уже 28х28), используя Pillow (image = Image.open(file).convert('L')), затем преобразую в массив numpy и стандартизирую. Добавляю получившиеся массивы в список и создаю массив numpy на основе этого списка. Далее подаю нейросети, но она видит везде тройки. В чем может быть ошибка? Помимо Pillow пробовал использовать OpenCV, но происходило всё то же самое.

  • @selfedu_rus

    @selfedu_rus

    2 жыл бұрын

    Формат изображения должен быть 28x28 grayscale (градации серого) один цветовой канал. Возможно здесь ошибка.

  • @wian39

    @wian39

    2 жыл бұрын

    @@selfedu_rus , после преобразовании картинки в массив shape показывает (28, 28), а конечный массив, который подаётся на нейросеть (10, 28, 28). Попробовал сделать тоже самое, только на OpenCV видит те же тройки. Код: filenames = [...] data = [ ] for file in filenames: image = cv2.imread(file, cv2.IMREAD_GRAYSCALE) img = image / 255 data.append(img) ara = np.array(data) pred = model.predict(ara) res = np.argmax(pred, axis=1) print(res) upd: т.е. я загружаю картинки уже приведённые к размеру 28х28. Или стоит загружать обычные, приводя внутри программы их размер к нужному?

  • @selfedu_rus

    @selfedu_rus

    2 жыл бұрын

    @@wian39 нужно добавить 1-ю ось (например, с помощью метода expand_dims() массива array numpy)

  • @wian39

    @wian39

    2 жыл бұрын

    @@selfedu_rus Добавляя эту ось к изображению, на выходе получаю ошибку: ValueError: Input 0 of layer "sequential" is incompatible with the layer: expected shape=(None, 28, 28, 1), found shape=(None, 1, 28, 28). Конечный массив в этом случае получается (10, 1, 28, 28). Для сравнения взял изображение из тестовой выборки сделал для него всё тоже самое, на выходе получил верный результат. Попробовал сделать это для 1-го своего изображения, predict сработал, но распозналась тройка вместо нужной семёрки upd: Если сделать reshape массива, который подаётся на predict, к размеру (10, 28, 28,1), то сам predict работает, однако выдаёт те же тройки. Возможно проблема в том, что мои изображения умещаются в 10х10 пикселей, хотя в mnist изображения выглядят раза в 2 больше. upd: Подогнал размер цифры примерно под размер цифры в mnist, всё одно: видит тройку

  • @selfedu_rus

    @selfedu_rus

    2 жыл бұрын

    @@wian39 посмотрите внимательно формат осей в mnist и сделайте по аналогии для одного изображения

  • @nik0294
    @nik02943 жыл бұрын

    Привет. А как обучить нейросеть своими данными вместо mnist

  • @selfedu_rus

    @selfedu_rus

    3 жыл бұрын

    Очень просто, составляете свой набор данных (изображений, например) в виде многомерного массива NumPy и подаете на вход сети.

  • @nik0294

    @nik0294

    3 жыл бұрын

    @@selfedu_rus Ура у меня это получилось. СПАСИБО!!!

  • @Dmitrii82
    @Dmitrii823 жыл бұрын

    а где найти описания этих команд? flatten dense и тд.

  • @selfedu_rus

    @selfedu_rus

    3 жыл бұрын

    в официальной документации по Keras: keras.io/guides/

  • @user-km9re6om7j
    @user-km9re6om7j3 жыл бұрын

    Какие - то космические 99% получились у вас))

  • @user-qb5bo3jv3e
    @user-qb5bo3jv3e2 жыл бұрын

    Интересно, для Flatten input_shape выглядит так: (28,28,1), однако ближе к концу видео вы подаете на вход сети x, который равен x = np.expand_dims(x_test[n], axis=0). Но если посмотреть print("x.shape", x.shape), то окажется, что его форма имеет вид не (28,28,1) как это ожидает Flatten, а (1,28,28) и несмотря на это все работает. Как это следует понимать?)

  • @selfedu_rus

    @selfedu_rus

    2 жыл бұрын

    в Keras первая размерность - это всегда batch_size, то есть, размер мини-батча. Явно не прописывается, но автоматически добавляется.

  • @user-qb5bo3jv3e

    @user-qb5bo3jv3e

    2 жыл бұрын

    @@selfedu_rus Спасибо, просто не совсем понятно, как размерность входных данных согласуется с размерностью, которая задана для слоя Flatten. Размерность x это (1,28,28) тут все понятно. У нас батч, состоящий из одной картинки размера 28х28. На вход сети мы подаем картинки. То есть данные, размера 28х28. Согласно этой логике, input_shape на Flatten слое должен быть (28,28) а не (28,28,1) т.к это уже получается трехмерные данные, а мы на вход ведь подаем двумерные данные, вот что к сожалению непонятно...

  • @selfedu_rus

    @selfedu_rus

    2 жыл бұрын

    @@user-qb5bo3jv3e Последнее число - это количество каналов: 1 - градация серого (как правило); 3 - RGB (или какие-либо еще), поэтому, прописывая 28,28,1 мы тем самым оговариваем картинку с одним цветовым каналом.

  • @user-qb5bo3jv3e

    @user-qb5bo3jv3e

    2 жыл бұрын

    @@selfedu_rus Интересно, спасибо. Однако сеть ведь не знает что мы работаем с изображениями, разве в таком случае мы можем рассуждать в терминах изображений? (т.е упомянать градации серого и т.д). Я попробовал указать input_shape как (28,28) вместо (28,28,1) для Flatten, и все работает точно так же. Получается что последнюю единичку можно не писать?

  • @selfedu_rus

    @selfedu_rus

    2 жыл бұрын

    @@user-qb5bo3jv3e Сети все равно что поступает на вход, она лишь строит модель зависимости входов от выходов не более того. Насчет единички, возможно, ее можно и не указывать, но для цветного точно нужно.

  • @iwantapetfox9262
    @iwantapetfox92623 жыл бұрын

    Результат всегда 0. Как исправить?

  • @nikolaydd6219
    @nikolaydd62192 жыл бұрын

    А как передавать нейронке печатные буквы, ведь они разной ширины. Например буква П может уместится в 28х28 а вот буква Щ уже не поместится, либо ТОЧКА, она вообще в длину пару пикселей. Как распознавать печатный текст, а не по одной буквы рукописного?

  • @selfedu_rus

    @selfedu_rus

    2 жыл бұрын

    это уже другая задача, здесь мы полагаем, что буквы умещаются в 28x28 пикселей

  • @nikolaydd6219

    @nikolaydd6219

    2 жыл бұрын

    @@selfedu_rus А какие-то рекомендации есть =)? Думается мне, что например выходной нейрон ТОЧКИ должен считать только те веса, в входные нейроны которых умещается заданная буква, а веса от остальных нейронов по нулям. Такой подход сработает?

  • @selfedu_rus

    @selfedu_rus

    2 жыл бұрын

    @@nikolaydd6219 думаю нет, т.к. связи используются совместно для классификации разных образов и просто обнулять их, значит создавать проблемы для распознавания других символов

  • @rpuropu
    @rpuropu3 жыл бұрын

    а где размер y_train_cat задаётся? не понятен этот момент. через два урока вы очень детально поясните как можно вручную рандомно сделать валидационную выборку.. но я вот хотел поменять число батчей.. для этого хочу высчитать размерность... всего там 70 000 ... 10 000 тестовых это в самой библиотеке прпоисано что ли? а я вот хочу что бы у меня тестовая выборка из 10 000 каждый раз сама рандомилась от всех 70 тысяч.. есть методы? или в load_data() что-то там вшито... и там можно не писать mnist... а как тогда сделать заготовку... куда можно будет приписать load_data()

  • @selfedu_rus

    @selfedu_rus

    3 жыл бұрын

    При загрузке данных вы получаете весь объем данных, которые условно разбиты на обучающую и тестовую выборки. Вы можете взять обучающую из 60 000 образцов и уменьшить ее до любого другого числа и то же самое с тестовой. Также можете перемешать обучаюущую и тестовую выборки и самостоятельно решить сколько взять для обучения и сколько для теста. А как конкретно сделать - средствами NumPy + функции для перемешивания наблюдений о которых я говорил на занятиях.

  • @rpuropu

    @rpuropu

    3 жыл бұрын

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

  • @user-gx1zf3nf5y
    @user-gx1zf3nf5y Жыл бұрын

    А какой алгоритм здесь используется? Сеть хебба, розенблатта или что?

  • @selfedu_rus

    @selfedu_rus

    Жыл бұрын

    для обучения back propagation

  • @user-gx1zf3nf5y

    @user-gx1zf3nf5y

    Жыл бұрын

    @@selfedu_rus спасибо!

  • @_nickname_nickname_
    @_nickname_nickname_3 жыл бұрын

    У меня была проблема, при обучении и валидации всё норм, а при тесте выдает ошибку 97%)) Делал всё как у вас, посмотрел код на гите - всё как у вас. Может я где-то у вас это не заметил, но допер как решить проблему - надо добавить 2 строчки: x_test = x_test / 255 y_test = y_test / 255 и тогда всё заработало норм. Не понимаю как у вас без этого работает. А еще после первой эпохи у меня accuracy равен 1 upd чот я вообще не понимаю - поставил 1 скрытый нейрон вместо 128 и 2 эпохи, на тестовой выборке вывелось: 313/313 [==============================] - 1s 2ms/step - loss: 0.1420 - accuracy: 1.0000 upd_2 Короче я удалил строки со стандартизацией и всё стало нормально выдавать, как у вас) upd_3 Вернул обратно стандартизация (x/y)_train, а категории поставил выше - стало точнее считать. upd_4 В выделении неверных вариантов зачем строка "p_false = pred[~mask]" ?

  • @selfedu_rus

    @selfedu_rus

    3 жыл бұрын

    У меня тоже есть эти строчки (см. файл lesson 8. keras_digits.py на гите - ссылка под видео)

  • @_nickname_nickname_

    @_nickname_nickname_

    3 жыл бұрын

    @@selfedu_rus В этом плане ошибку у себя нашел, всё как всегда по не внимательности. Вместо x_test = x_test / 255 написал у_test = у_test / 255 и начались танцы с бубном. Еще не понимаю, почему не работает x_test /= 255 ?

  • @Federation1323
    @Federation13233 жыл бұрын

    ты бох

  • @torbokovsanat
    @torbokovsanat3 жыл бұрын

    +

  • @rpuropu
    @rpuropu3 жыл бұрын

    у меня 91-92%.. постоянно) .. не моё?)

  • @selfedu_rus

    @selfedu_rus

    3 жыл бұрын

    Это тоже хороший результат. Далее будет сверточная нейронная сеть она должна давать лучшие результаты при классификации изображений.

  • @rpuropu

    @rpuropu

    3 жыл бұрын

    @@selfedu_rus я заново по всем окнам в юпитере прошелся, получил 97%..) Спасибо) ради свёрточной я здесь и нахожусь) если честно я удивился что у вас она есть в альбоме с простым названием Нейронные сети. Как-то скромно. а это же уже диплёрнинг. Еслиб не гугл, то я бы даже не догадался заглянуть в этот альбом. так бы и изучал нампай, матплотлиб, жду пандоса, может повезёт и он будет?)

  • @uglevod184
    @uglevod1846 ай бұрын

    вот такой вот RElu...что за relu

  • @selfedu_rus

    @selfedu_rus

    6 ай бұрын

    f(x) = x, x >= 0 и f(x) = 0, иначе

  • @mark-tin
    @mark-tin2 жыл бұрын

    Вроде понятно, но ничего не понятно.

  • @dzakarath
    @dzakarath Жыл бұрын

    строка from transform.keras.datasets import mnist не только в VSC но и в колаборатории не работает, что делать?

  • @forpublic777
    @forpublic7773 жыл бұрын

    Со всем уважением, но слух режет от того что вы ставите ударение на первом слоге на слове сЕти. Привычней в единственном числе ставить на втором слоге (нейронные сЕти, нейронной сетИ).

  • @selfedu_rus

    @selfedu_rus

    3 жыл бұрын

    Правильно произносить сЕти

  • @forpublic777

    @forpublic777

    3 жыл бұрын

    @@selfedu_rus все с Горбачева пошло с его мЫшлением, вместо мышлЕнием

  • @selfedu_rus

    @selfedu_rus

    3 жыл бұрын

    @@forpublic777 проверочное слово сЕть

  • @korsman723
    @korsman7239 ай бұрын

    Много словоблудия, ноль практики. Структура объясняется очень оторвано от контекста, не понятно и откровенно говоря становится скучно смотреть

  • @dgofman1975
    @dgofman1975 Жыл бұрын

    Данные уже нормализированы не знаю зачем дважды нормализировать? # стандартизация входных данных #x_train = x_train / 255 #x_test = x_test / 255 Советую показать раздницу между редикт и тест значениями x_false = x_test[~mask] y_false = y_test[~mask] pred_false = pred[~mask] print(x_false.shape) # Вывод первых 25 неверных результатов plt.figure(figsize=(10,5)) for i in range(25): plt.subplot(5,5,i+1) plt.text(0, 0, "Значение {} != {}".format(y_false[i], pred_false[i])) plt.xticks([]) plt.yticks([]) plt.imshow(x_false[i], cmap=plt.cm.binary) в последних версиях tensorflow keras.layers импортируется так from keras.layers import Dense, Flatten

  • @selfedu_rus

    @selfedu_rus

    Жыл бұрын

    просто принято подавать значения в диапазоне от 0 до 1 (для некоторых функций активаций полезно, например, сигмоида, гиперболический тангенс)

  • @fruktiliyagoda6555
    @fruktiliyagoda6555 Жыл бұрын

    Что такое 'camp=plt.cm.binary'? У меня вообще выдаёт, что не существует такого. Удаляю, всё работает

  • @watson6954

    @watson6954

    10 ай бұрын

    Это влияет на отображение цвета на графиках. По умолчанию они цветные (viridis). Команда 'cmap = plt.cm.binary' (у Вас, кстати, ошибка в написании, поэтому команда не работает) делает изображение черно-белым.

  • @fruktiliyagoda6555

    @fruktiliyagoda6555

    10 ай бұрын

    @@watson6954 большое спасибо. Я и не заметил этой ошибки

  • @user-mu5cj4hv9l
    @user-mu5cj4hv9l7 ай бұрын

    3:45, а вы точно человек, а не нейросеть?)

Келесі