(十六)只从训练集计算预处理参数
分钟数大约在十到六十,次数在一到七,先把每个特征减去训练均值、再除以训练标准差,便于用相近尺度调整参数。目标页数也按训练目标的均值和标准差处理,预测结束后再还原单位。
# 续写同一文件:training_project/src/readingtorch/data.py
def load_bundle(task, path, seed=7):
path = Path(path)
x, y = read_raw(task, path)
splits = split_indices(y, task, seed)
preprocess = {}
if task == "regression":
# 均值和尺度只从训练样本求出,再原样应用到其余两组。
train_x, train_y = x[splits["train"]], y[splits["train"]]
preprocess = {
"x_mean": train_x.mean(0, keepdim=True),
"x_scale": train_x.std(0, correction=0, keepdim=True).clamp_min(1e-6),
"y_mean": train_y.mean(0, keepdim=True),
"y_scale": train_y.std(0, correction=0, keepdim=True).clamp_min(1e-6),
}
x = (x - preprocess["x_mean"]) / preprocess["x_scale"]
y = (y - preprocess["y_mean"]) / preprocess["y_scale"]
return Bundle(
x, y, splits, preprocess, hashlib.sha256(path.read_bytes()).hexdigest()
)mean(0, keepdim=True) 把样本轴合并,保留 (1,2) 的特征均值,之后可以向所有样本广播。std(..., correction=0) 按本组数据的平均平方偏差开方。clamp_min(1e-6) 给几乎没有变化的特征留下可用除数,常量特征减去均值后仍为零。
假如训练分钟数只有 10、20,均值为 15、标准差为 5,转换后是 -1、1。验证样本为 30 时,继续使用这两个训练统计量,得到 3,而不是重新把验证组也变成均值零。
先拿全体数据计算均值,就已经让验证和测试的信息影响了训练准备,这是一种数据泄漏。代码先划分编号,再只读取训练编号求统计量;检查点把这些统计量一起保存,推理时继续用同一套转换。
source_hash 记录输入文件的 SHA-256 摘要。恢复训练时会比较数据内容,防止把一份训练状态接到已经变化的数据上。