bioFAM / mofapy2

Multi-omics factor analysis v2
https://biofam.github.io/MOFA2/
GNU Lesser General Public License v3.0
36 stars 28 forks source link

AttributeError: 'BayesNet' object has no attribute 'train_stats' #28

Closed Connorr0 closed 1 month ago

Connorr0 commented 6 months ago

When running MOFA with muon an error can occur where the model cannot find the training stats when it goes to save the results. This is outlined in this issue in the R repository (linking it here because it seems more relevant here).

Output

Loaded view='rna' group='group1' with N=5412 samples and D=23519 features...
Loaded view='atac' group='group1' with N=5412 samples and D=135866 features...

Warning: 1 features(s) in view 0 have zero variance, consider removing them before training the model...

Model options:
- Automatic Relevance Determination prior on the factors: True
- Automatic Relevance Determination prior on the weights: True
- Spike-and-slab prior on the factors: False
- Spike-and-slab prior on the weights: True
Likelihoods:
- View 0 (rna): poisson
- View 1 (atac): bernoulli

GPU mode is activated

######################################
## Training the model with seed 1 ##
######################################

Attempting to save the model at the current iteration...
Saving model in /tmp/mofa_20240522-102240_interrupted.hdf5...
Note: the model to be saved is not trained.

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
File ~/.local/lib/python3.8/site-packages/mofapy2/run/entry_point.py:26, in keyboardinterrupt_saver.<locals>.saver(self, *args, **kwargs)
     25 try:
---> 26     func(self, *args, **kwargs)
     27 # Internal methods will raise TypeError when interrupted

File ~/.local/lib/python3.8/site-packages/mofapy2/run/entry_point.py:1400, in entry_point.run(self)
   1399 # Train the model
-> 1400 train_model(self.model)

File ~/.local/lib/python3.8/site-packages/mofapy2/build_model/train_model.py:26, in train_model(model)
     24 print("\n")
---> 26 model.iterate()
     28 print("\n")

File ~/.local/lib/python3.8/site-packages/mofapy2/core/BayesNet.py:267, in BayesNet.iterate(self)
    266 convergence_token = 1
--> 267 elbo.iloc[0] = self.precompute()
    268 number_factors[0] = self.dim["K"]

File ~/.local/lib/python3.8/site-packages/mofapy2/core/BayesNet.py:225, in BayesNet.precompute(self)
    224 for n in self.nodes:
--> 225     self.nodes[n].precompute(self.options)
    227 # Precompute ELBO

File ~/.local/lib/python3.8/site-packages/mofapy2/core/nodes/multiview_nodes.py:115, in Multiview_Node.precompute(self, options)
    114 for m in self.activeM:
--> 115     self.nodes[m].precompute(options)

File ~/.local/lib/python3.8/site-packages/mofapy2/core/nodes/nongaussian_nodes.py:206, in Poisson_PseudoY.precompute(self, options)
    205 self.updateParameters()
--> 206 self.updateExpectations()

File ~/.local/lib/python3.8/site-packages/mofapy2/core/nodes/nongaussian_nodes.py:222, in Poisson_PseudoY.updateExpectations(self)
    218 tau = self.markov_blanket["Tau"].getValue()
    219 self.E = (
    220     self.params["zeta"]
    221     - sigmoid(self.params["zeta"])
--> 222     * (1 - self.obs / self.ratefn(self.params["zeta"]))
    223     / tau
    224 )
    225 self.E[self.mask] = 0.0

File cupy/_core/core.pyx:1697, in cupy._core.core._ndarray_base.__array_ufunc__()

File cupy/_core/_kernel.pyx:1283, in cupy._core._kernel.ufunc.__call__()

File cupy/_core/_kernel.pyx:159, in cupy._core._kernel._preprocess_args()

File cupy/_core/_kernel.pyx:145, in cupy._core._kernel._preprocess_arg()

TypeError: Unsupported type <class 'numpy.ndarray'>

During handling of the above exception, another exception occurred:

AttributeError                            Traceback (most recent call last)
Cell In [4], line 1
----> 1 mu.tl.mofa(mdata, use_layer = "raw", gpu_mode=True)

File ~/.local/lib/python3.8/site-packages/muon/_core/tools.py:586, in mofa(data, groups_label, use_raw, use_layer, use_var, use_obs, likelihoods, n_factors, scale_views, scale_groups, center_groups, ard_weights, ard_factors, spikeslab_weights, spikeslab_factors, n_iterations, convergence_mode, use_float32, gpu_mode, gpu_device, svi_mode, svi_batch_size, svi_learning_rate, svi_forgetting_rate, svi_start_stochastic, smooth_covariate, smooth_warping, smooth_kwargs, save_parameters, save_data, save_metadata, seed, outfile, expectations, save_interrupted, verbose, quiet, copy)
    584 ent.build()
    585 logging.info(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] Running the model...")
--> 586 ent.run()
    588 if (
    589     smooth_kwargs is not None
    590     and "new_values" in smooth_kwargs
    591     and smooth_kwargs["new_values"]
    592     and smooth_covariate
    593 ):
    594     logging.info(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] Interpolating factors...")

File ~/.local/lib/python3.8/site-packages/mofapy2/run/entry_point.py:39, in keyboardinterrupt_saver.<locals>.saver(self, *args, **kwargs)
     34     else:
     35         tmp_file = os.path.join(
     36             "/tmp",
     37             "mofa_{}_interrupted.hdf5".format(strftime("%Y%m%d-%H%M%S")),
     38         )
---> 39     self.save(outfile=tmp_file)
     40     print(
     41         "Saved partially trained model in {}. Exiting now.".format(tmp_file)
     42     )
     43 else:

File ~/.local/lib/python3.8/site-packages/mofapy2/run/entry_point.py:1743, in entry_point.save(self, outfile, save_data, save_parameters, expectations)
   1740     tmp.saveSmoothOptions(self.smooth_opts)
   1742 # Save training statistics
-> 1743 tmp.saveTrainingStats()
   1745 # Save variance explained values
   1746 tmp.saveVarianceExplained()

File ~/.local/lib/python3.8/site-packages/mofapy2/build_model/save_model.py:741, in saveModel.saveTrainingStats(self)
    738 """Method to save the training statistics"""
    740 # Get training statistics
--> 741 stats = self.model.getTrainingStats()
    743 # Create HDF5 group
    744 stats_grp = self.hdf5.create_group("training_stats")

File ~/.local/lib/python3.8/site-packages/mofapy2/core/BayesNet.py:502, in BayesNet.getTrainingStats(self)
    500 def getTrainingStats(self):
    501     """Method to return training statistics"""
--> 502     return self.train_stats

AttributeError: 'BayesNet' object has no attribute 'train_stats'

Pip freeze:

using Python: /app/software/Python/3.8.2-GCCcore-9.3.0/bin/python3
absl-py==1.2.0
alembic==1.8.1
anndata==0.9.2
asttokens==2.0.8
autopage==0.5.1
backcall==0.2.0
blosc2==2.0.0
cachetools==5.2.0
cliff==4.0.0
cmaes==0.8.2
cmd2==2.4.2
colorlog==6.7.0
contourpy==1.0.5
cupy-cuda12x==12.3.0
cycler==0.11.0
debugpy==1.6.3
entrypoints==0.4
executing==1.1.1
fastrlock==0.8.2
fcsparser==0.2.8
fonttools==4.37.4
greenlet==1.1.3.post0
h5py==3.7.0
igraph==0.10.8
importlib-resources==5.10.0
ipykernel==6.16.0
ipython==8.5.0
jedi==0.18.1
jupyter-client==8.6.1
jupyter-core==5.7.2
kiwisolver==1.4.4
leidenalg==0.10.1
lisa2==2.3.0
llvmlite==0.41.1
MACS2==2.2.7.1
Mako==1.2.3
Markdown==3.4.1
matplotlib==3.6.3
matplotlib-inline==0.1.6
mellon==1.4.1
mira-multiome==1.0.4
ml-dtypes==0.2.0
mofapy2==0.7.1
MOODS-python==1.9.4.1
msgpack==1.0.8
mudata==0.2.3
muon==0.1.6
natsort==8.2.0
nest-asyncio==1.5.6
networkx==2.8.7
numba==0.58.1
numexpr==2.8.6
numpy==1.24.4
opt-einsum==3.3.0
optuna==2.10.1
pandas==1.5.3
parso==0.8.3
patsy==0.5.3
pexpect==4.8.0
pickleshare==0.7.5
Pillow==9.2.0
platformdirs==4.2.2
prettytable==3.4.1
prompt-toolkit==3.0.31
protobuf==5.26.1
ptyprocess==0.7.0
pure-eval==0.2.2
py-cpuinfo==9.0.0
pyasn1-modules==0.2.8
pynndescent==0.5.7
pyperclip==1.8.2
pyro-api==0.1.2
pyro-ppl==1.8.2
pyzmq==24.0.1
requests-oauthlib==1.3.1
rsa==4.9
scanpy==1.8.2
scikit-learn==1.3.2
scipy==1.10.1
seaborn==0.12.0
sinfo==0.3.4
SQLAlchemy==1.4.42
stack-data==0.5.1
statsmodels==0.13.2
stdlib-list==0.8.0
stevedore==4.0.0
tables==3.8.0
tensorboard-plugin-wit==1.8.1
threadpoolctl==3.1.0
torch==1.12.1
tornado==6.2
tqdm==4.64.1
traitlets==5.14.3
typing-extensions==4.4.0
tzdata==2024.1
umap-learn==0.5.3
xgboost==2.0.3
gtca commented 1 month ago

Hey, thanks for reporting this!

So far do not see that error with poisson or bernoulli likelihoods and the same model options — on CPU. I imagine the actual error is the TypeError from cupy rather than what's in the title of this issue.

gtca commented 1 month ago

Should be fixed in 0.7.2!