提交 ccc1213e 编写于 作者: Y Yang Zhang

Return output along with loss in train or eval mode

上级 79a08599
...@@ -136,9 +136,12 @@ if __name__ == '__main__': ...@@ -136,9 +136,12 @@ if __name__ == '__main__':
for e in range(2): for e in range(2):
for idx, batch in enumerate(train_loader()): for idx, batch in enumerate(train_loader()):
out = model.train(batch[0], batch[1], device='gpu', out, loss = model.train(batch[0], batch[1], device='gpu',
device_ids=[0, 1, 2, 3]) device_ids=[0, 1, 2, 3])
print("=============== output =========")
print(out) print(out)
print("=============== loss ===========")
print(loss)
if idx > 10: if idx > 10:
model.save("test.{}".format(e)) model.save("test.{}".format(e))
break break
......
...@@ -40,6 +40,14 @@ def to_list(value): ...@@ -40,6 +40,14 @@ def to_list(value):
return [value] return [value]
def to_numpy(var):
assert isinstance(var, (Variable, fluid.core.VarBase)), "not a variable"
if isinstance(var, fluid.core.VarBase):
return var.numpy()
t = global_scope().find_var(var.name).get_tensor()
return np.array(t)
def extract_args(func): def extract_args(func):
if hasattr(inspect, 'getfullargspec'): if hasattr(inspect, 'getfullargspec'):
return inspect.getfullargspec(func)[0] return inspect.getfullargspec(func)[0]
...@@ -115,15 +123,10 @@ class StaticGraphAdapter(object): ...@@ -115,15 +123,10 @@ class StaticGraphAdapter(object):
def save(self, path): def save(self, path):
def _save(state, path): def _save(state, path):
def to_numpy(var):
if not isinstance(var, Variable):
return var
t = global_scope().find_var(var.name).get_tensor()
return np.array(t)
if not state: if not state:
return return
state = {k: to_numpy(v) for k, v in state.items()} state = {k: to_numpy(v) if isinstance(v, Variable) else v
for k, v in state.items()}
with open(path, 'wb') as f: with open(path, 'wb') as f:
pickle.dump(state, f) pickle.dump(state, f)
...@@ -226,18 +229,24 @@ class StaticGraphAdapter(object): ...@@ -226,18 +229,24 @@ class StaticGraphAdapter(object):
for idx, v in enumerate(self._label_vars): for idx, v in enumerate(self._label_vars):
feed[v.name] = labels[idx] feed[v.name] = labels[idx]
outputs = self._executor.run( endpoints = self._endpoints[self.mode]
fetch_list = endpoints['output'] + endpoints['loss']
num_output = len(endpoints['output'])
out = self._executor.run(
compiled_prog, feed=feed, compiled_prog, feed=feed,
fetch_list=self._endpoints[self.mode]) fetch_list=fetch_list)
return outputs if self.mode == 'test':
return out[:num_output]
else:
return out[:num_output], out[num_output:]
def _make_program(self, inputs): def _make_program(self, inputs):
prog = self._main_prog.clone(self.mode != 'train') prog = self._main_prog.clone(self.mode != 'train')
with fluid.program_guard(prog, self._startup_prog): with fluid.program_guard(prog, self._startup_prog):
outputs = to_list(self.model.forward(*inputs)) outputs = to_list(self.model.forward(*inputs))
losses = []
label_vars = [] label_vars = []
if self.mode != 'test': if self.mode != 'test':
losses = []
loss_weights = self.model._loss_weights loss_weights = self.model._loss_weights
if loss_weights is None: if loss_weights is None:
loss_weights = [1. for _ in self.model._loss_functions] loss_weights = [1. for _ in self.model._loss_functions]
...@@ -250,13 +259,15 @@ class StaticGraphAdapter(object): ...@@ -250,13 +259,15 @@ class StaticGraphAdapter(object):
loss_fn = getattr(fluid.layers, l) loss_fn = getattr(fluid.layers, l)
loss = loss_fn(o, label_var) loss = loss_fn(o, label_var)
losses.append(fluid.layers.reduce_mean(loss) * w) losses.append(fluid.layers.reduce_mean(loss) * w)
outputs = losses
if self.mode == 'train': if self.mode == 'train':
self._label_vars = label_vars self._label_vars = label_vars
self._loss_endpoint = fluid.layers.sum(losses) self._loss_endpoint = fluid.layers.sum(losses)
self.model._optimizer.minimize(self._loss_endpoint) self.model._optimizer.minimize(self._loss_endpoint)
self._progs[self.mode] = prog self._progs[self.mode] = prog
self._endpoints[self.mode] = outputs self._endpoints[self.mode] = {
"output": outputs,
"loss": losses
}
def _infer_input_vars(self, inputs): def _infer_input_vars(self, inputs):
input_vars = [] input_vars = []
...@@ -346,7 +357,8 @@ class DynamicGraphAdapter(object): ...@@ -346,7 +357,8 @@ class DynamicGraphAdapter(object):
final_loss.backward() final_loss.backward()
self.model._optimizer.minimize(final_loss) self.model._optimizer.minimize(final_loss)
self.model.clear_gradients() self.model.clear_gradients()
return losses return [to_numpy(o) for o in to_list(outputs)], \
[to_numpy(l) for l in losses]
def eval(self, inputs, labels, device='CPU', device_ids=None): def eval(self, inputs, labels, device='CPU', device_ids=None):
assert self.model._loss_functions, \ assert self.model._loss_functions, \
...@@ -356,13 +368,16 @@ class DynamicGraphAdapter(object): ...@@ -356,13 +368,16 @@ class DynamicGraphAdapter(object):
inputs = to_list(inputs) inputs = to_list(inputs)
labels = to_list(labels) labels = to_list(labels)
outputs = self.model.forward(*[to_variable(x) for x in inputs]) outputs = self.model.forward(*[to_variable(x) for x in inputs])
return self._loss(outputs, labels) losses = self._loss(outputs, labels)
return [to_numpy(o) for o in to_list(outputs)], \
[to_numpy(l) for l in losses]
def test(self, inputs, device='CPU', device_ids=None): def test(self, inputs, device='CPU', device_ids=None):
super(Model, self.model).train() super(Model, self.model).train()
self.mode = 'test' self.mode = 'test'
inputs = to_list(inputs) inputs = [to_variable(x) for x in to_list(inputs)]
return self.model.forward(*[to_variable(x) for x in inputs]) outputs = self.model.forward(*inputs)
return [to_numpy(o) for o in to_list(outputs)]
def parameters(self, *args, **kwargs): def parameters(self, *args, **kwargs):
return super(Model, self.model).parameters(*args, **kwargs) return super(Model, self.model).parameters(*args, **kwargs)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册