Я так понимаю, что если B - матрица, то речь идёт о numpy? Тогда циклы, скорей всего, неуместны, и надо решать методами numpy.
Например так.
# import numpy as np
# B = np.array([[0, -1, 1], [2, 1, 2], [3, -1, -1]])
B[B <= 0] = B.max() # или можно B[B <= 0] = np.inf, если значения типа float
B.min(0)
Я бы использовал либо subplots с разными участками графика, либо библиотеку для построения интерактивных графиков plotly, чтобы при необходимости можно было масштабировать нужный участок графика.
Столкнулся с подобным явлением переполнения памяти GPU. Но в моем случае это происходило не сразу, а после обработки нескольких пакетов. То есть дело оказалось не в размере входного тензора, а в том, что у меня на определённом этапе сохранялись метрики в виде скалярных тензоров, а значения из них я извлекал на CPU уже позже.
Для object detection размечал с помощью labelImg, если не ошибаюсь. Простое и удобное приложение. Сохраняет адекватные аннотации в текстовый файл.
Для классификации писал простой скрипт на python, чтобы он мне штук 10 картинок в ряд показывал, а я в поле ввода писал 10 букв ассоциированных с классами. За вечер 10 тысяч так разметил.
Лучше говорить, не "функция ошибки" (error), а "функция потерь" (loss), в качестве которых может выступать среднеквадратичная ошибка (MSE), средняя абсолютная ошибка (MAE), перекрёстная энтропия и пр. С помощью этой функции оценивается отличие полученного результата от ожидаемого. Задача стоит в её минимизации. Производные нужны, чтобы рассчитать градиент для последующей коррекции весов. Градиенты рассчитываются по всем элементам сети, начиная с функции потерь, постепенно распространяя ошибку назад ко входу в виде коррекции весов.