Ты выучишь:

  1. Как найти фильтр автоматически, улучшив классификатор.
  2. Как повысить сложность обнаружения, добавив новые изображения большего размера
  3. Протестируйте классификатор с новыми изображениями

Автоматический поиск фильтра

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

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

Предварительно обработать изображение

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

Функция preprocess_img возьмет путь к изображению и вернет изображение, готовое для предварительной обработки классификатором.

Найдите фильтр

Как только изображения загружены, мы можем двигаться вперед и искать фильтр.

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

Как создать фильтр?
Мы создаем фильтр, помещая случайные числа от -1 до 1. Это делает функция numpy: np.random.randint ().
Размер должен совпадать с размером изображений, на которые мы хотим умножить фильтр, поэтому в данном случае это 9 чисел.

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

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

Мы поместим все в цикл и будем продолжать его, пока не найдем хороший фильтр.

2. Добавьте больше изображений.

Если бы мы могли легко и быстро обнаружить фильтр, который работал бы с одним изображением для каждого класса, поэтому одно изображение для «Вертикального» и одно для «Горизонтального», как бы этот метод работал, если бы у нас было больше изображений для каждого класса?

Мы собираемся к этому прямо сейчас, но чтобы усложнить обнаружение, мы попробуем на этот раз с более сложными изображениями размером 5 × 5.

Я подготовил 5 изображений с квадратами и 5 изображений с крестами.

Квадраты:

Кресты:

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

Давайте начнем с пути всех 10 изображений, чтобы мы могли легко их загрузить. Для квадратов у меня есть 5 изображений, и их имя начинается с квадрата, поэтому я беру все изображения с квадратом на их имени. То же самое я проделываю с крестиками.

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

Внутри цикла мы генерируем случайный фильтр.

Затем мы загружаем 5 квадратов и 5 крестиков и делаем свертку для каждого отдельного изображения.

Чтобы считать фильтр хорошим фильтром, мы устанавливаем два требования: все квадраты должны быть больше или равны 0, поэтому, если результат отличается, мы прерываем цикл for, возвращаемся к циклу while и начинаем все до тех пор, пока все 5 квадратов удовлетворяют условию быть больше или равным 0.

То же самое и с крестиками, если они не меньше 0, мы прерываем цикл for.

Как мы узнаем, что все 5 квадратов и 5 крестов удовлетворяют требованиям?
Мы знаем это, если сможем пройти через все изображения, не разрывая цикл. Итак, мы устанавливаем последнее условие: если count равно 4, это означает, что мы смогли перебрать все 5 изображений, поэтому фильтр хорош.
На этом этапе мы устанавливаем good_filter на True, и цикл while прекращается.

Как работает код?
Со временем, используя этот код, вы сможете найти хороший фильтр. Это может занять от нескольких секунд до нескольких минут, в течение которых компьютер сможет сделать несколько попыток найти хороший фильтр.
В моем случае потребовалось более 100 тысяч попыток найти хороший фильтр.

3. Протестируйте классификатор на новом изображении.

Найдя фильтр, мы можем быть уверены, что классификатор изображений будет работать с 5 изображениями, которые мы использовали для поиска фильтра, поскольку он был протестирован именно для этого.

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

На этот раз фильтр состоит из 25 чисел, так как изображения имеют размер 5 × 5 (всего 25 пикселей).

Но что, если мы попробуем это с каким-нибудь изображением, которое мы никогда раньше не использовали?
Я проверил его на нескольких изображениях, поместив кресты и квадраты в разные позиции, и он действительно сработал.
Например, изображение ниже, которое представляет собой квадрат, с фильтром, который у меня есть, определяется как крест.
Ваш фильтр может работать по-другому, но все же, скорее всего, он будет не так хорош, поскольку он не мой .