跳到主要内容

TensorFlow 速查表

本页面汇总了 TensorFlow 开发中最常用的语法和知识点,方便快速查阅。

张量操作

创建张量

import tensorflow as tf

# 常量张量
tf.constant([1, 2, 3]) # 从列表创建
tf.constant([[1, 2], [3, 4]]) # 矩阵
tf.constant(0, shape=[2, 3]) # 指定形状

# 变量
tf.Variable([1.0, 2.0, 3.0])
tf.Variable(initial_value=tf.zeros([3, 4]))

# 特殊张量
tf.zeros([2, 3]) # 全零
tf.ones([2, 3]) # 全一
tf.fill([2, 3], 9) # 填充值
tf.eye(3) # 单位矩阵

# 随机张量
tf.random.uniform([2, 3], 0, 1) # 均匀分布
tf.random.normal([2, 3], 0, 1) # 正态分布
tf.random.truncated_normal([2, 3]) # 截断正态

# 类型转换
tf.cast(x, tf.float32)
tf.convert_to_tensor(np_array)

张量属性

x.shape       # 形状
x.dtype # 数据类型
x.ndim # 维度数
x.numpy() # 转 NumPy

张量运算

# 基本运算
tf.add(a, b) # 加法
tf.subtract(a, b) # 减法
tf.multiply(a, b) # 逐元素乘法
tf.divide(a, b) # 除法
tf.pow(a, 2) # 幂运算
tf.sqrt(a) # 平方根

# 矩阵运算
tf.matmul(a, b) # 矩阵乘法
a @ b # 矩阵乘法(简写)
tf.transpose(a) # 转置
tf.linalg.inv(a) # 逆矩阵
tf.linalg.det(a) # 行列式

# 归约运算
tf.reduce_sum(x) # 求和
tf.reduce_mean(x) # 均值
tf.reduce_max(x) # 最大值
tf.reduce_min(x) # 最小值
tf.reduce_sum(x, axis=0) # 按轴求和
tf.reduce_sum(x, keepdims=True) # 保持维度

# 其他操作
tf.reshape(x, [2, 3]) # 改变形状
tf.squeeze(x) # 去除大小为1的维度
tf.expand_dims(x, axis=0) # 扩展维度
tf.concat([a, b], axis=0) # 拼接
tf.stack([a, b], axis=0) # 堆叠
tf.split(x, 3) # 分割

索引和切片

x[0]              # 第一个元素
x[-1] # 最后一个元素
x[1:3] # 切片
x[:, 0] # 第一列
x[::2] # 步长为2
x[::-1] # 反转
tf.gather(x, [0, 2]) # 按索引收集

自动微分

# 基本用法
x = tf.Variable(3.0)
with tf.GradientTape() as tape:
y = x ** 2
grad = tape.gradient(y, x) # 6.0

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

# 高阶导数
with tf.GradientTape() as tape2:
with tf.GradientTape() as tape1:
y = x ** 3
dy = tape1.gradient(y, x)
d2y = tape2.gradient(dy, x)

# persistent 模式(多次调用 gradient)
with tf.GradientTape(persistent=True) as tape:
y = x ** 2
z = x ** 3
dy = tape.gradient(y, x)
dz = tape.gradient(z, x)

# 监视常量
x = tf.constant(3.0)
with tf.GradientTape() as tape:
tape.watch(x)
y = x ** 2

# 梯度裁剪
tf.clip_by_value(grad, -1, 1) # 按值裁剪
tf.clip_by_norm(grad, clip_norm=1.0) # 按范数裁剪
tf.clip_by_global_norm(grads, 1.0) # 全局范数裁剪

Keras 模型

Sequential API

from tensorflow import keras
from tensorflow.keras import layers

model = keras.Sequential([
layers.Dense(64, activation='relu', input_shape=(784,)),
layers.Dropout(0.5),
layers.Dense(10, activation='softmax')
])

Functional API

inputs = keras.Input(shape=(784,))
x = layers.Dense(64, activation='relu')(inputs)
x = layers.Dense(32, activation='relu')(x)
outputs = layers.Dense(10, activation='softmax')(x)
model = keras.Model(inputs=inputs, outputs=outputs)

# 多输入
input_a = keras.Input(shape=(100,))
input_b = keras.Input(shape=(100,))
x = layers.Concatenate()([input_a, input_b])
outputs = layers.Dense(10)(x)
model = keras.Model(inputs=[input_a, input_b], outputs=outputs)

# 多输出
inputs = keras.Input(shape=(784,))
x = layers.Dense(64)(inputs)
output_a = layers.Dense(10, name='classification')(x)
output_b = layers.Dense(1, name='regression')(x)
model = keras.Model(inputs=inputs, outputs=[output_a, output_b])

Model 子类化

class MyModel(keras.Model):
def __init__(self):
super().__init__()
self.dense1 = layers.Dense(64, activation='relu')
self.dense2 = layers.Dense(10, activation='softmax')

def call(self, inputs):
x = self.dense1(inputs)
return self.dense2(x)

model = MyModel()

常用层

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

# 卷积层
layers.Conv2D(32, 3, padding='same', activation='relu')
layers.Conv2D(64, 3, strides=2, activation='relu')

# 池化层
layers.MaxPooling2D(2)
layers.AveragePooling2D(2)
layers.GlobalAveragePooling2D()

# 正则化
layers.Dropout(0.5)
layers.BatchNormalization()

# 展平和重塑
layers.Flatten()
layers.Reshape((28, 28, 1))

# 嵌入层
layers.Embedding(1000, 64)

# 循环层
layers.LSTM(64, return_sequences=True)
layers.GRU(64)

编译和训练

编译模型

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

# 自定义参数
model.compile(
optimizer=keras.optimizers.Adam(learning_rate=0.001),
loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=[keras.metrics.SparseCategoricalAccuracy()]
)

训练模型

# 基本训练
history = model.fit(
x_train, y_train,
epochs=10,
batch_size=32,
validation_split=0.1
)

# 使用验证数据
history = model.fit(
x_train, y_train,
epochs=10,
validation_data=(x_val, y_val)
)

# 使用 tf.data
train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
train_dataset = train_dataset.batch(32).shuffle(10000)
history = model.fit(train_dataset, epochs=10)

回调函数

callbacks = [
# 早停
keras.callbacks.EarlyStopping(
monitor='val_loss',
patience=5,
restore_best_weights=True
),
# 保存最佳模型
keras.callbacks.ModelCheckpoint(
'best_model.keras',
monitor='val_loss',
save_best_only=True
),
# 学习率衰减
keras.callbacks.ReduceLROnPlateau(
factor=0.5,
patience=3
),
# TensorBoard 日志
keras.callbacks.TensorBoard('./logs'),
# 学习率调度
keras.callbacks.LearningRateScheduler(
lambda epoch: 0.001 * 0.9 ** epoch
)
]

model.fit(x_train, y_train, epochs=10, callbacks=callbacks)

评估和预测

# 评估
loss, accuracy = model.evaluate(x_test, y_test)

# 预测
predictions = model.predict(x_test)
classes = tf.argmax(predictions, axis=1)

常用优化器

keras.optimizers.SGD(learning_rate=0.01, momentum=0.9)
keras.optimizers.Adam(learning_rate=0.001)
keras.optimizers.RMSprop(learning_rate=0.001)
keras.optimizers.AdamW(learning_rate=0.001, weight_decay=0.01)
keras.optimizers.Adagrad(learning_rate=0.01)

常用损失函数

# 分类
'binary_crossentropy' # 二分类
'categorical_crossentropy' # 多分类(one-hot)
'sparse_categorical_crossentropy' # 多分类(整数标签)

# 回归
'mse' # 均方误差
'mae' # 平均绝对误差
'huber_loss'

# 函数形式
keras.losses.BinaryCrossentropy()
keras.losses.CategoricalCrossentropy()
keras.losses.MeanSquaredError()

常用评估指标

['accuracy']
keras.metrics.Precision()
keras.metrics.Recall()
keras.metrics.AUC()
keras.metrics.MeanIoU(num_classes=10)

模型保存和加载

# 保存整个模型
model.save('model.keras')
model.save('saved_model_dir') # SavedModel 格式

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

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

# 只保存配置
config = model.get_config()
model = keras.Model.from_config(config)
json_str = model.to_json()
model = keras.models.model_from_json(json_str)

数据处理

tf.data.Dataset

# 创建数据集
dataset = tf.data.Dataset.from_tensor_slices((x, y))
dataset = tf.data.Dataset.from_tensor_slices({'x': x, 'y': y})

# 常用操作
dataset = dataset.shuffle(10000) # 打乱
dataset = dataset.batch(32) # 分批
dataset = dataset.map(preprocess) # 映射
dataset = dataset.filter(filter_fn) # 过滤
dataset = dataset.take(100) # 取前N个
dataset = dataset.skip(100) # 跳过前N个
dataset = dataset.repeat(10) # 重复
dataset = dataset.prefetch(tf.data.AUTOTUNE) # 预取

# 迭代
for batch_x, batch_y in dataset:
print(batch_x.shape)

数据增强

# 使用 ImageDataGenerator
datagen = keras.preprocessing.image.ImageDataGenerator(
rotation_range=20,
width_shift_range=0.2,
height_shift_range=0.2,
horizontal_flip=True,
zoom_range=0.2
)

# 使用预处理层
augmentation = keras.Sequential([
layers.RandomFlip('horizontal'),
layers.RandomRotation(0.1),
layers.RandomZoom(0.1),
])

GPU 配置

# 查看 GPU
gpus = tf.config.list_physical_devices('GPU')

# 设置 GPU 内存按需增长
for gpu in gpus:
tf.config.experimental.set_memory_growth(gpu, True)

# 限制 GPU 内存
tf.config.set_logical_device_configuration(
gpus[0],
[tf.config.LogicalDeviceConfiguration(memory_limit=4096)]
)

# 使用特定 GPU
with tf.device('/GPU:0'):
result = model(x)

混合精度训练

# 启用混合精度
policy = keras.mixed_precision.Policy('mixed_float16')
keras.mixed_precision.set_global_policy(policy)

# 输出层使用 float32
outputs = layers.Dense(10, dtype='float32')(x)

分布式训练

# 单机多 GPU
strategy = tf.distribute.MirroredStrategy()
with strategy.scope():
model = create_model()
model.compile(...)

# 多机训练
strategy = tf.distribute.MultiWorkerMirroredStrategy()

常见问题排查

梯度为 None

# 检查是否是 Variable
x = tf.Variable(3.0) # 正确
x = tf.constant(3.0) # 需要 tape.watch(x)

# 检查是否在 tape 外计算
with tf.GradientTape() as tape:
y = x ** 2 # 正确
# z = x ** 3 # 错误:在 tape 外

形状不匹配

# 检查形状
print(x.shape)
print(tf.shape(x)) # 动态形状

# 添加维度
x = x[..., tf.newaxis] # 或 tf.expand_dims(x, -1)

# 移除维度
x = tf.squeeze(x)

内存不足

# 减小 batch size
model.fit(x, y, batch_size=16)

# 使用梯度累积
# 启用内存增长
tf.config.experimental.set_memory_growth(gpu, True)

# 使用混合精度
keras.mixed_precision.set_global_policy('mixed_float16')