找到全书在附件~指路原下载地址GitHub - datawhalechina/leedl-tutorial: 《李宏毅深度学习教程》(李宏毅老师推荐👍,苹果书🍎),PDF下载地址:https://github.com/datawhalechina/leedl-tutorial/releases
自适应学习率
问题:学习率过大可能造成步长过大总是跳过梯度为0的点,降低学习率降低步长,到达梯度为0的点时,发现是鞍点,可以继续下降,但是此时学习率过小,下降缓慢。
昨天我在想找一找多元函数三阶泰勒展开的矩阵形式怎么写,但是看到这里我们可能会发现计算刚好落在海塞矩阵半正定/负定的点可能太精确以至于不现实,只要能找到下降的方向并且以合适的步伐下降再及时转换方向,可能就可以潦草地继续优化(而且投入产出协调)
解决:梯度陡峭(范数大)学习率小,平坦,学习率大。
1、AdaGrad
学习率=常数/所有梯度的RMS,意味着梯度变大,学习率变小,补偿变小
Question?
2、RMSProp
R for propagation
一步之前的所有梯度信息都包含在之前的学习率(的分母)里,遗忘门 马尔科夫假设
3、+动量:Adam
书上没有特别说明原理,动量指的是这一步的梯度更新不仅考虑这一步的梯度,还考虑上一步的梯度
,我们并没有根据梯度和函数形式(在神经网络中难以写出)计算梯度对应的最优步长,动量生效的隐含假设是在原来的方向上增加步长仍能下降。
Adam教程:
7.8. Adam算法 — 《动手学深度学习》 文档 (gluon.ai)
听说你了解深度学习最常用的学习算法:Adam优化算法? | 机器之心 (jiqizhixin.com)
4、学习率调度
(希望除了图3.22彩虹背景的图以外还有其他优化过程可视化的方法,这个图我一般是不愿意看的TAT)
衰减、退火、预热
RAdam
Batch Normalization
How Does Batch Normalization Help Optimization?1805.11604 (arxiv.org)
Page 70
批量重归一化(batch renormalization)[12]、层归一化(layer normalization)[13]、实例归一化(instance normalization) [14]、组归一化(group normalization)[15]、权重归一化(weight normalization)[16] 和谱归一 化(spectrum normalization)[17]
CNN实践
1、下载代码和数据集(数据集unzip失败可能要手动下载)
git clone https://www.modelscope.cn/datasets/Datawhale/LeeDL-HW3-CNN.git
wget https://www.modelscope.cn/datasets/Datawhale/LeeDL-HW3-CNN/resolve/master/hw3_data.zip
2、一键运行代码
可能有需要手动安装的包:sklearn
from tqdm import tqdm
import numpy as np
import matplotlib.pyplot as plt
from sklearn.manifold import TSNE
import matplotlib.cm as cm
import torch
def forward_to_layer(model, input_tensor, layer_index):
outputs = []
for i, layer in enumerate(model.children()):
input_tensor = layer(input_tensor)
if i == layer_index:
break
outputs.append(input_tensor)
return outputs[-1] # 返回所选层的输出
# 假设model, test_tfm, FoodDataset, DataLoader已经被定义且正确初始化
# 加载由TA定义的验证集
valid_set = FoodDataset("./hw3_data/valid", tfm=test_tfm)
valid_loader = DataLoader(valid_set, batch_size=64, shuffle=False, num_workers=0, pin_memory=True)
# 提取模型特定层的表示
index = 19 # 假设你想提取第19层的特征
features = []
labels = []
# 定义设备
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
for batch in tqdm(valid_loader):
imgs, lbls = batch
imgs, lbls = imgs.to(device), lbls.to(device) # 确保数据在正确的设备上
with torch.no_grad():
# 获取特定层的特征
logits = forward_to_layer(model.cnn, imgs, index)
logits = logits.view(logits.size(0), -1)
labels.extend(lbls.cpu().numpy())
features.extend(logits.cpu().numpy())
# 将features和labels列表转换为numpy数组
features = np.array(features)
labels = np.array(labels)
# 应用t-SNE到特征上
features_tsne = TSNE(n_components=2, init='pca', random_state=42).fit_transform(features)
# 绘制t-SNE可视化图
plt.figure(figsize=(10, 8))
for label in np.unique(labels):
# 使用布尔索引选择特定标签的数据点
mask = (labels == label)
plt.scatter(features_tsne[mask, 0], features_tsne[mask, 1], label=f'Class {label}', s=5)
plt.legend()
plt.title('All Classes t-SNE Visualization')
plt.show()
# 绘制特定类别的t-SNE可视化图
plt.figure(figsize=(10, 8))
selected_label = 5
mask = (labels == selected_label)
if mask.any(): # 使用 .any() 替代 .sum() 来检查是否有True值
plt.scatter(features_tsne[mask, 0], features_tsne[mask, 1], label=f'Class {selected_label}', s=5)
plt.legend()
plt.title(f'Class {selected_label} t-SNE Visualization')
plt.show()