Как стать автором
Обновить

Комментарии 18

Почему print_letter() нельзя было написать как

letters = "ЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЧЧШЩЪЫЬЭЮЯ"

def print_letter(result):
    return letters[result]
Простыню:
        if result == 1:
            self.line.setText('А')
            return 'А'

        elif result == 2:
            self.line.setText('Б')
            return 'Б'

        elif result == 3:
            self.line.setText('В')
            return 'В'

        elif result == 4:
            self.line.setText('Г')
            return 'Г'
   ...

нельзя чем-то более наглядным заменить? — хотя бы:
symbol = {
  1: 'A',
  2: 'Б',
  3: 'В',
...
}.get(result)

if symbol:
    self.line.setText(symbol)
return symbol

Размер картинки 278х278 это очень много. Можно выделить прямоугольник с символом, обрезать по нему и смасштабировать в центр квадрата 64х64 или даже меньше. Это уменьшит тренировочную базу, т.к. сдвиги будут не нужны, увеличит точность и в несколько раз повысит быстродействие.
Со всем полностью согласен, только часть статьи как раз таки была направлена на то, чтобы показать как увеличить тренировочную базу
Так смысл в том, что выгоднее нормализовать символы, а не раздувать базу. Посмотрите на MNIST с рукописными цифрами — 60000 картинок, символы вписаны в квадрат 28х28. Используя его как пример, делал распознавание печатных символов с вращением +- 30 градусов (обход капчи). Хватило 9000 картинок на весь алфавит, процесс тренировки занимает меньше 10 минут и точность практически 100%.
Да, действительно. Нормализовать данные было бы куда более эффективнее и выгоднее.
А с таким оно справится?
image
Тут сначала нужно произвести сегментацию данного изображения, а дальше нужно смотреть.

Я ни разу не специалист по нейронным сетям, но мне доводилось делать точно такое же задание (без GUI-части) для домашнего задания в университете. Мне кажется, вот такие вещи можно улучшить:


  1. Размер картинки в 278x278 избыточен, как выше уже отметили в комментариях. Мне оказалось достаточным размера 28x28.
  2. Альфа-канал вы удалили — но зачем вам все 3 оставшихся канала RGB на черно-белых картинках? На вход нейросети достаточно подавать grayscale изображения — у flow_from_directory есть опция color_mode.
  3. API для "размножения" датасета есть в самом ImageDataGenerator
  4. Аналогично, разбиение датасета на trainig и validation есть в ImageDataGenerator, не обязательно его осуществлять руками (хотя, возможно, ручное разбиение будет более надежным).
1.Да, размер действительно избыточен, но я не думаю, что Вам бы было удобно рисовать на холсте 28x28.
2. Всё верно, нужно было передавать Grayscale изображение.
3.Да, оно есть. Во-первых, оно работает немного иначе, нежели мой алгоритм. Во-вторых, часть статьи была нацелена на то, чтобы показать как вручную можно увеличить датасет( об этом я писал выше).
4. Да, можно. Только там разбиение возможно, на сколько мне известно, на тренировочные и тестовые. Я же предлагаю поделить датасет на три папки: тренировочные, валидационные и тестовые. Валидационные нужны для того, чтобы можно было самому проверить, что та точность, которую мы получили соответствует действительности.

Рисовать на 28x28, конечно, не удобно — можно рисовать на холсте в большом разрешении и потом ресайзить до маленького. Итоговая скорость работы (и, в особенности, обучения) будет выше на порядок.

Да, вы абсолютно правы) Только я всё равно не совсем уверен, что модель натренированная на картинках 28x28 выиграет в точности. Можете проверить)
А есть подобная база для тренировки только еще и с цифрами? Или как можно добавить в тренировку цифру?

Да, есть, гуглите MNIST. На практике, если честно, она не очень. Был опыт в реальном проекте, где одной из задач стояла распознавание рукописных чисел. Там у нас был другой датасет. Могу саму модельку скинуть

А что эти строки означают/делают?

model = tf.keras.models.Sequential([
tf.keras.layers.Conv2D(16, (3, 3), activation='relu',
input_shape=(278,278, 3)),
tf.keras.layers.MaxPooling2D(2, 2),
tf.keras.layers.Conv2D(32, (3, 3), activation='relu'),
tf.keras.layers.MaxPooling2D(2, 2),
tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),
tf.keras.layers.MaxPooling2D(2, 2),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(512, activation='relu'),
tf.keras.layers.Dense(33, activation='softmax')
])
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории