Python ML Libraries — TensorFlow vs PyTorch vs Sklearn

Photo: Christina Morillo / Pexels
You have a dataset and a question, and Python offers at least five serious libraries for turning one into the other: scikit-learn, PyTorch, TensorFlow, Keras, and JAX. They overlap less than their reputations suggest. Scikit-learn handles classic machine learning on tables of numbers. PyTorch and TensorFlow build neural networks. Keras is a friendlier layer on top, and since 2023 it can sit on top of more than one engine. This article explains what each library is for, how they differ in practice, and how to choose.
One caveat up front. Many "which library is best" articles lean on usage percentages and salary figures that cannot be traced to a source. This one avoids them and sticks to what the official documentation, the original papers, and government labor statistics support.
The 30-second answer
| If your data looks like... | Start with | Why |
|---|---|---|
| A spreadsheet or database table | scikit-learn, then a gradient-boosted tree library | Strong baselines in a few lines, no GPU needed |
| Images, audio, text, or sequences | PyTorch or Keras | Neural networks learn features that tables-oriented models cannot |
| A model that must run on phones or in browsers | TensorFlow ecosystem (LiteRT, TensorFlow.js), or export from PyTorch | Mature edge tooling |
| Research code with custom training loops | PyTorch, or JAX if you like functional programming | Flexible, debuggable, widely used in papers |
| You are learning and want the shortest path | scikit-learn first, then PyTorch or Keras | Concepts transfer, syntax does not matter much |
If you are still deciding what machine learning even covers, our introduction to what machine learning is is the right starting point, and the complete machine learning learning path lays out an order of study.
A mental model: workshop tools versus a factory line
Two analogies help keep the libraries straight.
Scikit-learn is a well-organized toolbox of hand tools. Every tool has the same handle: you create an object, call fit on training data, and call predict or transform on new data. You can pick up a random forest, a logistic regression, or a clustering algorithm and use it the same way. You rarely need to think about what happens inside.
PyTorch, TensorFlow, and JAX are closer to a machine shop. You are not choosing a finished tool; you are building one. You define the layers, the loss, and the training loop, and the library handles the heavy arithmetic (computing gradients, spreading work over a GPU). That flexibility is the point, and it is also why a neural network takes more lines of code than a scikit-learn model.
A second analogy covers the framework tradeoff. Think of the difference between a car with an automatic transmission and one with a manual. Keras is the automatic: you describe the layers and call fit, and it manages the training loop. PyTorch is more often written as a manual: you write the loop yourself, which costs lines of code and buys control. Both reach the destination, and the choice depends on how much of the drive you want to control.
Where each library came from
History explains many of the differences, so here is the short version, with dates from the projects' own documentation and reference works.
| Library | Origin | First public release | Maintained by |
|---|---|---|---|
| scikit-learn | Started in 2007 as a Google Summer of Code project by David Cournapeau; INRIA researchers took over leadership in 2010 | February 1, 2010 | Community-developed, BSD license |
| TensorFlow | Google Brain team, for internal research and production use | November 9, 2015 | Google, Apache 2.0 license |
| PyTorch | Originally developed by Meta Platforms (Facebook AI Research) | September 2016 (alpha) | PyTorch Foundation under the Linux Foundation since September 2022, BSD-3 license |
| Keras 3 | Full rewrite of the Keras library | After five months of public beta | Keras team, runs on JAX, TensorFlow, PyTorch, and (inference only) OpenVINO |
| JAX | Google's array-computation library with composable transformations | Described in its documentation as accelerator-oriented array computation | Google and open-source contributors |
Sources: scikit-learn About page, Wikipedia: TensorFlow, Wikipedia: PyTorch, Keras 3 announcement, and the JAX documentation.
Two things stand out. Scikit-learn is the oldest by far, and it was built by and for people who want machine learning without becoming specialists; the 2011 paper describing it in the Journal of Machine Learning Research puts "emphasis on ease of use, performance, documentation, and API consistency" (JMLR). The two big deep learning frameworks arrived within a year of each other and were designed by large companies for different priorities, Google for production deployment and Meta's research team for flexibility. They have been converging ever since.
Scikit-learn: the workhorse for tabular data
Scikit-learn covers regression, classification, clustering, dimensionality reduction, model selection, and preprocessing. It runs on the CPU, it works on NumPy arrays and pandas data frames, and its documentation is widely regarded as a model of the genre. If your data fits in a table (customer records, sensor readings, lab results), scikit-learn is usually where you start. For a refresher on the data structures underneath, see our NumPy guide.
The estimator pattern
Everything in scikit-learn follows one interface. A model is an "estimator" with fit(X, y) to learn from data and predict(X) to produce answers. A preprocessing step is a "transformer" with fit and transform. Because the interface is uniform, you can swap a decision tree for a support vector machine by changing one line. That consistency is the library's main design achievement.
Pipelines keep you honest
The most valuable scikit-learn feature for beginners is the Pipeline. According to the documentation, pipelines serve three purposes: convenience (one fit and one predict for the whole sequence), joint parameter selection (grid search over every step at once), and safety, because pipelines "help avoid leaking statistics from your test data into the trained model in cross-validation" (scikit-learn: Pipelines and composite estimators).
That last point is the one that matters. Suppose you scale your features by subtracting the mean and dividing by the standard deviation. If you compute that mean on the entire dataset before splitting, the test set has leaked information into training, and your reported accuracy will look better than it will in production. Putting the scaler inside a pipeline means it is refit on training data only. Our explainers on why training and test data must be separated and why data leakage breaks AI evaluations explain the failure in more depth.
Why trees still win on many tables
A common beginner assumption is that deep learning is the "advanced" option and should beat older methods on any problem. For tabular data, the evidence points the other way. A 2022 study by Léo Grinsztajn, Edouard Oyallon, and Gaël Varoquaux, titled "Why do tree-based models still outperform deep learning on tabular data?", found that tree-based models such as XGBoost and random forests "remain state-of-the-art on medium-sized data (~10K samples)," even without accounting for their speed advantage (arXiv:2207.08815). The authors attribute the gap to differences in inductive bias, meaning the built-in assumptions of each model family about what the data looks like.
This is the empirical basis for the old advice to start with scikit-learn on tables. It is a statement about medium-sized tabular datasets in one benchmark study, not a law, but it matches common practice. To see the algorithms in action, read our explainers on random forests and XGBoost, and the overview of classic ML algorithms.
Limits worth knowing
Scikit-learn is not built for deep learning, and it is not designed around GPUs. There is experimental support for running some estimators on GPU arrays through the Array API standard, using PyTorch tensors, CuPy, or similar libraries. The documentation states plainly that "this support is considered experimental" and that backward compatibility is not guaranteed, and only a specific list of estimators is covered, including PCA, ridge and logistic regression, linear discriminant analysis, and several scalers (scikit-learn: Array API support). Treat it as a convenience for certain workloads, not a reason to pick scikit-learn for GPU-heavy work.
PyTorch: the flexible deep learning framework
PyTorch is a tensor library (a tensor is a multi-dimensional array of numbers) with automatic differentiation. When you run a forward pass, PyTorch records the operations in a graph, and calling .backward() walks that graph in reverse to compute gradients (the numbers that tell the optimizer how to adjust each weight). The Wikipedia summary describes autograd as building a directed acyclic graph of the operations run during the forward pass (Wikipedia: PyTorch).
Eager by default
The practical consequence of this design is that PyTorch code runs like ordinary Python. Each line executes immediately, you can print a tensor in the middle of a model, use a normal debugger, and write if statements and for loops that depend on the data. This "eager" style is the main reason many researchers prefer it, and it is what people mean when they call PyTorch "Pythonic." For gradient descent, the algorithm underneath all of this, see our explainer on how gradient descent finds better answers.
torch.compile: speed without giving up flexibility
PyTorch 2.0, released on March 15, 2023, introduced a compiler path. The official tutorial describes torch.compile as "JIT-compiling PyTorch code into optimized kernels": you wrap a function or module, PyTorch traces the Python code to find the tensor operations, and generates faster code. Code it cannot trace causes a "graph break" instead of an error, so the program still runs. The tutorial's toy example shows a median speedup of about 2.4 times over eager mode on a GPU, and it cautions that the observed speedup varies with model architecture and batch size, and that the first few runs are slower because of compile time (PyTorch tutorial: torch.compile). That example is a toy, so do not read 2.4 times as a general promise.
Governance and ecosystem
In September 2022, Meta announced that governance of PyTorch would move to the PyTorch Foundation, a subsidiary of the Linux Foundation. That matters for long-term risk: no single company's roadmap controls the project. The ecosystem around it is large. In particular, Hugging Face's Transformers library, the main source of pretrained language and vision models, announced in December 2025 with its version 5 release that it is "focusing on PyTorch as the sole backend" and "sunsetting our Flax/TensorFlow support" (Hugging Face blog). If your work involves fine-tuning pretrained models, this is the strongest practical argument for PyTorch today. To understand the architecture those models share, see transformers explained simply.
Where PyTorch asks more of you
PyTorch usually requires you to write the training loop yourself: zero the gradients, run the forward pass, compute the loss, call backward, step the optimizer. That is a good way to learn what training really is, and it is also boilerplate that higher-level wrappers exist to remove. You also need to manage devices (CPU versus GPU) explicitly and remember to switch between training and evaluation modes. None of this is hard, but it is more to hold in your head than a one-line fit call. For what a GPU actually does for you, see how GPUs work and why AI needs them.
TensorFlow and Keras: the production-oriented ecosystem
TensorFlow was released by Google on November 9, 2015, under the Apache 2.0 license, and it was originally built for Google's internal research and production work. TensorFlow 2.0 was announced in January 2019 and released in September 2019, and it switched automatic differentiation to a define-by-run (eager) style, which closed much of the usability gap with PyTorch (Wikipedia: TensorFlow).
Keras is now a separate, multi-backend library
Keras began as a high-level API for building neural networks, and for years tf.keras was the standard way to use TensorFlow. That changed with Keras 3, a full rewrite. According to the Keras documentation, Keras 3 lets you run the same workflow on JAX, TensorFlow, or PyTorch for full training and inference, plus OpenVINO for inference only. TensorFlow 2.16 and later use Keras 3 by default, and tf.keras and Keras 3 cannot be used side by side because they are separate packages (Keras 3 documentation).
Keras is not deprecated or merged into TensorFlow, as some older guides claim. The reality is nearly the reverse: Keras has become more independent, and it is the one high-level API that can sit on top of all three major engines. You select the backend with the KERAS_BACKEND environment variable before importing Keras. The Keras page notes that JAX typically delivers the best performance on GPU, TPU, and CPU, though results vary by model.
Deployment tooling
TensorFlow's strongest advantage is the set of tools for taking a trained model somewhere. Four are worth knowing:
- TensorFlow Serving is a "flexible, high-performance serving system for machine learning models, designed for production environments" (TensorFlow documentation).
- LiteRT, formerly TensorFlow Lite (the rename happened in 2024), is Google's cross-platform inference runtime for edge devices. It targets Android, iOS and macOS, the web, desktop, and embedded devices including microcontrollers, and it can convert models from PyTorch, TensorFlow, and JAX into the
.tfliteformat (LiteRT). - TensorFlow.js runs machine learning in JavaScript, including in a browser.
- TFX (TensorFlow Extended) provides components for end-to-end production pipelines, from data validation to deployment.
Note the LiteRT detail: converters now accept PyTorch and JAX models too, so the deployment advantage is narrower than it was. For a broader look at the operational side, our MLOps primer explains what production machine learning involves beyond the model.
The honest summary on TensorFlow
TensorFlow remains a capable framework with unmatched breadth in deployment tools, but its momentum in the open-source research and pretrained-model community has shifted. The Hugging Face change above is one visible sign. If you work at a company with an existing TensorFlow stack, learning it is practical. If you are choosing from scratch for research or model fine-tuning, the evidence from the ecosystem points toward PyTorch or JAX. Our side-by-side article, PyTorch vs TensorFlow vs JAX, goes deeper on that three-way choice, while this article keeps scikit-learn and Keras in the picture.
JAX: functional transformations for research
JAX is often skipped in beginner guides, but it deserves a longer look because it is the third major framework in deep learning research. The JAX documentation describes it as a Python library for "accelerator-oriented array computation and program transformation," with a NumPy-style interface. Its core idea is composable transformations: jax.jit() compiles code, jax.grad() computes derivatives, and jax.vmap() automatically vectorizes a function over a batch. The same code runs on CPUs, GPUs, and TPUs, and JAX itself stays small, with neural network layers and optimizers provided by libraries such as Flax and Optax built on top (JAX documentation).
JAX asks you to write functions without side effects (pure functions), and in exchange you get a very clean way to express things like per-example gradients. It has a steeper learning curve than PyTorch for most people, and a smaller pool of tutorials. It makes sense when you are doing research that benefits from its transformations, or when you want Keras 3 running on its backend. For a first deep learning project, it is rarely the right place to start.
The same problem in three libraries
The best way to feel the differences is to solve the same problem three times. The task is the classic iris flower dataset: four measurements per flower, three species. The code below is illustrative and kept short; run it in a fresh virtual environment with the libraries installed. If you manage environments with modern tooling, our explainer on uv, the fast Python package manager is a good way to keep them reproducible.
Scikit-learn
from sklearn.datasets import load_iris
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
X, y = load_iris(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
# The scaler lives inside the pipeline, so it is fit on training data only.
model = make_pipeline(StandardScaler(), LogisticRegression(max_iter=1000))
model.fit(X_train, y_train)
print(f"Accuracy: {accuracy_score(y_test, model.predict(X_test)):.2%}")
That is the entire program: about a dozen lines, a few seconds to run, no GPU. Swapping in a different algorithm means replacing LogisticRegression with, for example, RandomForestClassifier. Note the class name: scikit-learn has no plain RandomForest; the real classes are RandomForestClassifier and RandomForestRegressor.
PyTorch
import torch
from torch import nn
from torch.utils.data import DataLoader, TensorDataset
# X_train, X_test, y_train, y_test are the scaled arrays from the example above.
X_train_t = torch.tensor(X_train, dtype=torch.float32)
y_train_t = torch.tensor(y_train, dtype=torch.long)
X_test_t = torch.tensor(X_test, dtype=torch.float32)
y_test_t = torch.tensor(y_test, dtype=torch.long)
loader = DataLoader(TensorDataset(X_train_t, y_train_t), batch_size=32, shuffle=True)
model = nn.Sequential(
nn.Linear(4, 64), nn.ReLU(),
nn.Linear(64, 32), nn.ReLU(),
nn.Linear(32, 3),
)
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
loss_fn = nn.CrossEntropyLoss()
for epoch in range(100):
model.train()
for xb, yb in loader:
optimizer.zero_grad()
loss = loss_fn(model(xb), yb)
loss.backward()
optimizer.step()
model.eval()
with torch.no_grad():
preds = model(X_test_t).argmax(dim=1)
print(f"Accuracy: {(preds == y_test_t).float().mean().item():.2%}")
Every step of training is visible: batching, gradient reset, forward pass, loss, backward pass, weight update. It is more code, and nothing is hidden. If you want to understand what "training" means, writing this loop once is worth the effort.
Keras
import keras
model = keras.Sequential([
keras.Input(shape=(4,)),
keras.layers.Dense(64, activation="relu"),
keras.layers.Dense(32, activation="relu"),
keras.layers.Dense(3, activation="softmax"),
])
model.compile(
optimizer="adam",
loss="sparse_categorical_crossentropy",
metrics=["accuracy"],
)
model.fit(X_train, y_train, epochs=100, batch_size=32, verbose=0)
loss, accuracy = model.evaluate(X_test, y_test, verbose=0)
print(f"Accuracy: {accuracy:.2%}")
Keras hides the training loop inside fit. The same code runs on a TensorFlow, JAX, or PyTorch backend, selected with the KERAS_BACKEND environment variable. For a four-feature, 150-row dataset, none of the neural-network versions will beat the scikit-learn one by a meaningful margin, and that is the point: deep learning is a tool for problems where tables-based methods stall, not a default.
Choosing by task
| Task | Reasonable first choice | Notes |
|---|---|---|
| Churn, fraud, pricing, other tabular prediction | scikit-learn, then gradient-boosted trees | Interpretability and speed matter; trees are strong on medium-sized tables |
| Image classification | PyTorch (with pretrained models) or Keras | Fine-tuning a pretrained network beats training from scratch for most teams |
| Text classification and language tasks | PyTorch with Hugging Face Transformers | Transformers v5 centers on PyTorch |
| Custom loss functions and research ideas | PyTorch or JAX | Eager execution or pure-function transformations make experiments cheap |
| Time series forecasting | Often a simpler statistical or tree-based model first | Deep models are not automatically better; compare against a simple baseline |
| Mobile or browser inference | LiteRT or TensorFlow.js, exporting from your framework | LiteRT converts from PyTorch, TensorFlow, and JAX |
| Recommendation systems | Depends on scale | See our article on how recommendation systems rank choices |
| Reinforcement learning | PyTorch is the common choice | Flexible training loops fit the problem |
| Running models on a Mac | PyTorch (MPS backend) or Apple's own framework | See what MLX is |
The table gives defaults, not verdicts. A team's existing code, hardware, and deployment target usually matter more than benchmark differences between frameworks.
The ecosystem around the big three
Most real projects use a stack, not one library. The pieces that come up most often:
Gradient-boosted tree libraries. XGBoost, described in a 2016 KDD paper by Tianqi Chen and Carlos Guestrin as "an end-to-end tree boosting system built for scale," is widely used to reach top results in machine learning competitions (arXiv:1603.02754). LightGBM is described in its documentation as a gradient boosting framework with faster training, lower memory use, and support for parallel, distributed, and GPU learning (LightGBM docs). Scikit-learn also ships its own HistGradientBoostingClassifier, which is "inspired by LightGBM," uses histogram binning, and the documentation says it can be "orders of magnitude faster" than the older GradientBoostingClassifier when there are more than tens of thousands of samples. It handles missing values natively, so no imputer is needed (scikit-learn: Ensembles). For many tabular problems, that built-in option is enough. How much any of them beats a random forest depends on the dataset, so benchmark on your own data.
Hugging Face Transformers. The standard library for pretrained language, vision, and audio models, now PyTorch-focused as noted above.
ONNX. The Open Neural Network Exchange is described as "the open standard for machine learning interoperability," a shared model format and operator set that lets you train in one framework and run in a chosen inference engine. It is a community project and an LF AI graduate project (ONNX).
Wrappers that reduce boilerplate. Third-party libraries exist that wrap PyTorch training loops so you do not rewrite them for every project. They are optional, and they are worth adopting only after you have written a raw loop yourself.
For a quick map of the data side of the Python stack, our Python data libraries cheat sheet covers pandas, NumPy, and friends.
Saving and shipping models
Training a model is half the job. Saving it safely and serving it reliably is the other half, and the documentation contains warnings that many tutorials skip.
The pickle problem
The common scikit-learn recipe is joblib.dump(model, "model.pkl") followed by joblib.load. The scikit-learn documentation states that pickle-based formats (pickle, joblib, and cloudpickle) "[have] many documented security vulnerabilities by design and should only be used if the artifact, i.e. the pickle-file, is coming from a trusted and verified source." Loading an untrusted pickle file is comparable to running untrusted code. The documentation offers alternatives: ONNX when you only need predictions, and skops.io when you need the Python object back with safer loading (scikit-learn: Model persistence).
There is a second trap. The same page says there is no supported way to load a model trained with a different scikit-learn version. It may load, but that is "entirely unsupported and inadvisable," and results may be wrong or the process may crash. The fix is to pin versions of scikit-learn, NumPy, SciPy, and other dependencies, freeze the environment in a container, and save metadata alongside the model: a reference to the training data snapshot, the training code, the library versions, and the cross-validation scores.
Deployment paths by framework
| Framework | Common routes | Notes |
|---|---|---|
| scikit-learn | joblib or skops for Python services; ONNX for lean serving |
Follow the version-pinning guidance above |
| PyTorch | Serve from Python; export to ONNX; convert to .tflite through LiteRT tooling |
ONNX models should be served in a sandboxed environment, since the format can represent arbitrary computation |
| TensorFlow and Keras | TensorFlow Serving; LiteRT for mobile and edge; TensorFlow.js for browsers | The most complete first-party deployment stack |
Quantization, which stores a model's numbers at lower precision to save memory and speed up inference, is a common step before deployment on constrained hardware. Our article on LLM quantization explains how it works for large language models.
The job market, with real numbers
Job postings are not tracked by library in any official statistic, so salary claims for "TensorFlow jobs" or "PyTorch jobs" have no authoritative source. The closest authoritative data is for the occupation as a whole. The US Bureau of Labor Statistics reports that data scientists had a median annual pay of $120,230 in May 2025, that employment was about 275,600 in 2025, and that employment is projected to grow 35 percent from 2025 to 2035, much faster than the average for all occupations (BLS Occupational Outlook Handbook).
Those figures describe the occupation, not a particular framework, and pay varies widely by employer, location, and experience. What the market consistently asks for, based on how roles are described, is the ability to frame a problem, clean data, build a defensible baseline, and communicate results, with familiarity with one deep learning framework as a plus. For a view of the career side, see the ML engineer career path, and for study options, our best ML courses roundup and the guide to free ML courses.
A learning order that holds up
Here is a sequence that follows from everything above, with no promised timelines because individual pace varies enormously.
- Learn the workflow in scikit-learn. Load data, split it properly, build a pipeline, evaluate with cross-validation, and learn to read a confusion matrix. Our tutorial on how to build your first ML model walks through it.
- Learn why models fail. Overfitting, leakage, and class imbalance cause more bad projects than the choice of library. See overfitting and underfitting and why 99 percent accuracy can be useless.
- Add one deep learning framework. PyTorch is the more common choice for learning today because its code reads like normal Python; Keras is a gentler first step if you want fewer lines. Pick one and build two or three projects before sampling the others.
- Learn the neighbors only when a job requires them. The concepts (tensors, gradients, batches, optimizers, loss functions) transfer between frameworks. Syntax is a matter of documentation lookups.
Common mistakes
- Reaching for deep learning on a spreadsheet. On medium-sized tabular data, tree-based models are a hard baseline to beat. Try one before building a network.
- Preprocessing before splitting. Scaling, imputing, or selecting features on the full dataset leaks test information. Put those steps in a pipeline.
- Trusting a single split. One lucky train-test split can mislead. Use cross-validation for model comparison.
- Loading pickles from strangers. Treat a model file like executable code.
- Ignoring versions. A model trained under one scikit-learn version is not guaranteed to load under another. Pin and record.
- Choosing a framework by benchmark headlines. Hardware, team skills, and deployment target dominate. A framework your team can debug at 2 a.m. beats a faster one it cannot.
What this means
The question "scikit-learn, PyTorch, or TensorFlow" is really three questions: what shape is your data, how much control do you need, and where will the model run. Tables point to scikit-learn and tree ensembles. Images, text, and audio point to a deep learning framework, with PyTorch the default for research and for working with pretrained models, and the TensorFlow ecosystem still strongest for its first-party deployment tools. Keras 3 blurs the lines by running on several engines, so learning it is not a bet on a single one.
The more durable skill is not syntax but judgment: knowing when a simple model is enough, how to evaluate honestly, and how to ship something safely. Libraries will keep changing, and the Hugging Face decision to focus on PyTorch is a reminder that ecosystems move. Check the documentation for current versions before you commit a project to a stack.
Frequently asked questions
Q: Should I learn scikit-learn before PyTorch or TensorFlow? A: For most people, yes. Scikit-learn teaches the workflow that every ML project shares: splitting data, preprocessing, fitting, and evaluating. It also gives you strong baselines, and research on medium-sized tabular datasets has found tree-based models hard to beat with neural networks. Deep learning frameworks make more sense once you have that foundation.
Q: Is PyTorch or TensorFlow more widely used? A: No single trustworthy figure covers all use. What can be said is that PyTorch dominates the open-source pretrained-model ecosystem: Hugging Face Transformers v5 announced PyTorch as its sole backend and the end of TensorFlow and Flax support. TensorFlow keeps strength in its deployment tools and in organizations with existing TensorFlow systems. Check your target employers or projects instead of relying on a global percentage.
Q: Is Keras deprecated? A: No. Keras 3 is a full rewrite that runs on JAX, TensorFlow, and PyTorch for training and inference, plus OpenVINO for inference only. TensorFlow 2.16 and later use Keras 3 by default.
Q: Can I use TensorFlow or PyTorch for tabular data? A: Yes, and sometimes it is the right call, for instance with very large datasets or when tabular data is one input among images and text. But for medium-sized tables, a 2022 study found tree-based models remain state-of-the-art, and they are faster to train and simpler to explain.
Q: Do I need a GPU? A: Not for scikit-learn, which is built for the CPU. Deep learning frameworks run on the CPU too, which is enough for small learning projects like the iris example, but larger networks train much faster on a GPU. Scikit-learn's GPU support through the Array API is experimental and limited to certain estimators.
Q: Is it safe to share a scikit-learn model as a pickle or joblib file?
A: Only with people who trust the source. The scikit-learn documentation warns that pickle-based formats can run arbitrary code on load, and it recommends ONNX for prediction-only serving or skops.io for safer loading. Models also should not be moved between scikit-learn versions.
Q: What about JAX?
A: JAX is a strong choice for research that benefits from composable function transformations (jit, grad, vmap) and for TPU-heavy work. It is a smaller ecosystem than PyTorch and a steeper start, so most learners pick up PyTorch or Keras first. Because Keras 3 supports a JAX backend, you can also try JAX without rewriting your model code.
Sources
- scikit-learn: About us
- Pedregosa et al., "Scikit-learn: Machine Learning in Python," JMLR 12 (2011)
- scikit-learn: Pipelines and composite estimators
- scikit-learn: Model persistence
- scikit-learn: Array API support
- scikit-learn: Ensembles
- Keras 3 documentation
- PyTorch tutorial: torch.compile
- Hugging Face: Transformers v5
- Grinsztajn, Oyallon, Varoquaux (2022), tree-based models vs deep learning on tabular data
- Chen and Guestrin (2016), XGBoost
- JAX documentation
- LiteRT, TensorFlow Serving, ONNX
- US Bureau of Labor Statistics: Data Scientists
Read next:
Follow new articles
Add SciHub101 to your feed reader to see new science and technology stories.
About the Author
SciHub101 is an independent science and technology publication founded and edited by Buğra Sözeri, a software engineer and app developer based in Türkiye. AI tools assist with drafting and research. Source documentation in the existing archive is uneven, and articles are being reviewed and corrected. The Editorial Team byline identifies editorial responsibility; it does not certify specialist or independent human review. Where we compare products, anything built by our own team is labelled as such — see the editorial guidelines and About page for how corrections and disclosures work.
Related Articles

Difference Between AI, ML, and Deep Learning Explained
AI, machine learning, and deep learning are nested, not synonyms. See how each works, where they differ, and when classic ML beats neural networks.

How to Build Your First ML Model — Step-by-Step Tutorial
Build your first ML model in Python with scikit-learn: load California housing data, split it, train, score with RMSE and R², then improve it honestly.

Python for Data Science: Complete Guide 2026
Master Python for data science in 2026. Covers essential libraries, workflows, career paths, and learning roadmap with real examples.

Random Forest Explained — The Reliable ML Algorithm 2026
Random Forest explained simply: how it works, when to use it, Python tutorial, hyperparameter tuning, and why it's still relevant in 2026 despite XGBoost.

PyTorch vs TensorFlow vs JAX 2026 — Which to Learn
Honest comparison of PyTorch, TensorFlow, and JAX in 2026 — which to learn first, where each one wins, and what hiring managers actually look for.

How to Handle Missing Data — Imputation Strategies
Handle missing data in ML datasets: deletion, mean/median imputation, forward fill, KNN imputation. When to use each method with Python code examples.