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

Поділитися
Вставка
  • Опубліковано 24 січ 2025

КОМЕНТАРІ • 176

  • @ИльяЗдобнов-т4н
    @ИльяЗдобнов-т4н 3 роки тому +59

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

  • @ВерещагинП.А
    @ВерещагинП.А 4 роки тому +130

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

    • @mmm43kir
      @mmm43kir 4 роки тому +7

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

  • @komazmt
    @komazmt 3 роки тому +34

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

  • @-USER_NAME
    @-USER_NAME Рік тому +9

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

  • @rodionkholodaev4104
    @rodionkholodaev4104 2 місяці тому +1

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

  • @paulkarkarin466
    @paulkarkarin466 2 роки тому +9

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

  • @andrewmaishev2834
    @andrewmaishev2834 4 роки тому +15

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

  • @ДмитрийАлексеев-ц5щ

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

  • @NizZerbergmaN
    @NizZerbergmaN 3 роки тому +3

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

  • @maximbravtsev3648
    @maximbravtsev3648 Рік тому +2

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

  • @sledleo
    @sledleo Рік тому +1

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

  • @TyomaStrum
    @TyomaStrum 4 роки тому +3

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

  • @Vivavatnik
    @Vivavatnik 3 роки тому +1

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

  • @RaceOTT
    @RaceOTT Рік тому +2

    Повторив НС из видео, в блоке "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))" - без единички в конце и всё заработало.
    А так, большое спасибо автору за очень классные видео!

  • @Листик-у3о
    @Листик-у3о Рік тому +1

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

  • @eswcpoker6562
    @eswcpoker6562 4 роки тому +5

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

  • @СарматПересветов
    @СарматПересветов 3 місяці тому +1

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

  • @hinomuratomisaburo4901
    @hinomuratomisaburo4901 4 роки тому +4

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

  • @RomanUnreal
    @RomanUnreal Рік тому +8

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

  • @krasnokutsky-denis
    @krasnokutsky-denis 4 роки тому +1

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

  • @ЮаньКитайский-и6ъ

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

  • @NoName-r7b3m
    @NoName-r7b3m 16 днів тому +1

    Не подскажете, почему без нормализации x_train и y_train все работает, а с нормализацией нет

  • @ДимаДмитрий-е1к
    @ДимаДмитрий-е1к 2 роки тому +1

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

  • @viktorpavlov4499
    @viktorpavlov4499 3 роки тому +1

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

  • @ГеоргийТаманский

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

  • @ТвойДруг-ы6ъ
    @ТвойДруг-ы6ъ Рік тому +1

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

  • @ЛадаХижинская
    @ЛадаХижинская 3 роки тому +1

    супер уроки!

  • @sergeygetto7480
    @sergeygetto7480 3 роки тому +1

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

    • @selfedu_rus
      @selfedu_rus  3 роки тому +1

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

    • @sergeygetto7480
      @sergeygetto7480 3 роки тому +1

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

  • @ЛераБ-и8ц
    @ЛераБ-и8ц 2 роки тому +1

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

  • @nikolaydd6219
    @nikolaydd6219 3 роки тому +2

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

    • @selfedu_rus
      @selfedu_rus  3 роки тому +2

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

    • @nikolaydd6219
      @nikolaydd6219 3 роки тому +1

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

  • @irvinexxi
    @irvinexxi 3 роки тому +2

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

  • @sergeyperevozchik3733
    @sergeyperevozchik3733 3 роки тому +2

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

  • @freshmen5491
    @freshmen5491 4 роки тому +2

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

  • @ВячеславДорофеев-о1б

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

    • @selfedu_rus
      @selfedu_rus  Рік тому

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

    • @ВячеславДорофеев-о1б
      @ВячеславДорофеев-о1б Рік тому

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

  • @utka111
    @utka111 2 роки тому +1

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

  • @ДенисАгапитов-э6у
    @ДенисАгапитов-э6у 3 роки тому +1

    В данный момент 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()

  • @xandrviking1113
    @xandrviking1113 6 місяців тому +1

    Спасибо за уроки 🖖👍

  • @АртёмУльхов
    @АртёмУльхов Рік тому +1

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

    • @selfedu_rus
      @selfedu_rus  Рік тому

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

    • @YbisZX
      @YbisZX 9 місяців тому

      @@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)]

  • @nik0294
    @nik0294 3 роки тому +2

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

    • @selfedu_rus
      @selfedu_rus  3 роки тому +2

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

    • @nik0294
      @nik0294 3 роки тому +2

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

  • @MurzNN
    @MurzNN Рік тому +1

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

    • @selfedu_rus
      @selfedu_rus  Рік тому

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

  • @sergeyv1534
    @sergeyv1534 4 роки тому

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

    • @selfedu_rus
      @selfedu_rus  4 роки тому +1

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

    • @sergeyv1534
      @sergeyv1534 4 роки тому

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

    • @selfedu_rus
      @selfedu_rus  4 роки тому +1

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

  • @vladislavkondak3055
    @vladislavkondak3055 4 роки тому +2

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

    • @selfedu_rus
      @selfedu_rus  4 роки тому +1

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

    • @vladislavkondak3055
      @vladislavkondak3055 4 роки тому +1

      @@selfedu_rus Спасибо!

  • @НұржанМұхаммед
    @НұржанМұхаммед 3 роки тому +1

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

    • @selfedu_rus
      @selfedu_rus  3 роки тому

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

  • @ВячеславДорофеев-о1б

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

    • @selfedu_rus
      @selfedu_rus  Рік тому

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

    • @ВячеславДорофеев-о1б
      @ВячеславДорофеев-о1б Рік тому +1

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

  • @vladimirtyushkin8580
    @vladimirtyushkin8580 3 роки тому +1

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

    • @selfedu_rus
      @selfedu_rus  3 роки тому +1

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

  • @deadmorose4741
    @deadmorose4741 Рік тому

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

  • @fedor_vaskin
    @fedor_vaskin 2 роки тому +1

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

    • @selfedu_rus
      @selfedu_rus  2 роки тому

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

    • @fedor_vaskin
      @fedor_vaskin 2 роки тому

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

    • @selfedu_rus
      @selfedu_rus  2 роки тому

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

    • @fedor_vaskin
      @fedor_vaskin 2 роки тому

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

    • @selfedu_rus
      @selfedu_rus  2 роки тому

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

  • @Кристина-ц1и5б
    @Кристина-ц1и5б 4 роки тому +1

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

    • @selfedu_rus
      @selfedu_rus  4 роки тому +2

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

  • @tsoer2976
    @tsoer2976 4 роки тому

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

    • @selfedu_rus
      @selfedu_rus  4 роки тому

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

    • @tsoer2976
      @tsoer2976 4 роки тому

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

    • @selfedu_rus
      @selfedu_rus  4 роки тому +1

      @@tsoer2976 В объяснении алгоритма back propagation его и нет - там только стандартный градиентный спуск. Оптимизатор модифицирует градиентный спуск для более быстрого нахождения точки минимума. Некоторую инофрмацию об этом можно посмотреть здесь ua-cam.com/video/xDpe9KlYj9Q/v-deo.html

  • @mar_kha
    @mar_kha 3 роки тому +3

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

    • @selfedu_rus
      @selfedu_rus  3 роки тому +2

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

    • @mar_kha
      @mar_kha 3 роки тому +1

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

  • @РусланКаменев-с5в
    @РусланКаменев-с5в 3 роки тому +3

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

  • @1980PaulL
    @1980PaulL 4 роки тому +2

    У меня ошибку выдает 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  4 роки тому

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

    • @1980PaulL
      @1980PaulL 4 роки тому +3

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

  • @dimapugach5586
    @dimapugach5586 2 роки тому +1

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

    • @selfedu_rus
      @selfedu_rus  2 роки тому

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

    • @dimapugach5586
      @dimapugach5586 2 роки тому

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

  • @ПриманкаТВ-о6ш
    @ПриманкаТВ-о6ш 2 роки тому

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

    • @selfedu_rus
      @selfedu_rus  2 роки тому

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

  • @dzakarath
    @dzakarath Рік тому +1

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

  • @ivanuppercube931
    @ivanuppercube931 3 роки тому

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

  • @antonevdokimov8218
    @antonevdokimov8218 3 роки тому +1

    🔥🔥🔥🔥🔥🔥🔥🔥🔥

  • @ЕвгенийСнятков-ц6ж
    @ЕвгенийСнятков-ц6ж 4 роки тому +2

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

  • @иваниванов-к5т4е
    @иваниванов-к5т4е 3 роки тому

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

    • @selfedu_rus
      @selfedu_rus  3 роки тому

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

  • @МихаилМитьков-т9ц
    @МихаилМитьков-т9ц 3 роки тому +2

    Здравствуйте! Спасибо за ваш прекрасный канал. Решил поэкспериментировать с вашим кодом где я преобразую 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  3 роки тому +1

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

    • @МихаилМитьков-т9ц
      @МихаилМитьков-т9ц 3 роки тому +1

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

  • @wian39
    @wian39 3 роки тому +1

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

    • @selfedu_rus
      @selfedu_rus  3 роки тому

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

    • @wian39
      @wian39 3 роки тому

      @@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  3 роки тому

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

    • @wian39
      @wian39 3 роки тому

      @@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  3 роки тому

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

  • @annaponomarova3472
    @annaponomarova3472 3 роки тому +1

    Amazing!!!!!!!!

  • @md5alx
    @md5alx 4 роки тому +1

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

    • @selfedu_rus
      @selfedu_rus  4 роки тому +1

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

    • @ЮаньКитайский-и6ъ
      @ЮаньКитайский-и6ъ Рік тому

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

    • @selfedu_rus
      @selfedu_rus  Рік тому

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

  • @nikolaydd6219
    @nikolaydd6219 3 роки тому +1

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

    • @selfedu_rus
      @selfedu_rus  3 роки тому +1

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

    • @nikolaydd6219
      @nikolaydd6219 3 роки тому

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

    • @selfedu_rus
      @selfedu_rus  3 роки тому +1

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

  • @РоманЛ-г6ш
    @РоманЛ-г6ш 3 роки тому

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

    • @selfedu_rus
      @selfedu_rus  3 роки тому +1

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

    • @РоманЛ-г6ш
      @РоманЛ-г6ш 3 роки тому

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

    • @РоманЛ-г6ш
      @РоманЛ-г6ш 3 роки тому +1

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

    • @selfedu_rus
      @selfedu_rus  3 роки тому +1

      @@РоманЛ-г6ш да, верно!

  • @alexanderdushenin7035
    @alexanderdushenin7035 4 роки тому

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

    • @selfedu_rus
      @selfedu_rus  4 роки тому

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

    • @alexanderdushenin7035
      @alexanderdushenin7035 4 роки тому +1

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

  • @ИванИванов-с3з4з
    @ИванИванов-с3з4з 3 роки тому

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

    • @selfedu_rus
      @selfedu_rus  3 роки тому

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

    • @ИванИванов-с3з4з
      @ИванИванов-с3з4з 3 роки тому

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

    • @selfedu_rus
      @selfedu_rus  3 роки тому

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

  • @rpuropu
    @rpuropu 3 роки тому

    а где размер 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 роки тому +1

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

  • @Dmitrii82
    @Dmitrii82 3 роки тому

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

    • @selfedu_rus
      @selfedu_rus  3 роки тому

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

  • @ЛераБ-и8ц
    @ЛераБ-и8ц 2 роки тому

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

  • @iwantapetfox9262
    @iwantapetfox9262 3 роки тому

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

  • @КоляВасильев-о5и
    @КоляВасильев-о5и 3 роки тому

    Интересно, для 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  3 роки тому +1

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

    • @КоляВасильев-о5и
      @КоляВасильев-о5и 3 роки тому

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

    • @selfedu_rus
      @selfedu_rus  3 роки тому +1

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

    • @КоляВасильев-о5и
      @КоляВасильев-о5и 3 роки тому

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

    • @selfedu_rus
      @selfedu_rus  3 роки тому +2

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

  • @ЮрийНовиков-и9е
    @ЮрийНовиков-и9е 4 роки тому +1

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

  • @СарматПересветов
    @СарматПересветов 3 місяці тому +1

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

  • @_nickname_nickname_
    @_nickname_nickname_ 3 роки тому +1

    У меня была проблема, при обучении и валидации всё норм, а при тесте выдает ошибку 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 роки тому +1

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

  • @ALxOBR15Q
    @ALxOBR15Q Місяць тому

    Изучаю эту xepнъю- ищу работу!

  • @mark-tin
    @mark-tin 3 роки тому +2

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

  • @uglevod184
    @uglevod184 Рік тому +1

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

    • @selfedu_rus
      @selfedu_rus  Рік тому

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

  • @rpuropu
    @rpuropu 3 роки тому +1

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

    • @selfedu_rus
      @selfedu_rus  3 роки тому

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

    • @rpuropu
      @rpuropu 3 роки тому +1

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

  • @Federation1323
    @Federation1323 3 роки тому +1

    ты бох

  • @korsman723
    @korsman723 Рік тому

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

  • @torbokovsanat
    @torbokovsanat 4 роки тому

    +

  • @forpublic777
    @forpublic777 4 роки тому

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

    • @selfedu_rus
      @selfedu_rus  4 роки тому +3

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

    • @forpublic777
      @forpublic777 4 роки тому

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

    • @selfedu_rus
      @selfedu_rus  4 роки тому +3

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

  • @user-mu5cj4hv9l
    @user-mu5cj4hv9l Рік тому +4

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

  • @fruktiliyagoda
    @fruktiliyagoda Рік тому +1

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

    • @watson6954
      @watson6954 Рік тому

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

    • @fruktiliyagoda
      @fruktiliyagoda Рік тому

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

  • @dgofman1975
    @dgofman1975 2 роки тому +2

    Данные уже нормализированы не знаю зачем дважды нормализировать?
    # стандартизация входных данных
    #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  2 роки тому

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