pytorch学习笔记

记录一些课程实验中用到的功能,方便以后回顾

1. 数据准备部分

1.1 数据集划分

torch.utils.data.random_split(dataset, lengths)

eg:

train_dataset,test_dataset = random_split( dataset = dataset, lengths = [6,7])

其中dataset为Dataset类型的数据集,lengths为长度序列。如果希望每次得到相同的划分结果,则可以用torch.manual_seed()函数设置随机数种子。

如果自己新定义了数据集类,务必要重写__len__()方法,否则length会出错

参考自这篇博客

1.2 读取各个文件夹下的数据

os.listdir(path)

eg:

path = "../data/iris"
dirs = os.listdir( path )

有些数据集下载后的格式为多个以类别为名的文件夹,每个文件夹中是同一类的数据。但是在读取数据进行划分的时候,不得不将所有数据都放到一起划分训练集,这就需要用到os.listdir()方法。

listdir()的参数是目标文件夹,该方法会返回path文件夹中的文件或文件夹列表【注意不带前缀,如../data/iris/1文件夹在返回值中为1,因此往往需要结合os.join()方法】

# 应用举例
labels = []
dir_path = "../data/101_ObjectCategories/"
for path in os.listdir(dir_path):
    path_name = os.path.join(dir_path, path)
    for name in os.listdir(path_name):
        file_name = os.path.join(path_name, name)
        labels.append(label)

2. 模型部分

2.1 model.train()的作用

在进行模型训练时,有时会看到代码中出现model.train()。该方法的作用是启用 batch normalization 和 dropout ,如果在训练中用到这技巧,就要在训练之前来一行.train()。

相对的,如果要进行测试,需要关闭BN和Dropout,则需要在测试前调用model.eval()。

 参考这篇博客

2.2 dropout()的用法

dropout让节点以概率p不激活【表现为对应值取0】,可以减少训练量,并降低过拟合的可能性。

通常dropout用在一层网络的定义之后,如下所示:

self.net = nn.Sequential(
    nn.Linear(128 * 6 * 6, 512),
    nn.ReLU(),
    nn.Dropout(p=0.5),
    nn.Linear(512, 256),
    nn.ReLU(),
    nn.Linear(256, 101)
)

2.3 loss.item()

进行模型训练的时候通常还会计算训练的损失,此时就会用到.item()方法,其效果是将一个tensor类型的值转为python的基本数据类型,如果是多个值则需要用.tolist()方法。

此外,计算loss时已经自动对batch_size个数据求过平均了,因此如果是算训练误差还需要将batch_size【即代码中的img.size(0)】乘回来

loss = lossfunc(outputs, label)
# 反向传播求梯度
loss.backward()
# 更新所有参数
optimizer.step()
# item()将单个的tensor类型转为python基本数据类型,多个要用tolist()
# 为什么要乘img.size(0)——计算loss时自动求了平均,乘上batch_size即img.size(0)还原为总损失
train_loss += loss.item() * img.size(0)
train_count += img.size(0)

参考这篇博客

2.4 GPU运行时out of memory

在用cuda跑VGG11时,在train中的output = model(image) 处出现了报错,提示CUDA out of memory

初步尝试:

首先尝试减小batch_size,可是从64减到16,还是提示报错。

第二次尝试:

然后参考这篇博客,在output = model(image)之前加入了一句,变成了如下的结果:

with torch.no_grad():  # 添加这行代码
    output = model(images)  # 再缩进这行
# output = model(images)

此时不再报out of memory的错误,但是出现了另外的错,RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn

第三次尝试:

在查看这篇博客 时,发现了解决办法,在原先计算loss之后加入一句loss.require_grad_(True),这样就成功跑起来啦!

大概的原因是,原先这里需要求梯度,但是用了with torch.no_grad()后显示地关闭了梯度的求解。

with torch.no_grad():  # 添加这行代码
    output = model(images)  # 再缩进这行
loss = loss_func(output, labels).to(device)
loss.requires_grad_(True)   # try

2.5 交叉熵损失函数

        交叉熵损失函数nn.CrossEntropyLoss(pred, label)对pred和label有维度的要求,具体可参考这篇博客

 

3. 分析部分

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值