Вопросы из руководства по Tensorflow PDE

#tensorflow

#tensorflow

Вопрос:

Я хотел бы знать, как разрешить Tensorflow обновлять только определенные элементы матрицы? Следующий код взят из Tensorflow tutorials ( https://www.tensorflow.org/versions/r0.11/tutorials/pdes/index.html#partial-differential-equations).

   #Import libraries for simulation
  import tensorflow as tf
  import numpy as np

  #Imports for visualization
  import PIL.Image

  def DisplayArray(a, fmt='jpeg', rng=[0,1]):
    """Display an array as a picture."""
    a = (a - rng[0])/float(rng[1] - rng[0])*255
    a = np.uint8(np.clip(a, 0, 255))
    with open("fig/image.jpg","w") as f:
        PIL.Image.fromarray(a).save(f, "jpeg")

  #sess = tf.Session()
  sess = tf.InteractiveSession()

  # Computational Convenience Functions

  def make_kernel(a):
    """Transform a 2D array into a convolution kernel"""
    a = np.asarray(a)
    a = a.reshape(list(a.shape)   [1,1])
    return tf.constant(a, dtype=1)

  def simple_conv(x, k):
    """A simplified 2D convolution operation"""
    x = tf.expand_dims(tf.expand_dims(x, 0), -1)
    y = tf.nn.depthwise_conv2d(x, k, [1, 1, 1, 1], padding='SAME')
    return y[0, :, :, 0]

  def laplace(x):
    """Compute the 2D laplacian of an array"""
    laplace_k = make_kernel([[0.5, 1.0, 0.5],
                             [1.0, -6., 1.0],
                             [0.5, 1.0, 0.5]])
    return simple_conv(x, laplace_k)

  # Define the PDE

  N = 500

  # Initial Conditions -- some rain drops hit a pond

  # Set everything to zero
  u_init = np.zeros([N, N], dtype=np.float32)
  ut_init = np.zeros([N, N], dtype=np.float32)

  # Some rain drops hit a pond at random points
  for n in range(40):
    a,b = np.random.randint(0, N, 2)
    u_init[a,b] = np.random.uniform()

  DisplayArray(u_init, rng=[-0.1, 0.1])

  # Parameters:
  # eps -- time resolution
  # damping -- wave damping
  eps = tf.placeholder(tf.float32, shape=())
  damping = tf.placeholder(tf.float32, shape=())

  # Create variables for simulation state
  U  = tf.Variable(u_init)
  Ut = tf.Variable(ut_init)

  # Discretized PDE update rules
  U_ = U   eps * Ut
  Ut_ = Ut   eps * (laplace(U) - damping * Ut)

  # Operation to update the state
  step = tf.group(
    U.assign(U_),
    Ut.assign(Ut_))

  # Initialize state to initial conditions
  tf.initialize_all_variables().run()

  # Run 1000 steps of PDE
  for i in range(1000):
    # Step simulation
    step.run({eps: 0.03, damping: 0.04})
    DisplayArray(U.eval(), rng=[-0.1, 0.1])
  

В step = tf.group(U.assign(U_),Ut.assign(Ut_)) я хотел бы знать, возможно ли обновлять значения только внутри U_[1: -1, 1: -1] и Ut_[1:-1, 1:-1], и сохраните остальные значения как константы.

Большое вам спасибо!

Комментарии:

1. Эта ошибка, похоже, не связана с вашим вопросом. Вам необходимо инициализировать переменные Tensorflow перед их первым использованием. Попробуйте добавить некоторый код в соответствии с session.run(tf.initialize_all_variables()) перед вашим первым реальным вызовом session.run() , предполагая, что у вас есть сеанс Tensorflow с именем session .

2. @Peter Hawkins Спасибо за комментарий. Чтобы быть более конкретным, я обновил свои вопросы. На самом деле я хочу обновить значение внутри U_[1:-1, 1:-1] , а остальные значения матрицы оставить постоянными.

Ответ №1:

В Tensorflow можно выполнять нарезанное назначение. Попробуйте что-то вроде этого:

 assign_op = U[1:-1,1:-1].assign(U_[1:-1, 1:-1])
  

(Точные индексы зависят от вас.)

Комментарии:

1. Я пробовал: step = tf.group(U[1:-1,1:-1].assign(U_[1:-1,1:-1]),Ut[1:-1,1:-1].assign(Ut_[1:-1,1:-1])) , но это не работает. Он возвращает некоторые ошибки, такие как Caused by op u'Variable_1/read', defined at: File "01_TF_Tutorial_PDE_test01.py", line 64, in <module> Ut = tf.Variable(ut_init) .

2. Можете ли вы показать полное сообщение об ошибке? Какую версию Tensorflow вы используете?

3. Вот ссылка на полное сообщение об ошибке вывода. Большое вам спасибо.

4. Похоже, что назначение фрагментов еще не поддерживается на устройствах с графическим процессором. Я полагаю, что он добавляется и должен появиться на github в ближайшие несколько дней. Тем временем вы могли бы либо запустить свой код на CPU (используя with tf.device("CPU"): , либо обойти проблему, вырезав часть оригинала, которую вы не изменяете (используя U_[0:1, 0:1] или аналогичный), а затем объединить его с битом, который вы изменяете (используя tf.concat )