我目前正在使用tensorflow 2.0中的分发策略,如此处https://www.tensorflow.org/versions/r2.0/api_docs/python/tf/distribute/Strategy
所述我想知道with ...scope()
块中必须包含什么,什么是“可选”。
特别是以下操作。我是否必须将...放在with ...scope()
内才能正常工作?
我开玩笑了一点,即使我完全不使用with ...scope
,我的代码也似乎可以正常工作。如果这有一些副作用,我现在不知道,我感到困惑。
不带scope
的代码:
strat = tf.distribute.MirroredStrategy()
BATCH_SIZE_PER_REPLICA = 5
print('Replicas: ', strat.num_replicas_in_sync)
global_batch_size = (BATCH_SIZE_PER_REPLICA * strat.num_replicas_in_sync)
dataset = tf.data.Dataset.from_tensors(tf.random.normal([100])).repeat(1000).batch(
global_batch_size)
g = Model('m', 10, 10, 1, 3)
dist_dataset = strat.experimental_distribute_dataset(dataset)
@tf.function
def train_step(dist_inputs):
def step_fn(inputs):
print([(v.name, v.device) for v in g.trainable_variables])
return g(inputs)
out = strat.experimental_run_v2(step_fn, args=(dist_inputs,))
for inputs in dist_dataset:
train_step(inputs)
break
具有范围的代码:
strat = tf.distribute.MirroredStrategy()
BATCH_SIZE_PER_REPLICA = 5
print('Replicas: ', strat.num_replicas_in_sync)
global_batch_size = (BATCH_SIZE_PER_REPLICA * strat.num_replicas_in_sync)
with strat.scope():
dataset = tf.data.Dataset.from_tensors(tf.random.normal([100])).repeat(1000).batch(
global_batch_size)
g = Model('m', 10, 10, 1, 3)
dist_dataset = strat.experimental_distribute_dataset(dataset)
@tf.function
def train_step(dist_inputs):
def step_fn(inputs):
print([(v.name, v.device) for v in g.trainable_variables])
return g(inputs)
out = strat.experimental_run_v2(step_fn, args=(dist_inputs,))
for inputs in dist_dataset:
train_step(inputs)
break
编辑:似乎strat.experimental_run_v2
自动进入strat
的范围。那么with strat.scope()
为什么存在?
答案 0 :(得分:0)
您无需将数据集,数据集迭代循环等放入scope()
中。您只需要定义顺序模型及其内部的编译即可。所以像这样-
mirrored_strategy = tf.distribute.MirroredStrategy()
with mirrored_strategy.scope():
model = tf.keras.Sequential()
model.add(tf.keras.layers.Embedding(vocab_size, 64))
model.add(tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(64, activation= 'tanh', recurrent_activation= 'sigmoid', recurrent_dropout = 0, unroll = False, use_bias= True)))
# One or more dense layers.
# Edit the list in the `for` line to experiment with layer sizes.
for units in [64, 64]:
model.add(tf.keras.layers.Dense(units, activation='relu'))
# Output layer. The first argument is the number of labels.
model.add(tf.keras.layers.Dense(3, activation='softmax'))
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
它将要做的是,它将在每个GPU上创建模型及其参数的副本,并在训练过程中对其进行训练。您将定义的批次大小将除以可用GPU的数量,然后将这些批次发送到这些GPU,例如,如果您拥有batch_size = 64
并且有两个GPU,则每个GPU将获得32个批次。您可以阅读更多here。
答案 1 :(得分:0)
根据我的实验,唯一需要在内部声明的是模型创建。如果您使用Keras .fit()
而不是自定义培训,那么model.compile()
也必须放在里面。
您可以执行以下操作:
def create_model():
""" This can be outside of the scope
""""
...
return model
with strategy.scope():
model = create_model()
如果您使用tf.train.Checkpoint
,请确保其实例化和checkpoint.resume()
的调用都在范围之内。
答案 2 :(得分:0)
您不需要致电strat.scope()
。
experimental_run_v2
是一种将计算放入strat.scope()
中的简单方法。
请参见下面的experimental_run_v2
源代码,它实际上将fn
包装在您的范围内。