@classmethod
def from_args(cls, args, observation_space, output_space, gpu_preprocessor,
    net_reg):
    """
        Construct a Modular Network from arguments.

        :param args: Dict[ArgName, Any]
        :param observation_space: Dict[ObsKey, Shape]
        :param output_space: Dict[OutputKey, Shape]
        :param gpu_preprocessor: ObsPreprocessor
        :param net_reg: NetworkRegistry
        :return: ModularNetwork
        """
    obs_key_to_submod = {}
    for obs_key, shape in observation_space.items():
        dim = len(shape)
        if dim == 1:
            submod = net_reg.lookup_submodule(args.net1d).from_args(args,
                shape, obs_key)
        elif dim == 2:
            submod = net_reg.lookup_submodule(args.net2d).from_args(args,
                shape, obs_key)
        elif dim == 3:
            submod = net_reg.lookup_submodule(args.net3d).from_args(args,
                shape, obs_key)
        elif dim == 4:
            submod = net_reg.lookup_submodule(args.net4d).from_args(args,
                shape, obs_key)
        else:
            raise ValueError('Invalid dim: {}'.format(dim))
        obs_key_to_submod[obs_key] = submod
    body_cls = net_reg.lookup_submodule(args.netbody)
    nb_body_feature = sum([submod.output_shape(dim=body_cls.dim)[0] for
        submod in obs_key_to_submod.values()])
    if body_cls.dim > 1:
        other_dims = [submod.output_shape(dim=body_cls.dim)[1:] for submod in
            obs_key_to_submod.values() if submod.dim == body_cls.dim][0]
    else:
        other_dims = []
    input_shape = [nb_body_feature] + list(other_dims)
    body_submod = body_cls.from_args(args, input_shape, 'body')
    head_submodules = {}
    for output_key, shape in output_space.items():
        dim = len(shape)
        if dim in head_submodules:
            continue
        elif dim == 1:
            submod_cls = net_reg.lookup_submodule(args.head1d)
        elif dim == 2:
            submod_cls = net_reg.lookup_submodule(args.head2d)
        elif dim == 3:
            submod_cls = net_reg.lookup_submodule(args.head3d)
        elif dim == 4:
            submod_cls = net_reg.lookup_submodule(args.head4d)
        else:
            raise ValueError('Invalid dim: {}'.format(dim))
        submod = submod_cls.from_args(args, body_submod.output_shape(
            submod_cls.dim), 'head' + str(dim) + 'd')
        head_submodules[str(dim)] = submod
    return cls(obs_key_to_submod, body_submod, head_submodules,
        output_space, gpu_preprocessor)
