что такое batch size keras
Влияет ли batch_size в Keras на качество результатов?
Я собираюсь обучить большую сеть LSTM с 2-3 миллионами статей и борюсь с ошибками памяти (я использую AWS EC2 g2x2large).
Я не против, если моя сеть займет больше времени на обучение, но я хотел бы знать, не снизит batch_size ли это качество моих прогнозов.
Через полтора года я возвращаюсь к своему ответу, потому что мой предыдущий ответ был неверным.
Размер партии значительно влияет на обучение. Когда вы помещаете пакет в свою сеть, происходит то, что вы усредняете градиенты. Концепция заключается в том, что если размер вашей партии достаточно велик, это обеспечит достаточно стабильную оценку того, каким будет градиент полного набора данных. Взяв образцы из вашего набора данных, вы оцените градиент при значительном снижении вычислительных затрат. Чем ниже вы идете, тем менее точной будет ваша оценка, однако в некоторых случаях эти шумовые градиенты могут фактически помочь избежать локальных минимумов. Когда оно слишком низкое, вес вашей сети может просто перепрыгнуть, если ваши данные шумят, и они могут быть неспособны к обучению или они сходятся очень медленно, что отрицательно влияет на общее время вычислений.
В случае, если вам нужны пакеты большего размера, но они не будут соответствовать вашему графическому процессору, вы можете подать небольшую партию, сохранить оценки градиента и одну или несколько партий, а затем выполнить обновление веса. Таким образом, вы получите более стабильный градиент, потому что вы увеличили размер виртуального пакета.
Что такое batch size keras
Создание нейронной сети (НС) средствами библиотеки Keras выполняется в следующем порядке:
Эффективность созданной НС определяется на этапе тестирования и оценивается по точности решения поставленной задачи, например, по точности классификации графических изображений:
где n – общее число классифицируемых на этапе тестирования изображений;
n_true – число правильно классифицированных на этапе тестирования изображений.
На каждом этапе создания НС библиотека Keras предоставляет большой выбор параметров, влияющих на результативность НС. Поэтому перед пользователем, создающим НС, опираясь на методы библиотеки Keras, стоит непростая задача выбора правильных значений параметров. (В [1] отмечается, что невозможно дать обобщенные рекомендации по выбору параметров модели НС ввиду большого разнообразия НС и решаемых с их помощью задач.)
Ниже описываются методы, используемые при построении сверточных нейронных сетей с помощью следующих слоев:
Замечание. Многослойный перцептрон может быть создан как комбинация слоев Input, BatchNormalization, Dropout и Dense).
Слои Flatten и Input далее не рассматриваются, поскольку слой Flatten используется без параметров, а Input имеет неизменяемый параметр, задающий форму входных данных. Например, в задаче классификации изображений рукописных цифр:
inp = Input(shape = (28, 28, 1))
Форма (28, 28, 1) означает, что каждая цифра задана в виде рисунка размера 28*28 пикселей, выполненного в оттенках серого цвета.
Параметры слоев нейронной сети
Задание слоев
Задание слоев НС выполняется следующими методами [3, 4, 5]:
Описание параметров слоев
Параметры слоев описаны в табл. 1.
Таблица 1. Параметры слоев (перечислены в алфавитном порядке)
Функции активации
Функции активации [6], которые можно указать в качестве значения параметра activation при задании слоя (также эти функции можно задать и в виде слоя):
Способы задания функций активации:
from keras.layers import Activation, Dense
model.add(Dense(64))
model.add(Activation(‘tanh’))
model.add(Dense(64, activation = ‘tanh’))
from keras import backend as K
model.add(Dense(64, activation = K.tanh))
Функции активации, которые задаются в виде слоя [7]:
Приложение 1. Использование метрик
Метрика – это функция, используемая для оценки эффективности модели НС [20]. Метрики задаются параметром metrics (в виде списка) метода compile, например:
model.compile(loss = ‘mean_squared_error’, optimizer = ‘sgd’, metrics = [‘mae’, ‘acc’])
from keras import metrics
model.compile(loss = ‘mean_squared_error’, optimizer = ‘sgd’, metrics = [metrics.mae, metrics.categorical_accuracy])
Функция метрики схожа с функцией потерь, однако результат оценки сети по метрике не используется при обучении модели. В качестве метрики может быть использована любая функция потерь.
Также в качестве метрики можно указать имя доступной метрики, например, ‘accuracy’ символьную функцию Theano/TensorFlow.
Параметры функции метрики:
Функция метрики возвращает единичный тензор, представляющий среднее значение по всем элементам массива, вычисляемого по входным данным в соответствии с заданной метрикой.
Пользовательские функции метрики так же должны иметь два параметра (y_true, y_pred) и возвращать единичный тензор, например:
import keras.backend as K
def mean_pred(y_true, y_pred):
return K.mean(y_pred)
model.compile(optimizer = ‘rmsprop’, loss=’binary_crossentropy’, metrics=[‘accuracy’, mean_pred])
Замечание 2. Для функции потерь binary crossentropy в случае указания метрики ‘accuracy’ возвращает завышенные значения точности (binary_accuracy).
Чтобы получить реальную точность, с binary crossentropy используется вдобавок метрика categorical_accuracy:
metrics = [‘accuracy’, keras.metrics.categorical_accuracy]
Приложение 2. Обеспечение повторяемости результата
Воспроизведение результатов эпизода обучения обеспечивает следующий код [20], который должен быть исполнен до начала создания НС и ее обучения:
# Флаг задания режима воспроизведения результатов
repeat_results = True # True
seedVal = 348
import numpy as np
np.random.seed(seedVal) # Задание затравки датчика случайных чисел
#
if repeat_results:
print(‘Режим воспроизведения (повторяемости) результатов’)
import random as rn
import tensorflow as tf
import os
from keras import backend as K
# Код, необходимый для воспроизведения результата
os.environ[‘PYTHONHASHSEED’] = ‘0’
rn.seed(seedVal)
tf.set_random_seed(seedVal)
session_conf = tf.ConfigProto(intra_op_parallelism_threads = 1,
inter_op_parallelism_threads = 1)
sess = tf.Session(graph = tf.get_default_graph(), config = session_conf)
K.set_session(sess)
В этом коде фиксируются затравки датчиков случайных чисел, значение системной переменной PYTHONHASHSEED и устанавливается в сессии tensorFlow однопоточность.
Неповторяемость результата обучения возникает также при использовании TensorFlow на GPU: некоторые операции, в частности tf.reduce_sum(), имеют нечеткий результат. Это обусловлено тем, что на GPU многие операции исполняются параллельно, поэтому порядок выполнения не всегда гарантирован. Из-за ограниченной точности вычислений даже сложение нескольких чисел может дать разные результаты при разных порядках выполнения этой операции. Можно попытаться при программировании избежать нечетких операций, но некоторые могут быть созданы автоматически TensorFlow при вычислении градиентов. Проще всего добиться повторяемости результатов, выполняя код на CPU. Для этого следует переменную окружения CUDA_VISIBLE_DEVICES инициализировать пустой строкой, например [21]:
$ CUDA_VISIBLE_DEVICES=»» PYTHONHASHSEED=0 python your_program.py
Приложение 3. Пакетная нормализация
Градиентные методы, лежащие в основе алгоритмов машинного обучения, весьма чувствительны к распределению индивидуальных признаков: результативность алгоритмов может быть неудовлетворительной, если распределение индивидуального признака существенно отличается от стандартного нормального распределения, имеющего нулевое математическое ожидание и единичную дисперсию.
Изменение распределения признака выполняется в результате нормализации или стандартизации.
Нормализация предполагает такое масштабирование признака, после которого он имеет единичную норму (l1 или l2).
Стандартизация – такое преобразование данных, после которого среднее значение каждого признака равно 0, а дисперсия равна 1 (то есть, как в стандартном нормальном распределении).
В библиотеке Scikit-Learn есть следующие функции нормализации и стандартизации:
from sklearn import preprocessing
normalized_X = preprocessing.normalize(X, norm = ‘l2’) # Нормализация (другая норма – ‘l1’)
standardized_X = preprocessing.scale(X) # Стандартизация
# Иная возможность нормализации и стандартизации данных
normalizer = preprocessing.Normalizer().fit(X)
X = normalizer.transform(X)
# fit – вычисляет среднее значение и стандартное отклонение для последующей стандартизации
scaler = preprocessing.StandardScaler(copy = False).fit(X)
X = scaler.transform(X) # Стандартизация за счет центрирования и масштабирования
В случае НС на вход 1D-слоя подается тензор формы (размер_пакета, карта_признаков), то есть пакет признаков. Поэтому нормализация признаков НС называется пакетной. Пакетная нормализация выполняется по следующему алгоритму [2]:
Пакетная нормализация позволяет:
Согласно [2], выполняемая по приведенному выше алгоритму пакетная нормализация, уменьшает эффект внутреннего сдвига переменных (internal covariate shift). Этот эффект иллюстрирует рис. П1 (пример взят из [22]).
Рис. П1. Иллюстрация эффекта внутреннего сдвига
Нейрон второго слоя первоначально обучится реагировать на входы из распределения, получаемого при весах w = (0, 0.5, 0.5) нейрона первого слоя, то есть на данные преимущественно из интервала [-0.5, 0.5]. Однако после изменения весов нейрона первого слоя выход этого нейрона попадает в интервал [0.5, 1] (чаще ближе к 1), то есть нейрон второго слоя придется обучать заново.
Пакетная нормализация позволяет устранить эту проблему, получившую название внутреннего сдвига переменных.
Боковая панель
НАЧАЛО РАБОТЫ
МОДЕЛИ
ПРЕДОБРАБОТКА
ПРИМЕРЫ
Sequential model: руководство
Модель Sequential представляет собой линейный стек слоев.
Вы может создать модель Sequential, передав список слоев конструктору модели:
from keras.models import Sequential from keras.layers import Dense, Activation model = Sequential([Dense(32, input_shape=(784,)), Activation(‘relu’), Dense(10), Activation(‘softmax’),]) |
model = Sequential() model.add(Dense(32, input_dim=784)) model.add(Activation(‘relu’)) |
Указание размерности входных данных
Ваша модель должна знать, какую размерность данных ожидать на входе. В связи с этим, первый слой модели Sequential (и только первый, поскольку последующие слои производят автоматический расчет размерности) должен получать информацию о размерности входных данных. Есть несколько способов сделать это:
Таким образом, следующие примеры эквивалентны:
model = Sequential() model.add(Dense(32, input_shape=(784,))) |
model = Sequential() model.add(Dense(32, input_dim=784)) |
Компиляция
Перед обучением модели необходимо настроить сам процесс. Это выполняется с помощью метода compile(). Он получает три аргумента:
# Задача бинарной классификации
model.compile(optimizer=’rmsprop’, loss=’binary_crossentropy’, metrics=[‘accuracy’])
# Среднеквадратичная ошибка регрессии
model.compile(optimizer=’rmsprop’, loss=’mse’)
# Пользовательская метрика
import keras.backend as K
def mean_pred(y_true, y_pred):
return K.mean(y_pred)
model.compile(optimizer=’rmsprop’, loss=’binary_crossentropy’, metrics=[‘accuracy’, mean_pred])
Обучение
Модели Keras обучаются на Numpy-массивах, содержащих набор исходных данных и метки. Для обучения обычно используется функция fit(). Документация по этой функции здесь.
# Модель с одномерными входными данными и бинарной классификацией
model.add(Dense(32, activation=’relu’, input_dim=100))
# Генерируем случайные данные
import numpy as np
data = np.random.random((1000, 100))
labels = np.random.randint(2, size=(1000, 1))
# Обучаем модель, перебирая данные в пакетах по 32 примера
model.fit(data, labels, epochs=10, batch_size=32)
# Модель с одномерными входными данными и 10 классами
model.add(Dense(32, activation=’relu’, input_dim=100))
# Генерируем случайные данные
import numpy as np
data = np.random.random((1000, 100))
labels = np.random.randint(10, size=(1000, 1))
# Преобразуем метки в OHE (one-hot encoding)
one_hot_labels = keras.utils.to_categorical(labels, num_classes=10)
# Обучаем модель, перебирая данные в пакетах по 32 примера
model.fit(data, one_hot_labels, epochs=10, batch_size=32)
Примеры
Вот несколько примеров, с которых можно начать!
В папке примеров вы также найдете варианты решения задач с реальными наборами данных:
Многослойный персептрон (MLP) для мультиклассовой классификаци (softmax):
import keras
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation
from keras.optimizers import SGD
# Генерируем случайные данные
import numpy as np
x_train = np.random.random((1000, 20))
y_train = keras.utils.to_categorical(
np.random.randint(10, size=(1000, 1)), num_classes=10)
x_test = np.random.random((100, 20))
y_test = keras.utils.to_categorical(
np.random.randint(10, size=(100, 1)), num_classes=10)
# Dense(64) — это полносвязный слой с 64 скрытыми нейронами.
# в первом слое вы должны указать размерность входных данных:
# здесь, это векторы длинной 20.
model.add(Dense(64, activation=’relu’, input_dim=20))
sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
score = model.evaluate(x_test, y_test, batch_size=128)
MLP для бинарной классификации:
import numpy as np
from keras.models import Sequential
from keras.layers import Dense, Dropout
# Генерируем случайные данные
x_train = np.random.random((1000, 20))
y_train = np.random.randint(2, size=(1000, 1))
x_test = np.random.random((100, 20))
y_test = np.random.randint(2, size=(100, 1))
model.add(Dense(64, input_dim=20, activation=’relu’))
score = model.evaluate(x_test, y_test, batch_size=128)
VGG-подобная сверточная сеть:
import numpy as np
import keras
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras.optimizers import SGD
# Генерируем случайные данные
x_train = np.random.random((100, 100, 100, 3))
y_train = keras.utils.to_categorical(
np.random.randint(10, size=(100, 1)), num_classes=10)
x_test = np.random.random((20, 100, 100, 3))
y_test = keras.utils.to_categorical(
np.random.randint(10, size=(20, 1)), num_classes=10)
# применим здесь сверточный слой с 32 нейронами и ядром свертки (3, 3)
model.add(Conv2D(32, (3, 3), activation=’relu’,
input_shape=(100, 100, 3)))
model.add(Conv2D(32, (3, 3), activation=’relu’))
model.add(Conv2D(64, (3, 3), activation=’relu’))
model.add(Conv2D(64, (3, 3), activation=’relu’))
sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
model.fit(x_train, y_train, batch_size=32, epochs=10)
score = model.evaluate(x_test, y_test, batch_size=32)
Классификация последовательностей с помощью LSTM:
from keras.models import Sequential
from keras.layers import Dense, Dropout
from keras.layers import Embedding
from keras.layers import LSTM
model.fit(x_train, y_train, batch_size=16, epochs=10)
score = model.evaluate(x_test, y_test, batch_size=16)
Классификация последовательностей с помощью одномерной свертки:
from keras.models import Sequential
from keras.layers import Dense, Dropout
from keras.layers import Embedding
from keras.layers import Conv1D, GlobalAveragePooling1D, MaxPooling1D
model.add(Conv1D(64, 3, activation=’relu’,
input_shape=(seq_length, 100)))
model.add(Conv1D(64, 3, activation=’relu’))
model.add(Conv1D(128, 3, activation=’relu’))
model.add(Conv1D(128, 3, activation=’relu’))
model.fit(x_train, y_train, batch_size=16, epochs=10)
score = model.evaluate(x_test, y_test, batch_size=16)
Классификация последовательностей с помощью LSTM с памятью:
В этой модели мы накладываем 3 слоя LSTM друг на друга, делая модель способной изучать временные представления более высокого уровня.
Первые два слоя возвращают свои полные выходные последовательности, но последний слой возвращает только последний шаг своей выходной последовательности. Таким образом отбрасывается временное измерение (то есть входная последовательность преобразуется в один вектор).
from keras.models import Sequential
from keras.layers import LSTM, Dense
import numpy as np
# ожидаемая размерность входных данных:
# (batch_size, timesteps, data_dim)
model.add(LSTM(32, return_sequences=True,
input_shape=(timesteps, data_dim)))
# возвращает последовательность векторов длинной 32
model.add(LSTM(32, return_sequences=True))
# возвращает последовательность векторов длинной 32
model.add(LSTM(32)) # возвращает одиночный векторов длинной 32
# Генерируем случайные данные
x_train = np.random.random((1000, timesteps, data_dim))
y_train = np.random.random((1000, num_classes))
# Генерируем случайные проверочные данные
x_val = np.random.random((100, timesteps, data_dim))
y_val = np.random.random((100, num_classes))
LSTM с передачей состояния
Рекуррентная модель с состоянием — это модель, для которой внутренней состояние, полученное после обработки очередного пакета данных, повторно используется в качестве начальных состояний для выборок следующей серии. Это позволяет обрабатывать более длинные последовательности.
from keras.models import Sequential
from keras.layers import LSTM, Dense
import numpy as np
# ожидаемая размерность входных данных:
# (batch_size, timesteps, data_dim)
# Обратите внимание, что мы должны указать полную размерность входных
# данных batch_input_shape, так как это сеть с состоянием
# i-тый пример в k-ом пакете является продолжением
# i-того примера в k-1-ом пакете
model.add(LSTM(32, return_sequences=True, stateful=True,
batch_input_shape=(batch_size, timesteps, data_dim)))
model.add(LSTM(32, return_sequences=True, stateful=True))
model.add(LSTM(32, stateful=True))
# Генерируем случайные данные
x_train = np.random.random((batch_size * 10, timesteps, data_dim))
y_train = np.random.random((batch_size * 10, num_classes))
# Генерируем случайные проверочные данные
x_val = np.random.random((batch_size * 3, timesteps, data_dim))
y_val = np.random.random((batch_size * 3, num_classes))
batch_size=batch_size, epochs=5, shuffle=False,
What is batch size in neural network?
I’m using Python Keras package for neural network. This is the link. Is batch_size equals to number of test samples? From Wikipedia we have this information:
However, in other cases, evaluating the sum-gradient may require expensive evaluations of the gradients from all summand functions. When the training set is enormous and no simple formulas exist, evaluating the sums of gradients becomes very expensive, because evaluating the gradient requires evaluating all the summand functions’ gradients. To economize on the computational cost at every iteration, stochastic gradient descent samples a subset of summand functions at every step. This is very effective in the case of large-scale machine learning problems.
Above information is describing test data? Is this same as batch_size in keras (Number of samples per gradient update)?
6 Answers 6
The batch size defines the number of samples that will be propagated through the network.
For instance, let’s say you have 1050 training samples and you want to set up a batch_size equal to 100. The algorithm takes the first 100 samples (from 1st to 100th) from the training dataset and trains the network. Next, it takes the second 100 samples (from 101st to 200th) and trains the network again. We can keep doing this procedure until we have propagated all samples through of the network. Problem might happen with the last set of samples. In our example, we’ve used 1050 which is not divisible by 100 without remainder. The simplest solution is just to get the final 50 samples and train the network.
Advantages of using a batch size batch_size equal to 1. In that case, the gradient changes its direction even more often than a mini-batch gradient.
In the neural network terminology:
Example: if you have 1000 training examples, and your batch size is 500, then it will take 2 iterations to complete 1 epoch.
The documentation for Keras about batch size can be found under the fit function in the Models (functional API) page
batch_size : Integer or None. Number of samples per gradient update. If unspecified, batch_size will default to 32.
If you have a small dataset, it would be best to make the batch size equal to the size of the training data. First try with a small batch then increase to save time. As itdxer mentioned, there’s a tradeoff between accuracy and speed.
The question has been asked a while ago but I think people are still tumbling across it. For me it helped to know about the mathematical background to understand batching and where the advantages/disadvantages mentioned in itdxer’s answer come from. So please take this as a complementary explanation to the accepted answer.
$$\theta_
Full-Batch Gradient Descent
$$\theta_
This is what is described in the wikipedia excerpt from the OP. For large number of training samples, the updating step becomes very expensive since the gradient has to be evaluated for each summand.
Stochastic Gradient Descent
In Stochastic Gradient Descent one computes the gradient for one training sample and updates the paramter immediately. These two steps are repeated for all training samples.
$$\theta_
One updating step is less expensive since the gradient is only evaluated for a single training sample j.
Difference between both approaches
Updating Speed: Batch gradient descent tends to converge more slowly because the gradient has to be computed for all training samples before updating. Within the same number of computation steps, Stochastic Gradient Descent already updated the parameter multiple times. But why should we then even choose Batch Gradient Descent?
Convergence Direction: Faster updating speed comes at the cost of lower «accuracy». Since in Stochastic Gradient Descent we only incorporate a single training sample to estimate the gradient it does not converge as directly as batch gradient descent. One could say, that the amount of information in each updating step is lower in SGD compared to BGD.
The less direct convergence is nicely depicted in itdxer’s answer. Full-Batch has the most direct route of convergence, where as mini-batch or stochastic fluctuate a lot more. Also with SDG it can happen theoretically happen, that the solution never fully converges.
Memory Capacity: As pointed out by itdxer feeding training samples as batches requires memory capacity to load the batches. The greater the batch, the more memory capacity is required.
Summary
In my example I used Gradient Descent and no particular loss function, but the concept stays the same since optimization on computers basically always comprises iterative approaches.
So, by batching you have influence over training speed (smaller batch size) vs. gradient estimation accuracy (larger batch size). By choosing the batch size you define how many training samples are combined to estimate the gradient before updating the parameter(s).