Как я могу обучить нейронную сеть с большим количеством данных, чем умещается в памяти?
Попытка обучить классификатор с помощью повторяющегося слоя, используя много данных. В результате все данные могут не поместиться в память. Это дает мне следующую ошибку:
Error using zeros
Requested 1x2114046976 (15.8GB) array exceeds maximum array size preference. Creation of arrays greater than this limit may take a long
time and cause MATLAB to become unresponsive. See array size limit or preference panel for more information.
Error in nnMex.perfsGrad (line 3)
TEMP = zeros(1,ceil(hints.tempSizeBG/8)*8);
Error in nnCalcLib/perfsGrad (line 294)
lib.calcMode.perfsGrad(calcNet,lib.calcData,lib.calcHints);
Error in trainscg>initializeTraining (line 153)
[worker.perf,worker.vperf,worker.tperf,worker.gWB,worker.gradient] = calcLib.perfsGrad(calcNet);
Error in nnet.train.trainNetwork>trainNetworkInMainThread (line 28)
worker = localFcns.initializeTraining(archNet,calcLib,calcNet,tr);
Error in nnet.train.trainNetwork (line 16)
[archNet,tr] = trainNetworkInMainThread(archNet,rawData,calcLib,calcNet,tr,feedback,localFcns);
Error in trainscg>train_network (line 147)
[archNet,tr] = nnet.train.trainNetwork(archNet,rawData,calcLib,calcNet,tr,localfunctions);
Error in trainscg (line 59)
[out1,out2] = train_network(varargin{2:end});
Error in network/train (line 369)
[net,tr] = feval(trainFcn,'apply',net,data,calcLib,calcNet,tr);
Следует отметить, что в настоящее время мой тренировочный ввод составляет 11x52266, и сеть имеет ~3 тыс. Элементов веса из-за повторяющегося слоя. Однако я хотел бы предоставить в 15 раз больше данных для обучения.
Как я могу справиться? Существуют ли способы сопоставления локальной переменной, которую он пытается инициализировать, на моем SSD вместо памяти?
Существует вариант "сокращения" для обучения, но это, похоже, не имеет никакого значения в этом вопросе. Такая же ошибка возникает независимо.
1 ответ
В общем, если ваш набор данных слишком велик, чтобы поместиться в память, вам придется обрабатывать его порциями. Для обучения больших сетей обычно используется стохастический градиентный спуск (для которого требуется доступ только к одной точке данных за раз) или обучение мини-пакета (для которого требуется только доступ к точкам данных в мини-пакете). Помимо того, что требуется меньше памяти, эти методы также имеют тенденцию сходиться намного быстрее, чем спуск с градиентом партии (который использует весь набор данных для каждого обновления веса). Доступ к диску медленный, поэтому, несмотря на то, что для обновления требуется всего несколько точек данных, вам все равно следует загрузить столько точек, сколько вы можете, затем разделить их на мини-пакеты и т. Д. Есть и другие приемы, которые можно использовать, чтобы уменьшить количество дисков. читает, как выполнение нескольких обновлений перед загрузкой следующего набора данных.
Другой момент относится к рекуррентным нейронным сетям (RNN). Когда вы обучаете RNN с использованием обратного распространения через время (BPTT), сеть должна быть "развернута" во времени и обрабатывается как очень глубокая сеть с прямой связью с копией рекуррентного уровня на каждом временном шаге. Это означает, что выполнение BPTT в течение большего количества временных шагов требует больше памяти (и большего времени вычислений). Решение состоит в том, чтобы использовать усеченный BPTT, где градиент распространяется только назад на фиксированное количество временных шагов.