跳到主要内容

TensorFlow

TensorFlow 是 Google 开发的开源端到端机器学习平台,提供全面的工具和库生态系统,适合从研究到生产的各种深度学习应用。

简介

TensorFlow 特性

"""
TensorFlow 核心特性:
- 灵活的架构: 静态计算图(1.x)和动态执行(2.x)
- Keras集成: 高级神经网络API
- TensorBoard: 可视化调试工具
- TensorFlow Serving: 生产部署
- TensorFlow Lite: 移动和嵌入式设备
- TensorFlow.js: 浏览器和Node.js
- TPUSupport: 谷歌TPU加速
- 分布式训练: 多GPU和多机训练

适用场景:
- 计算机视觉: 图像分类、目标检测
- 自然语言处理: 文本分类、翻译
- 推荐系统: 个性化推荐
- 时间序列: 预测、异常检测
- 强化学习: 游戏、机器人
- 生成模型: GAN、VAE
"""

安装 TensorFlow

# 创建虚拟环境
python -m venv venv

# Windows 激活
venv\Scripts\activate

# Linux/Mac 激活
source venv/bin/activate

# CPU版本
pip install tensorflow

# GPU版本 (CUDA 11.2)
pip install tensorflow-gpu==2.10.0

# 验证安装
python -c "import tensorflow as tf; print(tf.__version__)"

# 验证GPU
python -c "import tensorflow as tf; print(tf.config.list_physical_devices('GPU'))"

# 安装其他工具
pip install numpy matplotlib pandas scikit-learn
pip install pillow # 图像处理

快速开始

Tensor基础

import tensorflow as tf

# 查看版本
print(tf.__version__)

# 常量Tensor
const = tf.constant(42)
print(const)

# 创建Tensor
a = tf.constant([1, 2, 3, 4])
b = tf.constant([5, 6, 7, 8])

# 基本运算
print(a + b)
print(a * b)
print(tf.matmul(a, b))

# 查看形状和类型
print(a.shape)
print(a.dtype)

# 转换为NumPy
import numpy as np
arr = a.numpy()
print(type(arr))

# NumPy转Tensor
arr = np.array([1, 2, 3])
tensor = tf.constant(arr)

TensorFlow 2.x基础

Tensor操作

import tensorflow as tf

# 创建Tensor
# 从列表
x = tf.constant([1, 2, 3, 4])

# 指定类型
x = tf.constant([1, 2, 3], dtype=tf.float32)

# 全零Tensor
x = tf.zeros([3, 4])
x = tf.zeros_like(x)

# 全一Tensor
x = tf.ones([3, 4])
x = tf.ones_like(x)

# 随机Tensor
x = tf.random.normal([3, 4], mean=0.0, stddev=1.0)
x = tf.random.uniform([3, 4], minval=0, maxval=1)

# 范围Tensor
x = tf.range(10) # [0, 1, 2, ..., 9]
x = tf.linspace(0.0, 10.0, 5) # [0.0, 2.5, 5.0, 7.5, 10.0]

# 形状操作
x = tf.range(12)
x = tf.reshape(x, [3, 4])
x = tf.transpose(x)
x = tf.expand_dims(x, axis=0)

# 数学运算
x = tf.constant([1.0, 2.0, 3.0, 4.0])
print(tf.sqrt(x))
print(tf.exp(x))
print(tf.math.log(x))
print(tf.reduce_mean(x)) # 平均值
print(tf.reduce_sum(x)) # 求和

Variable

import tensorflow as tf

# 创建Variable (可训练的Tensor)
w = tf.Variable([[1.0, 2.0], [3.0, 4.0]])
b = tf.Variable([1.0, 2.0])

# 访问值
print(w.numpy())

# 修改值
w.assign([[2.0, 3.0], [4.0, 5.0]])
b.assign([0.0, 0.0])

# 查看是否可训练
print(w.trainable)

自动求导

import tensorflow as tf

# 定义Variable
x = tf.Variable(3.0)

# 记录梯度
with tf.GradientTape() as tape:
y = x ** 2

# 计算梯度
grad = tape.gradient(y, x)
print(grad) # dy/dx = 2*x = 6

# 多阶导数
x = tf.Variable(3.0)
with tf.GradientTape() as tape2:
with tf.GradientTape() as tape1:
y = x ** 3
dy_dx = tape1.gradient(y, x) # 一阶导数
d2y_dx2 = tape2.gradient(dy_dx, x) # 二阶导数

print(dy_dx) # 3*x^2 = 27
print(d2y_dx2) # 6*x = 18

# 多个变量
x = tf.Variable(2.0)
y = tf.Variable(3.0)
with tf.GradientTape() as tape:
z = x ** 2 + y ** 2
grad = tape.gradient(z, [x, y])
print(grad) # [4.0, 6.0]

Keras

Sequential模型

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers

# 创建Sequential模型
model = keras.Sequential([
layers.Dense(128, activation='relu', input_shape=(784,)),
layers.Dropout(0.2),
layers.Dense(64, activation='relu'),
layers.Dropout(0.2),
layers.Dense(10, activation='softmax')
])

# 查看模型结构
model.summary()

# 编译模型
model.compile(
optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy']
)

# 训练模型
# model.fit(x_train, y_train, epochs=10, batch_size=32)

# 评估模型
# model.evaluate(x_test, y_test)

# 预测
# model.predict(x_test)

Functional API

from tensorflow import keras
from tensorflow.keras import layers

# 定义输入
inputs = keras.Input(shape=(784,))

# 隐藏层
x = layers.Dense(128, activation='relu')(inputs)
x = layers.Dropout(0.2)(x)
x = layers.Dense(64, activation='relu')(x)
x = layers.Dropout(0.2)(x)

# 输出层
outputs = layers.Dense(10, activation='softmax')(x)

# 创建模型
model = keras.Model(inputs=inputs, outputs=outputs)

# 查看结构
model.summary()

# 编译和训练
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])

自定义模型

from tensorflow import keras
from tensorflow.keras import layers

class CustomModel(keras.Model):
def __init__(self, num_classes=10):
super(CustomModel, self).__init__()
# 定义层
self.dense1 = layers.Dense(128, activation='relu')
self.dropout1 = layers.Dropout(0.2)
self.dense2 = layers.Dense(64, activation='relu')
self.dropout2 = layers.Dropout(0.2)
self.dense3 = layers.Dense(num_classes, activation='softmax')

def call(self, inputs, training=False):
# 前向传播
x = self.dense1(inputs)
x = self.dropout1(x, training=training)
x = self.dense2(x)
x = self.dropout2(x, training=training)
return self.dense3(x)

# 创建模型
model = CustomModel(num_classes=10)

# 编译
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])

# 训练
# model.fit(x_train, y_train, epochs=10)

层与激活

Dense层

from tensorflow.keras import layers

# 全连接层
dense = layers.Dense(64, activation='relu')

# 相当于
# x = layers.Dense(64)(inputs)
# x = layers.Activation('relu')(x)

# 常用参数
layers.Dense(
units=64, # 输出维度
activation='relu', # 激活函数
use_bias=True, # 是否使用偏置
kernel_initializer='glorot_uniform', # 权重初始化
bias_initializer='zeros' # 偏置初始化
)

Conv2D层

from tensorflow.keras import layers

# 2D卷积层
conv = layers.Conv2D(
filters=64, # 卷积核数量
kernel_size=3, # 卷积核大小
strides=1, # 步长
padding='same', # 'valid'或'same'
activation='relu',
use_bias=True
)

# CNN示例
model = keras.Sequential([
layers.Conv2D(32, 3, activation='relu', padding='same', input_shape=(28, 28, 1)),
layers.MaxPooling2D(), # 28x28 -> 14x14
layers.Conv2D(64, 3, activation='relu', padding='same'),
layers.MaxPooling2D(), # 14x14 -> 7x7
layers.Flatten(),
layers.Dense(64, activation='relu'),
layers.Dense(10, activation='softmax')
])

LSTM层

from tensorflow.keras import layers

# LSTM层
lstm = layers.LSTM(
units=128, # 输出维度
return_sequences=True, # 是否返回所有时间步
return_state=False, # 是否返回最后状态
go_backwards=False, # 是否反向处理
stateful=False # 是否有状态
)

# LSTM示例
model = keras.Sequential([
layers.Embedding(input_dim=10000, output_dim=128, input_length=50),
layers.LSTM(64, return_sequences=True),
layers.LSTM(32),
layers.Dense(2, activation='sigmoid')
])

激活函数

from tensorflow.keras import layers

# ReLU
layers.Activation('relu')

# Sigmoid
layers.Activation('sigmoid')

# Tanh
layers.Activation('tanh')

# Softmax
layers.Activation('softmax')

# LeakyReLU
layers.LeakyReLU(alpha=0.01)

# PReLU
layers.PReLU()

# ELU
layers.ELU()

# 在Dense中使用
layers.Dense(64, activation='relu')

损失函数

回归损失

from tensorflow.keras import losses

# 均方误差
mse = losses.MeanSquaredError()
loss = mse(y_true, y_pred)

# 平均绝对误差
mae = losses.MeanAbsoluteError()

# 使用
model.compile(optimizer='adam', loss='mse')
# 或
model.compile(optimizer='adam', loss='mean_squared_error')

分类损失

from tensorflow.keras import losses

# 二分类交叉熵
bce = losses.BinaryCrossentropy()
# y_true: [batch_size, 1] (0或1)
# y_pred: [batch_size, 1] (概率)

# 分类交叉熵
cce = losses.CategoricalCrossentropy()
# y_true: [batch_size, num_classes] (one-hot)
# y_pred: [batch_size, num_classes] (概率)

# 稀疏分类交叉熵 (不需要one-hot)
scce = losses.SparseCategoricalCrossentropy()
# y_true: [batch_size] (类别索引)
# y_pred: [batch_size, num_classes] (logits)

# 使用
model.compile(
optimizer='adam',
loss='sparse_categorical_crossentropy' # 常用
)

自定义损失

from tensorflow.keras import backend as K

# 自定义损失函数
def custom_loss(y_true, y_pred):
return K.mean(K.square(y_true - y_pred))

# 使用
model.compile(optimizer='adam', loss=custom_loss)

# 添加正则化
def l2_loss(weight_decay=0.01):
def loss(y_true, y_pred):
mse = K.mean(K.square(y_true - y_pred))
# 添加L2正则化
l2 = weight_decay * sum([K.sum(K.square(w))
for w in model.trainable_weights])
return mse + l2
return loss

model.compile(optimizer='adam', loss=l2_loss(0.01))

优化器

SGD

from tensorflow.keras import optimizers

# SGD
optimizer = optimizers.SGD(
learning_rate=0.01,
momentum=0.0, # 动量
nesterov=False # Nesterov动量
)

# 使用
model.compile(optimizer=optimizer, loss='sparse_categorical_crossentropy')

Adam

# Adam
optimizer = optimizers.Adam(
learning_rate=0.001,
beta_1=0.9, # 一阶矩估计的指数衰减率
beta_2=0.999, # 二阶矩估计的指数衰减率
epsilon=1e-7 # 数值稳定常数
)

# AdamW (Adam权重衰减)
optimizer = optimizers.AdamW(
learning_rate=0.001,
weight_decay=0.01 # 权重衰减
)

学习率调度

from tensorflow.keras import optimizers

# 学习率衰减
optimizer = optimizers.SGD(learning_rate=0.01)
lr_schedule = optimizers.schedules.ExponentialDecay(
initial_learning_rate=0.01,
decay_steps=1000,
decay_rate=0.96
)
optimizer = optimizers.SGD(learning_rate=lr_schedule)

# 余弦退火
lr_schedule = optimizers.schedules.CosineDecay(
initial_learning_rate=0.01,
decay_steps=1000
)

# 在模型中使用
optimizer = optimizers.Adam(learning_rate=lr_schedule)
model.compile(optimizer=optimizer, loss='sparse_categorical_crossentropy')

# 使用回调函数调整学习率
from tensorflow.keras.callbacks import LearningRateScheduler

def scheduler(epoch, lr):
if epoch < 10:
return lr
else:
return lr * tf.math.exp(-0.1)

callback = LearningRateScheduler(scheduler)

数据处理

tf.data

import tensorflow as tf

# 从数组创建
dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))

# 打乱和批次
dataset = dataset.shuffle(buffer_size=10000)
dataset = dataset.batch(32)
dataset = dataset.repeat() # 重复数据集

# 预取
dataset = dataset.prefetch(buffer_size=tf.data.AUTOTUNE)

# 使用
model.fit(dataset, epochs=10, steps_per_epoch=len(x_train)//32)

# 从NumPy创建
dataset = tf.data.Dataset.from_tensor_slices((features, labels))

# 映射函数
def preprocess(x, y):
return x / 255.0, y

dataset = dataset.map(preprocess)

# 过滤
dataset = dataset.filter(lambda x, y: y < 5)

# 生成器数据集
def data_generator():
for i in range(100):
yield tf.random.normal([10]), tf.random.uniform([])

dataset = tf.data.Dataset.from_generator(
data_generator,
output_types=(tf.float32, tf.float32),
output_shapes=((10,), ()))

数据增强

from tensorflow.keras import layers

# 数据增强层
data_augmentation = keras.Sequential([
layers.RandomFlip("horizontal"),
layers.RandomRotation(0.1),
layers.RandomZoom(0.1),
])

# 使用
model = keras.Sequential([
data_augmentation,
layers.Conv2D(32, 3, activation='relu'),
layers.MaxPooling2D(),
layers.Flatten(),
layers.Dense(10)
])

# 图像预处理
preprocess = keras.Sequential([
layers.Rescaling(1./255) # 归一化
])

预处理层

from tensorflow.keras import layers

# 归一化层
normalization = layers.Normalization()
normalization.adapt(x_train) # 适配数据

# 文本向量化
vectorize_layer = layers.TextVectorization(
max_tokens=10000,
output_mode='int',
output_sequence_length=100
)
vectorize_layer.adapt(text_data)

# 离散化
discretization = layers.Discretization(bin_boundaries=[0.0, 0.5, 1.0])

# 类别编码
encoding = layers.CategoryEncoding(num_tokens=10)

训练模型

fit方法

# 基本训练
history = model.fit(
x_train, y_train,
batch_size=32,
epochs=10,
validation_data=(x_val, y_val),
verbose=1
)

# 使用生成器
model.fit(
train_generator,
steps_per_epoch=len(train_generator),
epochs=10,
validation_data=val_generator,
validation_steps=len(val_generator)
)

# 查看训练历史
import matplotlib.pyplot as plt
plt.plot(history.history['loss'], label='train loss')
plt.plot(history.history['val_loss'], label='val loss')
plt.legend()
plt.show()

自定义训练循环

import tensorflow as tf

# 定义优化器和损失
optimizer = tf.keras.optimizers.Adam()
loss_fn = tf.keras.losses.SparseCategoricalCrossentropy()

# 训练步骤
@tf.function
def train_step(x, y):
with tf.GradientTape() as tape:
logits = model(x, training=True)
loss = loss_fn(y, logits)
loss += sum(model.losses) # 正则化损失

gradients = tape.gradient(loss, model.trainable_variables)
optimizer.apply_gradients(zip(gradients, model.trainable_variables))
return loss

# 训练循环
for epoch in range(num_epochs):
for step, (x_batch, y_batch) in enumerate(dataset):
loss = train_step(x_batch, y_batch)
if step % 100 == 0:
print(f'Epoch {epoch}, Step {step}, Loss: {loss.numpy():.4f}')

回调函数

from tensorflow.keras import callbacks

# 1. ModelCheckpoint: 保存最佳模型
checkpoint = callbacks.ModelCheckpoint(
'best_model.h5',
monitor='val_loss',
save_best_only=True,
mode='min',
verbose=1
)

# 2. EarlyStopping: 早停
early_stop = callbacks.EarlyStopping(
monitor='val_loss',
patience=5,
mode='min',
verbose=1
)

# 3. ReduceLROnPlateau: 学习率衰减
reduce_lr = callbacks.ReduceLROnPlateau(
monitor='val_loss',
factor=0.1,
patience=3,
mode='min',
verbose=1
)

# 4. TensorBoard: 可视化
tensorboard = callbacks.TensorBoard(
log_dir='./logs',
histogram_freq=1
)

# 使用回调
model.fit(
x_train, y_train,
epochs=100,
validation_data=(x_val, y_val),
callbacks=[checkpoint, early_stop, reduce_lr, tensorboard]
)

CNN

卷积神经网络

from tensorflow import keras
from tensorflow.keras import layers

def create_cnn(input_shape, num_classes):
inputs = keras.Input(shape=input_shape)

# Block 1
x = layers.Conv2D(32, 3, padding='same')(inputs)
x = layers.BatchNormalization()(x)
x = layers.Activation('relu')(x)
x = layers.Conv2D(32, 3, padding='same')(x)
x = layers.BatchNormalization()(x)
x = layers.Activation('relu')(x)
x = layers.MaxPooling2D()(x)
x = layers.Dropout(0.25)(x)

# Block 2
x = layers.Conv2D(64, 3, padding='same')(x)
x = layers.BatchNormalization()(x)
x = layers.Activation('relu')(x)
x = layers.Conv2D(64, 3, padding='same')(x)
x = layers.BatchNormalization()(x)
x = layers.Activation('relu')(x)
x = layers.MaxPooling2D()(x)
x = layers.Dropout(0.25)(x)

# Flatten
x = layers.Flatten()(x)

# Dense
x = layers.Dense(512)(x)
x = layers.BatchNormalization()(x)
x = layers.Activation('relu')(x)
x = layers.Dropout(0.5)(x)

# Output
outputs = layers.Dense(num_classes, activation='softmax')(x)

model = keras.Model(inputs=inputs, outputs=outputs)
return model

# 创建模型
model = create_cnn(input_shape=(32, 32, 3), num_classes=10)
model.summary()

迁移学习

from tensorflow.keras.applications import VGG16
from tensorflow.keras import layers, models

# 加载预训练模型(不包括顶层)
base_model = VGG16(weights='imagenet', include_top=False,
input_shape=(224, 224, 3))

# 冻结基础模型
base_model.trainable = False

# 添加自定义顶层
inputs = keras.Input(shape=(224, 224, 3))
x = base_model(inputs, training=False)
x = layers.GlobalAveragePooling2D()(x)
x = layers.Dropout(0.2)(x)
outputs = layers.Dense(10, activation='softmax')(x)

model = keras.Model(inputs, outputs)

# 编译
model.compile(optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy'])

# 微调(解冻部分层)
base_model.trainable = True
# 冻结前几层
for layer in base_model.layers[:-10]:
layer.trainable = False

# 使用较低学习率微调
model.compile(optimizer=keras.optimizers.Adam(1e-5),
loss='categorical_crossentropy',
metrics=['accuracy'])

图像分类

import tensorflow as tf
from tensorflow.keras import layers, models
from tensorflow.keras.preprocessing.image import ImageDataGenerator

# 数据增强
train_datagen = ImageDataGenerator(
rescale=1./255,
rotation_range=20,
width_shift_range=0.2,
height_shift_range=0.2,
horizontal_flip=True
)

val_datagen = ImageDataGenerator(rescale=1./255)

# 数据加载
train_generator = train_datagen.flow_from_directory(
'data/train',
target_size=(224, 224),
batch_size=32,
class_mode='categorical'
)

val_generator = val_datagen.flow_from_directory(
'data/val',
target_size=(224, 224),
batch_size=32,
class_mode='categorical'
)

# 模型
model = models.Sequential([
layers.Conv2D(32, 3, activation='relu', input_shape=(224, 224, 3)),
layers.MaxPooling2D(),
layers.Conv2D(64, 3, activation='relu'),
layers.MaxPooling2D(),
layers.Flatten(),
layers.Dense(64, activation='relu'),
layers.Dense(10, activation='softmax')
])

# 训练
model.compile(optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy'])

history = model.fit(
train_generator,
epochs=50,
validation_data=val_generator
)

RNN

序列模型

from tensorflow.keras import layers

# 简单RNN
model = keras.Sequential([
layers.SimpleRNN(64, return_sequences=True, input_shape=(10, 32)),
layers.SimpleRNN(32),
layers.Dense(1)
])

LSTM

from tensorflow.keras import layers, models

# LSTM模型
model = models.Sequential([
layers.Embedding(input_dim=10000, output_dim=128, input_length=50),
layers.LSTM(64, return_sequences=True),
layers.LSTM(32),
layers.Dense(1, activation='sigmoid')
])

# 双向LSTM
inputs = keras.Input(shape=(50,))
x = layers.Embedding(10000, 128)(inputs)
x = layers.Bidirectional(layers.LSTM(64, return_sequences=True))(x)
x = layers.Bidirectional(layers.LSTM(32))(x)
outputs = layers.Dense(1, activation='sigmoid')(x)

model = keras.Model(inputs, outputs)

GRU

from tensorflow.keras import layers

# GRU模型
model = keras.Sequential([
layers.Embedding(input_dim=10000, output_dim=128),
layers.GRU(64, return_sequences=True),
layers.GRU(32),
layers.Dense(1)
])

# 双向GRU
x = layers.Bidirectional(layers.GRU(64, return_sequences=True))(x)

预训练模型

TensorFlow Hub

import tensorflow_hub as hub

# 加载预训练模型
model = tf.keras.Sequential([
hub.KerasLayer("https://tfhub.dev/google/imagenet/mobilenet_v2_100_224/classification/2"),
tf.keras.layers.Dense(10, activation='softmax')
])

# 文本模型
model = tf.keras.Sequential([
hub.KerasLayer("https://tfhub.dev/google/universal-sentence-encoder/4"),
tf.keras.layers.Dense(2, activation='softmax')
])

模型微调

from tensorflow.keras.applications import EfficientNetB0

# 加载预训练模型
base_model = EfficientNetB0(
weights='imagenet',
include_top=False,
input_shape=(224, 224, 3)
)

# 冻结
base_model.trainable = False

# 添加顶层
inputs = keras.Input(shape=(224, 224, 3))
x = base_model(inputs, training=False)
x = layers.GlobalAveragePooling2D()(x)
x = layers.Dropout(0.2)(x)
outputs = layers.Dense(10, activation='softmax')(x)

model = keras.Model(inputs, outputs)

# 预训练
model.compile(optimizer='adam', loss='categorical_crossentropy')
model.fit(train_generator, epochs=5)

# 微调
base_model.trainable = True
model.compile(optimizer=keras.optimizers.Adam(1e-5),
loss='categorical_crossentropy')
model.fit(train_generator, epochs=10)

TensorFlow Lite

模型转换

import tensorflow as tf

# 转换为TFLite模型
converter = tf.lite.TFLiteConverter.from_keras_model(model, tf.lite.OpsSet.TFLITE_BUILTINS)
converter.optimizations = [tf.lite.Optimize.DEFAULT] # 量化
converter.target_spec.supported_types = [tf.float16] # 半精度
tflite_model = converter.convert()

# 保存模型
with open('model.tflite', 'wb') as f:
f.write(tflite_model)

# 转换为量化模型
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8]
converter.inference_input_type = tf.uint8
converter.inference_output_type = tf.uint8
tflite_quant_model = converter.convert()

移动部署

import tensorflow as tf

# 加载TFLite模型
interpreter = tf.lite.Interpreter(model_path='model.tflite')
interpreter.allocate_tensors()

# 获取输入输出
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()

# 推理
input_data = tf.constant(np.random.randn(1, 224, 224, 3), dtype=tf.float32)
interpreter.set_tensor(input_details[0]['index'], input_data)
interpreter.invoke()
output_data = interpreter.get_tensor(output_details[0]['index'])

# 保存为C文件
with open('model.tflite', 'rb') as f:
model = f.read()

# 转换为C数组
hex_array = ', '.join(f'0x{b:02x}' for b in model)
print(f'const unsigned char model[] = {{{hex_array}}};')

TensorBoard

可视化

from tensorflow.keras import callbacks

# TensorBoard回调
tensorboard_callback = callbacks.TensorBoard(
log_dir='./logs',
histogram_freq=1,
write_graph=True,
write_images=True
)

# 训练时使用
model.fit(
x_train, y_train,
epochs=10,
validation_data=(x_val, y_val),
callbacks=[tensorboard_callback]
)

# 启动TensorBoard
# 在终端运行: tensorboard --logdir=./logs

监控训练

from tensorflow.keras.callbacks import TensorBoard
import datetime

# 创建日志目录
log_dir = "logs/fit/" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
tensorboard_cb = TensorBoard(log_dir=log_dir, histogram_freq=1)

# 训练
model.fit(
x_train, y_train,
epochs=10,
validation_data=(x_val, y_val),
callbacks=[tensorboard_cb]
)

# 记录自定义指标
import tensorflow as tf

file_writer = tf.summary.create_file_writer(log_dir)
with file_writer.as_default():
tf.summary.scalar('custom_metric', metric_value, step=epoch)
tf.summary.histogram('layer_weights', layer.weights, step=epoch)

实战案例

图像分类

import tensorflow as tf
from tensorflow.keras import layers, models
from tensorflow.keras.preprocessing import image
from tensorflow.keras.applications.vgg16 import preprocess_input, decode_predictions
import numpy as np

# 加载预训练VGG16
model = tf.keras.applications.VGG16(weights='imagenet')

# 预测图片
img_path = 'elephant.jpg'
img = image.load_img(img_path, target_size=(224, 224))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x)

preds = model.predict(x)
decoded = decode_predictions(preds, top=3)[0]

# 自定义CNN训练
def create_model(num_classes):
model = models.Sequential([
layers.Conv2D(32, 3, activation='relu', input_shape=(28, 28, 1)),
layers.MaxPooling2D(),
layers.Conv2D(64, 3, activation='relu'),
layers.MaxPooling2D(),
layers.Flatten(),
layers.Dense(128, activation='relu'),
layers.Dropout(0.5),
layers.Dense(num_classes, activation='softmax')
])
return model

model = create_model(10)
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])

# 加载MNIST数据
mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0
x_train = x_train[..., tf.newaxis]
x_test = x_test[..., tf.newaxis]

# 训练
model.fit(x_train, y_train, epochs=5,
validation_data=(x_test, y_test))

文本分类

import tensorflow as tf
from tensorflow.keras import layers
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences

# 数据
texts = ['This is positive', 'This is negative', ...]
labels = [1, 0, ...]

# 文本向量化
tokenizer = Tokenizer(num_words=10000)
tokenizer.fit_on_texts(texts)
sequences = tokenizer.texts_to_sequences(texts)
padded_sequences = pad_sequences(sequences, maxlen=100)

# 模型
model = tf.keras.Sequential([
layers.Embedding(10000, 128, input_length=100),
layers.Bidirectional(layers.LSTM(64)),
layers.Dense(32, activation='relu'),
layers.Dense(1, activation='sigmoid')
])

model.compile(optimizer='adam',
loss='binary_crossentropy',
metrics=['accuracy'])

# 训练
model.fit(padded_sequences, np.array(labels), epochs=10)

最佳实践

模型保存与加载

# 保存整个模型
model.save('model.h5')

# 加载模型
loaded_model = tf.keras.models.load_model('model.h5')

# 只保存权重
model.save_weights('weights.h5')
model.load_weights('weights.h5')

# 保存为SavedModel格式
tf.saved_model.save(model, 'saved_model/')

# 加载SavedModel
loaded_model = tf.keras.models.load_model('saved_model/')

性能优化

# 1. 混合精度
tf.keras.mixed_precision.set_global_policy('mixed_float16')

# 2. XLA编译
model.compile(optimizer='adam', loss='mse', jit_compile=True)

# 3. 数据预取
dataset = dataset.prefetch(tf.data.AUTOTUNE)

# 4. 分布式训练
strategy = tf.distribute.MirroredStrategy()
with strategy.scope():
model = create_model()
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy')

调试技巧

# 1. 打印模型结构
model.summary()

# 2. 可视化模型
tf.keras.utils.plot_model(model, to_file='model.png', show_shapes=True)

# 3. 检查权重
weights = model.get_weights()
for w in weights:
print(w.shape)

# 4. 评估每个批次
model.fit(x_train, y_train, validation_data=(x_val, y_val),
batch_size=32, epochs=1)

# 5. 使用TensorBoard
tensorboard --logdir logs/

总结

TensorFlow 是功能全面的深度学习平台:

核心概念

  • Tensor: 基本数据结构
  • Keras: 高级神经网络API
  • Eager Execution: 即时执行模式
  • Graph: 计算图优化

主要功能

  1. Tensor操作: 创建、运算、自动求导
  2. Keras模型: Sequential、Functional API、自定义模型
  3. 层与激活: Dense、Conv2D、LSTM、激活函数
  4. 损失函数: 回归损失、分类损失、自定义损失
  5. 优化器: SGD、Adam、学习率调度
  6. 数据处理: tf.data、数据增强、预处理层
  7. 训练模型: fit方法、自定义循环、回调函数
  8. 预训练模型: TensorFlow Hub、迁移学习
  9. 部署: TensorFlow Lite、TensorFlow Serving

最佳实践

  1. 使用Keras API快速构建模型
  2. 使用回调函数监控训练
  3. 使用TensorBoard可视化
  4. 利用预训练模型迁移学习
  5. 合理使用数据增强
  6. 保存模型检查点

TensorFlow 2.x 结合了灵活性和易用性,是生产级深度学习的首选平台。