建筑设计专业的网站,公司注册查询重名,运营培训班学费大概多少,wordpress二维码用户登录以下代码源自李沐
自定义模块类
继承module类
继承nn.Module重写构造函数前向传播
class MLP(nn.Module):# 用模型参数声明层。这里#xff0c;我们声明两个全连接的层def __init__(self):# 调用MLP的父类Module的构造函数来执行必要的初始化。# 这样#xff0c;在类实例…以下代码源自李沐
自定义模块类
继承module类
继承nn.Module重写构造函数前向传播
class MLP(nn.Module):# 用模型参数声明层。这里我们声明两个全连接的层def __init__(self):# 调用MLP的父类Module的构造函数来执行必要的初始化。# 这样在类实例化时也可以指定其他函数参数例如模型参数params稍后将介绍super().__init__()self.hidden nn.Linear(20, 256) # 隐藏层self.out nn.Linear(256, 10) # 输出层# 定义模型的前向传播即如何根据输入X返回所需的模型输出def forward(self, X):# 注意这里我们使用ReLU的函数版本其在nn.functional模块中定义。return self.out(F.relu(self.hidden(X)))顺序块 _module的本质是OrderedDict字典 利用enumerate(args)打包索引和module class MySequential(nn.Module):def __init__(self, *args):super().__init__()for idx, module in enumerate(args):# 这里module是Module子类的一个实例。我们把它保存在Module类的成员# 变量_modules中。_module的类型是OrderedDictself._modules[str(idx)] moduledef forward(self, X):# OrderedDict保证了按照成员添加的顺序遍历它们for block in self._modules.values():X block(X)return X参数访问
字典返回
print(net.state_dict())返回所有nn对应的weight和biasprint(net[2].state_dict()):返回第二层的weight和bias
直接访问 biasweight都是nn.Parameter的子类 例如 使用nn.bias返回的是nn.parameter使用nn.bias.data返回的是bias具体的数值
自定义层
含参数的自定义层 层的构造函数输入和输出单元个数 注意套上nn.Parameter 注意定义好forward函数 class MyLinear(nn.Module):def __init__(self, in_units, units):super().__init__()self.weight nn.Parameter(torch.randn(in_units, units))self.bias nn.Parameter(torch.randn(units,))def forward(self, X):linear torch.matmul(X, self.weight.data) self.bias.datareturn F.relu(linear)*数据预处理
这一部分从李沐中学到了很多新函数和操作技巧
选择部分行 排除某些行使用python的列表递推式 features[i for i in data.columns if not in Sale Price]选择数值型变量 dtype返回一个Series对每一个Series进行条件索引最后返回符合条件的index作为dataframe的索引 numeric_features all_features.dtypes[all_features.dtypes ! object].index
all_features[numeric_features] all_features[numeric_features].apply(lambda x: (x - x.mean()) / (x.std()))热编码 dummy_naTrue给nan也分个类型 all_features pd.get_dummies(all_features, dummy_naTrue)数据转换为dataset和dataloader dataset是torch的数据存储单位 dataloader是torch的数据处理器本质上是一个迭代器可以用于随机抽样返回batch_size大小的数据(打包返回)和与之对应的标签 *args将多个数据打包为元组 def load_array(data_arrays, batch_size, is_trainTrue):Construct a PyTorch data iterator.sDefined in :numref:sec_linear_concisedataset data.TensorDataset(*data_arrays)return data.DataLoader(dataset, batch_size, shuffleis_train)训练函数train
神经网络、数据集、测试集、学习率、衰减率、批量大小train_iter将数据转换为dataloaderX是数据y是标签
def train(net, train_features, train_labels, test_features, test_labels,num_epochs, learning_rate, weight_decay, batch_size):train_ls, test_ls [], []train_iter d2l.load_array((train_features, train_labels), batch_size)# 这里使用的是Adam优化算法optimizer torch.optim.Adam(net.parameters(),lr learning_rate,weight_decay weight_decay)for epoch in range(num_epochs):for X, y in train_iter:optimizer.zero_grad()l loss(net(X), y)l.backward()optimizer.step()train_ls.append(log_rmse(net, train_features, train_labels))if test_labels is not None:test_ls.append(log_rmse(net, test_features, test_labels))return train_ls, test_lsK折交叉验证 总共进行K*nums_epoch次的循环 沿着行拼接tensortorch.cat([y_train, y_part], 0)
如果i等于j选择作为验证集(CV)如果训练集为空生成新的训练集如果训练集不为空拼接新的训练集
def get_k_fold_data(k, i, X, y):assert k 1fold_size X.shape[0] // kX_train, y_train None, Nonefor j in range(k):idx slice(j * fold_size, (j 1) * fold_size)X_part, y_part X[idx, :], y[idx]if j i:X_valid, y_valid X_part, y_partelif X_train is None:X_train, y_train X_part, y_partelse:X_train torch.cat([X_train, X_part], 0)y_train torch.cat([y_train, y_part], 0)return X_train, y_train, X_valid, y_validdef k_fold(k, X_train, y_train, num_epochs, learning_rate, weight_decay,batch_size):train_l_sum, valid_l_sum 0, 0for i in range(k):data get_k_fold_data(k, i, X_train, y_train)net get_net()train_ls, valid_ls train(net, *data, num_epochs, learning_rate,weight_decay, batch_size)train_l_sum train_ls[-1]# 取最小的损失valid_l_sum valid_ls[-1]if i 0:d2l.plot(list(range(1, num_epochs 1)), [train_ls, valid_ls],xlabelepoch, ylabelrmse, xlim[1, num_epochs],legend[train, valid], yscalelog)print(f折{i 1}训练log rmse{float(train_ls[-1]):f}, f验证log rmse{float(valid_ls[-1]):f})return train_l_sum / k, valid_l_sum / k训练预测
preds net(test_features).detach().numpy()tensor转换为numpy前使用detach pd.concat:接受两个numpy数组或者dataframe注意索引不会重复添加
def train_and_pred(train_features, test_features, train_labels, test_data, num_epochs, lr, weight_decay, batch_size):net get_net()train_ls, _ train(net, train_features, train_labels, None, None, num_epochs, lr, weight_decay, batch_size)d2l.plot(np.arange(1, num_epochs 1), [train_ls], xlabelepoch,ylabellog rmse, xlim[1, num_epochs], yscalelog)print(flr:{weight_decay:.2f},训练log rmse{float(train_ls[-1]):f})# 将网络应用于测试集。preds net(test_features).detach().numpy()# 将其重新格式化以导出到Kaggletest_data[SalePrice] pd.Series(preds.reshape(1, -1)[0])# 返回一个一维数组用于拼接submission pd.concat([test_data[Id], test_data[SalePrice]], axis1)#submission.to_csv(submission.csv, indexFalse)# 不存储indextorch的存取
操作函数torch.save()
tensor的保存
y torch.zeros(4)
torch.save([x, y],x-files)
x2, y2 torch.load(x-files)
(x2, y2)mydict {x: x, y: y}
torch.save(mydict, mydict)
mydict2 torch.load(mydict)
mydict2*模型的保存
torch不是很好支持模型的定义存储我们只需要存储模型的参数最后克隆定义就好
torch.save(net.state_dict(), mlp.params) load_state_dict(torch.load(mlp.params))
clone MLP()
clone.load_state_dict(torch.load(mlp.params))
clone.eval()下一次直接调用clone(X)作为预测就好了
迁移学习
下载训练好的resnet18
finetune_net torchvision.models.resnet18(pretrainedTrue)
finetune_net.fc nn.Linear(finetune_net.fc.in_features, 2)# 修改输出层参数
nn.init.xavier_uniform_(finetune_net.fc.weight);# 重新初始化输出层对于靠近输入的层变化应该小一点对于输出的层变化应该大一点。 可以从net.named_parameters()中选取不同学习率的优化器。
if param_group:params_1x [param for name, param in net.named_parameters()if name not in [fc.weight, fc.bias]]trainer torch.optim.SGD([{params: params_1x},{params: net.fc.parameters(),lr: learning_rate * 10}],lrlearning_rate, weight_decay0.001)图像增广
图像增广可以提高数据集的多样性增强模型的泛化能力
翻转和裁剪
[左右翻转图像]通常不会改变对象的类别。这是最早且最广泛使用的图像增广方法之一。 接下来我们使用transforms模块来创建RandomFlipLeftRight实例这样就各有50%的几率使图像向左或向右翻转。 torchvision.transforms.RandomHorizontalFlip() torchvision.transforms.RandomVerticalFlip() 下面的代码将[随机裁剪]一个面积为原始面积10%到100%的区域该区域的宽高比从0.52之间随机取值。 然后区域的宽度和高度都被缩放到200像素。 在本节中除非另有说明 a a a和 b b b之间的随机数指的是在区间 [ a , b ] [a, b] [a,b]中通过均匀采样获得的连续值。
torchvision.transforms.RandomResizedCrop( (200, 200), scale(0.1, 1), ratio(0.5, 2)
改变颜色
另一种增广方法是改变颜色。 我们可以改变图像颜色的四个方面亮度、对比度、饱和度和色调。 在下面的示例中我们[随机更改图像的亮度]随机值为原始图像的50% 1 − 0.5 1-0.5 1−0.5到150% 1 0.5 10.5 10.5之间。 torchvision.transforms.ColorJitter( brightness0.5, contrast0.5, saturation0.5, hue0.5 最后使用transform类进行增广
train_augs torchvision.transforms.Compose([torchvision.transforms.RandomHorizontalFlip(),torchvision.transforms.ToTensor()])