跳到主要内容

pdf转word

· 阅读需 5 分钟

问题描述

学校的系统要求同时上交 pdf 和 word 版本的论文。latex 写的只能生成 pdf,就有了转 word 需求。通过搜索,先后尝试了 pandoc 的 tex2docx(可以生成,但是格式太简陋),adobe 的在线 pdf 转 word(总体美观,但是公式识别失败)。最后,还是选择了 adobe acrobat DC 本地将 pdf 转成 word,并结合 axmath 的 word 插件,输入公式。

acrobat DC 的使用

当初本科时候就装了这个软件。用它输出 word 有两种模式:

保持流动顺序和保持页面布局。其中,保持流动顺序是让段落顺序和 pdf 一样,转换结果的总页数和 pdf 可能不一致;而保持页面布局是强行让文字位置和 pdf 一样,但是丧失了可编辑性。因为后面还要加公式,所以选择第一种,同时也是默认模式。

初步转换后,大概比 pdf 多了七八页。有很多是空白导致的。现在的 word 很粗糙,里面很多隐藏的分割符,加上 word 各种隐藏 bug,所以要耐心。

页码和目录

学校要求是绪论之前(不包括封面)用罗马数字,绪论之后的正文用阿拉伯数字。把绪论之前编为一节,且每一页指定好页码样式,链接到前一节,这样才能自动编号。在绪论第一页开始新的一节,这样就从 1 开始编号了。页码和目录关系很大。这时候更新一下目录,也包括了绪论之前的内容。只能手动删除掉了。

样式管理

来到文字编辑部分。acrobat 会把文档的标题字体给改了,而且正文段落的缩进还各不相同。如果每一段都设置太麻烦了。所以,从“样式”选项卡修改,可以一劳永逸。首先,选择某个样式的文字,点开样式的修改选项卡,如图:

然后,设置好字体和段落,比如宋体、两端对齐,去除缩进等。勾上自动更新,然后相同样式的所有文字都会应用。

注意这个自动更新,如果后面你想对一些格式微调,那么自动更新会让你的微调作用于全局,所以,建议初步改完后,关掉自动更新。完成这一步后,文档大致美观了。

公式输入

现在市面上所有的 pdf 转 word 工具,识别公式的能力都很垃圾。大致排序就是 adobe 在线>acrobat>其他。adobe 也只能识别一些简单的公式,遇到稍微复杂的也是乱码。mathpix 是图片转 latex 的最强工具,识别率非常高,但是收费。我研一时候,买了 axmath,类似于 mathtype,但是功能更丰富,可以将 latex 转为 word 公式。把 overleaf 的公式复制过来,开一个行内公式,粘贴,整理好格式。删空格会碰到很多奇怪的东西,只要多保存,前后试一试,一般都能解决。

更新

axmath 在将 latex 公式转为 word 格式时,会导致文档其他部分出现空白。非常恶心!

Batch Normalization

· 阅读需 7 分钟

前言

Batch Normalization (BN)层,通过将数据批量归一化(使其分布在 N(0,1)),有下列好处:

缓解了梯度传递问题,使模型适应更大的学习率,加速了训练; 改善了饱和非线性模型不易训练的问题; 还起到了正则化的作用。

可以看出,BN 和之前学到的 Xavier 初始化权重的目的类似,都是使训练更容易。

实现

BN 的公式表达为:

$$\mathrm{BN}(\mathbf{x}) = \boldsymbol{\gamma} \odot \frac{\mathbf{x} - \hat{\boldsymbol{\mu}}_\mathcal{B}}{\hat{\boldsymbol{\sigma}}_\mathcal{B}} + \boldsymbol{\beta}.$$

$gamma$ $beta$都是可学习的参数,它们使得 BN 层像一个只有一个神经元的线性层。

import torch
from torch import nn
from d2l import torch as d2l


def batch_norm(X, gamma, beta, moving_mean, moving_var, eps, momentum):
# 通过is_grad_enabled来判断当前模式是训练模式还是预测模式
if not torch.is_grad_enabled():
# 如果是在预测模式下,直接使用传入的移动平均所得的均值和方差
X_hat = (X - moving_mean) / torch.sqrt(moving_var + eps)
else:
assert len(X.shape) in (2, 4)
if len(X.shape) == 2:
# 使用全连接层的情况,计算特征维上的均值和方差
mean = X.mean(dim=0)
var = ((X - mean) ** 2).mean(dim=0)
else:
# 使用二维卷积层的情况,计算通道维上(axis=1)的均值和方差。
# 这里我们需要保持X的形状以便后面可以做广播运算
mean = X.mean(dim=(0, 2, 3), keepdim=True)
var = ((X - mean) ** 2).mean(dim=(0, 2, 3), keepdim=True)
# 训练模式下,用当前的均值和方差做标准化
X_hat = (X - mean) / torch.sqrt(var + eps)
# 更新移动平均的均值和方差
moving_mean = momentum * moving_mean + (1.0 - momentum) * mean
moving_var = momentum * moving_var + (1.0 - momentum) * var
Y = gamma * X_hat + beta # 缩放和移位
return Y, moving_mean.data, moving_var.data

class BatchNorm(nn.Module):
# num_features:完全连接层的输出数量或卷积层的输出通道数。
# num_dims:2表示完全连接层,4表示卷积层
def __init__(self, num_features, num_dims):
super().__init__()
if num_dims == 2:
shape = (1, num_features)
else:
shape = (1, num_features, 1, 1)
# 参与求梯度和迭代的拉伸和偏移参数,分别初始化成1和0
self.gamma = nn.Parameter(torch.ones(shape))
self.beta = nn.Parameter(torch.zeros(shape))
# 非模型参数的变量初始化为0和1
self.moving_mean = torch.zeros(shape)
self.moving_var = torch.ones(shape)

def forward(self, X):
# 如果X不在内存上,将moving_mean和moving_var
# 复制到X所在显存上
if self.moving_mean.device != X.device:
self.moving_mean = self.moving_mean.to(X.device)
self.moving_var = self.moving_var.to(X.device)
# 保存更新过的moving_mean和moving_var
Y, self.moving_mean, self.moving_var = batch_norm(
X, self.gamma, self.beta, self.moving_mean,
self.moving_var, eps=1e-5, momentum=0.9)
return Y

预测和训练时 BN 层的作用方式不同。主要是因为训练时 BN 层是根据批量数据的均值方差来估计整个数据集的均值方差。训练是用了一个滑动估计下来的保留均值方差,BN 层用它来在测试时归一化。

我的实践

在我的弱光照增强网络中,Unet 结构在卷积层中也大量采用了 BN 层。由于显存的限制(8G),我的 batch_size 是 8,EnlightenGAN 作者设为 32。我的担心是,batch_size 设的太小会不会导致 BN 层失效?chatgpt 的回答是:

即使你的 batch_size 很小,使用批量归一化(Batch Normalization)也是有益的,因为它可以使神经网络训练更加稳定和快速。以下是几个原因: 减少内部协变量偏移(Internal Covariate Shift):内部协变量偏移是指在每一层输入的分布随着网络的训练而发生变化,这会导致网络训练变得困难。批量归一化通过在每个小批量上标准化输入,可以有效地减少内部协变量偏移的影响。 提高梯度传播:批量归一化可以缩小每层的激活值范围,使得梯度更容易传播,从而加快训练速度。 增强正则化:批量归一化可以在每个小批量上对激活进行标准化,这相当于对每个激活值都进行了一定的正则化,从而可以减少过拟合的风险。 虽然 batch_size 较小时批量归一化的效果可能不如 batch_size 较大时显著,但仍然可以提高神经网络的性能。因此,我建议在训练神经网络时,无论 batch_size 的大小,都使用批量归一化。

如果将 batch_size 设置为 1,那么使用批量归一化(Batch Normalization)的效果会受到影响,因为它需要在每个小批量上计算均值和方差来进行标准化。当 batch_size 为 1 时,每个小批量只有一个样本,这样计算出来的均值和方差可能不太准确,因此批量归一化的效果可能会降低。 不过,对于某些特殊的任务或架构,有些人可能会在 batch_size 为 1 时使用批量归一化。这时可以考虑使用“自适应批量归一化”(Adaptive Batch Normalization)或“实例归一化”(Instance Normalization)等变种方法,它们可以在 batch_size 为 1 时进行标准化。但需要注意的是,这些方法可能不如标准批量归一化在大批量数据上的效果好,所以在选择是否使用它们时需要根据具体情况进行权衡。

所以,应该还是可以用的。

pytorch装环境

· 阅读需 3 分钟

问题描述

跟李沐学 AI,装环境时,发现无论是本地,还是切到 colab,都出现环境问题。甚至还有奇葩的要求装 gpu,但是 conda 返回的是 cpu 版本的 pytorch。conda 的包容易过期,pip 的包由容易污染环境,甚至一声不吭地卸掉别的包。国内源还出现找不到特定版本 cuda 的 torch。

只有 whl 安装方式是可靠且高效的。首先,whl 纯手动选择版本,其次,挂了 vpn 的情况下,下载速度很快。以后装深度学习环境,我只去 whl 下载。

cuda 门道

对于有 GPU 的机器,需要下载 cuda 取代。然后输入nvidia-smi查看 cuda 版本。如下:

CUDA 分为两种,驱动 API 和运行 API,驱动 API 指的是指的显卡驱动支持的最高 cuda 版本,我们运行程序时用的是运行 API。图片右上角的是去掉 API,显示 11.2。而运行nvcc -V查看运行 API:

10.2. 所以驱动 API 一般高于运行 API。但是,当我们用 conda 虚拟环境时,还有另外一种情况:

这是平时我们所说的 CUDA 版本,由于运行 API 在 CUDA 里的 CUDA Toolkit 工具包中,所以运行 API 版本也是 CUDA Toolkit 工具包的版本。其实装了 Anaconda 之后 Anaconda 也会提供一个 cudatoolkit 工具包,同样包含了 CUDA 的运行 API,可以用来替代官方 CUDA 的 CUDA Toolkit。这也就是为什么有时候我们通过 nvcc-V 查看的 cuda 版本很低(比如 7.5),但是能成功运行 cuda9.0 的 pytorch 的原因。因为在安装完 anaconda 后,运行 pytorch 代码就会使用 anaconda 的 cudatoolkit,而忽视官方的 CUDA Toolkit,所以我们只需要根据 anaconda 的 cudaoolkit 包的版本来安装相应的 pytorch 即可。

conda list查看 cudatoolkit 的版本。这里是 10.2。最终确定要安装的 torch+torchaudio+torchvision 组合一定要是 cuda10.

whl 安装

whl 的网站:https://download.pytorch.org/whl/cu102 。打开搜索,以 torch 为例,输入 torch,找对 python 和操作系统版本,开梯子,下载。然后,在本地命令行内,激活虚拟环境,然后切到下载目录,运行pip install 包名

卷积

· 阅读需 2 分钟

前言

我的研究生方向是图像处理,也用到了深度学习工具,所以这部分相对熟悉一些。在学习过程中,也发现了一些以前没有注意到的知识,比如卷积这个词是怎么从数学转到神经网络的一种操作的。

感受野

卷积核是在局部窗口内操作的,所以,卷积核的大小反映了学习到的范围。浅层的时候,卷积核的感受野只有图像的一小部分;随着网络的变深,后面的卷积核能看到前面的,其感受野最终能大等于整张图。

填充和步幅

目前图像处理最常用的卷积核大小、填充和步幅组合是(3,1,1)。这样的卷积不会使输出特征图的尺寸发生变化。如果要使图像的尺寸缩小,还可以用池化层。

填充可以增加输出的高度和宽度。这常用来使输出与输入具有相同的高和宽。步幅可以减小输出的高和宽,例如输出的高和宽仅为输入的高和宽的 1/𝑛(𝑛 是一个大于 1 的整数)。

pytorch的基本使用

· 阅读需 4 分钟

之前我们有大量的从零实现一层网络,现在借用先进的pytorch框架,让很多功能得到封装,可以快捷的组建一个块。

nn.Module

nn.Module是pytorch一切网络的祖宗。例如,可以用nn.Sequential()搭建,也可以新写一个类:

class net(nn.Module):
def __init__(self):
super.__init__()
...

def forward(self, x):
...

nn.Sequential和net类都是继承于nn.Module。

参数管理

参数的访问用state_dict()函数:

print(net[2].state_dict())
OrderedDict([('weight', tensor([[ 0.3016, -0.1901, -0.1991, -0.1220,  0.1121, -0.1424, -0.3060,  0.3400]])), ('bias', tensor([-0.0291]))])

每一种参数(比如weight)都是一个类,下面包含数值,梯度等属性。比如:

net[2].weight.data, net[2].weight.grad

权重初始化

默认情况下,PyTorch会根据一个范围均匀地初始化权重和偏置矩阵, 这个范围是根据输入和输出维度计算出的。 PyTorch的 nn.init模块提供了多种预置初始化方法。用nn.init:

def init_normal(m):
if type(m) == nn.Linear:
nn.init.normal_(m.weight, mean=0, std=0.01)
nn.init.zeros_(m.bias)
net.apply(init_normal)
net[0].weight.data[0], net[0].bias.data[0]

m就是层的意思,apply函数会将init_normal函数遍历处理所有层。上述代码将所有的全连接层权重初始化为N~(0.0.01)的高斯分布。

共享权重

共享权重似乎在论文中见过很多次,就是将一个子网络训练的过程中,将权重分享给另一个相同结构的子网络。这里给出的,是两个全连接层的参数共享:

# 我们需要给共享层一个名称,以便可以引用它的参数
shared = nn.Linear(8, 8)
net = nn.Sequential(nn.Linear(4, 8), nn.ReLU(),
shared, nn.ReLU(),
shared, nn.ReLU(),
nn.Linear(8, 1))
net(X)
# 检查参数是否相同
print(net[2].weight.data[0] == net[4].weight.data[0])
net[2].weight.data[0, 0] = 100
# 确保它们实际上是同一个对象,而不只是有相同的值
print(net[2].weight.data[0] == net[4].weight.data[0])

创建全新的层

有时候,可能需要创建一个pytorch未实现的层。以自定义一个linear层为例:

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.data
return F.relu(linear)

核心步骤就是在init函数,设置好可以更新的权重,然后再forward函数里面定义计算方式。

权重的保存(checkpoint)

pytorch只能保存权重,而不能连同网络结构一起保存,不过听说tf可以。保存方式是torch.save():

假设要保存参数的对应模型是一个MLP:

class MLP(nn.Module):
def __init__(self):
super().__init__()
self.hidden = nn.Linear(20, 256)
self.output = nn.Linear(256, 10)

def forward(self, x):
return self.output(F.relu(self.hidden(x)))

net = MLP()
X = torch.randn(size=(2, 20))
Y = net(X)
torch.save(net.state_dict(), 'mlp.params') # 保存
net.load_state_dict(torch.load('mlp.params'))  # 加载

数值稳定性和权重初始化

· 阅读需 3 分钟

梯度爆炸和梯度消失问题

梯度爆炸

因为梯度的计算是通过偏导数的链式法则,所以,对于一个很深的网络,反向传播时,计算最后几层的梯度,很可能会超出数值的边界。比如cuda限制了16位的浮点数运算。这时,$1.1^100$超过了数值上界,程序就会报错。

梯度消失

如果某几个中间层的梯度很小,接近于0,那么前面几个层的梯度也是0,权重参数就得不到更新,这就是梯度消失。Sigmoid函数求导后,两头的梯度都接近于0,所以,很容易发生梯度消失。

合理初始化权重

合理初始化权重,可以缓解梯度爆炸和梯度消失问题。合理初始化化权重,就好比在选择一个离终点(最优点)近,且好走的起点。具体做法是,假设每层的输出和权重都满足独立正态分布,且均值、方差都相等。这种假设有以下几个原因(chatgpt):

避免梯度消失或梯度爆炸:如果每一层的输出和权重具有相同的均值和方差,那么它们传递的梯度也会有相同的大小,这可以避免梯度消失或梯度爆炸问题。

提高网络的收敛速度:假设每一层的输出和权重具有相同的均值和方差,可以使网络更容易收敛,因为权重初始化过大或过小可能会使得网络的训练变得非常缓慢。

减少过拟合的可能性:如果权重初始化过大,网络容易出现过拟合现象,而假设每一层的输出和权重具有相同的均值和方差可以避免这种情况的发生。

多层感知机(MLP)

· 阅读需 3 分钟

终于从前面的单层网络linear-regression和softmax过渡到多层神经网络了。为了对更加复杂的数据进行学习,多层感知机将多个全连接层叠加,并增加激活函数。激活函数是非线性的,因为如果不加激活函数或者激活函数线性,那么多层神经网络还是遵循线性规律,等同于一层。

多层感知机

中间的,就是隐藏层。所以,多加的隐藏层中神经元的个数也是一个超参数。

从零实现代码

import torch
from torch import nn
from d2l import torch as d2l

batch_size=256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
num_inputs, num_outputs, num_hiddens = 784, 10, 784

W1 = nn.Parameter(torch.randn(num_inputs, num_hiddens, requires_grad=True) * 0.01)
b1 = nn.Parameter(torch.zeros(num_hiddens, requires_grad=True))
W2 = nn.Parameter(torch.randn(num_hiddens, num_outputs, requires_grad=True) * 0.01)
b2 = nn.Parameter(torch.zeros(num_outputs, requires_grad=True))

params = [W1, b1, W2, b2]
def relu(X):
a = torch.zeros_like(X)
return torch.max(X, a)
def net(X):
X = X.reshape((-1, num_inputs))
H = relu(X@W1 + b1)
return (H@W2 + b2)
loss = nn.CrossEntropyLoss(reduction='none')
num_epochs, lr = 10, 0.1
updater = torch.optim.SGD(params, lr=lr)
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, updater)
d2l.predict_ch3(net, test_iter, n=20)

利用pytorch api实现

import torch
from torch import nn
from d2l import torch as d2l
## 网络搭建
net = nn.Sequential(nn.Flatten(),
nn.Linear(784, 256),
nn.ReLU(),
nn.Linear(256, 10))

## 初始化权重
def init_weights(m):
if type(m)==nn.Linear:
nn.init.normal_(m.weight, std=0.01)

net.apply(init_weights);
## 超参数设置
batch_size, lr, num_epochs = 256, 0.1, 10
## 损失函数
loss = nn.CrossEntropyLoss(reduction='none')
## 优化器
trainer = torch.optim.SGD(net.parameters(), lr=lr)
## 加载数据(dataloader)
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
## 正式训练
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, trainer)

总结

深度学习代码编写步骤:

网络搭建-》初始化权重-》超参数设置-》损失函数-》优化器-》加载数据-》正式训练

softmax回归(分类)

· 阅读需 2 分钟

回归和分类

机器学习(深度学习)的任务纷繁复杂。最基础的是回归和分类。回归是预测连续值,分类是预测离散类别。

分类问题是多输出,因此,训练标签和模型(网络)的输出应该是多维的。独热编码 (one-hot encoding)是一种表示多分类的方式。就是在一个向量中,将真实分类索引下的值设为 1,其他是 0,因此向量自身的内积为 1。另外,模型的线性表示为:

所以,softmax 也是一个单层全连接网络。


\begin{aligned}
o*1 &= x_1 w*{11} + x*2 w*{12} + x*3 w*{13} + x*4 w*{14} + b*1,\\
o_2 &= x_1 w*{21} + x*2 w*{22} + x*3 w*{23} + x*4 w*{24} + b*2,\\
o_3 &= x_1 w*{31} + x*2 w*{32} + x*3 w*{33} + x*4 w*{34} + b_3.
\end{aligned}

softmax 函数

分类问题的训练,可以用最大化正确分类的概率来表示。因此,要通过 softmax 函数将神经网络的输出$o_i$转化为 0-1 之间的概率。

\begin{equation}
\hat{\mathbf{y}} = \mathrm{softmax}(\mathbf{o})\quad \text{其中}\quad \hat{y}_j = \frac{\exp(o_j)}{\sum_k \exp(o_k)}
\end{equation}

softmax 可以保证输出在 0-1 之间,且 softmax 可导。

线性回归

· 阅读需 4 分钟

线性回归

一句话表示,就是数据的分布是按照如下的线性表达式:

$$ y=w_1x_1+w_2x_2+...+w_nx_n+b $$

$w_n$就是网络的权重(参数),b 也是一种权重。

代码实现

import random
import torch
from d2l import torch as d2l
## 自动生成数据集
def synthetic_data(w, b, num_examples):
X = torch.normal(0, 1, (num_examples, len(w)))
y = torch.matmul(X, w) + b
y += torch.normal(0, 0.01, y.shape)
return X, y.reshape(-1, 1)

true_w = torch.tensor([2, -3.4])
true_b = 4.2
features, labels = synthetic_data(true_w, true_b, 1000)
features.shape, labels.shape

(torch.Size([1000, 2]), torch.Size([1000, 1]))

def data_iter(batch_size,features,labels):
num_examples=len(features)
indices=list(range(num_examples))
#这些样本是随机读取的,没有特定的顺序
random.shuffle(indices)
for i in range(0,num_examples,batch_size):
batch_indices=torch.tensor(indices[i:min(i+batch_size,num_examples)])
yield features[batch_indices],labels[batch_indices]
batch_size=10
for X,y in data_iter(batch_size,features,labels):
print(X,'\n',y)
break

tensor([[-1.2750, 1.5482], [-0.0563, -2.0593], [-0.3648, -0.0083], [ 0.2933, 0.3219], [-0.6043, -0.0551], [-1.1544, -0.0258], [ 0.9690, -0.7872], [ 0.7860, 0.0937], [ 0.9102, -0.6743], [ 1.6593, 0.3044]]) tensor([[-3.5984], [11.0968], [ 3.5161], [ 3.6972], [ 3.1954], [ 1.9791], [ 8.8084], [ 5.4522], [ 8.3228], [ 6.4840]])

w = torch.normal(0, 0.01, size=(2, 1), requires_grad=True)
b = torch.zeros(1, requires_grad=True)
## 网络模型
def linreg(X, w, b):
return torch.matmul(X, w) + b
## 损失函数
def squared_loss(y_hat, y):
return (y_hat - y.reshape(y_hat.shape))**2/2
## 优化算法(用来更新网络参数)
def sgd(params, lr, batch_size):
with torch.no_grad():
for param in params:
param -= lr * param.grad / batch_size
param.grad.zero_()
## 训练代码
lr = 0.03
num_epochs = 3
net = linreg
loss = squared_loss

for epoch in range(num_epochs):
for X, y in data_iter(batch_size, features, labels):
l = loss(net(X, w, b), y)
l.sum().backward()
sgd([w, b], lr, batch_size)
with torch.no_grad():
train_l = loss(net(features, w, b), labels)
print(f'open {epoch+1}, loss {float(train_l.mean())}')

open 1, loss 5.805317050544545e-05 open 2, loss 5.791278090327978e-05 open 3, loss 5.7983954320661724e-05

print(f'w的估计误差:{true_w-w.reshape(true_w.shape)}')
print(f'b的估计误差:{true_b-b}')

w的估计误差:tensor([-2.5511e-05, -1.8573e-04], grad_fn=<SubBackward0>) b的估计误差:tensor([0.0001], grad_fn=<RsubBackward1>)

文字说明

所有深度学习训练过程都可以用四个步骤概括:1.前向传播(输入到网络),2.计算损失(损失函数可导,且损失函数的值必须是标量),3.计算梯度(用于下一步的更新参数。backward()),4.更新网络参数(这里用的是 SGD)

SGD

gpt:

随机梯度下降(Stochastic Gradient Descent,SGD)是一种常用的优化算法,常用于机器学习中的参数优化问题。在传统的梯度下降算法中,每次更新模型参数需要遍历整个训练集,计算所有样本的梯度平均值,这样的计算代价很大,尤其是在大规模数据集上。SGD 算法通过每次从训练集中随机选择一个样本进行梯度计算和模型参数更新,降低了计算代价,加快了模型收敛速度。此外,SGD 还可以避免陷入局部最优解,使得模型更有可能达到全局最优解。

然而,SGD 也有一些缺点,如对于数据的噪声敏感、容易受到初始点的影响等。因此,在实践中,常常使用一些改进的 SGD 算法,如动量优化、Adagrad、Adam 等来克服这些缺点。

这段话里面。SGD 每次应该不一定只选择一个样本,而是若干个样本。这也因此引入了 batch_size 的概念。batch_size 就是每次计算梯度时选取样本的数量。

动手pytorch

· 阅读需 1 分钟

这个系列记录我跟随 B 站上李沐的《动手学深度学习》的视频教程。每五个章节的笔记合成一篇 blog。

安装环境

我的学习平台时 win11, powershell, anaconda

conda create -n d2l-zh python=3.8
conda activate d2l-zh
pip install jupyter d21 torch torchvision
jupyter notebook

激活了 jupyter notebook。可以实时演示效果,适合初学时做一些 demo。

bug fix

使用 powershell 时,出现了红字错误:

. : File C:\Users\lfy\Documents\WindowsPowerShell\profile.ps1 cannot be loaded because running scripts is disabled on t
his system. For more information, see about_Execution_Policies at https:/go.microsoft.com/fwlink/?LinkID=135170.
At line:1 char:3
+ . 'C:\Users\lfy\Documents\WindowsPowerShell\profile.ps1'
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : SecurityError: (:) [], PSSecurityException
+ FullyQualifiedErrorId : UnauthorizedAccess

询问 chatgpt 后,这是 powershell 设立的脚本运行安全策略。解决方案是:

Set-ExecutionPolicy RemoteSigned