TensorFlow
TensorFlow is an open-source framework for machine learning (ML) and
artificial intelligence (AI) that was developed by Google Brain. It was designed
to facilitate the development of machine learning models, particularly deep
learning models by providing tools to easily build, train and deploy them across
different platforms.
TensorFlow supports a wide range of applications from natural language
processing (NLP) and computer vision (CV) to time series forecasting and
reinforcement learning.
Key Features of TensorFlow
1. Scalability
TensorFlow is designed to scale across a variety of platforms from desktops and
servers to mobile devices and embedded systems. It supports distributed
computing allowing models to be trained on large datasets efficiently.
2. Comprehensive Ecosystem
TensorFlow offers a broad set of tools and libraries including:
TensorFlow Core: The base API for TensorFlow that allows users to define
models, build computations and execute them.
Keras: A high-level API for building neural networks that runs on top of
TensorFlow, simplifying model development.
TensorFlow Lite: A lightweight solution for deploying models on mobile and
embedded devices.
TensorFlow.js: A library for running machine learning models directly in the
browser using JavaScript.
TensorFlow Extended (TFX): A production-ready solution for deploying
machine learning models in production environments.
TensorFlow Hub: A repository of pre-trained models that can be easily
integrated into applications.
3. Automatic Differentiation (Autograd)
TensorFlow automatically calculates gradients for all trainable variables in the
model which simplifies the backpropagation process during training. This is a
core feature that enables efficient model optimization using techniques like
gradient descent.
4. Multi-language Support
TensorFlow is primarily designed for Python but it also provides APIs for other
languages like C++, Java and JavaScript making it accessible to developers with
different programming backgrounds.
5. TensorFlow Serving and TensorFlow Model Optimization
TensorFlow includes tools for serving machine learning models in production
environments and optimizing them for inference allowing for lower latency and
higher efficien
cy.
TensorFlow Architecture
The architecture of TensorFlow revolves around the concept of a computational
graph which is a network of nodes (operations) and edges (data). Here's a
breakdown of key components:
Tensors: Tensors are the fundamental units of data in TensorFlow. They are
multi-dimensional arrays or matrices used for storing data. A tensor can have
one dimension (vector), two dimensions (matrix) or
more dimensions.
Type
The type represents the kind of data that the values in a tensor hold. Typically, all
values in a tensor hold an identical data type. The datatypes in TensorFlow are as
follows:
integers
floating point
unsigned integers
booleans
strings
integer with quantized ops
complex numbers
Shape
In the TensorFlow Python library, shape refers to the dimensionality of the
tensor.
In the above image, the shape of the tensor is (2,2,2).
Graph: A TensorFlow graph represents a computation as a flow of tensors
through a series of operations. Each operation in the graph performs a specific
mathematical function on the input tensors such as matrix multiplication,
addition or activation.
A graph is a set of computations that take place successively on input tensors. It
comprises an arrangement of nodes representing the mathematical operations in a
model.
Session: A session in TensorFlow runs the computation defined by the graph
and evaluates the tensors. This is where the actual execution of the model
happens enabling the training and inference processes.
TensorFlow Workflow
Step 1: Train a Model
Use TensorFlow to build and train a machine learning model on platform like
a PC or cloud.
Employ datasets relevant to your application like images, text, sensor data,
etc.
Evaluate and validate the model to ensure high accuracy before deployment.
Step 2: Convert the Model
Convert the trained model into TensorFlow Lite (.tflite) format using the
TFLite Converter.
This conversion prepares the model for resource-constrained edge
environments.
Supports different formats like saved models, Keras models or concrete
functions.
Step 3: Optimize the Model
Apply model optimization techniques such as quantization, pruning or weight
clustering.
Reduces the model size, improves inference speed and minimizes memory
footprint.
Crucial for running models efficiently on mobile, embedded or
microcontroller devices.
Step 4: Deploy the Model
Deploy the optimized .tflite model to edge devices like Android, iOS, Linux-
based embedded systems like Raspberry Pi and Microcontrollers like Arm
Cortex-M.
Ensure compatibility with TensorFlow Lite runtime for the target platform.
Step 5: Make Inferences at the Edge
Run real-time predictions directly on the edge device using the TFLite
Interpreter.
Enables low-latency, offline inference without relying on cloud computation.
Supports use cases like image recognition, voice detection and sensor data
analysis
MNIST Dataset and processed the image. Then we have built a simple neural
network using TensorFlow's Sequential API with two layers:
dense layer with ReLU activation
an output layer with softmax activation function
At last we compiled the model using Adam Optimizer and Sparse Categorical
Crossentropy and trained the model for 5 epochs.
!pip install tensorflow
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.datasets import mnist
# Load the MNIST dataset
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
# Preprocess the data: flatten the images and normalize the pixel values
train_images = train_images.reshape((train_images.shape[0], 28 *
28)).astype('float32') / 255
test_images = test_images.reshape((test_images.shape[0], 28 *
28)).astype('float32') / 255
# Build the model
model = Sequential([
Dense(128, activation='relu', input_shape=(28 * 28,)),
Dense(10, activation='softmax')
])
# Compile the model
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
# Train the model
model.fit(train_images, train_labels, epochs=5)
# Evaluate the model
test_loss, test_acc = model.evaluate(test_images, test_labels)
print(f"Test accuracy: {test_acc}")
TensorFlow’s Basic Programming Elements
TensorFlow Python allows us to assign data to three kinds of data elements:
constants, variables, and placeholders.
1. Constants:
Constants are tensors with fixed values that cannot be changed during computation.
They are defined using tf.constant().
Example: c = tf.constant(2.0, dtype=tf.float32).
2. Variables:
Variables are tensors whose values can be modified during computation.
They are defined using tf.Variable().
Variables need to be initialized before being used in a session.
Example: v = tf.Variable(tf.zeros([2, 3])).
3. Placeholders:
Placeholders are used to feed data into the TensorFlow graph from outside the model during
execution.
They are defined using tf.placeholder().
You specify the data type when defining a placeholder.
Example: x = tf.placeholder(tf.float32)
import tensorflow as tf
# Define constants
a = tf.constant(5.0)
b = tf.constant(3.0)
# Perform addition
c = tf.add(a, b)
# Print the result (in TensorFlow 2.x, operations are eagerly executed)
print(c)
was a key construct used to define input nodes in a computational
placeholder
graph. It allowed the specification of th
e data type and shape of the input data without providing the actual values at graph
construction time. The real data would then be "fed" into the graph through these
placeholders during session execution using the feed_dict argument in sess.run().
reduce_mean() is used to find mean of elements across dimensions of a tensor.
Syntax: tensorflow.math.reduce_mean( input_tensor, axis, keepdims, name)
input_tensor: It is numeric tensor to reduce.
axis(optional): It represent the dimensions to reduce. It's value should be in
range [-rank(input_tensor), rank(input_tensor)). If no value is given for this
all dimensions are reduced.
keepdims(optional): It's default value is False. If it's set to True it will retain
the reduced dimension with length 1.
name(optional): It defines the name for the operation.
Returns: It returns a tensor.
Example
# importing the library
import tensorflow as tf
# Initializing the input tensor
a = tf.constant([1, 2, 3, 4], dtype = tf.float64)
# Printing the input tensor
print('Input: ', a)
# Calculating result
res = tf.math.reduce_mean(a)
# Printing the result
print('Result: ', res)
Output:
Input: tf.Tensor([1. 2. 3. 4.], shape=(4, ), dtype=float64)
Result: tf.Tensor(2.5, shape=(), dtype=float64)
# importing the library
import tensorflow as tf
# Initializing the input tensor
a = tf.constant([[1, 2], [3, 4]], dtype = tf.float64)
# Printing the input tensor
print('Input: ', a)
# Calculating result
res = tf.math.reduce_mean(a, axis = 1, keepdims = True)
# Printing the result
print('Result: ', res)
Output:
Input: tf.Tensor(
[[1. 2.]
[3. 4.]], shape=(2, 2), dtype=float64)
Result: tf.Tensor(
[[1.5]
[3.5]], shape=(2, 1), dtype=float64)
reduce_sum() is used to find sum of elements across dimensions of a tensor.
Syntax: tensorflow.math.reduce_sum( input_tensor, axis, keepdims, name)
Parameters:
input_tensor: It is numeric tensor to reduce.
axis(optional): It represent the dimensions to reduce. It's value should be in
range [-rank(input_tensor), rank(input_tensor)). If no value is given for this
all dimensions are reduced.
keepdims(optional): It's default value is False. If it's set to True it will retain
the reduced dimension with length 1.
name(optional): It defines the name for the operation.
Returns: It returns a tensor.
# importing the library
import tensorflow as tf
# Initializing the input tensor
a = tf.constant([1, 2, 3, 4], dtype = tf.float64)
# Printing the input tensor
print('Input: ', a)
# Calculating result
res = tf.math.reduce_sum(a)
# Printing the result
print('Result: ', res)
Output:
Input: tf.Tensor([1. 2. 3. 4.], shape=(4, ), dtype=float64)
Result: tf.Tensor(10., shape=(), dtype=float64)
Example2
# importing the library
import tensorflow as tf
# Initializing the input tensor
a = tf.constant([[1, 2], [3, 4]], dtype = tf.float64)
# Printing the input tensor
print('Input: ', a)
# Calculating result
res = tf.math.reduce_sum(a, axis = 1, keepdims = True)
# Printing the result
print('Result: ', res)
Output:
Input: tf.Tensor(
[[1. 2.]
[3. 4.]], shape=(2, 2), dtype=float64)
Result: tf.Tensor(
[[3.]
[7.]], shape=(2, 1), dtype=float64)
To execute placeholders in Tensor F
low2
# placeholders are not executable immediately so we need to disable eager exicution in TF 2 not in 1
tf.compat.v1.disable_eager_execution()
import tensorflow as tf
x = tf.compat.v1.placeholder("float", None)
y=x*2
with tf.compat.v1.Session() as session:
result = session.run(y, feed_dict={x: [1, 2, 3]})
print(result)
Output
[2. 4. 6.]
Building a Model:
Import Libraries: Begin by importing the TensorFlow library and any other necessary
libraries.
Load and Preprocess Data: Prepare your data by loading it, cleaning it (if needed), and
splitting it into training and testing sets.
Define the Model: Construct your model using Keras layers. Common layers include:
o tf.keras.layers.Flatten(): Converts multi-dimensional data into a one-dimensional array.
o tf.keras.layers.Dense(): A fully connected layer.
o tf.keras.layers.Conv2D():
Convolutional layer for image processing.
Compile the Model: Specify the loss function, optimizer, and metrics for training.
Train the Model: Feed the training data to the model to learn the relationships between
inputs and outputs.
Evaluate the Model: Assess the model's performance on the test set to ensure it generalizes
well.
Save the Model: Store the trained model for later use.
Example:Simple Linear Regression
import tensorflow as tf;
// Create training data
const xs = tf.tensor1d([1, 2, 3, 4, 5]);
const ys = tf.tensor1d([1.2, 2.2, 3.2, 4.2, 5.2]);
// Define a simple linear regression model
const model = tf.sequential();
model.add(tf.layers.dense({units: 1, inputShape: [1]}));
// Compile the model
model.compile({loss: 'meanSquaredError', optimizer: 'sgd'});
// Train the model
model.fit(xs, ys, {epochs: 100}).then(() => {
// Make predictions
const prediction = model.predict(tf.tensor1d([6]));
prediction.print();
});
Checkpointing in Tensor Flow
Checkpointing generally involves saving the state of a system so that at a later time it can be restored
for use. In this way, information that would have been otherwise lost is retained and reloaded for use
later.
In machine learning, checkpointing involves saving the current state of a model (architecture, weight,
optimizer and so on) so that it can be reloaded for use later on.
Need of Checkpointing?
Interrupted Training Loops: When a training sequence gets intentionally or unintentionally
terminated, the entire progress can be lost. This can be costly in terms of the cost of
computing and development time. Checkpointing helps to store the model for later use when
the training can be continued.
Saving optimal models for production: During training, it is usually the case that the final
model is not the best in terms of the desired metric. This might lead to one trying to identify
the best epoch and then training for only that number of epochs. This however is an important
time that will be wasted given the stochastic nature of these models. Checkpointing helps
with saving the model when the desired condition is satisfied, making
It is often useful to checkpoint a TF computation | save the tensors in a computation so the
computation can be resumed at another time, or for reuse in a different program. In TF we do
so by creating and using saver
objects:
saveOb= tf.train.Saver()
Then after every n epochs of training, save the current values of all your variables:
saveOb.save(sess, "mylatest.ckpt")
mylatest.ckpt.data-00000-of-00001
mylatest.ckpt.index
mylatest.chpt.meta
The first of these has the parameter values you saved. The other two contain
metainformation that TF uses when you want to import these values
Next we want to, say, do further training epochs on the same NN model
we have already started training
saveOb.restore(sess, "mylatest.ckpt")
The next time you call the training program it resumes training with the
TF variables set to the values they had when you last saved them in your
previous training.
Tensordot
In TensorFlow, the "tensor dot" refers to the dot product operation applied to
tensors, which is a generalization of the dot product between vectors. This
operation is fundamental in linear algebra and machine learning.
tf.tensordot:
This function is the most general and flexible for computing dot products
between tensors of arbitrary ranks. It requires specifying the axes along which the sum-
reduction (contraction) should occur. This allows for various forms of tensor contractions,
including matrix multiplication and element-wise products followed by summation
tensordot is particularly powerful for operations on tensors with more than two dimensions, where
standard dot or matmul might not directly apply or require explicit reshaping
import numpy as np
# Define two tensors
A = np.array([[1, 2],
[3, 4]]) # Shape (2, 2)
B = np.array([[5, 6],
[7, 8]]) # Shape (2, 2)
# Example 1: Matrix multiplication (equivalent to np.dot or np.matmul)
# Contract the last axis of A with the first axis of B
result_1 = np.tensordot(A, B, axes=1)
print("Result with axes=1 (matrix multiplication):\n", result_1)
# Example 2: Outer product (no axes contracted)
# The result will have a shape combining all axes of A and B
result_0 = np.tensordot(A, B, axes=0)
print("\nResult with axes=0 (outer product):\n", result_0)
# Example 3: Contracting specific axes using tuples
# Contract the 0th axis of A with the 0th axis of B
result_specific_axes = np.tensordot(A, B, axes=((0,), (0,)))
print("\nResult with specific axes contracted (0th of A with 0th of B):\n",
result_specific_axes)
# Example 4: Contracting multiple axes (for higher-dimensional tensors)
C = np.arange(24).reshape(2, 3, 4) # Shape (2, 3, 4)
D = np.arange(24).reshape(4, 3, 2) # Shape (4, 3, 2)
# Contract the last axis of C (axis 2) with the first axis of D (axis 0),
# and the second-to-last axis of C (axis 1) with the second axis of D (axis 1)
result_multi_axes = np.tensordot(C, D, axes=([2, 1], [0, 1]))
print("\nResult with multiple axes contr
acted (3D tensors):\n", result_multi_axes)
axes=1
:
This is a common shorthand for matrix multiplication. It contracts the last N axes of the
first tensor with the first N axes of the second tensor, where N is the integer value of axes. In
this case, N=1, so the last axis of A is contracted with the first axis of B.
axes=0:
This performs an outer product. No axes are contracted, and the resulting tensor's shape is a
concatenation of the shapes of the input tensors.
axes=((a_axes),(b_axes)):
This allows for explicit control over which axes are contracted. a_axes is a sequence of axis
indices from the first tensor, and b_axes is a sequence of axis indices from the second
tensor. The lengths of these sequences must be equal, and the dimensions along the
specified axes must match.
Syntax
tf.tensordot(a, b, axes)
Parameters:
Argument Description
A First tensor
B Second tensor
Specifies which
Axes axes to contract
(dot over). Can be
An integer (for same number of last and first axes)
→ A pair of lists (to manually define axes)
1. axes = integer (common axes count)
tf.tensordot(a, b, axes=1)
import tensorflow as tf
a = tf.constant([1, 2, 3])
b = tf.constant([4, 5, 6])
result = tf.tensordot(a, b, axes=1) # Dot product
Argument Description
print(result) # 1*4 + 2*5 + 3*6 = 32
2. axes = ([axes_from_a], [axes_from_b])
This gives explicit control over which axes to sum
over.
tf.tensordot(a, b, axes=([axis_from_a], [axis_from_b]))
# a shape = (2, 4, 5)
# b shape = (4, 5, 3)
# You want to dot over axes 1 and 2 in a, and axes 0 and 1 in b
tf.tensordot(a, b, axes=([1, 2], [0, 1])) # Result: shape (2, 3)
Example: Matrix Multiplication Using
tensordot
a = tf.constant([[1, 2], [3, 4]]) # shape (2, 2)
b = tf.constant([[5, 6], [7, 8]]) # shape (2, 2)
result = tf.tensordot(a, b, axes=1) # shape (2, 2)
# Equivalent to tf.matmul(a, b)
a = tf.constant([
[ # a[0]
[1, 2, 3, 4, 5],
[6, 7, 8, 9, 10],
[11, 12, 13, 14, 15],
[16, 17, 18, 19, 20]
],
[ # a[1]
[21, 22, 23, 24, 25],
[26, 27, 28, 29, 30],
[31, 32, 33, 34, 35],
[36, 37, 38, 39, 40]
]
], dtype=tf.float32)
Shape: (2, 4, 5)
b = tf.constant([
[ # b[0]
[1, 2, 3],
Argument Description
[4, 5, 6],
[7, 8, 9],
[10, 11, 12],
[13, 14, 15]
],
[ # b[1]
[16, 17, 18],
[19, 20, 21],
[22, 23, 24],
[25, 26, 27],
[28, 29, 30]
],
[ # b[2]
[31, 32, 33],
[34, 35, 36],
[37, 38, 39],
[40, 41, 42],
[43, 44, 45]
],
[ # b[3]
[46, 47, 48],
[49, 50, 51],
[52, 53, 54],
[55, 56, 57],
[58, 59, 60]
]
], dtype=tf.float32)
Shape: (4, 5, 3)
Variable Initialization in Tensor Flow
In TensorFlow, variables must be explicitly initialized before they
can be used in a session. This process allocates memory for the
variable and assigns its initial value.
Methods for Variable Initialization:
Global Initialization.
The most common method is to initialize all global variables in the
graph at once using tf.global_variables_initializer(). This operation should
be run within a TensorFlow session after all variables have been
defined.
import tensorflow as tf
# Define variables
W = tf.Variable([.3], tf.float32)
b = tf.Variable([-.3], tf.float32)
# Add an op to initialize all variables
init_op = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init_op) # Run the initialization op
Argument Description
# Now variables W and b are initialized and can be used
print(sess.run(W))
Selective Initialization.
If only specific variables need to be
initialized, tf.variables_initializer() can be used with a list of the variables
to initialize.
import tensorflow as tf # Define variables
var1 = tf.Variable(0.0, name="variable1")
var2 = tf.Variable(10.0, name="variable2")
# Initialize only var1
init_var1_op = tf.variables_initializer(var_list=[var1])
with tf.Session() as sess:
sess.run(init_var1_op)
# var1 is initialized, var2 is not
print(sess.run(var1))
# Attempting to use var2 without initialization would raise an error
Initializing with Specific Values.
Variables can be initialized with tf.constant or NumPy arrays directly
when they are defined. The tf.global_variables_initializer() or
tf.variables_initializer() will then assign these initial values.
import tensorflow as tf
import numpy as np
# Initialize with a NumPy array
initial_value_np = np.array([[1.0, 1.0], [1.0, 1.0]])
x = tf.Variable(initial_value_np)
# Initialize with a TensorFlow constant
y = tf.Variable(tf.constant([5.0, 6.0]))
init_op = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init_op)
print(sess.run(x))
print(sess.run(y)
In TensorFlow (TF), initialization of variables is a crucial step before running computations that
involve them. TensorFlow Variables hold and update parameters during training (e.g., weights in a
neural network).
1. Creating a Variable
You create variables using tf.Variable():
import tensorflow as tf
# Example: Create a variable with initial value 3.0
my_var = tf.Variable(3.0)
2. Variable Initialization in TensorFlow 2.x
In TensorFlow 2.x (eager execution is enabled by default), variables are initialized
automatically when created, and there's typically no need for manual initialization as in
TensorFlow 1.x
3. If Using TensorFlow 1.x Style (Graph Mode)
In TF 1.x or if you're using tf.function (graph mode), you'll often need to initialize variables
explicitly using:
init = tf.compat.v1.global_variables_initializer()
sess = tf.compat.v1.Session()
sess.run(init)
tf.Variable(tf.zeros([2, 2]))
# Ones
tf.Variable(tf.ones([2, 2]))
# Random Normal
tf.Variable(tf.random.normal([2, 2], mean=0.0, stddev=1.0))
# Xavier/Glorot Initialization
initializer = tf.keras.initializers.GlorotUniform()
tf.Variable(initializer(shape=(2, 2)))
Xavier Initialization (also called Glorot Initialization) is a popular method to initialize the
weights of neural networks to keep the scale of the gradients roughly the same in all layers. It
helps avoid vanishing or exploding gradients early in training.
Proposed by Xavier Glorot and Yoshua Bengio in 2010.
Initializes weights with a distribution whose variance depends on the number of input and
output units of the layer.
The goal is to keep the variance of activations and gradients the same across layers.
Xavier initialization, also known as Glorot initialization, is a technique used to initialize the
weights of a neural network, aiming to address the vanishing/exploding gradients problem
during training. It helps ensure that the variance of activations remains relatively stable across
layers during both forward and backward passes, leading to more efficient training.
How it works:
Addresses vanishing/exploding gradients:
Deep neural networks can suffer from gradients that become too small (vanishing) or too large
(exploding) during backpropagation, hindering learning.
Preserves variance:
Xavier initialization helps maintain a similar variance of activations across layers, preventing the
signal from shrinking or exploding.
Uses a uniform distribution:
Typically, it initializes weights using a uniform distribution with a specific range. The range is
determined by the number of input and output connections (fan-in and fan-out) of each layer.
Formula:
The weights are often drawn from a uniform distribution U(-a, a), where a = sqrt(6 / (fan_in +
fan_out)). Some implementations might use a normal distribution with a standard deviation of
sqrt(2 / (fan_in + fan_out)).
fan_in and fan_out:
fan_in refers to the number of input units to a neuron, and fan_out is the number of output units
connected to that neuron.
Activation function consideration:
Xavier initialization is generally suitable for activation functions like tanh and sigmoid.
The difference between Xavier Uniform and simple random Normal data
initialization methods in neural networks lies in their underlying principles and
suitability for different activation functions:
o Simple Random Normal Initialization:
Method: Weights are initialized by drawing random values from a Gaussian (normal)
distribution, typically with a mean of 0 and a small standard deviation (e.g., 0.01 or 0.05).
Drawbacks: This method does not consider the architecture of the neural network (number
of input and output units in a layer). This can lead to issues like vanishing or exploding
gradients, especially in deep networks or when using activation functions like sigmoid or
tanh, where gradients can become very small or very large during backpropagation.
o
Xavier initialization, also known as Glorot initialization, aims to initialize neural
network weights in a way that helps maintain the variance of activations and
gradients across layers, preventing vanishing or exploding gradients, especially
with activation functions like sigmoid and tanh. It has two main variants:
Xavier Uniform Initialization:
Weights are drawn from a uniform distribution within a specific range.
The range is determined by: [-limit, limit], where limit = sqrt(6 / (fan_in + fan_out))
refers to the number of input units (neurons) to the layer, and fan_out refers to the
fan_in
number of output units from the layer.
Xavier Normal Initialization:
Weights are drawn from a normal (Gaussian) distribution with a mean of 0.
The standard deviation of this normal distribution is determined by: sqrt(2 / (fan_in + fan_out))
import tensorflow as tf
# Xavier/Glorot uniform initializer
initializer = tf.keras.initializers.GlorotUniform()
# Create a variable with Xavier initialization (shape: 3 inputs, 2 outputs)
weights = tf.Variable(initializer(shape=(3, 2)))
print(weights)
Simplifying Tensor Flow Graph Creation
TensorFlow 2.x (Simplified Way)
In TF 2.x, eager execution is enabled by default, which means operations are executed immediately
without needing to build a graph explicitly.
Basic Graph-Free Execution
import tensorflow as tf
# Simple computation
a = tf.constant(3.0)
b = tf.constant(4.0)
c=a+b
print(c)
# Outputs: tf.Tensor(7.0, shape=(), dtype=float32)
Using TensorFlow 1.x
import tensorflow as tf
# Build the graph
a = tf.constant(3.0)
b = tf.constant(4.0)
c=a+b
# Run the graph
with tf.Session() as sess:
result = sess.run(c)
print(result)
Using Keras (Simplified Model Building)
from tensorflow.keras import layers, models
model = models.Sequential([
layers.Dense(64, activation='relu', input_shape=(32,)),
layers.Dense(10)])
model.compile(optimizer='adam', loss='mse')
Task TF 1.x TF 2.x (Simplified)
Define tensors tf.placeholder, tf.constant tf.constant, tf.Variable
Build graph manually Yes Optional (@tf.function)
Session required Yes (tf.Session()) No (eager execution by default)
Model building Manual Use tf.keras.Sequential, Functional
Training loop Manual model.fit() with Keras