pytorch实现线性拟合
Contents
安装pytorch
我们以英伟达显卡为例,我们需要知道自己电脑对应cuda版本信息:
在控制台输入nvidia-smi我们可以看到对应cuda版本的信息内容:
从上图中,我们可知:当前我们CUDA的版本是11.2,之后我们去pytorch官方网页 查询对应pytorch的版本信息,按照给出的安装命令信息安装即可。
由于pytorch官网并没有cuda11.2的安装方法,所以我选择安装cuda11.1的环境
1
pip install torch==1.9.1+cu111 torchvision==0.10.1+cu111 torchaudio==0.9.1 -f https://download.pytorch.org/whl/torch_stable.html
我们可以通过一下代码来判断pytorch是否已经正确安装以及识别到显卡驱动
|
|
执行结果如下:
编写代码
现在我们可以进行代码编写过程了
构造数据集,我们假设拟合的结果是 $$ y=w_1\times x_1 + w_2\times x_2 + b\\ 即y=\begin{bmatrix} w_1 & w_2 \\ \end{bmatrix} \begin{bmatrix} x_1\\ x_2\\ \end{bmatrix}+b $$ 为了能够体现机器学习拟合的有效性,我们在生成数据点时会增加一些噪声,从而体现出数据的混乱
代码实现:
1 2 3 4 5 6 7 8 9 10
def synthetic_data(w, b, num_examples): """生成 y = Xw + b + 噪声。""" X = torch.normal(0, 1, (num_examples, len(w))) # X是均值为0,方差为1的随机数。有num_examples个样本,列就是len(w) y = torch.matmul(X, w) + b # Y是X与w的乘积(matmul == mm,矩阵相乘)加上偏差b y += torch.normal(0, 0.01, y.shape) # 加入一个噪音,均值为0,方差为0.01,形状与y相同 return X, y.reshape((-1, 1)) # 其中,y返回一个列向量。-1表示自动计算,1表示固定,即列向量为1 true_w = torch.tensor([2, -3.4]) true_b = 4.2 features, labels = synthetic_data(true_w, true_b, 1000)
我们可以绘制图像,用于显示我们构造的数据:
然后我们将数据进行封装成Dataset
1 2 3 4 5 6 7 8 9 10 11 12 13
class LinearDataSet(Dataset): def __init__(self, x, y): self.X = torch.FloatTensor(x) self.Y = torch.FloatTensor(y) def __getitem__(self, index): return self.X[index], self.Y[index] def __len__(self): return len(self.X) trainSet = LinearDataSet(features, labels) trainLoader = DataLoader(trainSet, batch_size=10, shuffle=True, pin_memory=True)
我们现在编写网络,以及编写一个训练过程:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
class LinearNetWork(nn.Module): def __init__(self, n_feature): super(LinearNetWork, self).__init__() self.layers = nn.Sequential( nn.Linear(n_feature, 1) # 定义一个最简单线性全连接层 ) def forward(self, x): y = self.layers(x) return y def Trainer(train_loader: DataLoader, model: LinearNetWork): criterion = nn.MSELoss() # 定义一个均方误差 optimizer = torch.optim.SGD(model.parameters(), lr=0.03) # 定义一个优化器 for i in range(epoch): model.train() for x, y in train_loader: optimizer.zero_grad() # 采用梯度下降,每次训练都需要将梯度信息清零 x, y = x.to(device), y.to(device) pred = model(x) loss = criterion(pred, y) print("loss=", loss.detach().item()) loss.backward() # 梯度回退 optimizer.step() model = LinearNetWork(2).to(device) # 因为我们总共就两个变量,所以我们传入的特征信息为2 Trainer(trainLoader, model) print(model.state_dict())
这样我们一个最简单的神经网络已经构成,我们执行上述代码查看网络每层的信息:
总结
总的来说,这次这个任务还是比较简单的,我们构造一个简单的神经网络,完成了最简单的线性拟合的问题,我们可以在这里面一窥机器学习的基本过程。我们需要获取数据、数据处理、构造网络、进行训练、调整参数,然后不断循环往复,从而得到一个加好的结果。