__init__函数和forward函数必须要有,class函数自动执行这两个函数,__init__函数中要定义整个网络中的所有网络层,前馈函数里要根据整个网络把__init__函数中定义的网络层连起来。
class Net(nn.Module): def __init__(self): ... def forward(self,x): ... def ...搭建网络
定义所有要用到的网络层
比喻:制作积木块
- 要注意维度问题,目前我是根据报错调试程序,程序说它需要什么类型的数据我就给他什么类型的数据
def __init__(self):
#使用super()方法调用基类的构造器,即nn.Module.__init__(self)
super(CNN,self).__init__()
# 1 input image channel ,6 output channels,5x5 square convolution kernel
self.conv1=nn.Conv1d(500,12,2)
# 6 input channl,16 output channels,5x5 square convolution kernel
self.conv2=nn.Conv1d(6,16,4)
# an affine operation:y=Wx+b
self.fc1=nn.Linear(32,16)
self.fc2=nn.Linear(16,8)
self.fc3=nn.Linear(8,1)
self.Sigmoid = nn.Sigmoid ()
前馈函数
将__init__函数中定义的各个网络层输入输出衔接起来
比喻:把积木块搭起来,用线串起来
- 网络的输入x,通常数据类型为张量,如果要用cuda并行,记得把x放入gpu
- 全连接层可以和激活函数写在一起,代码简洁并且不会忘写激活函数
def forward(self,x):
# x是网络的输入,然后将x前向传播,最后得到输出
x=torch.Tensor(x).to(device)
x=x.unsqueeze(0) # 输入,根据需要判断是否需要多加维度,比如LSTM、CNN需要三维数据,二维数据进来要多加一个维度
x=self.Sigmoid(self.conv1(x)) # 一个一维卷积层,一个sigmoid层
x=F.max_pool2d(x,(2,2)) # 定义了2x2的池化层
x=self.Sigmoid(self.conv2(x))
x=x.view(-1,self.num_flat_features(x))
x=self.Sigmoid(self.fc1(x))
x=self.Sigmoid(self.fc2(x))
x=self.fc3(x)
return x[0]
def num_flat_features(self,x): # 根据需要,自己定义的方法
size=x.size()[1:] # all dimensions except the batch dimension
num_features=1
for s in size:
num_features*=s
return num_features
查看模型参数
print(Net().parameters())
params=list(Net().parameters())
print(len(params))
for i in range(len(params)):
print(params[i].size())
# print(params[i])
创建模型类的对象,定义损失函数和优化器
model = Net().to(device) loss_function = nn.MSELoss() optimizer = torch.optim.SGD(model.parameters(), lr=0.01)#建立优化器实例 print(model)测试模型性能
这个函数是测试用来测试x_test y_test 数据
def eval(model): # 返回的是这10个 测试数据的平均loss
test_epoch_loss=[]
with torch.no_grad():
optimizer.zero_grad()
for i in range(0,10):
y_pre = model(x_test[i])
y_tru=torch.Tensor([y_test[i]]).to(device)
test_loss = loss_function(y_pre,y_tru)
test_epoch_loss.append(test_loss.item())
return mean(test_epoch_loss)
定义数组分别存放训练和测试的损失,对整个训练过程重复epochs次迭代,每一次迭代中,需要逐个将训练集中的个体放入模型进行训练,
epochs =100
sum_train_epoch_loss=[] # 存储每个epoch 下 训练train数据的loss
sum_test_epoch_loss=[] # 存储每个epoch 下 测试 test数据的loss
for epoch in range(epochs):
epoch_loss=[]
for i in range(0,85):
#清除网络先前的梯度值
optimizer.zero_grad()
y_pred = model(x_train[i])
y_true=torch.Tensor([y_train[i]]).to(device)
#训练过程中,正向传播生成网络的输出,计算输出和实际值之间的损失值
print("y_pred:",y_pred,",y_true:",y_true)
single_loss = loss_function(y_pred,y_true)
epoch_loss.append(single_loss.item())
single_loss.backward()#调用backward()自动生成梯度
optimizer.step()#使用optimizer.step()执行优化器,把梯度传播回每个网络
train_epoch_loss=mean(epoch_loss)
test_epoch_loss=eval(model)#返回的是这10个 测试数据的平均loss
sum_train_epoch_loss.append(train_epoch_loss)
sum_test_epoch_loss.append(test_epoch_loss)
print("epoch:"+str(epoch)+" train_epoch_loss: "+str(train_epoch_loss)+" test_epoch_loss: "+str(test_epoch_loss))



