Name: Towards AI Legal Name: Towards AI, Inc. Description: Towards AI is the world's leading artificial intelligence (AI) and technology publication. Read by thought-leaders and decision-makers around the world. Phone Number: +1-650-246-9381 Email: pub@towardsai.net
228 Park Avenue South New York, NY 10003 United States
Website: Publisher: https://towardsai.net/#publisher Diversity Policy: https://towardsai.net/about Ethics Policy: https://towardsai.net/about Masthead: https://towardsai.net/about
Name: Towards AI Legal Name: Towards AI, Inc. Description: Towards AI is the world's leading artificial intelligence (AI) and technology publication. Founders: Roberto Iriondo, , Job Title: Co-founder and Advisor Works for: Towards AI, Inc. Follow Roberto: X, LinkedIn, GitHub, Google Scholar, Towards AI Profile, Medium, ML@CMU, FreeCodeCamp, Crunchbase, Bloomberg, Roberto Iriondo, Generative AI Lab, Generative AI Lab Denis Piffaretti, Job Title: Co-founder Works for: Towards AI, Inc. Louie Peters, Job Title: Co-founder Works for: Towards AI, Inc. Louis-François Bouchard, Job Title: Co-founder Works for: Towards AI, Inc. Cover:
Towards AI Cover
Logo:
Towards AI Logo
Areas Served: Worldwide Alternate Name: Towards AI, Inc. Alternate Name: Towards AI Co. Alternate Name: towards ai Alternate Name: towardsai Alternate Name: towards.ai Alternate Name: tai Alternate Name: toward ai Alternate Name: toward.ai Alternate Name: Towards AI, Inc. Alternate Name: towardsai.net Alternate Name: pub.towardsai.net
5 stars – based on 497 reviews

Frequently Used, Contextual References

TODO: Remember to copy unique IDs whenever it needs used. i.e., URL: 304b2e42315e

Resources

Take our 85+ lesson From Beginner to Advanced LLM Developer Certification: From choosing a project to deploying a working product this is the most comprehensive and practical LLM course out there!

Publication

TensorFlow vs. PyTorch: What’s Better for a Deep Learning Project?
Data Science   Latest   Machine Learning

TensorFlow vs. PyTorch: What’s Better for a Deep Learning Project?

Last Updated on August 8, 2024 by Editorial Team

Author(s): Eashan Mahajan

Originally published on Towards AI.

Photo by Marius Masalar on Unsplash

Deep learning. A subset of machine learning utilizing multilayered neural networks, otherwise known as deep neural networks. Allowing society to simulate the decision-making prowess the human brain possesses, deep learning exists within some of the AI applications we use in our lives today.

If you’re getting started with deep learning, you’ll find yourself overwhelmed with the amount of frameworks. However, you’ll see two frameworks stand at the top: PyTorch and TensorFlow. Possessing their own strengths and weaknesses, both these frameworks are powerful deep learning tools. PyTorch powers Tesla’s autopilot feature and OpenAI’s ChatGPT, while TensorFlow is used in Google search and Uber.

Both TensorFlow and PyTorch are both relied on heavily in research and commercial code. APIs and cloud computing platforms extend the usage of both frameworks. If both of them have so much support and usage, how do you decide which one to use? Let’s answer that question.

What is TensorFlow?

TensorFlow is an end-to-end platform for machine learning, a prominent open-source library dedicated to accomplishing a wide range of machine and deep learning tasks. Developed by Google in 2015, TensorFlow boasts extensive capabilities, resulting in the tool being used often for research purposes or companies using it for their programming purposes. It can also be used in a variety of languages, such as Python, C++, JavaScript, and Java.

Functionality

One thing to note is the name “TensorFlow” tells you how you’re going to work with this framework. The basic data structure for TensorFlow are tensors. A tensor is an algebraic object detailing the multilinear relationship between sets of algebraic objects with respect to a vector space. There are many types of tensors, with some of the most popular ones being scalars and vectors, the 2 simplest tensors.

Now, a big focus for TensorFlow is on production and scalability. It becomes obvious when you take a look at its robust architecture and enormous support for deploying models on a variety of platforms. Let’s take a look at what other reasons makes TensorFlow so reliable for production and scalability.

Production:

1. TensorFlow Extended (TFX):

  • End-to-End Pipeline: Providing a variety of tools and libraries for production-ready machine learning pipelines, TFX takes care of the entire lifecycle from data ingestion and validation to model training, evaluation, and deployment.
  • Component Integration: TFX has components such as TensorFlow Data Validation, Transform, Model Analysis, and Serving. All of these components work well together and ensure a reliable production workflow.

2. TensorFlow Serving:

  • Model Deployment: TensorFlow serving was specifically reated for deploying machine learning models in production. Supporting features such as model versioning, it allows for updates to be implemented easily.
  • High Performance: TensorFlow has been optimized for low-latency and high-throughput serving, making it suitable for real-time interference applications.

3. TensorFlow Lite:

  • Edge Deployment: TensorFlow Lite allows for you to deploy your models on mobile and other embedded devices. Optimizing models for performance and resource usage, it ensures efficient performance on resource-constrained devices.
  • Hardware Acceleration: In addition, it supports various hardware accelerators, such as GPUs and TPUs, allowing for a performance boost on edge devices.

Scalability:

  1. Distributed Training:
  • Multi-GPU and Multi-TPU Support: TensorFlow allows for groups to train models across multiple GPUs and TPUs, decreasing training time.
  • Multi-Machine Training: It also facilitates training across several machines, enabling the handling of very large datasets and complex models.

2. Docker and Kubernetes:

  • Containerization: TensorFlow allows for its models to be containerized using Docker, making it significantly easier to deploy, scale, and manage applications in various environments.
  • Orchestration: You can also use Kubernetes to create TensorFlow workloads, which enables the automatic scaling, management of containerized applications, and deployment.

3. Cloud Integration:

  • Google Cloud AI Platform: Integrating well with the Google Cloud API, TensorFlow can provide managed services for training and serving models.
  • Other Cloud Providers: TensorFlow works well with other cloud platforms such as AWS and Azure, supporting scalable deployment and training in cloud environments.

From this, it becomes obvious how TensorFlow prioritizes production and scalability. Even with all of this functionality and support, TensorFlow has something else that makes users fall in love with it: Keras.

Keras is an open-source deep-learning framework with a popularity stemming from its user-friendly interface. A high-level, user-friendly API, Keras allows you to build, train, and deploy deep-learning models very minimal code.

In TensorFlow 2.0, Keras was added in to the TensorFlow package as “tf.keras”, making it officially an API of TensorFlow. This integration allows users to access the simplicity of Keras whilst also leverging the pwoer and flexibility that TensorFlow offers. Any of the advanced features of TensorFlow, such as custom training loops and the TensorFlow Data API can be utilized whilst using “tf.keras”.

It’s also very easy for beginners to start with deep learning through “tf.keras” because of the simplicity. At the same time, it gives advanced users the flexibility to build more complicated models.

Keras brings more life to TensorFlow, giving it a significant boost in popularity when the API was introduced to it. Now, with all these features, it may look like TensorFlow is the clear choice. TensorFlow has so much support and flexibility for designing deep learning models, so why ishere a need to look at a different framework? Well the answer is quite simple. PyTorch offers a dynamic experience whilst designing your deep learning models. So, let’s take a look at PyTorch.

What is PyTorch

PyTorch is an open-source deep learning framework developed by Facebook and released in 2016. Facebook released the framework with the intention of matching the production of TensorFlow while making it easier to write code for models. Since python programmers found it easy to use, PyTorch gained popularity at a rapid rate. PyTorch has an emphasis on providing a high-level user friendly interface while possessing immense power and flexibility for any deep learning task.

Functionality

Like TensorFlow, the unit of data for PyTorch remains the tensor. However, PyTorch is based on Torch, a framework designed for fast computations which was written in the language Lua. Torch provided implementations of deep learning algorithms and tools, which heavily inspired PyTorch’s design and fucntionality.

Now although PyTorch has an emphasis on easy usage and readability, it retains the power needed for users to accomplish complicated deep learning tasks. This allows for beginnners to easily learn thew framework while allowing more advanced users to build more complex models. Let’s take a look at a couple of ways PyTorch accomplishes this.

  1. Comprehensive Libraries and Tools:
  • Torchvision: Library that provides datasets, model architectures, and image transformations.
  • TorchText: Library for natural language processing (NLP). Offers datasets, tokenizers, and pre-trained word vectors.
  • TorchAudio: Library for audio processing
  • PyTorch Lightning: Framework for structuring PyTorch code, which makes it easier to manage training loops and logging.

2. Dynamic Computation Graphs:

  • Eager Execution: PyTorch builds computation graphs as operations are executed. This dynamic nature makes PyTorch more flexible, allowing for debugging and modification.
  • Immediate Feedback: Since operations are executed immediately, PyTorch gives immediate feedback, which makes it easier to experiment with different architectures and strategies.

3. Production-Ready:

  • TorchScript: Allows you to run PyTorch models independent of Python. Easier to deploy models in production environments.
  • ONNX (Open Neural Network Exchange): PyTorch supports exporting models to the ONNX format, which allows for interoperability with other frameworks and deployment on other platforms.

4. Research and Prototyping:

  • Flexibility: The dynamic nature of PyTorch makes it perfect for research and prototyping. Researchers can implement and test new ideas without being concerned about static-graph constraints.
  • Active Community: PyTorch has an active community of researchers and developers who are constantly contributing to its development.

5. Visualization and Debugging:

  • TensorBoard Integration: Integrating with TensorBoard allows PyTorch to access visualizations of training metrics, model graphs, and other information.
  • Advanced Debugging Tools: The dynamic nature of PyTorch simplifies debugging, allowing people to use the standard Python debugging tools.
Photo by Mohammad Rahmani on Unsplash

Use Cases

We’ve talked about the individual strengths of PyTorch and TensorFlow, but what about their use cases? When it is it most appropriate to implement one or the other? The use cases for TensorFlow are:

  • Production Deployment: With components such as TensorFlow Serving and Lite, TensorFlow is very well-suited for deploying machine learning models in production. TensorFlow provides a high performance serving system for models while allowing the user to deploy on mobile and embedded devices.
  • Large -Scale Machine Learning: TensorFlow has built-in support for training across several GPUs and machines. This makes it very suitable for large-scale machine learning tasks.
  • Applications: TensorFlow integrates well with commercial and enterprise applications such as Google Cloud, where TensorFlow can use the AI Platform, BigQuery, and Cloud Storage.

As for PyTorch, they are as follows:

  • Research: PyTorch’s dynamic computation graph allows it work well for researching and prototyping purposes. This allows for more intuitive and flexible model development.
  • Computer Vision and NLP: Utilizing torchvision with PyTorch, you will have access to tools for computer vision, including pre-trained models, datasets, and image transformations. TorchText offers datasets, tokenizers, and pre-trained embeddings for natural language processing.
  • Education: As PyTorch follows Python’s syntax, it makes it very easy for beginners to learn and use. PyTorch is used in academic courses often.

Concluding Thoughts

Let’s recap — TensorFlow and PyTorch are powerful frameworks for deep learning. TensorFlow is often used for deployment purposes, while PyTorch is used for research. Based on what your task is, you can then choose either PyTorch or TensorFlow.

However, don’t just stop with learning just one of the frameworks. Try and learn both. Both have their weaknesses and strengths and for a task where PyTorch may not work, TensorFlow could. For a task where TensorFlow may struggle, PyTorch may excel. Both frameworks are great at what they do and have made machine learning and deep learning much more accessible for everyone. I hope you enjoyed this article, and thank you for reading it!

Join thousands of data leaders on the AI newsletter. Join over 80,000 subscribers and keep up to date with the latest developments in AI. From research to projects and ideas. If you are building an AI startup, an AI-related product, or a service, we invite you to consider becoming a sponsor.

Published via Towards AI

Feedback ↓

Sign Up for the Course
`; } else { console.error('Element with id="subscribe" not found within the page with class "home".'); } } }); // Remove duplicate text from articles /* Backup: 09/11/24 function removeDuplicateText() { const elements = document.querySelectorAll('h1, h2, h3, h4, h5, strong'); // Select the desired elements const seenTexts = new Set(); // A set to keep track of seen texts const tagCounters = {}; // Object to track instances of each tag elements.forEach(el => { const tagName = el.tagName.toLowerCase(); // Get the tag name (e.g., 'h1', 'h2', etc.) // Initialize a counter for each tag if not already done if (!tagCounters[tagName]) { tagCounters[tagName] = 0; } // Only process the first 10 elements of each tag type if (tagCounters[tagName] >= 2) { return; // Skip if the number of elements exceeds 10 } const text = el.textContent.trim(); // Get the text content const words = text.split(/\s+/); // Split the text into words if (words.length >= 4) { // Ensure at least 4 words const significantPart = words.slice(0, 5).join(' '); // Get first 5 words for matching // Check if the text (not the tag) has been seen before if (seenTexts.has(significantPart)) { // console.log('Duplicate found, removing:', el); // Log duplicate el.remove(); // Remove duplicate element } else { seenTexts.add(significantPart); // Add the text to the set } } tagCounters[tagName]++; // Increment the counter for this tag }); } removeDuplicateText(); */ // Remove duplicate text from articles function removeDuplicateText() { const elements = document.querySelectorAll('h1, h2, h3, h4, h5, strong'); // Select the desired elements const seenTexts = new Set(); // A set to keep track of seen texts const tagCounters = {}; // Object to track instances of each tag // List of classes to be excluded const excludedClasses = ['medium-author', 'post-widget-title']; elements.forEach(el => { // Skip elements with any of the excluded classes if (excludedClasses.some(cls => el.classList.contains(cls))) { return; // Skip this element if it has any of the excluded classes } const tagName = el.tagName.toLowerCase(); // Get the tag name (e.g., 'h1', 'h2', etc.) // Initialize a counter for each tag if not already done if (!tagCounters[tagName]) { tagCounters[tagName] = 0; } // Only process the first 10 elements of each tag type if (tagCounters[tagName] >= 10) { return; // Skip if the number of elements exceeds 10 } const text = el.textContent.trim(); // Get the text content const words = text.split(/\s+/); // Split the text into words if (words.length >= 4) { // Ensure at least 4 words const significantPart = words.slice(0, 5).join(' '); // Get first 5 words for matching // Check if the text (not the tag) has been seen before if (seenTexts.has(significantPart)) { // console.log('Duplicate found, removing:', el); // Log duplicate el.remove(); // Remove duplicate element } else { seenTexts.add(significantPart); // Add the text to the set } } tagCounters[tagName]++; // Increment the counter for this tag }); } removeDuplicateText(); //Remove unnecessary text in blog excerpts document.querySelectorAll('.blog p').forEach(function(paragraph) { // Replace the unwanted text pattern for each paragraph paragraph.innerHTML = paragraph.innerHTML .replace(/Author\(s\): [\w\s]+ Originally published on Towards AI\.?/g, '') // Removes 'Author(s): XYZ Originally published on Towards AI' .replace(/This member-only story is on us\. Upgrade to access all of Medium\./g, ''); // Removes 'This member-only story...' }); //Load ionic icons and cache them if ('localStorage' in window && window['localStorage'] !== null) { const cssLink = 'https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css'; const storedCss = localStorage.getItem('ionicons'); if (storedCss) { loadCSS(storedCss); } else { fetch(cssLink).then(response => response.text()).then(css => { localStorage.setItem('ionicons', css); loadCSS(css); }); } } function loadCSS(css) { const style = document.createElement('style'); style.innerHTML = css; document.head.appendChild(style); } //Remove elements from imported content automatically function removeStrongFromHeadings() { const elements = document.querySelectorAll('h1, h2, h3, h4, h5, h6, span'); elements.forEach(el => { const strongTags = el.querySelectorAll('strong'); strongTags.forEach(strongTag => { while (strongTag.firstChild) { strongTag.parentNode.insertBefore(strongTag.firstChild, strongTag); } strongTag.remove(); }); }); } removeStrongFromHeadings(); "use strict"; window.onload = () => { /* //This is an object for each category of subjects and in that there are kewords and link to the keywods let keywordsAndLinks = { //you can add more categories and define their keywords and add a link ds: { keywords: [ //you can add more keywords here they are detected and replaced with achor tag automatically 'data science', 'Data science', 'Data Science', 'data Science', 'DATA SCIENCE', ], //we will replace the linktext with the keyword later on in the code //you can easily change links for each category here //(include class="ml-link" and linktext) link: 'linktext', }, ml: { keywords: [ //Add more keywords 'machine learning', 'Machine learning', 'Machine Learning', 'machine Learning', 'MACHINE LEARNING', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, ai: { keywords: [ 'artificial intelligence', 'Artificial intelligence', 'Artificial Intelligence', 'artificial Intelligence', 'ARTIFICIAL INTELLIGENCE', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, nl: { keywords: [ 'NLP', 'nlp', 'natural language processing', 'Natural Language Processing', 'NATURAL LANGUAGE PROCESSING', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, des: { keywords: [ 'data engineering services', 'Data Engineering Services', 'DATA ENGINEERING SERVICES', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, td: { keywords: [ 'training data', 'Training Data', 'training Data', 'TRAINING DATA', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, ias: { keywords: [ 'image annotation services', 'Image annotation services', 'image Annotation services', 'image annotation Services', 'Image Annotation Services', 'IMAGE ANNOTATION SERVICES', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, l: { keywords: [ 'labeling', 'labelling', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, pbp: { keywords: [ 'previous blog posts', 'previous blog post', 'latest', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, mlc: { keywords: [ 'machine learning course', 'machine learning class', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, }; //Articles to skip let articleIdsToSkip = ['post-2651', 'post-3414', 'post-3540']; //keyword with its related achortag is recieved here along with article id function searchAndReplace(keyword, anchorTag, articleId) { //selects the h3 h4 and p tags that are inside of the article let content = document.querySelector(`#${articleId} .entry-content`); //replaces the "linktext" in achor tag with the keyword that will be searched and replaced let newLink = anchorTag.replace('linktext', keyword); //regular expression to search keyword var re = new RegExp('(' + keyword + ')', 'g'); //this replaces the keywords in h3 h4 and p tags content with achor tag content.innerHTML = content.innerHTML.replace(re, newLink); } function articleFilter(keyword, anchorTag) { //gets all the articles var articles = document.querySelectorAll('article'); //if its zero or less then there are no articles if (articles.length > 0) { for (let x = 0; x < articles.length; x++) { //articles to skip is an array in which there are ids of articles which should not get effected //if the current article's id is also in that array then do not call search and replace with its data if (!articleIdsToSkip.includes(articles[x].id)) { //search and replace is called on articles which should get effected searchAndReplace(keyword, anchorTag, articles[x].id, key); } else { console.log( `Cannot replace the keywords in article with id ${articles[x].id}` ); } } } else { console.log('No articles found.'); } } let key; //not part of script, added for (key in keywordsAndLinks) { //key is the object in keywords and links object i.e ds, ml, ai for (let i = 0; i < keywordsAndLinks[key].keywords.length; i++) { //keywordsAndLinks[key].keywords is the array of keywords for key (ds, ml, ai) //keywordsAndLinks[key].keywords[i] is the keyword and keywordsAndLinks[key].link is the link //keyword and link is sent to searchreplace where it is then replaced using regular expression and replace function articleFilter( keywordsAndLinks[key].keywords[i], keywordsAndLinks[key].link ); } } function cleanLinks() { // (making smal functions is for DRY) this function gets the links and only keeps the first 2 and from the rest removes the anchor tag and replaces it with its text function removeLinks(links) { if (links.length > 1) { for (let i = 2; i < links.length; i++) { links[i].outerHTML = links[i].textContent; } } } //arrays which will contain all the achor tags found with the class (ds-link, ml-link, ailink) in each article inserted using search and replace let dslinks; let mllinks; let ailinks; let nllinks; let deslinks; let tdlinks; let iaslinks; let llinks; let pbplinks; let mlclinks; const content = document.querySelectorAll('article'); //all articles content.forEach((c) => { //to skip the articles with specific ids if (!articleIdsToSkip.includes(c.id)) { //getting all the anchor tags in each article one by one dslinks = document.querySelectorAll(`#${c.id} .entry-content a.ds-link`); mllinks = document.querySelectorAll(`#${c.id} .entry-content a.ml-link`); ailinks = document.querySelectorAll(`#${c.id} .entry-content a.ai-link`); nllinks = document.querySelectorAll(`#${c.id} .entry-content a.ntrl-link`); deslinks = document.querySelectorAll(`#${c.id} .entry-content a.des-link`); tdlinks = document.querySelectorAll(`#${c.id} .entry-content a.td-link`); iaslinks = document.querySelectorAll(`#${c.id} .entry-content a.ias-link`); mlclinks = document.querySelectorAll(`#${c.id} .entry-content a.mlc-link`); llinks = document.querySelectorAll(`#${c.id} .entry-content a.l-link`); pbplinks = document.querySelectorAll(`#${c.id} .entry-content a.pbp-link`); //sending the anchor tags list of each article one by one to remove extra anchor tags removeLinks(dslinks); removeLinks(mllinks); removeLinks(ailinks); removeLinks(nllinks); removeLinks(deslinks); removeLinks(tdlinks); removeLinks(iaslinks); removeLinks(mlclinks); removeLinks(llinks); removeLinks(pbplinks); } }); } //To remove extra achor tags of each category (ds, ml, ai) and only have 2 of each category per article cleanLinks(); */ //Recommended Articles var ctaLinks = [ /* ' ' + '

Subscribe to our AI newsletter!

' + */ '

Take our 85+ lesson From Beginner to Advanced LLM Developer Certification: From choosing a project to deploying a working product this is the most comprehensive and practical LLM course out there!

'+ '

Towards AI has published Building LLMs for Production—our 470+ page guide to mastering LLMs with practical projects and expert insights!

' + '
' + '' + '' + '

Note: Content contains the views of the contributing authors and not Towards AI.
Disclosure: This website may contain sponsored content and affiliate links.

' + 'Discover Your Dream AI Career at Towards AI Jobs' + '

Towards AI has built a jobs board tailored specifically to Machine Learning and Data Science Jobs and Skills. Our software searches for live AI jobs each hour, labels and categorises them and makes them easily searchable. Explore over 10,000 live jobs today with Towards AI Jobs!

' + '
' + '

🔥 Recommended Articles 🔥

' + 'Why Become an LLM Developer? Launching Towards AI’s New One-Stop Conversion Course'+ 'Testing Launchpad.sh: A Container-based GPU Cloud for Inference and Fine-tuning'+ 'The Top 13 AI-Powered CRM Platforms
' + 'Top 11 AI Call Center Software for 2024
' + 'Learn Prompting 101—Prompt Engineering Course
' + 'Explore Leading Cloud Providers for GPU-Powered LLM Training
' + 'Best AI Communities for Artificial Intelligence Enthusiasts
' + 'Best Workstations for Deep Learning
' + 'Best Laptops for Deep Learning
' + 'Best Machine Learning Books
' + 'Machine Learning Algorithms
' + 'Neural Networks Tutorial
' + 'Best Public Datasets for Machine Learning
' + 'Neural Network Types
' + 'NLP Tutorial
' + 'Best Data Science Books
' + 'Monte Carlo Simulation Tutorial
' + 'Recommender System Tutorial
' + 'Linear Algebra for Deep Learning Tutorial
' + 'Google Colab Introduction
' + 'Decision Trees in Machine Learning
' + 'Principal Component Analysis (PCA) Tutorial
' + 'Linear Regression from Zero to Hero
'+ '

', /* + '

Join thousands of data leaders on the AI newsletter. It’s free, we don’t spam, and we never share your email address. Keep up to date with the latest work in AI. From research to projects and ideas. If you are building an AI startup, an AI-related product, or a service, we invite you to consider becoming a sponsor.

',*/ ]; var replaceText = { '': '', '': '', '
': '
' + ctaLinks + '
', }; Object.keys(replaceText).forEach((txtorig) => { //txtorig is the key in replacetext object const txtnew = replaceText[txtorig]; //txtnew is the value of the key in replacetext object let entryFooter = document.querySelector('article .entry-footer'); if (document.querySelectorAll('.single-post').length > 0) { //console.log('Article found.'); const text = entryFooter.innerHTML; entryFooter.innerHTML = text.replace(txtorig, txtnew); } else { // console.log('Article not found.'); //removing comment 09/04/24 } }); var css = document.createElement('style'); css.type = 'text/css'; css.innerHTML = '.post-tags { display:none !important } .article-cta a { font-size: 18px; }'; document.body.appendChild(css); //Extra //This function adds some accessibility needs to the site. function addAlly() { // In this function JQuery is replaced with vanilla javascript functions const imgCont = document.querySelector('.uw-imgcont'); imgCont.setAttribute('aria-label', 'AI news, latest developments'); imgCont.title = 'AI news, latest developments'; imgCont.rel = 'noopener'; document.querySelector('.page-mobile-menu-logo a').title = 'Towards AI Home'; document.querySelector('a.social-link').rel = 'noopener'; document.querySelector('a.uw-text').rel = 'noopener'; document.querySelector('a.uw-w-branding').rel = 'noopener'; document.querySelector('.blog h2.heading').innerHTML = 'Publication'; const popupSearch = document.querySelector$('a.btn-open-popup-search'); popupSearch.setAttribute('role', 'button'); popupSearch.title = 'Search'; const searchClose = document.querySelector('a.popup-search-close'); searchClose.setAttribute('role', 'button'); searchClose.title = 'Close search page'; // document // .querySelector('a.btn-open-popup-search') // .setAttribute( // 'href', // 'https://medium.com/towards-artificial-intelligence/search' // ); } // Add external attributes to 302 sticky and editorial links function extLink() { // Sticky 302 links, this fuction opens the link we send to Medium on a new tab and adds a "noopener" rel to them var stickyLinks = document.querySelectorAll('.grid-item.sticky a'); for (var i = 0; i < stickyLinks.length; i++) { /* stickyLinks[i].setAttribute('target', '_blank'); stickyLinks[i].setAttribute('rel', 'noopener'); */ } // Editorial 302 links, same here var editLinks = document.querySelectorAll( '.grid-item.category-editorial a' ); for (var i = 0; i < editLinks.length; i++) { editLinks[i].setAttribute('target', '_blank'); editLinks[i].setAttribute('rel', 'noopener'); } } // Add current year to copyright notices document.getElementById( 'js-current-year' ).textContent = new Date().getFullYear(); // Call functions after page load extLink(); //addAlly(); setTimeout(function() { //addAlly(); //ideally we should only need to run it once ↑ }, 5000); }; function closeCookieDialog (){ document.getElementById("cookie-consent").style.display = "none"; return false; } setTimeout ( function () { closeCookieDialog(); }, 15000); console.log(`%c 🚀🚀🚀 ███ █████ ███████ █████████ ███████████ █████████████ ███████████████ ███████ ███████ ███████ ┌───────────────────────────────────────────────────────────────────┐ │ │ │ Towards AI is looking for contributors! │ │ Join us in creating awesome AI content. │ │ Let's build the future of AI together → │ │ https://towardsai.net/contribute │ │ │ └───────────────────────────────────────────────────────────────────┘ `, `background: ; color: #00adff; font-size: large`); //Remove latest category across site document.querySelectorAll('a[rel="category tag"]').forEach(function(el) { if (el.textContent.trim() === 'Latest') { // Remove the two consecutive spaces (  ) if (el.nextSibling && el.nextSibling.nodeValue.includes('\u00A0\u00A0')) { el.nextSibling.nodeValue = ''; // Remove the spaces } el.style.display = 'none'; // Hide the element } }); // Add cross-domain measurement, anonymize IPs 'use strict'; //var ga = gtag; ga('config', 'G-9D3HKKFV1Q', 'auto', { /*'allowLinker': true,*/ 'anonymize_ip': true/*, 'linker': { 'domains': [ 'medium.com/towards-artificial-intelligence', 'datasets.towardsai.net', 'rss.towardsai.net', 'feed.towardsai.net', 'contribute.towardsai.net', 'members.towardsai.net', 'pub.towardsai.net', 'news.towardsai.net' ] } */ }); ga('send', 'pageview'); -->