Search
Write a publication
Pull to refresh
1
0
Дмитрий Негода @ndv79

Программист GPU

Send message

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

Впервые столкнулся с багами Rust лет пять назад, даже парочку исправил. Оказалось, для того, чтобы Rust можно было использовать с либами на Си, к либе нужно написать враппер. Вот там и проблемы. Да, из программ на Rust баги ушли, но они пришли во врапперы.

Go - язык высокого уровня, Rust - низкого. Это как сравнивать трактор и автомобиль.

if (MSVC)
	add_compile_options("$<$<CONFIG:RELEASE>:/GS->")
	add_compile_options("$<$<CONFIG:RELEASE>:/Oi>")
	add_compile_options("$<$<CONFIG:RELEASE>:/Ot>")
	add_compile_options("$<$<CONFIG:RELEASE>:/Oy>")
	add_compile_options("$<$<CONFIG:RELEASE>:/MT>")
else()
	add_compile_options("$<$<CONFIG:RELEASE>:-static-libstdc++>")
endif ()

Ускоряет код в разы, если интенсивно используются std контейнеры и прочие функции стандартной библиотеки. Благодарность сюда: bc1qavr5sxnj420gt2ql0wnwtxeqwmhl08frw0ja8k

У меня ушло минуты 3 чтобы понять откуда «XR = m^2 — XP — XQ». А что такое "(XP,YP) + (XQ,YQ) = (XR, -YR)" — я вообще не понял.
А пожарная вентилляция не помогла бы?
kraidiky, напишите статью. У вас хорошо получается.
«Вы не умеете его готовить» :)
см. мой коммент как сделать чтобы не было проблем.
Frank59, вопрос был «как сделать вдохновляющую атмосферу», а не «как замучить и перессорить программистов».
А разве кто-то вообще учит сетки, считая градиент ошибки сразу по всей выборке?

Вообще-то, да. Например, все квазиньютоновские методы оптимизации. Либа netlab для octave/matlab вообще не умеет минибатчи.

Эта статья — про минимизацию функции. Алгоритм Нестерова — про то же. А когда мы обучаем сеть, то на каждом шаге функция разная. Очень разная. Градиентный спуск в этих условиях, очевидно, сходится (в гугле это доказали математически недавно). Квазиньютоновские методы в этих условиях, очевидно, не сходятся, так как оценивают гессианскую матрицу по значениям градиента в соседних точках, используя BFGS. Если они посчитаны на разных батчах, в гессианской матрице будет мусор.

С алгоритмом Нестерова не все так однозначно. В scikit и caffe он идёт опцией, а не по умолчанию.
как создать эту самую атмосферу


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

1. сложные не-UI методы должны быть покрыты unit-тестами
2. поля таблиц БД должны быть документированы
и т.д.

А, ну тогда нет проблем
SGD — стохастический, поэтому движение происходит не в сторону градиента целевой функции ошибки (которая включает всю обучающую выборку), а в сторону градиента ошибки от случайной подвыборки. Считайте, что вы к настоящему градиенту прибавили нормально распределенный шум. Этот шум и позволяет выбираться из локальных минимумов.
Nesterov — это конвексная оптимизация, а так как обучение нейронных сетей — мягко говоря, не конвексная задача, то Nesterov более подвержен застреванию в локальном минимуме, чем SGD.
Boost.Spirit та ещё гадость. Проще писать самому, да и код получается более читабельный. Пример парсинга конструкции типа __attribute__ ((reqd_work_group_size(x,y,z))) на чистом Си:

	bool attribute(KernelDeclaration & kd) {
		auto was = current;
		int x,y,z;
		if (sterm("__attribute__") && sterm("(") && sterm("(") && sterm("reqd_work_group_size") && sterm("(")
		&& sint(x) && sterm(",") && sint(y) && sterm(",") && sint(z) && sterm(")") && sterm(")") && sterm(")")) {
			kd.requiredWorkgroupSize[0] = x;
			kd.requiredWorkgroupSize[1] = y;
			kd.requiredWorkgroupSize[2] = z;
			return true;
		}
		current = was;
		return false;
	}


Где sterm(t) пропускает пробелы и комментарии, после чего считывает данный терминал. На Boost.Spirit даже не рискну это воспроизвести — не силён в головоломках.
Автор, берите сразу быка за рога! Мы итак знаем, что космические корабли бороздят пространство.

Везде, где я встречался с ассемблером (в последнее время — это видео-кодэки), делается так: берется программа на Си, компилируется в ассемблер с -O3, после чего руками делается множество научных тыков: там заменили память на регистр, сям поменяли ветки при ветвлении. Так и рождается чуть-более-оптимальный ассемблерный код.
Я конечно не математик, но позвольте выразить свой скептис по поводу «был плохой период, трубочка разваливалась».
Рандомные числа можно сгенерировать с помощью get_global_id() и побитовых операций. См пример тут: http://stackoverflow.com/questions/9912143/how-to-get-a-random-number-in-opencl
Тут что-то не так: на вашей GPU должно выполняться на порядок быстрее, чем на вашем CPU. Возможно, у вас расходятся потоки, или слишком много используется переменных и как результат они выделяются в глобальной памяти, или вы не используете память local, или вы недостаточно хорошо распараллелили свой алгоритм, или слишком часто используете барьер, или еще что-то.

Да, на всякий случай: OpenCL — хороший выбор для программирования GPU, он не медленнее CUDЫ.
1

Information

Rating
Does not participate
Location
Ульяновск, Ульяновская обл., Россия
Date of birth
Registered
Activity