Как правильно управлять памятью и размером партии с помощью TensorFlow
Я использую TensorFlow для создания простой нейронной сети с обратной связью, и я использую пакеты с переменным размером. Я не использую GPU, у меня 8 ГБ оперативной памяти и работает на Python 3.5.2.
Моя проблема в том, что у меня есть несколько партий, которые слишком велики и генерируют типичную ошибку из памяти. Я понимаю, что это не проблема. Однако, если я использую Keras с TF-сервером, у меня нет этой проблемы. Я привел пример (с партиями с фиксированным размером), который иллюстрирует это.
Есть ли проблема с моей реализацией? Как я должен обрабатывать слишком большие партии?
Пример TensorFlow (память выхлопов)
import numpy as np
import tensorflow as tf
n_observations = 100000
n_input = 6
batch_size = 20000
X = np.random.rand(n_observations, n_input)
Y = X[:,0] ** 3 + X[:,1] ** 2 + X[:,2] + X[:,3] + X[:,4] + X[:,5]+ np.random.rand(n_observations)
n_hidden = 16
n_output = 1
def generatebatch(n_observations, batch_size):
for batch_i in range(n_observations // batch_size):
start = batch_i*batch_size
end = start + batch_size
batch_xs = X[start:end, :]
batch_ys = Y[start:end]
yield batch_xs, batch_ys
with tf.Session() as sess:
# placeholders for input and target
net_input = tf.placeholder(tf.float32, [None, n_input])
y_true = tf.placeholder(tf.float32)
# Hidden Layer
W1 = tf.Variable(tf.random_normal([n_input, n_hidden]))
b1 = tf.Variable(tf.random_normal([n_hidden]))
net_output1 = tf.nn.relu(tf.matmul(net_input, W1) + b1)
# Yet another Hidden Layer
yaW1 = tf.Variable(tf.random_normal([n_hidden, n_hidden]))
yab1 = tf.Variable(tf.random_normal([n_hidden]))
yanet_output1 = tf.nn.relu(tf.matmul(net_output1, yaW1) + yab1)
# Output Layer
W2 = tf.Variable(tf.random_normal([n_hidden, n_output]))
b2 = tf.Variable(tf.random_normal([n_output]))
net_output2 = tf.nn.relu(tf.matmul(yanet_output1, W2) + b2)
# The loss function
cost = tf.reduce_mean(tf.pow(y_true - net_output2, 2))
# Configure the optimizer
optimizer = tf.train.AdamOptimizer().minimize(cost)
# Initialize variables
sess.run(tf.global_variables_initializer())
n_epochs = 100
for epoch_i in range(n_epochs):
batchloss = []
for batch_xs, batch_ys in generatebatch(n_observations, batch_size):
_, loss = sess.run(
[optimizer, cost],
feed_dict={
net_input: batch_xs,
y_true: batch_ys
})
batchloss.append(loss)
print(np.mean(batchloss))
Пример Keras (как-то обрабатывает размер партии)
import numpy as np
from keras.models import Sequential
from keras.layers import Dense
import logging
#just to hide the deprecation warnings
logging.basicConfig(level=logging.CRITICAL)
n_input = 6
n_observations = 100000
n_hidden = 16
n_epochs = 10
batch_size = 35000
# input data
X = np.random.rand(n_observations, n_input)
Y = X[:,0] ** 3 + X[:,1] ** 2 + X[:,2] + X[:,3] + X[:,4] + X[:,5]+ np.random.rand(n_observations)
# create and fit Multilayer Perceptron model
model = Sequential()
model.add(Dense(n_hidden, input_dim=n_input, activation='relu'))
model.add(Dense(n_hidden, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='mse', optimizer='adam')
model.fit(X, Y, nb_epoch=n_epochs, batch_size=batch_size, verbose=1)
Ответы
Ответ 1
Твой Y
имеет неправильную форму, что может привести к тому, что tensorflow неправильно выводит форму тензоров (20000, 20000) вместо (20000, 6)), потребляя много памяти.
Y = np.reshape(Y, [n_observations, 1])
Таким образом, ваш заполнитель должен иметь ОДНУЮ форму:
net_input = tf.placeholder(tf.float32, shape=[None, n_input])
y_true = tf.placeholder(tf.float32, shape=[None, 1])
Ответ 2
Я думаю, что Keras переопределяет параметры конфигурации по умолчанию в TensorFlow. Ваш собственный код TensorFlow работает отлично с меньшими размерами партий (например, 10k, 15k) на графическом процессоре. Но с настройкой по умолчанию предполагается, что вам нужны преимущества графического процессора и проблема с OOM, потому что недостаточно памяти GPU.
Ваш пример TensorFlow отлично работает, когда вы меняете поведение по умолчанию на CPU (как вы указали в вопросе). Вот строки, которые я изменил, чтобы сделать это:
config = tf.ConfigProto(
log_device_placement=True, allow_soft_placement=True
)
config.gpu_options.allow_growth = True
with tf.Session(config=config) as sess, \
tf.device('cpu:0'): # placeholders for input and target