编辑:Tensorflow内存问题,但与Keras工作正常

时间:2017-10-13 11:59:42

标签: python tensorflow keras

调用sess.run(init)时,我的代码卡住了。

我试着查一查,我尝试了一些可能的解决方案......仍然无法超越sess.run(init)

有人有建议吗?我首先想到的是网络定义出了问题。代码已经简化。

编辑:感谢@pop和@gdelab,问题被缩小到内存问题。 BUT 当我使用TF + Keras时网络正常工作。

也许它只是TF代码中的网络定义问题?我的任务是将TF + Keras脚本转换为仅TF的脚本。

这是仅包含TF的代码:

def conv2d(x, W):
    return tf.nn.conv2d(x, W, strides=[1,1,1,1], padding="SAME")

def weight_variable(shape):
    return tf.Variable(tf.truncated_normal(shape, stddev=0.1))

def bias_variabel(shape):
    return tf.Variable(tf.constant(0.1, shape=shape))

def sig2d(x):
    return tf.nn.sigmoid(x, name='Sigmoid-normalization')


  import tensorflow as tf

  tf.reset_default_graph()
  sess = tf.Session()

  xs = tf.placeholder(tf.float32, [None, 153600])
  x_image = tf.reshape(xs, [-1, 160, 320, 3])
  ys = tf.placeholder(tf.float32, [None, 1])

  x_image = tf.nn.sigmoid(x_image)

  W_conv1 = weight_variable([4,4,3,16])  
  b_conv1 = bias_variabel([16])
  h_conv1 = tf.nn.elu(conv2d(x_image, W_conv1) + b_conv1)

  W_conv2 = weight_variable([5,5,16,32])
  b_conv2 = bias_variabel([32])
  h_conv2 = tf.nn.elu(conv2d(h_conv1, W_conv2) + b_conv2)

  W_conv3 = weight_variable([5,5,32,64])
  b_conv3 = bias_variabel([64])
  h_conv3 = tf.nn.elu(conv2d(h_conv2, W_conv3) + b_conv3)

  flat1 = tf.reshape(h_conv3, [-1, 160*320*64])
  drop1 = tf.nn.dropout(flat1, 0.2)
  elu1 = tf.nn.elu(drop1)
  dense1 = tf.layers.dense(elu1, 512)
  drop2 = tf.nn.dropout(dense1, 0.5)
  elu2 = tf.nn.elu(drop2)
  output = tf.layers.dense(elu2, 1)

  loss = tf.sqrt(tf.reduce_mean(tf.square(tf.subtract(ys, output))))

  gs=tf.train.get_global_step()
  train = tf.train.AdamOptimizer().minimize(loss,global_step=gs)

  init = tf.global_variables_initializer()
  sess.run(init) # STUCK

  for i in range(2000):
      batch_xs, batch_ys = next(gen(20, args.host, port=args.port))
      batch_xs = np.reshape(batch_xs,(-1,153600))
      sess.run(train, feed_dict={xs: batch_xs, ys: batch_ys})

这是TF + Keras的代码:

import tensorflow as tf
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten, Lambda, ELU
from keras.layers.convolutional import Convolution2D
from keras.utils import plot_model

def gen(hwm, host, port):
  for tup in client_generator(hwm=hwm, host=host, port=port):
    X, Y, _ = tup
    Y = Y[:, -1]
    if X.shape[1] == 1:  # no temporal context
      X = X[:, -1]
    yield X, Y


def get_model(time_len=1):
  ch, row, col = 3, 160, 320  # camera format

  model = Sequential()
  model.add(Lambda(lambda x: x/127.5 - 1., # Normalize data from -1 to 1
            input_shape=(ch, row, col),
            output_shape=(ch, row, col)))
  model.add(Convolution2D(16, 8, 8, subsample=(4, 4), border_mode="same"))
  model.add(ELU())
  model.add(Convolution2D(32, 5, 5, subsample=(2, 2), border_mode="same"))
  model.add(ELU())
  model.add(Convolution2D(64, 5, 5, subsample=(2, 2), border_mode="same"))
  model.add(Flatten())
  model.add(Dropout(.2))
  model.add(ELU())
  model.add(Dense(512))
  model.add(Dropout(.5))
  model.add(ELU())
  model.add(Dense(1))

  model.compile(optimizer="adam", loss="mse")

  return model

if __name__ == "__main__":

  tf.reset_default_graph()
  sess = tf.Session()

  model = get_model()

  model.fit_generator(
    gen(20, args.host, port=args.port),
    samples_per_epoch=10000,
    nb_epoch=args.epoch,
    validation_data=gen(20, args.host, port=args.val_port),
    nb_val_samples=1000
  )

  init = tf.global_variables_initializer()
  sess.run(init)

2 个答案:

答案 0 :(得分:1)

我认为这只是因为您创建的张量大小。 如果我用153600替换50,它会正常工作...... 所以,这必须是一个记忆问题。

你需要减少一些变量的大小(或者使用更多的RAM,如果这是一个选项)。例如,您可以在卷积层之间进行均值或最大池化。这样,output张量变得更小并且适合你的记忆

答案 1 :(得分:0)

这是一个记忆问题:第一个密集层的矩阵太大:160*320*64*512 ~ 1.7e9个元素=>仅此层的7GB左右!例如,您需要在网络中使用max_pool来缩小大小。

在实践中,如果您将512更改为1,或者如果您减小输入图像大小(例如,对我来说它使用16 * 16,则不会尝试更大),它可以正常工作。