序言
本次设计一个简单的三层神经网络模型。上一章学习了一个线性的分类模型。但如果数据集无法用一条线、一个面进行分类呢?此时神经网络就有用武之地了。但是本次实验还是用的上次的数据集,有效果就行~
原理与数据集
https://pan.baidu.com/s/1kkZl3Shj6D5djmx0H8ifqw
为什么要标准化,有哪些标准化的方法,详细自行百度。本实验采用常用的简单标准化方法min-max。
详细代码
import torch
import numpy as np
o_data = []
#读取数据
with open('./data.txt','r') as f:
for i in f.readlines():
o_data.append(i.strip('\n').split(','))
data = np.array(o_data,dtype='float32')
#min-max标准化
x_max = data.max(0)
x_min = data.min(0)
data = (data - x_min)/(x_max-x_min)
#数据集 入参、出参
x_train = torch.tensor(data[:,:2]) #(100,2)
y_train = torch.tensor(data[:,-1]).unsqueeze(1)#(100,1)
#定义一个三层的神经网络 输入层 2节点 隐含层 10节点 输出层 1节点 激活函数使用relu
class Net(torch.nn.Module):# 继承 torch 的 Module
def __init__(self, n_feature, n_hidden, n_output):
super(Net, self).__init__() # 继承 __init__ 功能
# 定义每层用什么样的形式
self.hidden = torch.nn.Linear(n_feature, n_hidden) # 隐藏层线性输出
self.predict = torch.nn.Linear(n_hidden, n_output) # 输出层线性输出
def forward(self, x): # 这同时也是 Module 中的 forward 功能
x = self.hidden(x)
x = torch.relu(x) # 隐含层输出 relu sigmod tanh等
x = self.predict(x) # 输出值
x = torch.sigmoid(x) # 输出层输出
return x
net = Net(2,10,1)
print(net)
#反向传播算法 SGD Adam等
optimizer = torch.optim.SGD(net.parameters(),lr=1)
#损失函数
criterion = torch.nn.BCELoss()
for i in range(100):
y_ = net(x_train)
loss = criterion(y_,y_train)
optimizer.zero_grad()
loss.backward()
optimizer.step()
#计算准确率
pre_y = y_.ge(0.5).float()
acc = 1-sum(abs(pre_y-y_train)).squeeze().numpy()/y_train.size(0)
print('epoch: {}, loss: {},acc: {}'.format(i, loss.detach().numpy(), acc))
结果
epoch: 95, loss: 0.23738327622413635,acc: 0.92
epoch: 96, loss: 0.23519432544708252,acc: 0.87
epoch: 97, loss: 0.2386966496706009,acc: 0.92
epoch: 98, loss: 0.23591306805610657,acc: 0.86
epoch: 99, loss: 0.2392745167016983,acc: 0.92