# Summary
**Batch size** 是指**一次训练中同时处理的样本数量**。
# Cues
# Notes
## 直观理解
想象你是一位老师批改作业:
```
方式1:一本一本改(batch_size = 1)
😫 效率低,但能仔细看每本
方式2:10本一起改(batch_size = 10)
😊 效率适中,能发现共同问题
方式3:100本一起改(batch_size = 100)
😰 效率高,但可能忽略个体差异
```
## 具体例子
### 图像分类任务
```python
# 假设有1000张猫狗图片
total_images = 1000
# batch_size = 32 意味着:
# - 每次取32张图片一起处理
# - 需要 1000/32 ≈ 32次 才能看完所有图片
batch_size = 32
num_batches = total_images // batch_size # 31个完整批次
```
### 代码实现
```python
import torch
from torch.utils.data import DataLoader
# 创建数据集
dataset = YourDataset() # 假设有1000个样本
# 设置batch_size
train_loader = DataLoader(dataset, batch_size=32, shuffle=True)
# 训练循环
for batch_idx, (images, labels) in enumerate(train_loader):
print(f"批次 {batch_idx}:")
print(f" 图片形状: {images.shape}") # [32, 3, 224, 224]
print(f" 标签形状: {labels.shape}") # [32]
# 这32张图片会一起:
# 1. 前向传播
# 2. 计算损失
# 3. 反向传播
# 4. 更新参数
```
## 数据形状变化
```python
# 单个样本
image = torch.randn(3, 224, 224) # [通道, 高, 宽]
# 批处理后
batch = torch.randn(32, 3, 224, 224) # [batch_size, 通道, 高, 宽]
# ↑
# 新增的批次维度
```
## 不同Batch Size的影响
### Batch Size = 1(SGD)
```python
for i in range(1000):
x, y = dataset[i] # 取一个样本
loss = model(x) - y
loss.backward() # 每个样本都更新
optimizer.step()
# 优点:更新频繁,能处理在线数据
# 缺点:噪声大,训练不稳定,GPU利用率低
```
### Batch Size = 32(Mini-batch)
```python
for batch in dataloader: # 每批32个
x, y = batch
loss = model(x) - y
loss.backward() # 32个样本的平均梯度
optimizer.step()
# 优点:平衡了效率和稳定性
# 缺点:需要调参找合适的值
```
### Batch Size = 1000(Full Batch)
```python
x, y = dataset[:] # 一次取所有数据
loss = model(x) - y
loss.backward() # 所有样本的精确梯度
optimizer.step()
# 优点:梯度准确,收敛稳定
# 缺点:内存需求大,更新慢,容易陷入局部最优
```
## 实际例子:训练过程
```python
# 假设训练MNIST手写数字识别
epochs = 10
batch_size = 64
total_samples = 60000 # MNIST训练集大小
for epoch in range(epochs):
for batch_idx, (images, labels) in enumerate(train_loader):
# images: [64, 1, 28, 28] - 64张28x28的灰度图
# labels: [64] - 64个数字标签
# 前向传播
outputs = model(images) # [64, 10] - 64个样本的10类预测
# 计算损失(64个样本的平均损失)
loss = criterion(outputs, labels)
# 反向传播
loss.backward()
# 更新参数
optimizer.step()
optimizer.zero_grad()
if batch_idx % 100 == 0:
print(f"第{epoch}轮,第{batch_idx}批,损失: {loss.item():.4f}")
```
## Batch Size对内存的影响
```python
# 模型输入: [batch_size, 3, 224, 224]
# 内存使用 ≈ batch_size × 3 × 224 × 224 × 4字节
batch_size = 1: 约 0.6 MB
batch_size = 32: 约 19 MB
batch_size = 128: 约 76 MB
batch_size = 512: 约 304 MB
# GPU显存不够时会报错:
# RuntimeError: CUDA out of memory
```
## 常见Batch Size选择
|任务类型|典型Batch Size|原因|
|---|---|---|
|图像分类|32-256|平衡效率和性能|
|语言模型|8-64|序列长,显存限制|
|BERT微调|16-32|模型大,显存限制|
|GAN训练|64-128|需要足够样本多样性|
|强化学习|32-512|需要足够探索|
## 动态Batch Size
```python
# 学习率预热时使用小batch
warmup_batch_size = 16
# 正常训练时使用大batch
normal_batch_size = 128
# 梯度累积实现大batch效果
accumulation_steps = 4
for i, (x, y) in enumerate(dataloader):
loss = model(x, y) / accumulation_steps
loss.backward()
if (i + 1) % accumulation_steps == 0:
optimizer.step()
optimizer.zero_grad()
```
## 总结
Batch Size就是:
- **定义**:一次处理的样本数量
- **作用**:平衡训练效率和稳定性
- **权衡**:大batch稳定但慢,小batch快但不稳定
- **限制**:主要受显存/内存限制
- **技巧**:可以通过梯度累积等方法灵活调整
就像批改作业,一次改几本需要根据实际情况权衡!