Я очень новичок в Git и GitHub, но думаю, вы можете найти весь проект здесь (за исключением наборов данных, поскольку они слишком велики): https://github.com/SomeCucumber/ML_fabr ... lation.git
Для визуализации: https://github.com/SomeCucumber/OpenGL.git
По сути, я начал с создания очень простой симуляции ткани Эйлера, которая имитирует квадрат точек произвольного размера, соединенных пружинами по горизонтали и вертикали (структура), по диагонали (сдвиг) и изгибу. Затем я запускаю его в режиме реального времени и записываю положения, скорости и силы на каждом временном шаге, а затем сохраняю как набор данных.
Наконец, у меня есть программа обучения, использующая pytorch для обучения сверточной нейронной сети (CNN) с позициями и скоростями в качестве входных каналов и силами в качестве выходных каналов. Затем я просто объединяю эти силы следующим образом:
Код: Выделить всё
def step(self):
with torch.no_grad():
self.total_forces = my_models.run(
self.model,
torch.cat((self.pos, self.vel), axis=0),
self.device
)
self.total_forces *= self.force_scale
self.acc = self.total_forces/self.mass
self.vel[self.all_but_fastened] += self.acc[self.all_but_fastened]*self.dt
self.pos[self.all_but_fastened] += self.vel[self.all_but_fastened]*self.dt
Код: Выделить всё
class CNN(nn.Module):
def __init__(self, input_channels, output_channels, hidden_channels=[], kernel_size=3):
super().__init__()
# Channels:
channels = [input_channels] + hidden_channels + [output_channels]
# Convolutional layers:
self.conv = nn.ModuleList()
for i in range(len(channels)-1):
self.conv.append(nn.Conv2d(channels[i], channels[i+1], kernel_size=kernel_size, padding=int((kernel_size-1)/2)))
def forward(self, x):
for i, layer in enumerate(self.conv):
x = layer(x)
if i != (len(self.conv)-1):
x = activation(x)
return x
В конце концов, когда я пытаюсь запустить симуляцию с помощью моего движка CNN, это вроде как работает, но именно здесь я ищу совета. Я начал проект с очень маленьких тканей, чтобы все было быстро и компактно с точки зрения хранения, поэтому, когда я использую размер ткани 3x3, где закреплены 3 верхних, он действительно работает, он стабилен, когда просто висит, и я также могу перетаскивать некоторые точки, не взрываясь, хотя при использовании ткани большего размера (самый большой размер, который я пробовал, - 50x50), симуляция мгновенно ломается, и кажется, что проблемы возникают по краям, что имеет смысл, поскольку это где структура полностью отличается от остальной части ткани... См. рисунок ниже:

Теперь то, что я сделал для улучшения обучения, является наиболее важным: при использовании интегратора Эйлера и создании набора данных я добавляю немного шума к рассчитанным позиции, это значительно сглаживает кривую обучения, но я не увидел никакой реальной разницы в моделировании... Я также пытаюсь нормализовать набор данных, но я не уверен, насколько это успешно.
Некоторые заключительные замечания:
Я осознал, что современное решение подобных проблем заключается в использовании нейронных сетей Graph, но изначально я решил, что, поскольку я моделирую только квадратные ткани, это не должно иметь никакого значения, теперь я начал задаться вопросом, может быть, края являются достаточной проблемой, чтобы потребовать GNN?
Я также узнал, что вы можете использовать torch.compile(self.model), чтобы уменьшить накладные расходы Python и в целом улучшить производительность прямого прохода, но для меня это привело только к потере производительности, когда без компиляции я получаю около 800-900 шагов физики в секунду, а при компиляции я получаю примерно 700 шагов физики в секунду, но гораздо менее стабильно, я использую gtx 5070, если это представляет интерес.
Сначала я просто пытался передать CNN позицию и позволить ей напрямую предсказывать следующую позицию, хотя это было крайне нестабильно и, по сути, каждый раз предсказывало облако движения, но оно работало намного быстрее.
Если это не было ясно, я в основном ищу любую полезную обратную связь, что я мог бы сделать, чтобы улучшить движок ML с точки зрения стабильности, но также и производительности, я не вижу никакого способа улучшить производительность, но я по какой-то причине я получаю только около 10 кадров в секунду... В любом случае, спасибо за вашу помощь!
Редактировать: я забыл сказать, форма CNN, с которой я добился наибольшего успеха, заключалась в том, чтобы иметь только один скрытый сверточный слой с где-то от 4 до 64 каналов, это тоже то, с чем я действительно не уверен, что делать, вот какую форму придать сети...
Мобильная версия