Вопрос или проблема
Я работал над следующей задачей leetcode:
Дана двумерная сетка из ‘1’ (суша) и ‘0’ (вода), посчитайте количество островов. Остров окружен водой и образуется за счет соединения соседних участков суши по горизонтали или вертикали. Вы можете предположить, что все четыре края сетки окружены водой.
Пример 1:
Входные данные: 11110 11010 11000 00000
Выходные данные: 1
Пример 2:
Входные данные: 11000 11000 00100 00011
Выходные данные: 3
И я написал следующее явное решение:
from collections import OrderedDict
class Solution:
def numIslands(self, grid: List[List[str]]) -> int:
if len(grid) == 0:
return 0
land = ones(grid)
parcels = len(land)
islands = 0
while parcels > 0:
unexplored = []
start = land.popitem()[0]
parcels = parcels - 1
print(start)
up = (start[0] + 1, start[1])
down = (start[0] - 1, start[1])
left = (start[0], start[1] - 1)
right = (start[0], start[1] + 1)
if up in land:
unexplored.append(up)
del land[up]
if down in land:
unexplored.append(down)
del land[down]
if left in land:
unexplored.append(left)
del land[left]
if right in land:
unexplored.append(right)
del land[right]
while len(unexplored) > 0:
start = unexplored.pop()
parcels = parcels - 1
up = (start[0] + 1, start[1])
down = (start[0] - 1, start[1])
left = (start[0], start[1] - 1)
right = (start[0], start[1] + 1)
if up in land:
unexplored.append(up)
del land[up]
if down in land:
unexplored.append(down)
del land[down]
if left in land:
unexplored.append(left)
del land[left]
if right in land:
unexplored.append(right)
del land[right]
islands += 1
return islands
def ones(grid):
ones = OrderedDict()
height = len(grid)
width = len(grid[0])
for i in range(0,height):
for j in range(0,width):
if grid[i][j] == "1":
ones[(i,j)] = 1
return ones
Но моя интуиция подсказала мне, что нахождение количества островов в сетке из единиц и нулей должно быть хорошей задачей для машинного обучения, связанной с обнаружением изображений.
Поэтому я написал следующий код для генерации тестовых случаев:
from random import randint
def make_grid():
width = 30
height = 30
grid = []
for i in range(0,height):
row = []
for j in range(0,width):
if randint(0,1) == 0:
row.append("0")
else:
row.append("1")
grid.append(row)
return grid
Затем я сгенерировал 60 000 случаев и оценил их с помощью моего явного решения. Я разделил их на 50 000 обучающих случаев и 10 000 тестовых случаев.
Затем я попытался подать обучающие случаи в сеть Keras, где было 64 узла на слой и 10 слоев, используя relu и функцию активации softmax в конце. Я обучал модель в течение 250 итераций.
Я получил низкую точность статистики по распознаванию количества островов на “изображениях” как на обучающих, так и на тестовых случаях.
Затем я попытался подать их в сеть Keras, используя два сверточных слоя, первый 2×2, а второй 4×4 с 64 узлами каждый, за которыми следовали 2 полносвязных слоя с 64 узлами на слой. Я обучал модель в течение 3 итераций.
Я получил низкую точность статистики по предсказанию количества островов на “изображении” как на обучающих, так и на тестовых случаях.
Это просто плохая задача для нейронных сетей? Я использую неправильные сети? Мои сети слишком маленькие? Мне нужно увеличивать количество тестовых случаев?
Любое мнение будет признано полезным!
Для начала я бы начал с более простых тестовых случаев, так как они выглядят довольно сложными (смотрите пример того, что вы, похоже, пытаетесь смоделировать, ниже). Возможно, начните с сетки 10×10 и генерируйте от 1 до 5 островов разных размеров.
Ответ или решение
Обучение модели машинного обучения по задаче "Острова" на основе нейронных сетей
Введение
Ваша задача заключается в подсчете количества "островов" в двумерной сетке, где "1" обозначает землю, а "0" — воду. Это классическая задача в области алгоритмов и поиска, но ваш интерес к применению нейронных сетей делает эту тему особенно актуальной. Здесь мы рассмотрим, каким образом можно модифицировать ваш подход к использованию нейронных сетей для решения данной задачи, а также обсудим, почему ваша текущая архитектура может не давать ожидаемых результатов.
Анализ проблемы
Чтобы правильно измерить эффективность нейронной сети для решения проблемы, важно понимать, что бинарные задачи, такие как подсчет островов, могут быть сложными для нейронных сетей. Они требуют не только распознавания характерных паттернов, но и эффективного обобщения на новых данных.
Почему нейронные сети могут не срабатывать?
-
Сложность данной задачи: Определение количества островов требует контекстуального понимания структуры данных, что нейронным сетям может быть сложно, особенно если они не были правильно настроены и обучены.
-
Неоднородные тренинговые данные: Если вы генерируете случайные сетки, без четкой структуры в количестве и размерах островов, ваша модель может не обучиться на что-то действительно полезное. Рекомендуется начать с упрощенных случаев.
-
Архитектура сети: Архитектура 64 узла на слой, с использованием 10 слоев, может быть слишком большой для простых случаев и слишком маленькой для сложных. Лучше всего начать с меньшей глубины и постепенно увеличивать её по мере необходимости.
-
Гиперпараметры и количество эпох: Вам стоит проводить больше эпох обучения и использовать различные методы оптимизации, такие как Adam или SGD, чтобы увидеть, как это повлияет на точность модели.
Рекомендации по улучшению подхода
-
Упрощение тестовых случаев: Начните с более простых случаев с меньшими размерами сеток (например, 10×10) и ограничьте количество островов до 1-5. Это позволит легче анализировать поведение модели.
-
Модификация данных: Помимо случайных данных, вы можете создать наборы данных с предсказуемыми паттернами, которые помогут модели обучиться.
-
Изменение архитектуры: Рассмотрите возможность использования рекуррентных нейронных сетей (RNN) или даже специализированных архитектур, таких как U-Net, которые хорошо себя зарекомендовали в задачах сегментации и обработки изображений. Эти архитектуры могут лучше учитывать пространственные отношения.
-
Аугментация данных: Используйте методы аугментации данных, чтобы повысить объем ваших обучающих данных и улучшить обобщающую способность модели. Например, поворот, отражение, изменение масштаба сетки и т.д.
-
Периодическая оценка: Часто проверяйте точность на тренировочных и тестовых данных, чтобы избежать переобучения.
Заключение
Обучение нейронной сети для решения задачи подсчета островов является интересным вызовом, который требует продуманного подхода к данным, архитектуре и гиперпараметрам. Применяя приведенные выше рекомендации, вы сможете значительно улучшить результаты вашей модели. Не забывайте, что нейронные сети не всегда являются оптимальным решением для всех задач — традиционные алгоритмы поиска могут оказаться более эффективными в данной ситуации.