当前位置: 首页 > news >正文

深度学习·Pytorch

以下代码源自李沐

自定义模块类

继承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和bias
  • print(net[2].state_dict()):返回第二层的weight和bias

直接访问

bias,weight都是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_na=True:给nan也分个类型

all_features = pd.get_dummies(all_features, dummy_na=True)

数据转换为dataset和dataloader

dataset是torch的数据存储单位
dataloader是torch的数据处理器,本质上是一个迭代器,可以用于随机抽样,返回batch_size大小的数据(打包返回)和与之对应的标签
*args:将多个数据打包为元组

def load_array(data_arrays, batch_size, is_train=True):"""Construct a PyTorch data iterator.sDefined in :numref:`sec_linear_concise`"""dataset = data.TensorDataset(*data_arrays)return data.DataLoader(dataset, batch_size, shuffle=is_train)

训练函数train

  • 神经网络、数据集、测试集、学习率、衰减率、批量大小
  • train_iter:将数据转换为dataloader,X是数据,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_ls

K折交叉验证

总共进行K*nums_epoch次的循环

沿着行拼接tensor:torch.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_valid
def 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],xlabel='epoch', ylabel='rmse', xlim=[1, num_epochs],legend=['train', 'valid'], yscale='log')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], xlabel='epoch',ylabel='log rmse', xlim=[1, num_epochs], yscale='log')print(f'lr:{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']], axis=1)#submission.to_csv('submission.csv', index=False)# 不存储index

torch的存取

操作函数: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(pretrained=True)
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}],lr=learning_rate, weight_decay=0.001)

图像增广

图像增广可以提高数据集的多样性,增强模型的泛化能力

翻转和裁剪

[左右翻转图像]通常不会改变对象的类别。这是最早且最广泛使用的图像增广方法之一。
接下来,我们使用transforms模块来创建RandomFlipLeftRight实例,这样就各有50%的几率使图像向左或向右翻转。
torchvision.transforms.RandomHorizontalFlip()
torchvision.transforms.RandomVerticalFlip()
下面的代码将[随机裁剪]一个面积为原始面积10%到100%的区域,该区域的宽高比从0.5~2之间随机取值。
然后,区域的宽度和高度都被缩放到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 10.5)到150%( 1 + 0.5 1+0.5 1+0.5)之间。
torchvision.transforms.ColorJitter( brightness=0.5, contrast=0.5, saturation=0.5, hue=0.5


最后使用transform类进行增广

train_augs = torchvision.transforms.Compose([torchvision.transforms.RandomHorizontalFlip(),torchvision.transforms.ToTensor()])

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Java TCP练习1
  • 部署 K8s 图形化管理工具 Dashboard
  • 【与C++的邂逅】--- 类和对象(上)
  • 【数据结构-1】二叉树
  • haproxy负载均衡(twenty-eight day)
  • C# 重载运算符
  • web自动化测试Day5
  • 举例说明自然语言处理(NLP)技术。
  • Web前端:CSS篇(二)背景,文本,链接
  • 【ML】Image Augmentation)的作用、使用方法及其分类
  • UIScrollView 的 pagingEnabled属性(UIScrollView默认一次滑动多少距离?)
  • 掌握SQL的威力:批量更新与删除的艺术
  • 如何在 Windows/Mac/在线/iPhone/Android 上将 PDF 转换为 Word
  • leetcode算法题之N皇后
  • 软件测试要学习的基础知识——黑盒测试
  • 分享的文章《人生如棋》
  • [deviceone开发]-do_Webview的基本示例
  • 【每日笔记】【Go学习笔记】2019-01-10 codis proxy处理流程
  • 【许晓笛】 EOS 智能合约案例解析(3)
  • ES6核心特性
  • extjs4学习之配置
  • JavaScript 是如何工作的:WebRTC 和对等网络的机制!
  • JS字符串转数字方法总结
  • linux学习笔记
  • MySQL主从复制读写分离及奇怪的问题
  • React+TypeScript入门
  • SpriteKit 技巧之添加背景图片
  • tweak 支持第三方库
  • 道格拉斯-普克 抽稀算法 附javascript实现
  • 那些被忽略的 JavaScript 数组方法细节
  • 排序算法学习笔记
  • 浅谈web中前端模板引擎的使用
  • 协程
  • AI又要和人类“对打”,Deepmind宣布《星战Ⅱ》即将开始 ...
  • linux 淘宝开源监控工具tsar
  • RDS-Mysql 物理备份恢复到本地数据库上
  • 如何通过报表单元格右键控制报表跳转到不同链接地址 ...
  • ​14:00面试,14:06就出来了,问的问题有点变态。。。
  • ​LeetCode解法汇总518. 零钱兑换 II
  • # 数仓建模:如何构建主题宽表模型?
  • ###项目技术发展史
  • #162 (Div. 2)
  • #Datawhale AI夏令营第4期#AIGC文生图方向复盘
  • (zt)基于Facebook和Flash平台的应用架构解析
  • (ZT)一个美国文科博士的YardLife
  • (二十三)Flask之高频面试点
  • (四)React组件、useState、组件样式
  • (一)SvelteKit教程:hello world
  • (译)计算距离、方位和更多经纬度之间的点
  • (转) SpringBoot:使用spring-boot-devtools进行热部署以及不生效的问题解决
  • ./configure、make、make install 命令
  • .ai域名是什么后缀?
  • .env.development、.env.production、.env.staging
  • .net 7 上传文件踩坑
  • .NET C# 使用GDAL读取FileGDB要素类