import torch
from matplotlib import pyplot as plt
import numpy as np
import torch.utils.data as Data
import torch.nn as nn
from torch.nn import init
import sys
import torch.optim as optim
sys.path.append("/home/eilab2023/yml/project/limu/")
from d2lzh_pytorch import *
'''
----------------------------------生成数据集----------------------------------------------------
'''
num_inputs = 2
num_examples = 1000
true_w = [2, -3.4]
true_b = 4.2
features = torch.tensor(np.random.normal(0, 1, size=(num_examples, num_inputs)), dtype=torch.float)
labels = true_w[0] * features[:, 0] + true_w[1] * features[:, 1] + true_b
labels += torch.tensor(np.random.normal(0, 0.01, size=labels.size()), dtype=torch.float)
'''
---------------------------------读取数据-------------------------------------------
'''
batch_size = 10
dataset = Data.TensorDataset(features, labels)
data_iter = Data.DataLoader(dataset, batch_size, shuffle=True)
'''
---------------------------------模型定义,分两种---------------------------------------------------
'''
'''
torch.nn 仅支持一个batch大写啊哦的样本输入而不支持单个样本输入
定义方式一 定义类
'''
class LinearNet(nn.Module):
def __init__(self, n_feature):
super(LinearNet, self).__init__()
self.linear = nn.Linear(n_feature, 1)
def forward(self, x):
x = self.linear(x)
return x
net = LinearNet(num_inputs)
'''
定义方式二 使用nn.Sequential搭建网络,Sequential是一个有序容器,网络层将按照在传入Sequential的顺序依次添加进计算图中
'''
net1 = nn.Sequential(
nn.Linear(num_inputs, 1)
)
net2 = nn.Sequential()
net2.add_module('linear', nn.Linear(num_inputs, 1))
from collections import OrderedDict
net3 = nn.Sequential(
OrderedDict([('linear', nn.Linear(num_inputs, 1))])
)
'''
--------------------------------------初始化权重和偏差-----------------------------------------------------------
'''
'''
使用net之前需要预先将模型权重和偏差进行初始化,初始化一般会对其正态分布初始化 可以使用nn模块中的init模块里的normal_方法初始化
当net的定义使用的是自定义类时,网络层的权重访问方式为 net.linear.weight 一个特征对应一个权重
当net的定义方式使用的是Sequential模块,网络层权重访问方式是 net[0].weight
'''
init.normal_(net.linear.weight, mean=0, std=0.01)
init.constant_(net.linear.bias, val=0)
'''
--------------------------------------定义损失函数--------------------------------------------------
损失函数pytorch提供了各种调用函数
'''
loss = nn.MSELoss()
'''
--------------------------------------定义优化算法--------------------------------------------------
torch.optim模块中提供了很多优化算法:SGD,Adam,RMSProp等优化算法
'''
'''
统一设置学习率
'''
optimizer = optim.SGD(net.parameters(), lr=0.01)
'''
为不同网络层设置学习率,finetune经常使用
optimizer_f = optim.SGD([
# 如果对某个参数不指定学习率,就是用最外层的默认学习率
{'params': net.netname1.parameters()}, # lr=0.03
{'params': net.netname2.parameters(), 'lr': 0.01}
], lr=0.03)
'''
'''
动态设置学习率,不固定设置它,方法有两种:
1.修改optimizer.param_groups中对应的学习率
2.新建优化器(推荐做法,但不适合应用于Adam算法)
# 调整学习率
for param_groups in optimizer.param_groups:
param_groups['lr'] *= 0.1 # 学习率变为之前的0.1倍
'''
'''
------------------------------------------训练模型----------------------------------------------
通过调用optim实例的step迭代更新模型参数:权重和偏置
'''
num_epochs = 10
epoch_list = []
loss_list = []
for epoch in range(1, num_epochs + 1):
epoch_list.append(epoch)
for X, y in data_iter:
y_hat = net(X)
ll = loss(y_hat, y.view(y_hat.size()))
optimizer.zero_grad()
ll.backward()
optimizer.step()
loss_list.append(ll.item())
dense = net.linear
print(true_w, dense.weight)
print(true_b, dense.bias)
plt.plot(epoch_list, loss_list)
plt.savefig('路径')